<?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 game)</title><link>https://bgstack15.ddns.net/blog/</link><description></description><atom:link href="https://bgstack15.ddns.net/blog/categories/game.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>Sun, 12 Apr 2026 13:31:31 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Luanti mods that sound cool</title><link>https://bgstack15.ddns.net/blog/posts/2026/04/12/luanti-mods-that-sound-cool/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;This is intended to be a living list of mods that sound interesting but don't quite make the cut for &lt;a href="https://bgstack15.ddns.net/blog/posts/2025/12/01/my-necessary-luanti-mods-for-mineclonia/"&gt;essential mods&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Interesting mods for Mineclonia&lt;/h2&gt;
&lt;p&gt;These sound interesting. Some of these I have investigated or used or even contributed to. These are listed in no particular order, but probably in order than I came across them.&lt;/p&gt;
&lt;h3&gt;Inventory admin&lt;/h3&gt;
&lt;p&gt;This lets an admin view and change inventory of other players. Haha, like the stadium guards checking those clear bags! This is from the same guy who wrote inventory_pouches, so it must be good! I haven't actually tried this one; I haven't needed to moderate players' inventories.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-inventory_admin.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-inventory_admin-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/LudusExe/Italian-Food-for-Voxelibre"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/JamesClarke7283/inventory_admin"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Extra Woolstuff&lt;/h3&gt;
&lt;p&gt;In case I want to add stairs and slabs made of wool. I haven't wanted those in my worlds yet, but I might. Same guy as Inventory Admin above! I like his work.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-extra_woolstuff.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-extra_woolstuff-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/extra_wool_stuff/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/JamesClarke7283/extra_woolstuff"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Protector&lt;/h3&gt;
&lt;p&gt;This sounds like the big, popular protection mod. I haven't needed protection on my servers because we have live moderators, but if I needed this, I would check this out first.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-protector.jpg"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-protector-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2026/04/12/luanti-mods-that-sound-cool/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/TenPlus1/protector/"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Magicsquare&lt;/h3&gt;
&lt;p&gt;I like this one, and use it on a few servers, but it's not essential. It would simplify survival games, for moving animals around, but I can play without it if I had to. It is a rapid replacement of its slightly earlier version known as "mobcrate." When I use this, I use my own fork with &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/Twinsonian/magicsquare/pull/2"&gt;patches&lt;/a&gt; which have not yet been merged into upstream.&lt;/p&gt;
&lt;p&gt;(no picture)&lt;/p&gt;
&lt;p&gt;(no contentdb entry) &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/forum.luanti.org/viewtopic.php?p=447128#p447128"&gt;Forum post&lt;/a&gt; scm: &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/Twinsonian/magicsquare"&gt;upstream&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/magicsquare/?h=feature%2Fhold-items"&gt;mine&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Invisiblocks&lt;/h3&gt;
&lt;p&gt;From TenPlus1 again (like Protector), this mod sounds more useful for creative mode, when making a game or puzzle map or something. The mob wall item works with Mobs Redo but not Mineclonia mobs. I wouldn't even want to waste my time asking Mineclonia devs to support it because it's not related to Mineclonia directly so they'd decline immediately. The invisible barrier and invisible light blocks are pretty great though.&lt;/p&gt;
&lt;p&gt;I love this idea and implementation, but it's not directly related to survival gameplay, so it's hardly essential. Man, if I could get the MCL animals to obey the mob walls, I probably would put this on my survival servers. But fences work too (minus the mobs lag-jumping over them).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-invisiblocks.jpg"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-invisiblocks-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/TenPlus1/invisiblocks/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/tenplus1/invisiblocks"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Ancient Stuff&lt;/h3&gt;
&lt;p&gt;A random idea from another supercreator &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/users/m16b/"&gt;michi16bit&lt;/a&gt;: some more armor and tools with a cool design!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-m16b_ancient_armor.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-m16b_ancient_armor-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/m16b/m16b_ancient_armor/"&gt;ContentDB&lt;/a&gt; scm: no upstream &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti-readonly/m16b_ancient_armor"&gt;mine&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Italian Food for VoxeLibre&lt;/h3&gt;
&lt;p&gt;I helped this author with some mineclonia-related modding questions. I personally don't see the need for a million food mods in my survival worlds, but if I start adding any, I would start here.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-italian_food.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-italian_food-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/Ludus/italian_food/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/LudusExe/Italian-Food-for-Voxelibre"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Automatic Storage &amp;amp; Retrieval System&lt;/h3&gt;
&lt;p&gt;This adds a nifty way to throw tons of items in a single location and you can sort and search. You wouldn't to track individual boxes anymore. This works in Mineclonia, but it doesn't quite fit with the style of gameplay for it.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-asrs-1.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-asrs-1-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-asrs-2.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-asrs-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/Nathan.S/asrs/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/NathanS21/asrs"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Whiter List (whitelist)&lt;/h3&gt;
&lt;p&gt;This uses a file in the world directory to manage a whitelist of users who can join the world. If I need this feature, this is the one I would use. There are a host of alternatives but this one uses a local file which appeals to me, instead of mod storage which is more obtuse to manage.&lt;/p&gt;
&lt;p&gt;(no picture)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/AntumDeluge/whitelist/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/AntumMT/mod-whitelist"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Bulldozer&lt;/h3&gt;
&lt;p&gt;Obvious. It has no recipe, because it's so powerful, so it is for creative mode only.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-bulldozer.png"&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-bulldozer-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/celeron55/bulldozer/"&gt;ContentDB&lt;/a&gt; &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/celeron55/minetest_bulldozer"&gt;scm&lt;/a&gt;&lt;/p&gt;
&lt;!--
#### Updates
--&gt;</description><category>game</category><category>git</category><category>luanti</category><category>mod</category><category>notes</category><guid>https://bgstack15.ddns.net/blog/posts/2026/04/12/luanti-mods-that-sound-cool/</guid><pubDate>Sun, 12 Apr 2026 13:24:00 GMT</pubDate></item><item><title>New Luanti mod: mcl_ruby_stuff</title><link>https://bgstack15.ddns.net/blog/posts/2026/04/08/new-luanti-mod-mcl-ruby-stuff/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote another clone of &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/rudzik8/mcl_emerald_stuff"&gt;mcl_emerald_stuff&lt;/a&gt;, which I named &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/mcl_ruby_stuff"&gt;mcl_ruby_stuff&lt;/a&gt;. I also previously wrote &lt;a href="https://bgstack15.ddns.net/blog/cgit/luanti/mcl_lapis_stuff"&gt;mcl_lapis_stuff&lt;/a&gt; but I failed to have a separate post for that.&lt;/p&gt;
&lt;p&gt;This mod today is only for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;Mineclonia&lt;/a&gt; and &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/git.minetest.land/VoxeLibre/VoxeLibre"&gt;VoxeLibre&lt;/a&gt;. It is published in official &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/bgstack15/mcl_ruby_stuff/"&gt;ContentDB&lt;/a&gt; and in the internal &lt;a href="https://bgstack15.ddns.net/blog/outbound/http:/contentdb.example.com"&gt;ContentDB&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Description&lt;/h3&gt;
&lt;p&gt;You have to fashion rubies before you can make the gear.&lt;/p&gt;
&lt;p&gt;Not only is this gear scaled for very late-game play, it also looks fashionable because it is red.&lt;/p&gt;
&lt;h3&gt;Using&lt;/h3&gt;
&lt;p&gt;Craft rubies based on the recipe chosen by the server admin. Craft with rubies to fashion all the ordinary gear like tools, armors, and horse armor. Equip the tools and armor!&lt;/p&gt;
&lt;h3&gt;Screenshots&lt;/h3&gt;
&lt;p&gt;Screenshot of armor and tools made with rubies&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mcl_ruby_stuff_screenshot.png"&gt;&lt;/p&gt;
&lt;p&gt;Screenshot of horse armor on a horse&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mcl_ruby_stuff_screenshot_horse_armor.png"&gt;&lt;/p&gt;
&lt;h3&gt;Optional support&lt;/h3&gt;
&lt;p&gt;Mod &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/codeberg.org/camelia/farmtools/pulls/23"&gt;farmtools&lt;/a&gt; has been requested to support this mod.&lt;/p&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;For a &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/minetest_game"&gt;Minetest Game&lt;/a&gt; ruby experience, use mod &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ReinPlayz/ruby_tools_plus/"&gt;Ruby Tools+&lt;/a&gt;. That mod is entirely unrelated to this one.&lt;/p&gt;
&lt;h3&gt;Settings&lt;/h3&gt;
&lt;p&gt;Once at installation time, configure the build recipe in &lt;code&gt;minetest.conf&lt;/code&gt;, entry &lt;code&gt;mcl_ruby_stuff.recipe&lt;/code&gt;. The options are the following. The recipe affects the strength of the equipment.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;emerald_and_redstone_dust&lt;/code&gt;: 1 emerald + 1 redstone dust.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/mcl_core/textures/mcl_core_emerald.png" alt="emerald" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eight_redstone_dust&lt;/code&gt;: 8 redstone dust.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://codeberg.org/mineclonia/mineclonia/raw/tag/0.120.1/mods/ITEMS/REDSTONE/mcl_redstone/textures/redstone_redstone_dust.png" alt="redstone dust" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nine_redstone_blocks&lt;/code&gt;: 9 redstone blocks. This will make the strength of the equipment 2x that of emerald equipment.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
        &lt;td&gt;&lt;img src="https://bgstack15.ddns.net/blog/2026/redstone-block.png" alt="redstone block" width="48" height="48"&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;</description><category>game</category><category>git</category><category>luanti</category><category>mod</category><guid>https://bgstack15.ddns.net/blog/posts/2026/04/08/new-luanti-mod-mcl-ruby-stuff/</guid><pubDate>Wed, 08 Apr 2026 13:07:00 GMT</pubDate></item><item><title>Mod for Luanti: Highlighter Pen</title><link>https://bgstack15.ddns.net/blog/posts/2026/03/11/new-luanti-mod-highlighter-pen/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wrote a novel Luanti mod, that works in any game. I have tested it specifically in the following games.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;Mineclonia&lt;/a&gt;, also on &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/ryvnf/mineclonia/"&gt;ContentDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/luanti-org/minetest_game"&gt;Minetest Game&lt;/a&gt;, also on &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Luanti/minetest_game/"&gt;ContentDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/git.minetest.land/VoxeLibre/VoxeLibre"&gt;VoxeLibre&lt;/a&gt;, also on &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/Wuzzy/mineclone2/"&gt;ContentDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Description&lt;/h3&gt;
