Categories: parenting » play

RSS - Atom - Subscribe via email

Updating my Minecraft command book using Emacs, TRAMP, and mcf.el

| minecraft, play, emacs

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 mcf if you set enable-rcon=true in your server.properties (also a good idea to set rcon.password) and you configure variables like mcf-rcon-password on the Emacs side. It needed a little tweaking to get it to connect to a remote server, so I've submitted a pull request. Anyway, since Emacs can talk to Minecraft and I can write sequences of Minecraft commands as functions, I thought about turning my Minecraft command books into something that I could update right from Emacs.

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

{
    "pack": {
        "pack_format": 10,
        "description": "sachac's tweaks"
    }
}

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

I used /reload to reload my Minecraft configuration and /datapack list to confirm that my datapack was loaded. Then /function sachac:command_book 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.

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.

(defun my-minecraft-datapack-function-file-name (world datapack-name function-name)
  "Return the filename for a mcfunction file given WORLD, DATAPACK-NAME, and FUNCTION-NAME."
  (seq-reduce
   (lambda (path subdir) (expand-file-name subdir path))
   (list "datapacks"
         datapack-name
         "data"
         datapack-name
         "functions"
         (concat function-name ".mcfunction"))
   world))

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

#+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
(with-temp-file
    (my-minecraft-datapack-function-file-name
     (org-entry-get-with-inheritance "WORLD")
     "sachac"
     "command_book")
  (insert (my-minecraft-book "Commands 8.5" "Mom" (append team quick body effects items))))
(mcf-eval "reload")
#+end_src

So now I can use C-c C-c 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.

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.

Using Org Mode tables and Emacs Lisp to create Minecraft Java JSON command books

| minecraft, org, emacs, play
  • [2023-04-12 Wed]: Remove / from the beginning so that I can use this in a function. Split book function into JSON and command. Updated effects to hide particles.
  • [2023-04-10 Mon]: Separated trident into channeling and riptide.

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 JourneyMap to teleport around. I didn't want to be the keeper of coordinates and be in charge of teleporting people to various places.

It turns out that you can make clickable books using JSON. I used the Minecraft book editor 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.

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.

Here's a screenshot:

2023-04-09_10-09-48.png
Figure 1: Screenshot of command book

This is the code to make it:

(defun my-minecraft-remove-markup (s)
  (if (string-match "^[=~]\\(.+?\\)[=~]$" s)
      (match-string 1 s)
    s))

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

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

With this code, I can generate a simple book like this:

(my-minecraft-book "Simple book" "sachac"
                   '(("Daytime" "set time 0800")
                     ("Creative" "gamemode creative" "#0000cd")))
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"}

To place it in the world:

  1. I changed my server.properties to set enable-command-block=true.
  2. In the game, I used /gamemode creative to switch to creative mode.
  3. I used /give @p minecraft:command_block to give myself a command block.
  4. I right-clicked an empty place to set the block there.
  5. I right-clicked on the command block and pasted in the command.
  6. I added a button.

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

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 #+name: mc-quick, I can refer to it with :var quick=mc-quick in the Emacs Lisp source block. (You can check the Org source for this post if that makes it easier to understand.)

Daytime time set 0800  
Clear weather weather clear  
Creative gamemode creative #0000cd
Survival gamemode survival #ff4500
Spectator gamemode spectator #228b22
(my-minecraft-book "Book from table" "sachac" quick)
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"}

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

Water breathing effect give @p minecraft:water_breathing infinite 255 true  
Night vision effect give @p minecraft:night_vision infinite 255 true  
Regeneration effect give @p minecraft:regeneration infinite 255 true  
Haste effect give @p minecraft:haste infinite 2 true  
Health boost effect give @p minecraft:health_boost infinite 255 true  
Slow falling effect give @p minecraft:slow_falling infinite 255 true  
Fire resist effect give @p minecraft:fire_resistance infinite 255 true  
Resistance effect give @p minecraft:resistance infinite 255 true  
Clear effects effect clear @p  

Some commands are pretty long. Specifying a width like <20> in the first row lets me use C-c TAB to toggle width.

