<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
	<title>Sacha Chua - category - minecraft</title>
	<atom:link href="https://sachachua.com/blog/category/minecraft/feed/index.xml" rel="self" type="application/rss+xml" />
	<atom:link href="https://sachachua.com/blog/category/minecraft" rel="alternate" type="text/html" />
	<link>https://sachachua.com/blog/category/minecraft/feed/index.xml</link>
	<description>Emacs, sketches, and life</description>
	<lastBuildDate>Mon, 06 Apr 2026 14:36:57 GMT</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>11ty</generator>
  <item>
		<title>Playing Minecraft parkour together</title>
		<link>https://sachachua.com/blog/2025/01/playing-minecraft-parkour-together/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Thu, 30 Jan 2025 14:21:25 GMT</pubDate>
    <category>minecraft</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2025/01/playing-minecraft-parkour-together/</guid>
		<description><![CDATA[<p>
A+ eight years old and she won't always want to play with me,
so while I can, we play together.
Lately, she's been interested in Minecraft parkour maps.
</p>

<p>
I remember when parkour was too frustrating for us
to do. In the beginning, I felt my stomach flip
every time I fell. I kept having to tell myself
that I wasn't the one actually falling. When we
first played through <a href="https://www.minecraft.net/en-us/marketplace/pdp?id=abac29cb-2229-4423-94a7-db2383ad4089">Path of the Jedi</a>, we spent a
long, long time on the stage with the parkour
challenge until we found out that we could bounce
on the leaves to reset the timers. That was too
hard for her before, so I ended up moving her
character through that stage.
</p>

<p>
Now, she enjoys the challenge. She zips ahead
through the different levels. Whenever she falls,
she just gets back up and does it again. "It's
frustration practice," she tells me cheerfully, my
words echoing from her mouth. I'm getting slightly
better at it too. My stomach no longer flip-flops,
and I can sometimes get those double-slime jumps
on the first try. It still takes me multiple tries
to get through a puzzle that she does in one go,
though. Still, I have the most patient tour guide
and teacher. She often stays a step or two ahead
of me so that she can point out where to go.
Sometimes I'm the one who spots the thing we need
to do to progress. If there's a particularly
tricky jump that I'm having a hard time with and
she's already far ahead, she lets her character
AFK while she stands beside me and cheers me on. I
still tend to yelp when I fall down, which she
finds amusing.
</p>

<p>
We started playing with <a href="https://hielkemaps.com/maps/parkour-spiral-2">Parkour Spiral 2</a>, and
we've been slowly working our way through other
ones released by <a href="https://hielkemaps.com/maps/">Hielke Maps</a>. I liked the multiple
paths in <a href="https://hielkemaps.com/maps/parkour-town">Parkour Town</a>, the small, self-contained
puzzles of <a href="https://hielkemaps.com/maps/parkour-paradise">Parkour Paradise</a>, and the colours of
<a href="https://hielkemaps.com/maps/parkour-egg">Parkour Egg</a>. We might not play <a href="https://hielkemaps.com/maps/parkour-volcano">Parkour Volcano</a>
though. We're not yet good at timed parkour, and
we ended up cheating our way past the
lava-is-rising stage in <a href="https://hielkemaps.com/maps/parkour-pyramid">Parkour Pyramid</a>. Anyway,
once we get through those puzzles, there are <a href="https://www.minecraftmaps.com/parkour-maps/1-19">tons</a>
<a href="https://www.planetminecraft.com/projects/tag/parkour/">of</a> <a href="https://www.9minecraft.net/tag/parkour-maps/">other</a> <a href="https://www.curseforge.com/minecraft/search?page=1&amp;pageSize=20&amp;sortBy=relevancy&amp;class=worlds&amp;categories=parkour">maps</a>.
</p>

<p>
I like how she works hard on figuring out puzzles
and is so satisfied when she makes a hard jump.
I'm glad I can semi-sort-of keep up with her, or
at least trail along behind her at a pace that
isn't too frustrating for her. It's fun figuring
out tougher levels together.
</p>

<p>
I'm glad that she talks about the cycle of trying
and failing and trying and learning, and how
feelings play into it: building that frustration
tolerance, trying hard things, feeling the
satisfaction of accomplishment. She still gets
frustrated in other contexts, but I'm confident
it'll transfer. I'm learning, too.
</p>
<div><a href="https://sachachua.com/blog/2025/01/playing-minecraft-parkour-together/index.org">View org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2025%2F01%2Fplaying-minecraft-parkour-together%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Minecraft tree orbs, tree farm upgrade</title>
		<link>https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Fri, 17 Jan 2025 01:10:06 GMT</pubDate>
    <category>minecraft</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/</guid>
		<description><![CDATA[<p>
A+ was inspired by the <a href="https://wingsoffire.fandom.com/wiki/SapWing_village">SapWing villages from Wings
of Fire</a> to make a couple of orb houses up in the trees.
</p>


<figure id="org30f5296">
<img src="https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/2025-01-16_17.33.21.png" alt="2025-01-16_17.33.21.png">

<figcaption><span class="figure-number">Figure 1: </span>A+'s latest creation: tree orbs</figcaption>
</figure>

<p>
I think she used copycat blocks and vertical slabs
from the modpack in order to get it to look so
round. "I'm excellent at creating things that are
not supposed to exist in Minecraft, in Minecraft,"
she says. The rope ladder is from me, as I needed
a non-creative-mode way to get up there.
</p>


<figure id="org5838402">
<img src="https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/2025-01-16_18.01.13.png" alt="2025-01-16_18.01.13.png">

<figcaption><span class="figure-number">Figure 2: </span>A bridge connects the two tree orbs. A+ is a big fan of safety railings.</figcaption>
</figure>


<figure id="orgdb70367">
<img src="https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/2025-01-16_18.02.05.png" alt="2025-01-16_18.02.05.png">

<figcaption><span class="figure-number">Figure 3: </span>My orb has a hammock, a furnace, and a crafting table</figcaption>
</figure>


<figure id="orgd7e2ada">
<img src="https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/2025-01-16_18.29.08.png" alt="2025-01-16_18.29.08.png">

<figcaption><span class="figure-number">Figure 4: </span>She also decided to upgrade my tree farm with rich soil, a portable storage interface, and an item sorter.</figcaption>
</figure>

<p>
The smart chute is set to drop only full stacks (64 items) so that the extra saplings will stay in the chest and feed the deployer.
The brass funnels have the different items in their filter slots. She has them feeding into netherite backpacks.
</p>


<figure id="orgc498575">
<img src="https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/2025-01-16_17.36.34.png" alt="2025-01-16_17.36.34.png">

<figcaption><span class="figure-number">Figure 5: </span>As for me, I made a simple library with an enchanting table.</figcaption>
</figure>

<p>
I've got a couple of librarians. I'll probably set
up some more eventually, maybe in a large wing
focused on trading. I've also been upgrading the
wheat farm with organic compost that's broken down
into rich soil. I started some flax plants for
string.
</p>

<p>
Just toodling along&#x2026;
</p>
<div><a href="https://sachachua.com/blog/2025/01/minecraft-tree-orbs-tree-farm-upgrade/index.org">View org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2025%2F01%2Fminecraft-tree-orbs-tree-farm-upgrade%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>A brief foray into Underdog, a realistic Minecraft modpack; returning to Total Animation</title>
		<link>https://sachachua.com/blog/2025/01/a-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Sun, 05 Jan 2025 16:55:04 GMT</pubDate>
    <category>minecraft</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2025/01/a-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation/</guid>
		<description><![CDATA[<p>
A+ often enjoys watching Minecraft videos on
Youtube where streamers take on challenges like
surviving harder, more realistic worlds. We
briefly gave <a href="https://www.curseforge.com/minecraft/modpacks/rlcraft">RL Craft</a> a spin the other day, but I
died to a dragon and that wasn't realistic enough
for A+, so we checked out <a href="https://www.curseforge.com/minecraft/modpacks/underdog">Underdog</a> today.
</p>

<p>
We couldn't get Underdog to work under <a href="https://gdlauncher.com/">GDLauncher</a>
on her computer even when I changed the Java
interpreter and memory settings as suggested in
the <a href="https://github.com/juraj-hrivnak/Underdog/wiki/Installation">Underdog installation instructions</a>. I
installed <a href="https://prismlauncher.org/">PrismLauncher</a> on her computer and that
worked fine.
</p>

<p>
As usual, when we started the world, we set it to
peaceful and turned the day/night cycle off. The
early progression quests went all right, except
for the one about obtaining 32 balls of clay. We
found a few, but I'm not sure if there were enough
clay blocks near our spawn or maybe they were just
hard to see under the water. I liked how the
process of making charcoal involved making a pit
and burning the stacked firewood blocks under a
nonflammable material (I used dirt).
</p>


<figure id="orgdf1203e">
<img src="https://sachachua.com/blog/2025/01/a-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation/2025-01-02_12.27.05.png" alt="2025-01-02_12.27.05.png">

<figcaption><span class="figure-number">Figure 1: </span>Our little crafting area in Underdog.</figcaption>
</figure>


<figure id="org5bbfb4f">
<img src="https://sachachua.com/blog/2025/01/a-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation/2025-01-02_12.27.10.png" alt="2025-01-02_12.27.10.png">

<figcaption><span class="figure-number">Figure 2: </span>Making some charcoal by burying burning wood under dirt</figcaption>
</figure>

<p>
A+ wasn't a fan of how much work was involved in
everything, though, so I'm not sure we'll return
to this world. I think when she says "realistic",
she's looking for something more like <a href="https://www.curseforge.com/minecraft/modpacks/total-animation">Total
Animation</a> than <a href="https://www.curseforge.com/minecraft/mc-mods/terrafirmacraft">TerraFirmaCraft</a>. Here's what Total
Animation looks like:
</p>


<figure id="org912f98a">
<img src="https://sachachua.com/blog/2025/01/a-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation/2025-01-02_14.17.33.png" alt="2025-01-02_14.17.33.png">

<figcaption><span class="figure-number">Figure 3: </span>Screenshot of Total Animation</figcaption>
</figure>

<p>
(You can tell I built the house because it's a
boring box-like thing made with whatever wood was
handy.)
</p>

<p>
We last checked out Total Animation in October.
It's a little too laggy on my Lenovo P52 laptop,
so I usually play without the shaders and visual
effects that make it special. A+ has more patience
for that, and since she plays in Windows, her
P52's (small) Nvidia GPU can accelerate it enough
to be tolerable.
</p>

<p>
There are a ton of modpacks that focus on more
realistic textures/shaders/etc., so she'll
probably flip through a few of them. I might as
well practise my journaling along the way.
</p>
<div><a href="https://sachachua.com/blog/2025/01/a-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation/index.org">View org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2025%2F01%2Fa-brief-foray-into-underdog-a-realistic-minecraft-modpack-returning-to-total-animation%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Cuberventures: Early game Create Mod</title>
		<link>https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Wed, 01 Jan 2025 22:14:08 GMT</pubDate>
    <category>minecraft</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/</guid>
		<description><![CDATA[<p>
A+ likes exploring different Minecraft Java
modpacks in creative mode. We're currently playing
<a href="https://www.curseforge.com/minecraft/modpacks/fxnt-create-2">FXNT Create 2</a>. I like challenging myself to figure
things out in survival mode, so I'm getting a lot
of practice in building early-game survival farms
with Create. My setup has changed a little bit
over the last few modpacks/worlds. I usually start
by mining enough iron and zinc to make a
<a href="https://create.fandom.com/wiki/Mechanical_Press">mechanical press</a> so that I can make the iron
sheets used in other machines. Then I make a
<a href="https://create.fandom.com/wiki/Mechanical_Mixer">mechanical mixer</a> so that I can make andesite
nuggets more efficiently. Then I make a <a href="https://create.fandom.com/wiki/Millstone">millstone</a>
and an <a href="https://create.fandom.com/wiki/Encased_Fan">encased fan</a> so that I can process
cobblestone and wash the resulting gravel
manually.
</p>

<p>
Once that's in place, I can start making more elaborate things.
</p>


<figure id="org2a24bad">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_16.47.59.png" alt="2025-01-01_16.47.59.png">

<figcaption><span class="figure-number">Figure 1: </span>A simple radial tree farm uses a mechanical saw.</figcaption>
</figure>


<figure id="org8a428c3">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_16.47.03.png" alt="2025-01-01_16.47.03.png">

<figcaption><span class="figure-number">Figure 2: </span>This time, I experimented with putting my crop farm under the tree farm.</figcaption>
</figure>

<p>
I used to have the encased fans just blowing
horizontally. After I learned that I can use
encased fans to blow upwards through a depot, I
switched to setting up my blasting/smoking/washing
stations vertically so that I didn't burn myself
as often.
</p>


<figure id="org455d154">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_16.36.12.png" alt="2025-01-01_16.36.12.png">

<figcaption><span class="figure-number">Figure 3: </span>My blasting/smoking/washing stations</figcaption>
</figure>

<p>
The most recent thing I added to this world is this
cobblestone-gravel-iron nugget machine.
</p>


<figure id="orgce9120b">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_13.27.19.png" alt="2025-01-01_13.27.19.png">

<figcaption><span class="figure-number">Figure 4: </span>The cobblestone generator&#x2026;</figcaption>
</figure>


<figure id="org317da73">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_13.28.06.png" alt="2025-01-01_13.28.06.png">

<figcaption><span class="figure-number">Figure 5: </span>&#x2026; feeds into a millstone/washer</figcaption>
</figure>


<figure id="org0e5fffc">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_13.29.02.png" alt="2025-01-01_13.29.02.png">

<figcaption><span class="figure-number">Figure 6: </span>All together now</figcaption>
</figure>


<figure id="orgca0f238">
<img src="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/2025-01-01_16.07.40.png" alt="2025-01-01_16.07.40.png">

<figcaption><span class="figure-number">Figure 7: </span>I changed the cobblestone output to feed into two millstones, dropping the results with chutes</figcaption>
</figure>

<p>
I needed to upgrade to a large waterwheel to drive
the two millstones along with the fans.
</p>

<p>
Next things I'll probably try:
</p>

<ul class="org-ul">
<li>The lava farm is filling up nicely, so I can put
some pipes underneath it and have a pump move
lava into a basin for making andesite. That'll
give me something to do with the flint from the
iron nugget farm. I'll need to mine some copper
first, though.</li>
<li>I can start mining for diamonds so that I can
get obsidian and go to the Nether. I made a rope
pulley + drills mining contraption, but (a) I
think it got stuck after going past some lava
and water, and (b) the shaft it made uncovered a
deep dark biome, so&#x2026; that's a little scary.
Maybe I'll do some branch mining, or cave mining
when the world is set to peaceful.</li>
</ul>
<div><a href="https://sachachua.com/blog/2025/01/cuberventures-early-game-create-mod/index.org">View org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2025%2F01%2Fcuberventures-early-game-create-mod%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Updating my Minecraft command book using Emacs, TRAMP, and mcf.el</title>
		<link>https://sachachua.com/blog/2023/04/updating-my-minecraft-command-book-using-emacs-tramp-and-mcf-el/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Wed, 12 Apr 2023 14:28:27 GMT</pubDate>
    <category>minecraft</category>
<category>play</category>
<category>emacs</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2023/04/updating-my-minecraft-command-book-using-emacs-tramp-and-mcf-el/</guid>
		<description><![CDATA[<p>
I wanted to see what else people have done in terms of combining
Minecraft and Emacs. It turns out that you can control Minecraft from
Emacs via <a href="https://github.com/rasensuihei/mcf">mcf</a> if you set <code>enable-rcon=true</code> in your
<code>server.properties</code> (also a good idea to set <code>rcon.password</code>) and you
configure variables like <code>mcf-rcon-password</code> on the Emacs side. It
needed a little tweaking to get it to connect to a remote server, so
I've submitted a <a href="https://github.com/rasensuihei/mcf/pull/11">pull request</a>. Anyway, since Emacs can talk to
Minecraft and I can write sequences of Minecraft commands as
functions, I thought about turning my <a href="https://sachachua.com/blog/">Minecraft command books</a> into
something that I could update right from Emacs.
</p>

<p>
Creating my own datapack was pretty straightforward once I figured out
the directory structure. I needed to put functions in
<code>&lt;world-name&gt;/datapacks/sachac/data/sachac/functions</code>. Inside
<code>&lt;world-name&gt;/datapacks/sachac</code>, I created <code>pack.mcmeta</code> with the
following contents:
</p>

<div class="org-src-container">
<pre class="src src-json">{
    "pack": {
        "pack_format": 10,
        "description": "sachac's tweaks"
    }
}
</pre>
</div>

<p>
Inside <code>&lt;world-name&gt;/datapacks/sachac/data/sachac/functions</code>, I
created a <code>command_book.mcfunction</code> file with the command to give me
the book. I updated my command book function to remove the <code>/</code> from
the beginning.
</p>

<p>
I used <code>/reload</code> to reload my Minecraft configuration and <code>/datapack
list</code> to confirm that my datapack was loaded. Then <code>/function
sachac:command_book</code> ran the function to give me the command book, so
that all worked out. I replaced the command in the command block with
the function call.
</p>

<p>
The next step was to update it directly from Emacs, including
reloading. First, I needed a function to give me the filename of a
function file.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my-minecraft-datapack-function-file-name</span> (world datapack-name function-name)
  <span class="org-doc">"Return the filename for a mcfunction file given WORLD, DATAPACK-NAME, and FUNCTION-NAME."</span>
  (seq-reduce
   (<span class="org-keyword">lambda</span> (path subdir) (expand-file-name subdir path))
   (list <span class="org-string">"datapacks"</span>
         datapack-name
         <span class="org-string">"data"</span>
         datapack-name
         <span class="org-string">"functions"</span>
         (concat function-name <span class="org-string">".mcfunction"</span>))
   world))
</pre>
</div>

<p>
I used <code>C-c C-x p</code> (<code>org-set-property</code>) to add a <code>WORLD</code> property to
my Org subtree. For example, my snapshot world is at
<code>/ssh:desktop:~/.minecraft/saves/Snapshot</code>. Then I can get the correct
value within the subtree by using <code>org-entry-get-with-inheritance</code>.
This is how I wrote the command book function for my snapshot world:
</p>

<div class="org-src-container">
<pre class="src src-org"><span class="org-org-block-begin-line">#+begin_src emacs-lisp :var body=mc-snapshot :var team=mc-team :var quick=mc-quick :var effects=mc-effects :var items=mc-items :results silent</span>
<span class="org-org-block">(</span><span class="org-org-block"><span class="org-keyword">with-temp-file</span></span>
<span class="org-org-block">    (my-minecraft-datapack-function-file-name</span>
<span class="org-org-block">     (org-entry-get-with-inheritance </span><span class="org-org-block"><span class="org-string">"WORLD"</span></span><span class="org-org-block">)</span>
<span class="org-org-block">     </span><span class="org-org-block"><span class="org-string">"sachac"</span></span>
<span class="org-org-block">     </span><span class="org-org-block"><span class="org-string">"command_book"</span></span><span class="org-org-block">)</span>
<span class="org-org-block">  (insert (my-minecraft-book </span><span class="org-org-block"><span class="org-string">"Commands 8.5"</span></span><span class="org-org-block"> </span><span class="org-org-block"><span class="org-string">"Mom"</span></span><span class="org-org-block"> (append team quick body effects items))))</span>
<span class="org-org-block">(</span><span class="org-org-block"><span class="org-keyword">mcf-eval</span></span><span class="org-org-block"> </span><span class="org-org-block"><span class="org-string">"reload"</span></span><span class="org-org-block">)</span>
<span class="org-org-block-end-line">#+end_src</span>
</pre>
</div>

<p>
So now I can use <code>C-c C-c</code> to execute the Emacs Lisp block and have my
Minecraft world updated. Then I just need to right-click on my command
block's button or run the function in order to get the new version.
</p>

<p>
I'm looking forward to learning more about mcfunctions so that I can
write a function that automatically replaces the book in everyone's
inventories. Could be fun.
</p>

<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2023%2F04%2Fupdating-my-minecraft-command-book-using-emacs-tramp-and-mcf-el%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Using Org Mode tables and Emacs Lisp to create Minecraft Java JSON command books</title>
		<link>https://sachachua.com/blog/2023/04/using-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Sun, 09 Apr 2023 14:57:36 GMT</pubDate>
    <category>minecraft</category>
<category>org</category>
<category>emacs</category>
<category>play</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2023/04/using-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books/</guid>
		<description><![CDATA[<div class="update" id="org0d8a965">
<ul class="org-ul">
<li><span class="timestamp-wrapper"><span class="timestamp">[2023-04-12 Wed]</span></span>: Remove <code>/</code> from the beginning so that I can use
this in a function. Split book function into JSON and command. Updated effects to hide particles.</li>
<li><span class="timestamp-wrapper"><span class="timestamp">[2023-04-10 Mon]</span></span>: Separated trident into channeling and riptide.</li>
</ul>

</div>

<p>
A+ likes playing recent Minecraft snapshots because of the new
features. The modding systems haven't been updated for the snaphots
yet, so we couldn't use mods like <a href="https://www.curseforge.com/minecraft/mc-mods/journeymap">JourneyMap</a> to teleport around. I
didn't want to be the keeper of coordinates and be in charge of
teleporting people to various places.
</p>

<p>
It turns out that you can make clickable books using JSON. I used the
<a href="https://minecraft.tools/en/book.php">Minecraft book editor</a> to make a prototype book and figure out the
syntax. Then I used a command block to give it to myself in order to
work around the length limits on commands in chat. A+ loved being able
to carry around a book that could teleport her to either of us or to
specified places, change the time of day, clear the weather, and
change game mode. That also meant that I no longer had to type all the
commands to give her water breathing, night vision, or slow falling,
or give her whatever tools she forgot to pack before she headed out.
It was so handy, W- and I got our own copies too.
</p>

<p>
Manually creating the clickable targets was annoying, especially since
we wanted the book to have slightly different content depending on the
instance we were in. I wanted to be able to specify the contents using
Org Mode tables and generate the JSON for the book using Emacs.
</p>

<p>
Here's a screenshot:
</p>


<figure id="orgae5b5bb">
<img src="https://sachachua.com/blog/2023/04/using-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books/2023-04-09_10-09-48.png" alt="2023-04-09_10-09-48.png">

<figcaption><span class="figure-number">Figure 1: </span>Screenshot of command book</figcaption>
</figure>

<p>
This is the code to make it:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my-minecraft-remove-markup</span> (s)
  (<span class="org-keyword">if</span> (string-match <span class="org-string">"^[=~]</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">(</span></span><span class="org-string">.+?</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">)</span></span><span class="org-string">[=~]$"</span> s)
      (match-string 1 s)
    s))

(<span class="org-keyword">defun</span> <span class="org-function-name">my-minecraft-book-json</span> (title author book)
  <span class="org-doc">"Generate the JSON for TITLE AUTHOR BOOK.</span>
<span class="org-doc">BOOK should be a list of lists of the form (text click-command color)."</span>
  (json-encode
   <span class="org-highlight-quoted-quote">`</span>((pages . 
            ,(apply <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">vector</span>
                    (mapcar
                     (<span class="org-keyword">lambda</span> (page)
                       (json-encode
                        (apply <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">vector</span> 
                               (seq-mapcat
                                (<span class="org-keyword">lambda</span> (command)
                                  (<span class="org-keyword">let</span> ((text (my-minecraft-remove-markup (<span class="org-keyword">or</span> (elt command 0) <span class="org-string">""</span>)))
                                        (click (my-minecraft-remove-markup (<span class="org-keyword">or</span> (elt command 1) <span class="org-string">""</span>)))
                                        (color (<span class="org-keyword">or</span> (elt command 2) <span class="org-string">""</span>)))
                                    (<span class="org-keyword">unless</span> (<span class="org-keyword">or</span> (string-match <span class="org-string">"^&lt;.*&gt;$"</span> text)
                                                (string-match <span class="org-string">"^&lt;.*&gt;$"</span> click)
                                                (string-match <span class="org-string">"^&lt;.*&gt;$"</span> color))
                                      (list
                                       (append
                                        (list (cons <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">text</span> text))
                                        (<span class="org-keyword">unless</span> (string= click <span class="org-string">""</span>)
                                          <span class="org-highlight-quoted-quote">`</span>((clickEvent 
                                             (action . <span class="org-string">"run_command"</span>)
                                             (value . ,(concat <span class="org-string">"/"</span> click)))))                                    
                                        (<span class="org-keyword">unless</span> (string= color <span class="org-string">""</span>)
                                          (list (cons <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">color</span>
                                                      color))))
                                       (<span class="org-keyword">if</span> (string= color <span class="org-string">""</span>)
                                           <span class="org-highlight-quoted-quote">'</span>((text . <span class="org-string">"\n"</span>))
                                         <span class="org-highlight-quoted-quote">'</span>((text . <span class="org-string">"\n"</span>)
                                           (color . <span class="org-string">"reset"</span>)))))))
                                page))))
                     (seq-partition book 14)
                     )))
     (author . ,author)
     (title . ,title))))