&lt;p&gt;This mod for Luanti adds highlighter pen tools. A player can highlight nodes, and erase highlights. The highlights persist after a safe server restart.&lt;/p&gt;
&lt;p&gt;The canonical scm repo for this mod is at &lt;a href="https://bgstack15.ddns.net/cgit/luanti/highlighter_pen"&gt;https://bgstack15.ddns.net/cgit/luanti/highlighter_pen&lt;/a&gt;, and an additional repo suitable for collaboration is at &lt;a href="https://gitlab.com/bgsack15/highlighter_pen"&gt;https://gitlab.com/bgsack15/highlighter_pen&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Using&lt;/h3&gt;
&lt;p&gt;Craft a highlighter pen. Right-click a node with the tool to set a highlight. Left-click to remove a highlight on a node.&lt;/p&gt;
&lt;p&gt;Craft and use a blotter to remove highlights in a small radius (default radius is 3).&lt;/p&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Vendors &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/forum.luanti.org/viewtopic.php?t=31761"&gt;node_highlighter&lt;/a&gt; because that is not in ContentDB. You can also use that mod, and it will load that instead of using the vendored components.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Optional dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/content.luanti.org/packages/mt-mods/unifieddyes/"&gt;Unifieddyes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Screenshots&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-highlighter-pen-recipe1.png"&gt;Crafting recipe for a highlighter pen&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-highlighter-pen-recipe1.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-highlighter-pen-recipe2.png"&gt;Crafting recipe for a blotter&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-highlighter-pen-recipe2.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2026/mod-highlighter-pen-screenshot.png"&gt;Screenshot of some highlight strokes in the world&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2026/mod-highlighter-pen-screenshot-small.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Settings&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;How many nodes can a highlighter pen be used in survival mode on before the pen runs out (default 200)&lt;/li&gt;
&lt;li&gt;Highlighter pen can erase all highlight-colors from a node (default true)&lt;/li&gt;
&lt;li&gt;Using a highlighter in the air (an empty node) erases this color entirely, on all nodes (default false)&lt;/li&gt;
&lt;li&gt;Blotter radius, where 1 is the single node that was right-clicked (default 3)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Current weaknesses&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The blotter is the only component that respects &lt;code&gt;core.is_protected&lt;/code&gt;, and only on the center of the usage.&lt;/li&gt;
&lt;li&gt;Unifieddyes does not produce highlighter pens for each color variant for creative mode inventory; you have to craft them.&lt;/li&gt;
&lt;/ul&gt;</description><category>game</category><category>luanti</category><category>mod</category><category>opensource</category><guid>https://bgstack15.ddns.net/blog/posts/2026/03/11/new-luanti-mod-highlighter-pen/</guid><pubDate>Wed, 11 Mar 2026 13:19:00 GMT</pubDate></item><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>Writing init script for explorer.lu</title><link>https://bgstack15.ddns.net/blog/posts/2026/01/14/writing-init-script-for-explorer-lu/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;Great artists steal, so I just copied the certmonger init script for Devuan and adapted it for running the &lt;a href="link://slug/lu-explorer-tools"&gt;explorer-lu&lt;/a&gt; instance.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/files/2026/listings/explorer-lu.html"&gt;files/2026/listings/explorer-lu&lt;/a&gt;  &lt;a href="https://bgstack15.ddns.net/blog/files/2026/listings/explorer-lu"&gt;(Source)&lt;/a&gt;&lt;/p&gt;&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;  1&lt;/span&gt;
&lt;span class="normal"&gt;  2&lt;/span&gt;
&lt;span class="normal"&gt;  3&lt;/span&gt;
&lt;span class="normal"&gt;  4&lt;/span&gt;
&lt;span class="normal"&gt;  5&lt;/span&gt;
&lt;span class="normal"&gt;  6&lt;/span&gt;
&lt;span class="normal"&gt;  7&lt;/span&gt;
&lt;span class="normal"&gt;  8&lt;/span&gt;
&lt;span class="normal"&gt;  9&lt;/span&gt;
&lt;span class="normal"&gt; 10&lt;/span&gt;
&lt;span class="normal"&gt; 11&lt;/span&gt;
&lt;span class="normal"&gt; 12&lt;/span&gt;
&lt;span class="normal"&gt; 13&lt;/span&gt;
&lt;span class="normal"&gt; 14&lt;/span&gt;
&lt;span class="normal"&gt; 15&lt;/span&gt;
&lt;span class="normal"&gt; 16&lt;/span&gt;
&lt;span class="normal"&gt; 17&lt;/span&gt;
&lt;span class="normal"&gt; 18&lt;/span&gt;
&lt;span class="normal"&gt; 19&lt;/span&gt;
&lt;span class="normal"&gt; 20&lt;/span&gt;
&lt;span class="normal"&gt; 21&lt;/span&gt;
&lt;span class="normal"&gt; 22&lt;/span&gt;
&lt;span class="normal"&gt; 23&lt;/span&gt;
&lt;span class="normal"&gt; 24&lt;/span&gt;
&lt;span class="normal"&gt; 25&lt;/span&gt;
&lt;span class="normal"&gt; 26&lt;/span&gt;
&lt;span class="normal"&gt; 27&lt;/span&gt;
&lt;span class="normal"&gt; 28&lt;/span&gt;
&lt;span class="normal"&gt; 29&lt;/span&gt;
&lt;span class="normal"&gt; 30&lt;/span&gt;
&lt;span class="normal"&gt; 31&lt;/span&gt;
&lt;span class="normal"&gt; 32&lt;/span&gt;
&lt;span class="normal"&gt; 33&lt;/span&gt;
&lt;span class="normal"&gt; 34&lt;/span&gt;
&lt;span class="normal"&gt; 35&lt;/span&gt;
&lt;span class="normal"&gt; 36&lt;/span&gt;
&lt;span class="normal"&gt; 37&lt;/span&gt;
&lt;span class="normal"&gt; 38&lt;/span&gt;
&lt;span class="normal"&gt; 39&lt;/span&gt;
&lt;span class="normal"&gt; 40&lt;/span&gt;
&lt;span class="normal"&gt; 41&lt;/span&gt;
&lt;span class="normal"&gt; 42&lt;/span&gt;
&lt;span class="normal"&gt; 43&lt;/span&gt;
&lt;span class="normal"&gt; 44&lt;/span&gt;
&lt;span class="normal"&gt; 45&lt;/span&gt;
&lt;span class="normal"&gt; 46&lt;/span&gt;
&lt;span class="normal"&gt; 47&lt;/span&gt;
&lt;span class="normal"&gt; 48&lt;/span&gt;
&lt;span class="normal"&gt; 49&lt;/span&gt;
&lt;span class="normal"&gt; 50&lt;/span&gt;
&lt;span class="normal"&gt; 51&lt;/span&gt;
&lt;span class="normal"&gt; 52&lt;/span&gt;
&lt;span class="normal"&gt; 53&lt;/span&gt;
&lt;span class="normal"&gt; 54&lt;/span&gt;
&lt;span class="normal"&gt; 55&lt;/span&gt;
&lt;span class="normal"&gt; 56&lt;/span&gt;
&lt;span class="normal"&gt; 57&lt;/span&gt;
&lt;span class="normal"&gt; 58&lt;/span&gt;
&lt;span class="normal"&gt; 59&lt;/span&gt;
&lt;span class="normal"&gt; 60&lt;/span&gt;
&lt;span class="normal"&gt; 61&lt;/span&gt;
&lt;span class="normal"&gt; 62&lt;/span&gt;
&lt;span class="normal"&gt; 63&lt;/span&gt;
&lt;span class="normal"&gt; 64&lt;/span&gt;
&lt;span class="normal"&gt; 65&lt;/span&gt;
&lt;span class="normal"&gt; 66&lt;/span&gt;
&lt;span class="normal"&gt; 67&lt;/span&gt;
&lt;span class="normal"&gt; 68&lt;/span&gt;
&lt;span class="normal"&gt; 69&lt;/span&gt;
&lt;span class="normal"&gt; 70&lt;/span&gt;
&lt;span class="normal"&gt; 71&lt;/span&gt;
&lt;span class="normal"&gt; 72&lt;/span&gt;
&lt;span class="normal"&gt; 73&lt;/span&gt;
&lt;span class="normal"&gt; 74&lt;/span&gt;
&lt;span class="normal"&gt; 75&lt;/span&gt;
&lt;span class="normal"&gt; 76&lt;/span&gt;
&lt;span class="normal"&gt; 77&lt;/span&gt;
&lt;span class="normal"&gt; 78&lt;/span&gt;
&lt;span class="normal"&gt; 79&lt;/span&gt;
&lt;span class="normal"&gt; 80&lt;/span&gt;
&lt;span class="normal"&gt; 81&lt;/span&gt;
&lt;span class="normal"&gt; 82&lt;/span&gt;
&lt;span class="normal"&gt; 83&lt;/span&gt;
&lt;span class="normal"&gt; 84&lt;/span&gt;
&lt;span class="normal"&gt; 85&lt;/span&gt;
&lt;span class="normal"&gt; 86&lt;/span&gt;
&lt;span class="normal"&gt; 87&lt;/span&gt;
&lt;span class="normal"&gt; 88&lt;/span&gt;
&lt;span class="normal"&gt; 89&lt;/span&gt;
&lt;span class="normal"&gt; 90&lt;/span&gt;
&lt;span class="normal"&gt; 91&lt;/span&gt;
&lt;span class="normal"&gt; 92&lt;/span&gt;
&lt;span class="normal"&gt; 93&lt;/span&gt;
&lt;span class="normal"&gt; 94&lt;/span&gt;
&lt;span class="normal"&gt; 95&lt;/span&gt;
&lt;span class="normal"&gt; 96&lt;/span&gt;
&lt;span class="normal"&gt; 97&lt;/span&gt;
&lt;span class="normal"&gt; 98&lt;/span&gt;
&lt;span class="normal"&gt; 99&lt;/span&gt;
&lt;span class="normal"&gt;100&lt;/span&gt;
&lt;span class="normal"&gt;101&lt;/span&gt;
&lt;span class="normal"&gt;102&lt;/span&gt;
&lt;span class="normal"&gt;103&lt;/span&gt;
&lt;span class="normal"&gt;104&lt;/span&gt;
&lt;span class="normal"&gt;105&lt;/span&gt;
&lt;span class="normal"&gt;106&lt;/span&gt;
&lt;span class="normal"&gt;107&lt;/span&gt;
&lt;span class="normal"&gt;108&lt;/span&gt;
&lt;span class="normal"&gt;109&lt;/span&gt;
&lt;span class="normal"&gt;110&lt;/span&gt;
&lt;span class="normal"&gt;111&lt;/span&gt;
&lt;span class="normal"&gt;112&lt;/span&gt;
&lt;span class="normal"&gt;113&lt;/span&gt;
&lt;span class="normal"&gt;114&lt;/span&gt;
&lt;span class="normal"&gt;115&lt;/span&gt;
&lt;span class="normal"&gt;116&lt;/span&gt;
&lt;span class="normal"&gt;117&lt;/span&gt;
&lt;span class="normal"&gt;118&lt;/span&gt;
&lt;span class="normal"&gt;119&lt;/span&gt;
&lt;span class="normal"&gt;120&lt;/span&gt;
&lt;span class="normal"&gt;121&lt;/span&gt;
&lt;span class="normal"&gt;122&lt;/span&gt;
&lt;span class="normal"&gt;123&lt;/span&gt;
&lt;span class="normal"&gt;124&lt;/span&gt;
&lt;span class="normal"&gt;125&lt;/span&gt;
&lt;span class="normal"&gt;126&lt;/span&gt;
&lt;span class="normal"&gt;127&lt;/span&gt;
&lt;span class="normal"&gt;128&lt;/span&gt;
&lt;span class="normal"&gt;129&lt;/span&gt;
&lt;span class="normal"&gt;130&lt;/span&gt;
&lt;span class="normal"&gt;131&lt;/span&gt;
&lt;span class="normal"&gt;132&lt;/span&gt;
&lt;span class="normal"&gt;133&lt;/span&gt;
&lt;span class="normal"&gt;134&lt;/span&gt;
&lt;span class="normal"&gt;135&lt;/span&gt;
&lt;span class="normal"&gt;136&lt;/span&gt;
&lt;span class="normal"&gt;137&lt;/span&gt;
&lt;span class="normal"&gt;138&lt;/span&gt;
&lt;span class="normal"&gt;139&lt;/span&gt;
&lt;span class="normal"&gt;140&lt;/span&gt;
&lt;span class="normal"&gt;141&lt;/span&gt;
&lt;span class="normal"&gt;142&lt;/span&gt;
&lt;span class="normal"&gt;143&lt;/span&gt;
&lt;span class="normal"&gt;144&lt;/span&gt;
&lt;span class="normal"&gt;145&lt;/span&gt;
&lt;span class="normal"&gt;146&lt;/span&gt;
&lt;span class="normal"&gt;147&lt;/span&gt;
&lt;span class="normal"&gt;148&lt;/span&gt;
&lt;span class="normal"&gt;149&lt;/span&gt;
&lt;span class="normal"&gt;150&lt;/span&gt;
&lt;span class="normal"&gt;151&lt;/span&gt;
&lt;span class="normal"&gt;152&lt;/span&gt;
&lt;span class="normal"&gt;153&lt;/span&gt;
&lt;span class="normal"&gt;154&lt;/span&gt;
&lt;span class="normal"&gt;155&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c1"&gt;### BEGIN INIT INFO&lt;/span&gt;
&lt;span class="c1"&gt;# Provides:          explorer-lu&lt;/span&gt;
&lt;span class="c1"&gt;# Required-Start:    $local_fs&lt;/span&gt;
&lt;span class="c1"&gt;# Required-Stop:     $local_fs&lt;/span&gt;
&lt;span class="c1"&gt;# Default-Start:     2 3 4 5&lt;/span&gt;
&lt;span class="c1"&gt;# Default-Stop:      0 1 6&lt;/span&gt;
&lt;span class="c1"&gt;# Short-Description: Run explorer.lu instance&lt;/span&gt;
&lt;span class="c1"&gt;# Description:       Explorer.lu is a featureful web app for examining Lego&lt;/span&gt;
&lt;span class="c1"&gt;#                    Universe data from whichever dataset is configured.&lt;/span&gt;
&lt;span class="c1"&gt;### END INIT INFO&lt;/span&gt;

