<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Knowledge Base (Posts about mod)</title><link>https://bgstack15.ddns.net/blog/</link><description></description><atom:link href="https://bgstack15.ddns.net/blog/categories/mod.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:bgstack15@gmail.com"&gt;bgstack15&lt;/a&gt; 
&lt;a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.html"&gt;
&lt;img alt="GNU General Public License v3.0"
style="border-width:0; margin-bottom:12px;"
src="https://bgstack15.ddns.net/.images/gplv3-127x51.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Tue, 03 Mar 2026 16:28:18 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Script to stay synced to upstreams for Luanti mods</title><link>https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I added a script to my &lt;a href="https://bgstack15.ddns.net/blog/posts/2026/02/15/initialize-mineclonia-git-repo/"&gt;repo for initializing a Mineclonia installation&lt;/a&gt; that uses a separate location to synchronize my local repositories to the upstream paths, if they still exist.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/files/2026/listings/mod-upstreams.sh.html"&gt;files/2026/listings/mod-upstreams.sh&lt;/a&gt;  &lt;a href="https://bgstack15.ddns.net/blog/files/2026/listings/mod-upstreams.sh"&gt;(Source)&lt;/a&gt;&lt;/p&gt;&lt;div class="code"&gt;&lt;table class="codetable"&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-1"&gt;&lt;code data-line-number="  1"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-2"&gt;&lt;code data-line-number="  2"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Startdate: 2026-01-30-6 13:35&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-3"&gt;&lt;code data-line-number="  3"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Purpose: List and track git remotes for Luanti mods I care about&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-4"&gt;&lt;code data-line-number="  4"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-5"&gt;&lt;code data-line-number="  5"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Config&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-6"&gt;&lt;code data-line-number="  6"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://server3/git/luanti"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-7"&gt;&lt;code data-line-number="  7"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/mod-upstreams&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-8"&gt;&lt;code data-line-number="  8"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-9"&gt;&lt;code data-line-number="  9"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Functions&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-10"&gt;&lt;code data-line-number=" 10"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-11"&gt;&lt;code data-line-number=" 11"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;ginit&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-12"&gt;&lt;code data-line-number=" 12"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    err&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-13"&gt;&lt;code data-line-number=" 13"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-14"&gt;&lt;code data-line-number=" 14"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-15"&gt;&lt;code data-line-number=" 15"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    err &lt;span class="s2"&gt;"# ginit &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="p"&gt;*&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-16"&gt;&lt;code data-line-number=" 16"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${#}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; -lt &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-17"&gt;&lt;code data-line-number=" 17"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-18"&gt;&lt;code data-line-number=" 18"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        err &lt;span class="s2"&gt;"Usage: ginit &amp;lt;repository_url&amp;gt; [branch_name] [dirname]"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-19"&gt;&lt;code data-line-number=" 19"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-20"&gt;&lt;code data-line-number=" 20"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-21"&gt;&lt;code data-line-number=" 21"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;REPO_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-22"&gt;&lt;code data-line-number=" 22"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; basename &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; .git &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-23"&gt;&lt;code data-line-number=" 23"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-24"&gt;&lt;code data-line-number=" 24"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;DIRNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-25"&gt;&lt;code data-line-number=" 25"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -n &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIRNAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIRNAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-26"&gt;&lt;code data-line-number=" 26"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -d &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-27"&gt;&lt;code data-line-number=" 27"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-28"&gt;&lt;code data-line-number=" 28"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        err &lt;span class="s2"&gt;"Directory &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; already exists. Changing directory to it."&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-29"&gt;&lt;code data-line-number=" 29"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-30"&gt;&lt;code data-line-number=" 30"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -n &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-31"&gt;&lt;code data-line-number=" 31"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-32"&gt;&lt;code data-line-number=" 32"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            err &lt;span class="s2"&gt;"Switching to branch &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-33"&gt;&lt;code data-line-number=" 33"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            git fetch --all
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-34"&gt;&lt;code data-line-number=" 34"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="c1"&gt;# my old redirect trick to filter stderr&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-35"&gt;&lt;code data-line-number=" 35"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-36"&gt;&lt;code data-line-number=" 36"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-37"&gt;&lt;code data-line-number=" 37"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                    &lt;span class="c1"&gt;# Use 'git switch' (modern) or 'git checkout' (older versions)&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-38"&gt;&lt;code data-line-number=" 38"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                    &lt;span class="c1"&gt;# 'git switch -c' creates and switches to a new branch if it doesn't exist locally&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-39"&gt;&lt;code data-line-number=" 39"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                    git switch -c &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"origin/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-40"&gt;&lt;code data-line-number=" 40"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                        git checkout -b &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"origin/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-41"&gt;&lt;code data-line-number=" 41"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                        git checkout &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-42"&gt;&lt;code data-line-number=" 42"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -r -e &lt;span class="s1"&gt;'/fatal: a branch named.*already exists/d'&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-43"&gt;&lt;code data-line-number=" 43"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-44"&gt;&lt;code data-line-number=" 44"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-45"&gt;&lt;code data-line-number=" 45"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-46"&gt;&lt;code data-line-number=" 46"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -n &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-47"&gt;&lt;code data-line-number=" 47"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-48"&gt;&lt;code data-line-number=" 48"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            err &lt;span class="s2"&gt;"Cloning branch &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; into &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-49"&gt;&lt;code data-line-number=" 49"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            git clone -b &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-50"&gt;&lt;code data-line-number=" 50"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-51"&gt;&lt;code data-line-number=" 51"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            err &lt;span class="s2"&gt;"Cloning default branch into &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-52"&gt;&lt;code data-line-number=" 52"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            git clone &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-53"&gt;&lt;code data-line-number=" 53"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-54"&gt;&lt;code data-line-number=" 54"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -d &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-55"&gt;&lt;code data-line-number=" 55"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-56"&gt;&lt;code data-line-number=" 56"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-57"&gt;&lt;code data-line-number=" 57"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            git pull
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-58"&gt;&lt;code data-line-number=" 58"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            err &lt;span class="s2"&gt;"Changed directory to &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;REPO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-59"&gt;&lt;code data-line-number=" 59"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;else&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-60"&gt;&lt;code data-line-number=" 60"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            err &lt;span class="s2"&gt;"Failed to clone repository"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-61"&gt;&lt;code data-line-number=" 61"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-62"&gt;&lt;code data-line-number=" 62"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-63"&gt;&lt;code data-line-number=" 63"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-64"&gt;&lt;code data-line-number=" 64"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-65"&gt;&lt;code data-line-number=" 65"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-66"&gt;&lt;code data-line-number=" 66"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-67"&gt;&lt;code data-line-number=" 67"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;_origin&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-68"&gt;&lt;code data-line-number=" 68"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;_dest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-69"&gt;&lt;code data-line-number=" 69"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nv"&gt;_branches&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-70"&gt;&lt;code data-line-number=" 70"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;WORKDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-71"&gt;&lt;code data-line-number=" 71"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;if&lt;/span&gt; ginit &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_origin&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-72"&gt;&lt;code data-line-number=" 72"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-73"&gt;&lt;code data-line-number=" 73"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-74"&gt;&lt;code data-line-number=" 74"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            git remote add dest &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_dest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-75"&gt;&lt;code data-line-number=" 75"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -r -e &lt;span class="s1"&gt;'/error: remote.*already exists/d'&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-76"&gt;&lt;code data-line-number=" 76"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        git pull --all
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-77"&gt;&lt;code data-line-number=" 77"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;_branches&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,main,master"&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tr &lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;'!x[$0]++'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; branch &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-78"&gt;&lt;code data-line-number=" 78"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-79"&gt;&lt;code data-line-number=" 79"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-80"&gt;&lt;code data-line-number=" 80"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                git switch -c &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"origin/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-81"&gt;&lt;code data-line-number=" 81"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                    git checkout -b &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"origin/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-82"&gt;&lt;code data-line-number=" 82"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                    git checkout &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-83"&gt;&lt;code data-line-number=" 83"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;                git push dest &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-84"&gt;&lt;code data-line-number=" 84"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -r -e &lt;span class="s1"&gt;'/fatal: a branch named.*already exists/d'&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-85"&gt;&lt;code data-line-number=" 85"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;        &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-86"&gt;&lt;code data-line-number=" 86"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-87"&gt;&lt;code data-line-number=" 87"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-88"&gt;&lt;code data-line-number=" 88"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-89"&gt;&lt;code data-line-number=" 89"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# sync_repos origin dest "branches,comma-separated"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-90"&gt;&lt;code data-line-number=" 90"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/JamesClarke7283/enchantments_extractor &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/enchantments_extractor"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-91"&gt;&lt;code data-line-number=" 91"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# enchantments_workbench is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-92"&gt;&lt;code data-line-number=" 92"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/camelia/farmtools &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/farmtools"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-93"&gt;&lt;code data-line-number=" 93"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/Wuzzy/minetest_inventory_icon &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/minetest_inventory_icon"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-94"&gt;&lt;code data-line-number=" 94"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/JamesClarke7283/inventory_pouches &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/inventory_pouches"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-95"&gt;&lt;code data-line-number=" 95"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/ketwaroo/minetest-k-ambient-light &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/minetest-k-ambient-light"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-96"&gt;&lt;code data-line-number=" 96"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/ketwaroo/minetest-k-recycler &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/minetest-k-recycler"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-97"&gt;&lt;code data-line-number=" 97"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# lava_furnace is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-98"&gt;&lt;code data-line-number=" 98"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/SilverSandstone/leads &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/leads"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-99"&gt;&lt;code data-line-number=" 99"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# list_to_file is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-100"&gt;&lt;code data-line-number="100"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/minetest-mapserver/mapserver_mod &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/mapserver_mod"&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-101"&gt;&lt;code data-line-number="101"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# mcl_chiseled_bookshelf is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-102"&gt;&lt;code data-line-number="102"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# mcl_colored_chests is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-103"&gt;&lt;code data-line-number="103"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/TomCon/mcl_copper_stuff &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/mcl_copper_stuff"&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-104"&gt;&lt;code data-line-number="104"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/rudzik8/mcl_cozy &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mcl_cozy"&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-105"&gt;&lt;code data-line-number="105"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/rudzik8/mcl_decor &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/mcl_decor"&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-106"&gt;&lt;code data-line-number="106"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/rudzik8/mcl_emerald_stuff &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mcl_emerald_stuff"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-107"&gt;&lt;code data-line-number="107"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# mcl_lapis_stuff is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-108"&gt;&lt;code data-line-number="108"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/ketwaroo/minetest-mcl-misk-recipes &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mcl_misk_recipes"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-109"&gt;&lt;code data-line-number="109"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://codeberg.org/rudzik8/mcl_morefood &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mcl_morefood"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-110"&gt;&lt;code data-line-number="110"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# milk_potion is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-111"&gt;&lt;code data-line-number="111"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# molten_sailor_mcl is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-112"&gt;&lt;code data-line-number="112"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://git.0x7be.net/dirk/mtimer &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mtimer"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-113"&gt;&lt;code data-line-number="113"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/minetest-go/mtui_mod &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/mtui_mod"&lt;/span&gt; &lt;span class="s2"&gt;"master"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-114"&gt;&lt;code data-line-number="114"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# obsidian_extra is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-115"&gt;&lt;code data-line-number="115"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/LizzyFleckenstein03/playerlist &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/playerlist"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-116"&gt;&lt;code data-line-number="116"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/acmgit/minetest_poi &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/minetest_poi"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-117"&gt;&lt;code data-line-number="117"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# privs_per_world is mine&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-118"&gt;&lt;code data-line-number="118"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://gitlab.com/cronvel/mt-respawn &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/mt-respawn"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-119"&gt;&lt;code data-line-number="119"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# safe_chest upstream is gone, so I guess I am upstream now.&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-120"&gt;&lt;code data-line-number="120"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# sync_repos https://github.com/smnoe01/safe_chest "${host}/safe_chest"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-121"&gt;&lt;code data-line-number="121"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/mt-historical/snippets &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/snippets"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-122"&gt;&lt;code data-line-number="122"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/DonBatman/myairwand &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-readonly/myairwand"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/#-123"&gt;&lt;code data-line-number="123"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;sync_repos https://github.com/Twinsonian/magicsquare &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/magicsquare"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;The purpose of this script is to make synchronizing to upstream easy. I tend to have very small changes to upstream. On occasion my changes get merged into upstream, and I don't need any feature branches! For some of these, I have private patches that have been declined by upstream or never sent to them in the first place.&lt;/p&gt;
&lt;p&gt;This script also documents the mods I care about. Any of the "readonly" ones are ones for which I have no changes at all. I have changed my mind and have had to move some around, when I realized I wanted to patch them after all.&lt;/p&gt;</description><category>game</category><category>git</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2026/03/03/script-to-stay-synced-to-upstreams-for-luanti-mods/</guid><pubDate>Tue, 03 Mar 2026 14:27:00 GMT</pubDate></item><item><title>New Luanti csm: node_inv_read</title><link>https://bgstack15.ddns.net/blog/posts/2026/02/23/new-luanti-csm-node-inv-read/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote a new client side mod for Luanti that is an inventory cheat. Technically it doesn't work in Minetest Game, so it only works in Mineclonia. I couldn't figure that out.&lt;/p&gt;
&lt;p&gt;This mod lets you punch any node, and if it has inventory, it will show all the inventories to you. I have tested it with up to 6 inventories. And if a node does not use the &lt;code&gt;allow_metadata_inventory_put&lt;/code&gt; functions, you can even move items around!&lt;/p&gt;
&lt;p&gt;Get the &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/node_inv_read"&gt;code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/screenshot-node_inv_read-big.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/screenshot-node_inv_read.png"&gt;&lt;/a&gt;&lt;/p&gt;</description><category>game</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2026/02/23/new-luanti-csm-node-inv-read/</guid><pubDate>Mon, 23 Feb 2026 14:13:00 GMT</pubDate></item><item><title>My necessary Luanti mods for Minetest Game</title><link>https://bgstack15.ddns.net/blog/posts/2025/12/09/my-necessary-luanti-mods-for-minetest-game/</link><dc:creator>bgstack15</dc:creator><description>&lt;div&gt;&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;I recently published my &lt;a href="https://bgstack15.ddns.net/blog/posts/2025/12/01/my-necessary-luanti-mods-for-mineclonia/"&gt;list of mods for Mineclonia&lt;/a&gt;, and here is my list of mods I want for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/minetest/minetest_game"&gt;Minetest Game&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Luanti/minetest_game/"&gt;ContentDB&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;It's been said that most Minetest Game servers are just a mod soup that the admin wants. Well, it's true.&lt;/p&gt;
&lt;h2&gt;Mods I use for Minetest Game&lt;/h2&gt;
&lt;h3&gt;Airutils&lt;/h3&gt;
&lt;p&gt;This is a dependency library and helper components for the specific airplanes added by other mods. I do not have any patches for this.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/mod-airutils.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/mod-airutils-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/apercy/airutils/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/APercy/airutils"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Automobiles Pack (automobiles_pck)&lt;/h3&gt;
&lt;p&gt;Written by the same prolific Luanti mod author &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/apercy/"&gt;Apercy&lt;/a&gt; as the previous mod, this one adds a bunch of cool ground vehicles. I never sent any patches, but I did submit a single &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/APercy/automobiles_pck/issues/39"&gt;bug report&lt;/a&gt;. I want automobiles, and this seemed to be the premiere way to get them!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/mod-automobiles-pck.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/mod-automobiles-pck-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/apercy/automobiles_pck/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/APercy/automobiles_pck/"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2025/12/09/my-necessary-luanti-mods-for-minetest-game/"&gt;Read more…&lt;/a&gt; (17 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>game</category><category>luanti</category><category>minetest</category><category>mod</category><category>notes</category><guid>https://bgstack15.ddns.net/blog/posts/2025/12/09/my-necessary-luanti-mods-for-minetest-game/</guid><pubDate>Tue, 09 Dec 2025 14:15:00 GMT</pubDate></item><item><title>My necessary Luanti mods for Mineclonia</title><link>https://bgstack15.ddns.net/blog/posts/2025/12/01/my-necessary-luanti-mods-for-mineclonia/</link><dc:creator>bgstack15</dc:creator><description>&lt;div&gt;&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;I like the Free Software game &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/www.luanti.org/"&gt;Luanti&lt;/a&gt;. You can play in a sandbox world, with a great base for mods in &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/minetest/minetest_game"&gt;Minetest Game&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Luanti/minetest_game/"&gt;ContentDB&lt;/a&gt;). You can even get a premium experience with &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/mineclonia/mineclonia"&gt;Mineclonia&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;ContentDB&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;While Mineclonia can be played without mods because it already bundles many mods in with it, mods improve it even more. And I would definitely want to add mods to MTG. Here is my official list of mods to use in Mineclonia, in alphabetical order. I have even &lt;a href="https://bgstack15.ddns.net/blog/categories/cat_mod/"&gt;written&lt;/a&gt; about some of these before, particuarly the ones I wrote. I will publish my list of MTG mods next time.&lt;/p&gt;
&lt;!-- after 2025-12-09, add link link://slug/my-necessary-luanti-mods-for-minetest-game --&gt;

&lt;h2&gt;Mods I use for Mineclonia&lt;/h2&gt;
&lt;h3&gt;Enchantments extractor (enchantments_extractor)&lt;/h3&gt;
&lt;p&gt;Enchantments extractor is a nifty object that lets you strip enchantments from objects into books, or splits an object with multiple enchantments into each individual enchanted book. This is very useful to remove the scavenged items with random enchantments, for further use.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/mod-enchantments-extractor.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/mod-enchantments-extractor-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Impulse/enchantments_extractor/"&gt;ContentDB&lt;/a&gt; scm: &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/JamesClarke7283/enchantments_extractor"&gt;upstream&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/enchantments_extractor/?h=dev"&gt;mine&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Enchantments workbench (enchantments_workbench)&lt;/h3&gt;
&lt;p&gt;I &lt;a href="https://bgstack15.ddns.net/blog/posts/2025/09/04/new-luanti-mod-enchantments-workbench/"&gt;wrote this one&lt;/a&gt;. This was directly inspired by the enchantments extractor, and it gives you an object that lets you upgrade enchanted books and duplicate them: These abilities are very useful in a survival world.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/mod-enchantments-workbench.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/mod-enchantments-workbench-small.png"&gt;&lt;/a&gt;
&lt;a href="https://bgstack15.ddns.net/blog/2025/mod-enchantments-workbench-2.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/mod-enchantments-workbench-2-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/bgstack15/enchantments_workbench/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/enchantments_workbench"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2025/12/01/my-necessary-luanti-mods-for-mineclonia/"&gt;Read more…&lt;/a&gt; (18 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>game</category><category>luanti</category><category>mineclonia</category><category>mod</category><category>notes</category><guid>https://bgstack15.ddns.net/blog/posts/2025/12/01/my-necessary-luanti-mods-for-mineclonia/</guid><pubDate>Mon, 01 Dec 2025 13:44:00 GMT</pubDate></item><item><title>New Luanti mod: privs_per_world</title><link>https://bgstack15.ddns.net/blog/posts/2025/10/10/new-luanti-mod-privs-per-world/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote a novel mod for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/www.luanti.org/"&gt;Luanti&lt;/a&gt;, specifically for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;Mineclonia&lt;/a&gt;. This mod is named &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/privs_per_world"&gt;privs_per_world&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/bgstack15/privs_per_world"&gt;codeberg&lt;/a&gt;, &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/bgstack15/privs_per_world/"&gt;ContentDB&lt;/a&gt;) and it is an engine for automatically granting and revoking privileges based on entering and leaving the various &lt;em&gt;worlds&lt;/em&gt; (Overworld, Nether, End) of Mineclonia.&lt;/p&gt;
&lt;p&gt;The default settings grant &lt;code&gt;fast, fly, noclip&lt;/code&gt; to players entering the Nether, and revokes these privileges upon leaving.&lt;/p&gt;
&lt;p&gt;The server admin can configure settings in minetest.conf. See &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/privs_per_world/tree/settingtypes.txt"&gt;settingtypes.txt&lt;/a&gt;, but it is easier to use &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/privs_per_world/tree/settings.lua.example"&gt;settings.lua&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I know that the Mineclonia guys tend to adapt existing mods, so if there's some "worlds" mod that facilitates different "dimensions" and the transport to and from them, this might be useful elsewhere but I don't have any test environments for that.&lt;/p&gt;
&lt;p&gt;Here is the default settings, which are useful for a Mineclonia survival server.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;ppw.settings = {
    nether = {
        enter = { 
            give = core.settings:get("privs_per_world.nether_enter_give") or "fly,noclip,fast",
            take = core.settings:get("privs_per_world.nether_enter_take") or "",
        },
        leave = {
            give = core.settings:get("privs_per_world.nether_leave_give") or "",
            take = core.settings:get("privs_per_world.nether_leave_take") or "fly,noclip,fast",
        },
    },
    overworld = {
        enter = {
            give = core.settings:get("privs_per_world.overworld_enter_give") or "",
            take = core.settings:get("privs_per_world.overworld_enter_take") or "",
        },
        leave = {
            give = core.settings:get("privs_per_world.overworld_leave_give") or "",
            take = core.settings:get("privs_per_world.overworld_leave_take") or "",
        },
    }
}
&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Future improvements&lt;/h2&gt;
&lt;p&gt;I might need to use mod storage to store privileges of user before entering/leaving the world, so we can restore them. But this would lose any privileges that change while the user is in the world. So register_on_grant_priv might be useful, if this mod's own set_privileges does not trigger those.&lt;/p&gt;</description><category>game</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2025/10/10/new-luanti-mod-privs-per-world/</guid><pubDate>Fri, 10 Oct 2025 13:10:00 GMT</pubDate></item><item><title>New Luanti mod: mcl_chiseled_bookshelf</title><link>https://bgstack15.ddns.net/blog/posts/2025/09/16/new-luanti-mod-mcl-chiseled-bookshelf/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote a novel Luanti mod, specifically for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;Mineclonia&lt;/a&gt;, named &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/mcl_chiseled_bookshelf"&gt;mcl_chiseled_bookshelf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I wrote this to be &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/mineclonia/mineclonia/pulls/3540"&gt;incorporated into Mineclonia&lt;/a&gt; but as of the time of this writing, Mineclonia is taking it in a different direction (it is not yet in a released version of the game), so I'm going to keep my work separate so I will use my implementation. It's not any harder than managing the other dozens of mods I use on every server.&lt;/p&gt;
&lt;h3&gt;Using&lt;/h3&gt;
&lt;p&gt;See &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/minecraft.wiki/w/Chiseled_Bookshelf"&gt;Chiseled Bookshelf – Minecraft Wiki&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Screenshots&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/recipe-mcl_chiseled_bookshelf.png"&gt;Crafting recipe for chiseled bookshelf&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/recipe-mcl_chiseled_bookshelf.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/screenshot-mcl_chiseled_bookshelf.png"&gt;Screenshot of a chiseled bookshelf&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/screenshot-mcl_chiseled_bookshelf.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Settings&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;</description><category>game</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2025/09/16/new-luanti-mod-mcl-chiseled-bookshelf/</guid><pubDate>Tue, 16 Sep 2025 13:24:00 GMT</pubDate></item><item><title>How I keep Luanti mods updated</title><link>https://bgstack15.ddns.net/blog/posts/2025/09/12/how-i-keep-luanti-mods-updated/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;Some of my mods for my game server of &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/luanti.org/"&gt;Luanti&lt;/a&gt; come from various git scm sources, and some just from ContentDB. I don't update the ContentDB ones during regular maintenance. I might spot update them, but mostly I switch them to git when I want to make some changes.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;minetest&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mods&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;maxdepth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"${word}"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"s@^@${word}: @"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For regular maintenance, I visit just pull down all the info for each git remote and then I visit any that report they are behind, and manually &lt;code&gt;git pull&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Sure, it's manual, but updates to applications should be reviewed by a human and not just blindly applied.&lt;/p&gt;</description><category>game</category><category>luanti</category><category>mod</category><category>server</category><guid>https://bgstack15.ddns.net/blog/posts/2025/09/12/how-i-keep-luanti-mods-updated/</guid><pubDate>Fri, 12 Sep 2025 13:13:00 GMT</pubDate></item><item><title>New luanti mod: Enchantments Workbench</title><link>https://bgstack15.ddns.net/blog/posts/2025/09/04/new-luanti-mod-enchantments-workbench/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote a novel Luanti mod, specifically for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;Mineclonia&lt;/a&gt;, named &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/enchantments_workbench/"&gt;enchantments_workbench&lt;/a&gt;. You can get it from &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/bgstack15/enchantments_workbench/"&gt;ContentDB&lt;/a&gt; too, in-game.&lt;/p&gt;
&lt;p&gt;I was inspired by mod &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/enchantments_extractor/log/?h=dev"&gt;enchantments_extractor&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Impulse/enchantments_extractor/"&gt;ContentDB&lt;/a&gt;), and some ideas I had had for a while about facilitating the enchantments on my tools.&lt;/p&gt;
&lt;h2&gt;Description&lt;/h2&gt;
&lt;p&gt;This mod is designed for Mineclonia and adds a node, enchantment workbench, that performs 2 different operations on enchanted books.&lt;/p&gt;
&lt;h2&gt;Using&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Enhance: e.g., Efficiency I + Efficiency I = Efficiency II&lt;/li&gt;
&lt;li&gt;Copy: e.g., Efficiency I + empty book = two Efficiency I books&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use lapis lazuli or emeralds to make the very slow process happen faster. While the slot is labeled catalyst, the item is consumed! But it is not strictly necessary if you can wait.&lt;/p&gt;
&lt;h2&gt;Screenshots&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/recipe-enchantments-extractor.png"&gt;Crafting recipe for enchantment workbench&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/recipe-enchantments-extractor.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/screenshot-enchantments-extractor.png"&gt;Screenshot of formspec (dialog) for enchantment workbench&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/screenshot-enchantments-extractor.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Settings&lt;/h2&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;# &lt;span class="nv"&gt;Workflow&lt;/span&gt; &lt;span class="nv"&gt;time&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;enchantment&lt;/span&gt; &lt;span class="nv"&gt;workbench&lt;/span&gt;, &lt;span class="nv"&gt;seconds&lt;/span&gt;
# &lt;span class="nv"&gt;default&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;game&lt;/span&gt; &lt;span class="nv"&gt;days&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;enchantments_workbench&lt;/span&gt;.&lt;span class="nv"&gt;workflow_time&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Workflow&lt;/span&gt; &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;int&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;