(<span class="org-keyword">defun</span> <span class="org-function-name">my-minecraft-book</span> (title author book)
  <span class="org-doc">"Generate a command to put into a command block in order to get a book.</span>
<span class="org-doc">Label it with TITLE and AUTHOR.</span>
<span class="org-doc">BOOK should be a list of lists of the form (text click-command color).</span>
<span class="org-doc">Copy the command text to the kill ring for pasting into a command block."</span>
  (<span class="org-keyword">let</span> ((s (concat <span class="org-string">"item replace entity @p weapon.mainhand with written_book"</span>
                   (my-minecraft-book-json title author book))))
    (kill-new s)
    s))
</pre>
</div>

<p>
With this code, I can generate a simple book like this:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(my-minecraft-book <span class="org-string">"Simple book"</span> <span class="org-string">"sachac"</span>
                   <span class="org-highlight-quoted-quote">'</span>((<span class="org-string">"Daytime"</span> <span class="org-string">"set time 0800"</span>)
                     (<span class="org-string">"Creative"</span> <span class="org-string">"gamemode creative"</span> <span class="org-string">"#0000cd"</span>)))
</pre>
</div>

<pre class="example" id="org1188d1b">
item replace entity @p weapon.mainhand with written_book{"pages":["[{\"text\":\"Daytime\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/set time 0800\"}},{\"text\":\"\\n\"},{\"text\":\"Creative\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/gamemode creative\"},\"color\":\"#0000cd\"},{\"text\":\"\\n\",\"color\":\"reset\"}]"],"author":"sachac","title":"Simple book"}
</pre>