&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/bgstack15/.cargo/bin:/sbin:/usr/sbin:/bin:/usr/bin
&lt;span class="nv"&gt;DESC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"explorer-lu"&lt;/span&gt;
&lt;span class="nv"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;paradox-server
&lt;span class="nv"&gt;DAEMON&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/bgstack15/.cargo/bin/&lt;span class="nv"&gt;$NAME&lt;/span&gt;
&lt;span class="nv"&gt;DAEMON_ARGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;RUST_LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info
&lt;span class="nv"&gt;PIDFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/run/&lt;span class="nv"&gt;$NAME&lt;/span&gt;.pid
&lt;span class="nv"&gt;SCRIPTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/init.d/explorer-lu
&lt;span class="nv"&gt;DESTDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/src/lu-explorer

. /lib/init/vars.sh
. /lib/lsb/init-functions

&lt;span class="c1"&gt;# Exit if the package is not installed&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; -x &lt;span class="nv"&gt;$DAEMON&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

&lt;span class="c1"&gt;# Read configuration variable file if it is present&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; -r /etc/default/&lt;span class="nv"&gt;$NAME&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; . /etc/default/&lt;span class="nv"&gt;$NAME&lt;/span&gt;

&lt;span class="c1"&gt;# Load the VERBOSE setting and other rcS variables&lt;/span&gt;
. /lib/init/vars.sh