Pickaxe give @p minecraft:diamond_pickaxe{Enchantments:[{id:"minecraft:fortune",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:efficiency",lvl:4s}]}  
Silk touch pickaxe give @p minecraft:diamond_pickaxe{Enchantments:[{id:"minecraft:silk_touch",lvl:1s},{id:"minecraft:mending",lvl:1s}]}  
Sword give @p minecraft:diamond_sword{Enchantments:[{id:"minecraft:looting",lvl:4s},{id:"minecraft:mending",lvl:1s}]}  
Axe give @p minecraft:diamond_axe{Enchantments:[{id:"minecraft:looting",lvl:4s},{id:"minecraft:mending",lvl:1s}]}  
Shovel give @p minecraft:diamond_shovel{Enchantments:[{id:"minecraft:fortune",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:efficiency",lvl:4s}]}  
Bow give @p minecraft:bow{Enchantments:[{id:"minecraft:infinity",lvl:1s},{id:"minecraft:mending",lvl:1s}]}  
Arrows give @p minecraft:arrow 64  
Torches give @p minecraft:torch 64  
Fishing give @p minecraft:fishing_rod{Enchantments:[{id:"minecraft:lure",lvl:4s},{id:"minecraft:luck_of_the_sea",lvl:4s},{id:"minecraft:mending",lvl:1s}]}  
Riptide trident give @p minecraft:trident{Enchantments:[{id:"minecraft:loyalty",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:riptide",lvl:4s}]}  
Channeling trident give @p minecraft:trident{Enchantments:[{id:"minecraft:loyalty",lvl:4s},{id:"minecraft:mending",lvl:1s},{id:"minecraft:channeling",lvl:1s}]}  
Weather rain weather rain  
Weather thunder weather thunder  
Birch signs give @p minecraft:birch_sign 16  
Bucket of water give @p minecraft:water_bucket  
Bucket of milk give @p minecraft:milk_bucket  
Bucket of lava give @p minecraft:lava_bucket  
Water bottles give @p minecraft:potion{Potion:"minecraft:water"} 3  
Blaze powder give @p minecraft:blaze_powder 16  
Brewing stand give @p minecraft:brewing_stand  
Magma cream give @p minecraft:magma_cream  

Here's what that table looks like in Org Mode:

2023-04-10_09-55-57.png
Figure 2: With column width

Here's how to combine multiple tables:

#+begin_src emacs-lisp :results silent :var quick=mc-quick :var effects=mc-effects :var items=mc-items :exports code
(my-minecraft-book "Book from multiple tables" "sachac" (append quick effects items))
#+end_src

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.

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!

View org source for this post

Minetest and MineClone 2

| fun, geek, play

A number of A+'s friends play Minecraft, so she got curious about it and started reading lots of e-books. We figured it might be time to let the video game genie out of the bottle since she tends to dive deeply into new interests and learn a lot. I wanted to get her started on Minetest, though, instead of buying one of the Minecraft editions. (Yay free and open source software!)

I installed MineTest, then used the Content tab to install MineClone 2 and the tutorial. I updated the other X220 so that I could run it there too, and we eventually turned it into a server. I went through the tutorial and then I showed it to her. We drew up an agreement to treat it the same as video time (20-minute timers for eye breaks, daily limits, need to be in the green zone). W- connected the other X220 to the TV with a VGA cable, and I used a USB hub to connect two keyboards and two mice to the laptop. A+ completed part of the tutorial. She found it hard to work the keyboard and the mouse while looking at the screen. She liked giving me directions to follow, taking over clicking or crafting whenever she felt comfortable.

We've been playing MineClone for almost a week, and it's starting to feel comfortable. We have a little base with a wheat/carrot farm, a well, and a fishing pond, and we're exploring the world. We might try creative mode in a while.

It looks like A+'s mostly curious about mobs, farming, ores, and flying around. She loves noticing things to explore and new recipes to craft. W- sometimes joins us, which is extra fun and helpful.

Minetest gives me opportunities to learn useful things, too. I'm getting better at saying yes to A+ when she wants to craft something, even if I wanted to save the materials for something else. (I should make a MineClone version of the reminder in our kitchen that says "Groceries are tuition for raising a cook.")

I'm still too impatient for the regular process of navigating around and bumping into resources, especially since we're working within 20-minute segments. I flew around with noclip/fast and set up some Travelnet boxes near interesting things, which A+ has liked a lot because now she can teleport independently.

I'm way too chicken to deal with damage, hostile mobs, or even night time at the moment. Since A+ would really like me to go fight the mobs she loves to read about, I'm thinking about how to gradually build up my courage with some kind of exposure therapy. =) I started learning how to modify armor so that I can keep myself mostly protected while leaving damage enabled for anyone who's braver (like W-). Maybe as I get the hang of it, I'll be able to dial down the protection or just let it keep a minimum HP level.

Lots of learning ahead!

Making a menu of activities

| sketchnotes, drawing, parenting, play

A- wants to be with me almost all the time. This can be challenging.

A multiple-choice question is easier than a fill-in-the-blank one, especially when it comes to "What do we do now?" A- seems less grumpy throughout the day when she can go from one activity to another of her choosing. I like letting her take the lead. I also like not having to come up with stuff. During bedtime, I sketched this menu:

Expanding our pretend play with roleplaying games

Posted: - Modified: | parenting, play

When we reorganized our living room to bring more things down to A-‘s level, W- thought of bringing the LEGO Heroica games down even though the boxes said 8+ years old. A- noticed them, of course. We built the different game elements and started playing. At first, she was too anxious to go near monsters. Her voice quavered and she made amusing attempts to distract us from the game. We said she could pick the wizard, hide behind our characters, use her ranged attack whenever the opportunity came up, and dash in to grab the treasure. She did so gleefully.

She eventually worked up the courage to deal with monsters with 1 strength, and then 2 strength, and even the occasional 3-strength final boss. She mixed in elements from other LEGO sets and invented her own rules, like letting cupcakes and cookies restore 1 health point. In pretend play, she fluidly shifted between being a golem, a goblin, and a wizard. We made up stories about a LEGO Friends cupcake cafe owner making friends with goblins by giving them free samples. She mixed game terms into everyday life: “I rolled shield!” She played with words like ranger and ranged. We took turns reading the comics and the manuals, and she had plenty of questions.

W- was curious about whether A- was ready for other roleplaying games, so he printed out Monster Slayers: The Heroes of Hesiod and The Champions of the Elements. I acted as the dungeon master, she played the wizard, and I played the fighter as well. We used the Heroica figures instead of the paper hero tokens, and we used LEGO cones for health points instead of shading in circles. She got the hang of rolling the dice and taking off the monsters' health points whenever she landed an attack. (I did the math for her.) It was lots of fun.

I wonder if I can enrich our pretend play to expand her world knowledge, help her practise solving problems, and maybe even motivate mark-making. We've been doing a bit of pretending with our improvised version of the LEGO Friends Lighthouse Rescue Center. I've shown her a few videos of veterinarians working in rescue centres, including one of a fish getting a prosthetic eye. She pretended to rescue some LEGO animals we had. I asked her to draw diagrams of where the animals were injured, come up with names for them, and write down the first letters of their names and the first letter of her name.

Amazing Tales released 2-page quickstart rules and lots of adventures for free. I might be able to adapt A Very Rainy Day to a wildlife rescue scenario. Hmmm…

Playground season

Posted: - Modified: | parenting, play

We spent the whole day at the playground and splash pad. I have a feeling that many days in summer will be like that. A- loved playing in the sand, climbing up the ladders, sliding on the slides, and touching the cold water. She mostly played by herself or with me, but sometimes she played with other kids. She didn’t want to go home until she got hungry.

What’s different about the playground compared to the drop-in centres that we often go to? She needs a little more supervision and assistance, because she often wants to climb. The bathrooms are a bit more of a walk. And of course, there’s sand everywhere, which means being a little more careful during snack time and when we get home.

What can I do to make the most of this change? I can make a list of things to think about, and I can use typing or dictation to jot down those thoughts. I can practise colouring or drawing. If I prepare, I can even use the time for my own exercise. That way, I can ease into more physical activity myself. There’s plenty of space, so I can do jumping jacks and other little ways to get myself moving.

I can pack more snacks and a light sweater for when it’s cool. I need to get better at applying sunscreen and encouraging A- to wear clothes that block the sun. A- would probably like a bucket or a yogurt container for collecting water or making sand castles. Napping in the stroller or on the couch can keep sand out of the bedrooms, and we can make a routine of showering before dinner. I’d like to find a hat she likes.

When the weather is nice, the best place for A- to be is outside. I’m just going to have to get used to being an outside person. It’s good for us!

Montessori, Reggio, and other thoughts on toddler learning

Posted: - Modified: | parenting, play

Montessori

I like the Montessori approach of taking kids seriously and helping them develop practical life skills. On its recommendation, we:

  • got A- real glasses and let her use real plates: Duralex Picardie tumblers and Corelle
  • introduced spreaders, knives, and scissors early
  • involved her in cooking and doing household chores: The Learning Tower is such a great help.
  • got two sets of magnetic letters as our movable alphabet
  • chose simple clothes to promote independence
  • got a small pitcher (actually a creamer) so that she can practise pouring
  • resisted the temptation to go overboard on toys, keeping her play area organized
  • respected play as the work of the child: be patient with repetition, help her find the right level of challenge, and so on.

I look forward to using sandpaper letters and other manipulatives. I like the idea of self-correcting materials and may experiment with a few. On the other hand, they do take up some space and are essentially unitaskers. Maybe the Montessori tackle boxes approach might be a reasonable compromise.

We might consider the Montessori casa system next year, when A- is 3.5, if finances permit. I think she likes pretend play a lot, though, and that doesn't seem to be as aligned with the Montessori approach. I think we'd lean toward a Reggio Emilia-inspired approach for preschool or kindergarten, mixing in elements from Montessori.

Reggio Emilia

The Reggio Emilia approach resonates strongly with me. I like its focus on child-led projects, with the grown-up focused on designing the environment, supporting exploration, and documenting projects. I like its support of play. I like its belief that kids are capable of amazing things if we let them, and the Wonder of Learning exhibit I got to see in 2016 had many examples of that.

The Ontario kindergarten curriculum looks great on paper, with lots of aspects like pedagogical documentation reminding me of Reggio Emilia. I'm all for play-based learning thoughtfully supported by grown-ups. While I'm home with A- and she's more oriented toward playing with me than with other kids, I want to focus on supporting and documenting her play.

Here are some ideas In applying from Reggio Emilia:

  • Co-learning: A- is the primary investigator. I help ask questions and explore ideas, and I take advantage of the opportunity to learn from her too.
  • Art for exploration and expression
  • Pedagogical documentation: making learning visible
  • The use of technology: We take a lot of photos and videos, and A- loves reviewing them. I talk about taking pictures to help us remember. She also has her own waterproof, shockproof camera, although she still tends to take pictures with her finger over the lens. She sometimes asks me to take a picture for her.
  • Embedding print in play: I write down her order when we're playing pretend restaurant, and I take advantage of other opportunities to model reading and writing
  • Going out into the community

I want to get better at designing her environment to provoke her interest, and collecting loose parts that we can transform.

I'm also working on building social ties with other families who might be interested in regular playdates so that the kids can come up with projects together when the time comes. I'm also really curious about floor books, but I'm not entirely sure how to implement them one on one with a toddler. Time to experiment!

There's a Reggio-inspired daycare opening up close to us, but I'm reluctant to commit to it while it's under construction. There's a highly recommended private school that follows a Reggio-inspired approach for preschool and kindergarten, and we might go for that if finances permit. Alternatively, I can probably help make public school kindergarten a great fit with parental involvement.

Tools of the Mind

I'm curious about Tools of the Mind's approach to developing executive function and self-regulation. Play planning sounds like fun. I want to talk about plans more with A- and model drawing the plans too.

In general…

A- is pretty good at learning stuff. She imitates quickly, can focus on an activity for a surprisingly long time, and comes up with new variations. She's starting to ask questions, and I look forward to helping her explore them.

I tend to be pleasantly surprised by what A- can do when other people try activities with her, which probably means that my developmental expectations are calibrated a little low. Bringing her to drop-in centres and classes helps me work around that by exposing her to other people's ideas and interactions. If I get better at pedagogical documentation and reflection, I might be able to improve my ability to scaffold her play, or I might be able to bring in more help from someone who can get more of a longitudinal view of A-.

If I keep involving her in daily life, I'm sure she'll learn all the important stuff. I'll also make room for unstructured play and exploration, because the world is an interesting place. If I pay attention to what she's learning and how, I think I'll have tons of fun and growth along the way too.