<p>
To place it in the world:
</p>
<ol class="org-ol">
<li>I changed my <code>server.properties</code> to set <code>enable-command-block=true</code>.</li>
<li>In the game, I used <code>/gamemode creative</code> to switch to creative mode.</li>
<li>I used <code>/give @p minecraft:command_block</code> to give myself a command block.</li>
<li>I right-clicked an empty place to set the block there.</li>
<li>I right-clicked on the command block and pasted in the command.</li>
<li>I added a button.</li>
</ol>

<p>
Then I clicked on the button and it replaced whatever I was holding
with the book. I used <code>item replace</code> instead of <code>give</code> so that it's
easy to replace old versions.
</p>

<p>
On the Org Mode side, it's much nicer to specify commands in a named
table. For example, if I name the following table with <code>#+name:
mc-quick</code>, I can refer to it with <code>:var quick=mc-quick</code> in the Emacs
Lisp source block. (<a href="https://sachachua.com/2023/04/using-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books/index.org">You can check the Org source for this post if that makes it easier to understand.</a>)
</p>

<table id="orgf6f03b5">


<colgroup>
<col class="org-left">

<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">Daytime</td>
<td class="org-left">time set 0800</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Clear weather</td>
<td class="org-left">weather clear</td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Creative</td>
<td class="org-left">gamemode creative</td>
<td class="org-left">#0000cd</td>
</tr>