&lt;span class="c1"&gt;# Define LSB log_* functions.&lt;/span&gt;
&lt;span class="c1"&gt;# Depend on lsb-base (&amp;gt;= 3.0-6) to ensure that this file is present.&lt;/span&gt;
. /lib/lsb/init-functions

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Function that starts the daemon/service&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
do_start&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="c1"&gt;# Return&lt;/span&gt;
	&lt;span class="c1"&gt;#   0 if daemon has been started&lt;/span&gt;
	&lt;span class="c1"&gt;#   1 if daemon was already running&lt;/span&gt;
	&lt;span class="c1"&gt;#   2 if daemon could not be started&lt;/span&gt;
	start-stop-daemon --start --background --quiet --pidfile &lt;span class="nv"&gt;$PIDFILE&lt;/span&gt; --chdir &lt;span class="nv"&gt;$DESTDIR&lt;/span&gt; --exec &lt;span class="nv"&gt;$DAEMON&lt;/span&gt; --test &amp;gt; /dev/null &lt;span class="se"&gt;\&lt;/span&gt;
		&lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
	start-stop-daemon --start --background --quiet --pidfile &lt;span class="nv"&gt;$PIDFILE&lt;/span&gt; --chdir &lt;span class="nv"&gt;$DESTDIR&lt;/span&gt; --exec &lt;span class="nv"&gt;$DAEMON&lt;/span&gt; -- &lt;span class="se"&gt;\&lt;/span&gt;
		&lt;span class="nv"&gt;$DAEMON_ARGS&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
		&lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
	&lt;span class="c1"&gt;# Add code here, if necessary, that waits for the process to be ready&lt;/span&gt;
	&lt;span class="c1"&gt;# to handle requests from services started subsequently which depend&lt;/span&gt;
	&lt;span class="c1"&gt;# on this one.  As a last resort, sleep for some time.&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Function that stops the daemon/service&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