# &lt;span class="nv"&gt;Catalyst&lt;/span&gt; &lt;span class="nv"&gt;values&lt;/span&gt; &lt;span class="nv"&gt;required&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;speed&lt;/span&gt; &lt;span class="nv"&gt;up&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;process&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;
# &lt;span class="nv"&gt;Comma&lt;/span&gt; &lt;span class="nv"&gt;separate&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt; &lt;span class="nv"&gt;of&lt;/span&gt; `&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;`
# &lt;span class="nv"&gt;default&lt;/span&gt; `&lt;span class="nv"&gt;mcl_core&lt;/span&gt;:&lt;span class="nv"&gt;lapis&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;,&lt;span class="nv"&gt;mcl_core&lt;/span&gt;:&lt;span class="nv"&gt;emerald&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;`
&lt;span class="nv"&gt;enchantments_workbench&lt;/span&gt;.&lt;span class="nv"&gt;catalysts&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Catalyst&lt;/span&gt; &lt;span class="nv"&gt;values&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;mcl_core&lt;/span&gt;:&lt;span class="nv"&gt;lapis&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;,&lt;span class="nv"&gt;mcl_core&lt;/span&gt;:&lt;span class="nv"&gt;emerald&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>game</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2025/09/04/new-luanti-mod-enchantments-workbench/</guid><pubDate>Thu, 04 Sep 2025 13:21:00 GMT</pubDate></item><item><title>Mod for Luanti: lava furnace</title><link>https://bgstack15.ddns.net/blog/posts/2025/05/27/mod-for-luanti-lava-furnace/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote a novel mod for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/www.luanti.org/"&gt;Luanti&lt;/a&gt;, specifically for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;Mineclonia&lt;/a&gt;: &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/bgstack15/lava_furnace/"&gt;Lava Furnace&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Go get the &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/lava_furnace"&gt;code&lt;/a&gt; for yourself!&lt;/p&gt;
&lt;h3&gt;Snippets of the readme&lt;/h3&gt;
&lt;p&gt;Furnaces powered by being adjacent to lava for Mineclonia. Yes, this breaks balance because it does not need fuel. This is for fun, for large-scale operations in the lategame. Do not install this mod if the imbalance bothers you.&lt;/p&gt;
&lt;p&gt;Heavily based on Minetest Game (default/furnace.lua).&lt;/p&gt;
&lt;h4&gt;Using&lt;/h4&gt;
&lt;p&gt;Build a lava-powered furnace with a gold block surrounded by 8 cobblestone, or a gold block and a furnace. Lava source or flowing lava must be adjacent (NESWUD) touching this lava furnace.&lt;/p&gt;
&lt;h4&gt;Configuring&lt;/h4&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Speed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cooking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lava&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;furnace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;regular&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;furnace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;blast&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;furnace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Requires&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;restart&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;lava_furnace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cooking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lava&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;float&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;16.0&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Comma&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;separated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;'&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lava&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;furnace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;when&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;immediately&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;adjacent&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;lava_furnace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fuel_nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lava&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;furnace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;mcl_core:&lt;/span&gt;&lt;span class="n"&gt;lava_source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;mcl_core:&lt;/span&gt;&lt;span class="n"&gt;lava_flowing&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By default these settings make a lava furnace 4x faster than a regular furnace, and the lava furnace must touch a lava source or flowing lava.&lt;/p&gt;
&lt;p&gt;It's a little overpowered for early gameplay, but it makes lategame play easier because you don't have to keep every single furnace stocked with fuel.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/screenshot-lava-furnace-big.png"&gt;Screenshot of lava furnace cooking while in front of flowing lava&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/screenshot-lava-furnace.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Additional credits&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/minetest_game"&gt;Minetest Game authors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/Wuzzy"&gt;Wuzzy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Additional notes&lt;/h2&gt;
&lt;p&gt;Thankfully, I was able to just adapt the existing furnace code. I just disabled consuming the fuel, and made it "fueled" if any of the 6 surface-adjacent nodes is lava source or flowing lava. I also disabled putting fuel in the fuel slot, which is still there in case you want to put a bucket for drying out a wet sponge.&lt;/p&gt;
&lt;p&gt;It took me less than a day to build and test this, which means, of course, that it has not been battle-tested beyond my small server. Contributions welcome!&lt;/p&gt;</description><category>game</category><category>luanti</category><category>mod</category><category>opensource</category><guid>https://bgstack15.ddns.net/blog/posts/2025/05/27/mod-for-luanti-lava-furnace/</guid><pubDate>Tue, 27 May 2025 12:43:00 GMT</pubDate></item><item><title>Icons and inventory pouches now load at player login</title><link>https://bgstack15.ddns.net/blog/posts/2025/04/01/icons-and-inventory-pouches-now-load-at-player-login/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I really like these 2 mods for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/www.luanti.org/"&gt;Luanti&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Wuzzy/inventory_icon/"&gt;inventory_icon&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/Wuzzy/minetest_inventory_icon"&gt;codeberg upstream&lt;/a&gt;, &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/minetest_inventory_icon"&gt;my source&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Impulse/inventory_pouches/"&gt;inventory_pouches&lt;/a&gt; (&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/JamesClarke7283/inventory_pouches"&gt;github upstream&lt;/a&gt;, &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/inventory_pouches"&gt;my source&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I added the original functionality for &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/minetest_inventory_icon/log/?h=feature%2Fadd-pouches"&gt;inventory_icon to show the player's pouches&lt;/a&gt; in the HUD. But inventory_pouches only loads the inventory for a pouch when the player first opens the pouch to use it, so the HUD doesn't display it until then.&lt;/p&gt;
&lt;p&gt;So I have written my latest commit to inventory_pouches which loads the player's pouch inventories &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/inventory_pouches/commit/?h=combined&amp;amp;id=e7b73be96569ef2bd1edc1ea4752d34db531b12b"&gt;at login time&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Happy mining!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/inventory-icons-for-inventory-pouches.png"&gt;Corner of Luanti HUD showing some inventory pouch icons&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/inventory-icons-for-inventory-pouches.png"&gt;&lt;/a&gt;&lt;/p&gt;</description><category>game</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2025/04/01/icons-and-inventory-pouches-now-load-at-player-login/</guid><pubDate>Tue, 01 Apr 2025 13:25:00 GMT</pubDate></item></channel></rss>