<tr>
<td class="org-left">Survival</td>
<td class="org-left">gamemode survival</td>
<td class="org-left">#ff4500</td>
</tr>

<tr>
<td class="org-left">Spectator</td>
<td class="org-left">gamemode spectator</td>
<td class="org-left">#228b22</td>
</tr>
</tbody>
</table>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(my-minecraft-book <span class="org-string">"Book from table"</span> <span class="org-string">"sachac"</span> quick)
</pre>
</div>

<pre class="example" id="org2d670cd">
item replace entity @p weapon.mainhand with written_book{"pages":["[{\"text\":\"Daytime\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/time set 0800\"}},{\"text\":\"\\n\"},{\"text\":\"Clear weather\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/weather clear\"}},{\"text\":\"\\n\"},{\"text\":\"Creative\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/gamemode creative\"},\"color\":\"#0000cd\"},{\"text\":\"\\n\",\"color\":\"reset\"},{\"text\":\"Survival\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/gamemode survival\"},\"color\":\"#ff4500\"},{\"text\":\"\\n\",\"color\":\"reset\"},{\"text\":\"Spectator\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/gamemode spectator\"},\"color\":\"#228b22\"},{\"text\":\"\\n\",\"color\":\"reset\"}]"],"author":"sachac","title":"Book from table"}
</pre>