do_stop&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="c1"&gt;# Return&lt;/span&gt;
	&lt;span class="c1"&gt;#   0 if daemon has been stopped&lt;/span&gt;
	&lt;span class="c1"&gt;#   1 if daemon was already stopped&lt;/span&gt;
	&lt;span class="c1"&gt;#   2 if daemon could not be stopped&lt;/span&gt;
	&lt;span class="c1"&gt;#   other if a failure occurred&lt;/span&gt;
	start-stop-daemon --stop --quiet --retry&lt;span class="o"&gt;=&lt;/span&gt;TERM/3/KILL/5 --chdir &lt;span class="nv"&gt;$DESTDIR&lt;/span&gt; --pidfile &lt;span class="nv"&gt;$PIDFILE&lt;/span&gt; --name &lt;span class="nv"&gt;$NAME&lt;/span&gt;
	&lt;span class="nv"&gt;RETVAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
	&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RETVAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
	&lt;span class="c1"&gt;# Wait for children to finish too if this is a daemon that forks&lt;/span&gt;
	&lt;span class="c1"&gt;# and if the daemon is only ever run from this initscript.&lt;/span&gt;
	&lt;span class="c1"&gt;# If the above conditions are not satisfied then add some other code&lt;/span&gt;
	&lt;span class="c1"&gt;# that waits for the process to drop all resources that could be&lt;/span&gt;
	&lt;span class="c1"&gt;# needed by services started subsequently.  A last resort is to&lt;/span&gt;
	&lt;span class="c1"&gt;# sleep for some time.&lt;/span&gt;
	start-stop-daemon --stop --quiet --oknodo --chdir &lt;span class="nv"&gt;$DESTDIR&lt;/span&gt; --retry&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;/3/KILL/5 --exec &lt;span class="nv"&gt;$DAEMON&lt;/span&gt;
	&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
	&lt;span class="c1"&gt;# Many daemons don't delete their pidfiles when they exit.&lt;/span&gt;
	rm -f &lt;span class="nv"&gt;$PIDFILE&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RETVAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Function that sends a SIGHUP to the daemon/service&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
do_reload&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
	&lt;span class="c1"&gt;#&lt;/span&gt;
	&lt;span class="c1"&gt;# If the daemon can reload its configuration without&lt;/span&gt;
	&lt;span class="c1"&gt;# restarting (for example, when it is sent a SIGHUP),&lt;/span&gt;
	&lt;span class="c1"&gt;# then implement that here.&lt;/span&gt;
	&lt;span class="c1"&gt;#&lt;/span&gt;
	start-stop-daemon --stop --signal &lt;span class="m"&gt;1&lt;/span&gt; --quiet --chdir &lt;span class="nv"&gt;$DESTDIR&lt;/span&gt; --pidfile &lt;span class="nv"&gt;$PIDFILE&lt;/span&gt; --name &lt;span class="nv"&gt;$NAME&lt;/span&gt;
	&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  start&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; no &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; log_daemon_msg &lt;span class="s2"&gt;"Starting &lt;/span&gt;&lt;span class="nv"&gt;$DESC&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    do_start
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
		&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; no &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; log_end_msg &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
		&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; no &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; log_end_msg &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
	&lt;span class="k"&gt;esac&lt;/span&gt;
  &lt;span class="p"&gt;;;&lt;/span&gt;
  stop&lt;span class="o"&gt;)&lt;/span&gt;
	&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; no &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; log_daemon_msg &lt;span class="s2"&gt;"Stopping &lt;/span&gt;&lt;span class="nv"&gt;$DESC&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
	do_stop
	&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
		&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; no &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; log_end_msg &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
		&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERBOSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; no &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; log_end_msg &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
	&lt;span class="k"&gt;esac&lt;/span&gt;
	&lt;span class="p"&gt;;;&lt;/span&gt;
  status&lt;span class="o"&gt;)&lt;/span&gt;
       status_of_proc &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DAEMON&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
       &lt;span class="p"&gt;;;&lt;/span&gt;
  &lt;span class="c1"&gt;#reload|force-reload)&lt;/span&gt;
	&lt;span class="c1"&gt;#&lt;/span&gt;
	&lt;span class="c1"&gt;# If do_reload() is not implemented then leave this commented out&lt;/span&gt;
	&lt;span class="c1"&gt;# and leave 'force-reload' as an alias for 'restart'.&lt;/span&gt;
	&lt;span class="c1"&gt;#&lt;/span&gt;
	&lt;span class="c1"&gt;#log_daemon_msg "Reloading $DESC" "$NAME"&lt;/span&gt;
	&lt;span class="c1"&gt;#do_reload&lt;/span&gt;
	&lt;span class="c1"&gt;#log_end_msg $?&lt;/span&gt;
	&lt;span class="c1"&gt;#;;&lt;/span&gt;
  restart&lt;span class="p"&gt;|&lt;/span&gt;force-reload&lt;span class="o"&gt;)&lt;/span&gt;
	&lt;span class="c1"&gt;#&lt;/span&gt;
	&lt;span class="c1"&gt;# If the "reload" option is implemented then remove the&lt;/span&gt;
	&lt;span class="c1"&gt;# 'force-reload' alias&lt;/span&gt;
	&lt;span class="c1"&gt;#&lt;/span&gt;
	log_daemon_msg &lt;span class="s2"&gt;"Restarting &lt;/span&gt;&lt;span class="nv"&gt;$DESC&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
	do_stop
	&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
	  &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
		do_start
		&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
			&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; log_end_msg &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
			&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; log_end_msg &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c1"&gt;# Old process is still running&lt;/span&gt;
			*&lt;span class="o"&gt;)&lt;/span&gt; log_end_msg &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c1"&gt;# Failed to start&lt;/span&gt;
		&lt;span class="k"&gt;esac&lt;/span&gt;
		&lt;span class="p"&gt;;;&lt;/span&gt;
	  *&lt;span class="o"&gt;)&lt;/span&gt;
	  	&lt;span class="c1"&gt;# Failed to stop&lt;/span&gt;
		log_end_msg &lt;span class="m"&gt;1&lt;/span&gt;
		&lt;span class="p"&gt;;;&lt;/span&gt;
	&lt;span class="k"&gt;esac&lt;/span&gt;
	&lt;span class="p"&gt;;;&lt;/span&gt;
  *&lt;span class="o"&gt;)&lt;/span&gt;
	&lt;span class="c1"&gt;#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" &amp;gt;&amp;amp;2&lt;/span&gt;
	&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: &lt;/span&gt;&lt;span class="nv"&gt;$SCRIPTNAME&lt;/span&gt;&lt;span class="s2"&gt; {start|stop|status|restart|force-reload}"&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="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
	&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;