<p>
Then I can define several named tables and append them together. Here's one for different effects:
</p>

<table id="orgb83d075">


<colgroup>
<col class="org-left">

<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">Water breathing</td>
<td class="org-left"><code>effect give @p minecraft:water_breathing infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Night vision</td>
<td class="org-left"><code>effect give @p minecraft:night_vision infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Regeneration</td>
<td class="org-left"><code>effect give @p minecraft:regeneration infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Haste</td>
<td class="org-left"><code>effect give @p minecraft:haste infinite 2 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Health boost</td>
<td class="org-left"><code>effect give @p minecraft:health_boost infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Slow falling</td>
<td class="org-left"><code>effect give @p minecraft:slow_falling infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Fire resist</td>
<td class="org-left"><code>effect give @p minecraft:fire_resistance infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Resistance</td>
<td class="org-left"><code>effect give @p minecraft:resistance infinite 255 true</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Clear effects</td>
<td class="org-left"><code>effect clear @p</code></td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
Some commands are pretty long. Specifying a width like <code>&lt;20&gt;</code> in the first row lets me use <code>C-c TAB</code> to toggle width.
</p>

<table id="orga2e7d34">


<colgroup>
<col class="org-left">

<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">Pickaxe</td>
<td class="org-left"><code>give @p minecraft:diamond_pickaxe{Enchantments:[{id:"minecraft:fortune",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:efficiency",lvl:4s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Silk touch pickaxe</td>
<td class="org-left"><code>give @p minecraft:diamond_pickaxe{Enchantments:[{id:"minecraft:silk_touch",lvl:1s},{id:"minecraft:mending",lvl:1s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Sword</td>
<td class="org-left"><code>give @p minecraft:diamond_sword{Enchantments:[{id:"minecraft:looting",lvl:4s},{id:"minecraft:mending",lvl:1s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Axe</td>
<td class="org-left"><code>give @p minecraft:diamond_axe{Enchantments:[{id:"minecraft:looting",lvl:4s},{id:"minecraft:mending",lvl:1s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Shovel</td>
<td class="org-left"><code>give @p minecraft:diamond_shovel{Enchantments:[{id:"minecraft:fortune",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:efficiency",lvl:4s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Bow</td>
<td class="org-left"><code>give @p minecraft:bow{Enchantments:[{id:"minecraft:infinity",lvl:1s},{id:"minecraft:mending",lvl:1s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Arrows</td>
<td class="org-left"><code>give @p minecraft:arrow 64</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Torches</td>
<td class="org-left"><code>give @p minecraft:torch 64</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Fishing</td>
<td class="org-left"><code>give @p minecraft:fishing_rod{Enchantments:[{id:"minecraft:lure",lvl:4s},{id:"minecraft:luck_of_the_sea",lvl:4s},{id:"minecraft:mending",lvl:1s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Riptide trident</td>
<td class="org-left"><code>give @p minecraft:trident{Enchantments:[{id:"minecraft:loyalty",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:riptide",lvl:4s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Channeling trident</td>
<td class="org-left"><code>give @p minecraft:trident{Enchantments:[{id:"minecraft:loyalty",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:channeling",lvl:1s}]}</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Weather rain</td>
<td class="org-left"><code>weather rain</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Weather thunder</td>
<td class="org-left"><code>weather thunder</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Birch signs</td>
<td class="org-left"><code>give @p minecraft:birch_sign 16</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Bucket of water</td>
<td class="org-left"><code>give @p minecraft:water_bucket</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Bucket of milk</td>
<td class="org-left"><code>give @p minecraft:milk_bucket</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Bucket of lava</td>
<td class="org-left"><code>give @p minecraft:lava_bucket</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Water bottles</td>
<td class="org-left"><code>give @p minecraft:potion{Potion:"minecraft:water"} 3</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Blaze powder</td>
<td class="org-left"><code>give @p minecraft:blaze_powder 16</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Brewing stand</td>
<td class="org-left"><code>give @p minecraft:brewing_stand</code></td>
<td class="org-left">&#xa0;</td>
</tr>

<tr>
<td class="org-left">Magma cream</td>
<td class="org-left"><code>give @p minecraft:magma_cream</code></td>
<td class="org-left">&#xa0;</td>
</tr>
</tbody>
</table>

<p>
Here's what that table looks like in Org Mode:
</p>


<figure id="orgcccb400">
<img src="https://sachachua.com/blog/2023/04/using-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books/2023-04-10_09-55-57.png" alt="2023-04-10_09-55-57.png">

<figcaption><span class="figure-number">Figure 2: </span>With column width</figcaption>
</figure>

<p>
Here's how to combine multiple tables:
</p>

<div class="org-src-container">
<pre class="src src-org"><span class="org-org-block-begin-line">#+begin_src emacs-lisp :results silent :var quick=mc-quick :var effects=mc-effects :var items=mc-items :exports code</span>
<span class="org-org-block">(my-minecraft-book </span><span class="org-org-block"><span class="org-string">"Book from multiple tables"</span></span><span class="org-org-block"> </span><span class="org-org-block"><span class="org-string">"sachac"</span></span><span class="org-org-block"> (append quick effects items))</span>
<span class="org-org-block-end-line">#+end_src</span>
</pre>
</div>

<p>
Now producing instance-specific books is just a matter of including
the sections I want, like a table that has coordinates for different
bases in that particular instance.
</p>

<p>
I thought about making an Org link type for click commands and some
way of exporting that will convert to JSON and keep the whitespace.
That way, I might be able to write longer notes and export them to
Minecraft book JSON for in-game references, such as notes on villager
blocks or potion ingredients. The table + Emacs Lisp approach is
already quite useful for quick shortcuts, though, and it was easy to
write. We'll see if we need more fanciness!</p>
<div><a href="https://sachachua.com/blog/2023/04/using-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books/index.org">View org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2023%2F04%2Fusing-org-mode-tables-and-emacs-lisp-to-create-minecraft-java-json-command-books%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item>
	</channel>
</rss>