:
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I had to add the --chdir and --background parameters myself. I also greatly shortened the timeout for killing the app. It appears it doesn't listen to the first signal. But it's a very simple webapp that doesn't matter if it gets hard-killed.&lt;/p&gt;</description><category>game</category><category>init</category><category>webserver</category><guid>https://bgstack15.ddns.net/blog/posts/2026/01/14/writing-init-script-for-explorer-lu/</guid><pubDate>Wed, 14 Jan 2026 13:52:00 GMT</pubDate></item><item><title>LU Explorer tools</title><link>https://bgstack15.ddns.net/blog/posts/2025/12/25/lu-explorer-tools/</link><dc:creator>bgstack15</dc:creator><description>&lt;h2&gt;README for lu-explorer-tools&lt;/h2&gt;
&lt;p&gt;This is a collection of tools that help set up a local copy of &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/explorer.lu"&gt;https://explorer.lu&lt;/a&gt;. You need a lot of assets, such as images, and a customized sqlite and fdb (database used by the game client). It's not either/or: It's both the sqlite and fdb files. The map files are optional.&lt;/p&gt;
&lt;p&gt;All these tools help prepare the game contents, but you still need to compile the code for the site (&lt;a href="https://github.com/LUDevNet/lu-explorer/"&gt;https://github.com/LUDevNet/lu-explorer/&lt;/a&gt;) and point it to the output assets of these scripts.&lt;/p&gt;
&lt;h3&gt;Upstream&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;This project's upstream is at &lt;a href="https://bgstack15.ddns.net/cgit/lu-explorer-tools"&gt;https://bgstack15.ddns.net/cgit/lu-explorer-tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/LUDevNet/lu-explorer/"&gt;code&lt;/a&gt; for the &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/explorer.lu"&gt;real site&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/2025/scrot-lu-explorer-custom-patchset.png"&gt;Screenshot showing a customized loot table 444 (Crux Prime enemies)&lt;br&gt;&lt;img alt="" src="https://bgstack15.ddns.net/blog/2025/scrot-lu-explorer-custom-patchset.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Visit &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/explorer.lu"&gt;upstream&lt;/a&gt; which shows you the vanilla dataset.&lt;/p&gt;
&lt;h3&gt;Reason for existence&lt;/h3&gt;
&lt;p&gt;By running your own copy of explorer.lu, you can point it at any fdb/sqlite combo, such as the &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/nexusuniverse.online/join"&gt;Nexus Universe dataset&lt;/a&gt;, to view their loot tables and items. Note that their custom &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/nexusuniverse.online/vendor-items"&gt;vendor items&lt;/a&gt; are defined in a &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/DarkflameUniverse/DarkflameServer/tree/main/vanity"&gt;vanity xml&lt;/a&gt; and not in the database.&lt;/p&gt;
&lt;h3&gt;Using&lt;/h3&gt;
&lt;p&gt;Start by preparing the client assets, e.g., to &lt;code&gt;/usr/src/lu-explorer/res&lt;/code&gt;. That would be directory &lt;code&gt;res/&lt;/code&gt; from an unpacked client.&lt;/p&gt;
&lt;p&gt;Some tools listed below are from the &lt;a href="https://github.com/LUDevNet/Assembly/releases/tag/v0.8"&gt;Assembly tools release tarball&lt;/a&gt; and are not from this lu-explorer-tools package.&lt;/p&gt;
&lt;p&gt;First, you have to build a template fdb file. Res-patches is the path of the expanded internal patchsets.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;explorer&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;patches&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cdclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, prepare the fdb from the original cdserver.sqlite file you wish to use. Use Assembly tools binary sqlite-to-fdb or &lt;a href="https://fdb.lu-dev.net/"&gt;https://fdb.lu-dev.net/&lt;/a&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;sqlite&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;CDS&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sqlite&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;patches&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;CDServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;09.&lt;/span&gt;&lt;span class="n"&gt;batlordcape&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;loottable1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sqlite&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;patches&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cdserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fdb&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run &lt;code&gt;prepare-sqlite-from-fdb-and-locale.sh&lt;/code&gt; which adds the PRIMARY KEY constraints needed by the lu-explorer web app, and localized strings.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;CDCLIENT_SCHEMA=cdclient_schema.sql.attempt1 ./prepare-sqlite-from-fdb-and-locale.sh res-patches/res/cdclient.fdb res-patches/locale/locale.xml res-patches/cdclient.sqlite
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, prepare the images by converting the .dds files to .png files.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;APPLY=1 INDIR=/usr/src/lu-explorer/res OUTDIR=/usr/src/lu-explorer/lu-res ./convert-res-to-lu-res.sh
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For additional patches on top of a vanilla client, that are extracted to this input directory, run this.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;VERBOSE=1 APPLY=1 INDIR=/usr/src/lu-explorer/res-patches/res OUTDIR=/usr/src/lu-explorer/lu-res ./convert-res-to-lu-res.sh
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Optionally, retrieve the map contents, which are json format.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;./fetch-luz-json.sh cdserver.sqlite
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The Assembly git &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/LUDevNet/Assembly/"&gt;repo&lt;/a&gt; and its &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/LUDevNet/Assembly/releases/tag/v0.8"&gt;releases v2&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An unpacked client.&lt;/li&gt;
&lt;li&gt;Be aware that the lu-explorer tool also depends on a packed client, because of directory &lt;code&gt;versions/&lt;/code&gt; and probably more.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Building&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;p&gt;Inline.&lt;/p&gt;</description><category>game</category><category>lego</category><category>shell</category><guid>https://bgstack15.ddns.net/blog/posts/2025/12/25/lu-explorer-tools/</guid><pubDate>Thu, 25 Dec 2025 14:27:00 GMT</pubDate></item><item><title>compiling Darkflame Lego Universe for myself</title><link>https://bgstack15.ddns.net/blog/posts/2025/12/17/compiling-darkflame-lego-universe-for-myself/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I wanted to try to make some code changes to &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/DarkflameUniverse/DarkflameServer"&gt;Darkflameserver Lego Universe&lt;/a&gt;, which of course necessitates compiling the application.&lt;/p&gt;
&lt;!-- And for the deep thinkers: if you've played much DLU you could guess what feature is specifically not supported. And then you can figure out what /cgit/DarkflameServer?h=feature%2Fuint32-and-chatfilter does --&gt;

&lt;p&gt;I cloned the repository and made a branch, and wrote my changes. Of course I used the main branch, instead of whatever commit would have been the last tag. Once I got the compilation process working, my database was migrated to the latest schema.&lt;/p&gt;
&lt;p&gt;While my changes worked, I learned that some interim commits which haven't been noticed yet broke the bananas and mermaid head item drops. They do not work at all! That is, none of those items drop, which will completely break the storyline missions. So I then reverted to the correct commit for whatever the last tag was, but my database had already been migrated. Apparently the project changed the datatype for a column for character id. And rather than trying to restore from backup (which I did have), I figured it would be easier to just rebase my commit on top of the commit that had updated that database schema change. That commit came before any of the faffing around with the bananas.&lt;/p&gt;
&lt;p&gt;And all this took quite some time, to iterate and realize the problem, and decide the path to rollback.&lt;/p&gt;
&lt;p&gt;So the next time I want to implement changes for myself in any project, I will work more carefully with commits.&lt;/p&gt;</description><category>docker</category><category>game</category><category>narrative</category><guid>https://bgstack15.ddns.net/blog/posts/2025/12/17/compiling-darkflame-lego-universe-for-myself/</guid><pubDate>Wed, 17 Dec 2025 13:40:00 GMT</pubDate></item><item><title>My contributions to Nexus Dashboard for Darkflame Lego Universe, part 1</title><link>https://bgstack15.ddns.net/blog/posts/2025/12/13/my-contributions-to-nexus-dashboard-for-darkflame-lego-universe-part-1/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I love the &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/DarkflameUniverse/DarkflameServer"&gt;Darkflame&lt;/a&gt; server emulator for Lego Universe. Part of this server is the &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/github.com/DarkflameUniverse/NexusDashboard"&gt;Nexus Dashboard&lt;/a&gt;, which is necessary for initializing users. It has auxiliary functions like admin messages to users, and approval of pet names.&lt;/p&gt;
&lt;p&gt;This is a great dashboard, and I have spent some time recently adding features to this. Upstream hasn't looked at my pull requests, but I have added a number of features in my &lt;a href="https://bgstack15.ddns.net/blog/cgit/NexusDashboard/?h=combined"&gt;own branch&lt;/a&gt; of the code.&lt;/p&gt;
&lt;p&gt;The major features I have added include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support working under a virtual path of the reverse proxy&lt;/li&gt;
&lt;li&gt;Add Leaderboards!&lt;/li&gt;
&lt;li&gt;Show equipped items on characters&lt;/li&gt;
&lt;li&gt;Add an "Approve all" button for pet names&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And minor features that I implemented:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Handle booleans from the config file better&lt;/li&gt;
&lt;/ul&gt;</description><category>flask</category><category>game</category><category>lego-universe</category><category>opensource</category><category>python</category><guid>https://bgstack15.ddns.net/blog/posts/2025/12/13/my-contributions-to-nexus-dashboard-for-darkflame-lego-universe-part-1/</guid><pubDate>Sat, 13 Dec 2025 13:53: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></channel></rss>