I've been really enjoying playing sungka with my eight-year-old daughter. We've been playing it for a number of years now. Usually she likes to start out with one shell in each cup and working our way up to seven shells in each cup over a series of rounds.
Over the last week, she's gotten a lot better at playing. In the past, she used to make her moves fairly randomly, and she liked having the advantage of starting off with a few extra shells in her home. Now she doesn't need that starting point, and she's beginning to plan ahead. She counts the shells to predict where she's going to end up. She recognizes common patterns like clearing out the cups closest to her home. She loves moving shells out of the way so that she can make a very large capture, cupped hands full of shells.
Sungka has taken over as her current hyperfocus. It's the game she asks to play with me when her virtual school is on a recess break. I enjoy playing with her. Even when I'm losing, I enjoy watching her become more dextrous as she drops the shells in one at a time, and I like watching her plan ahead.
I played sungka a lot when I was a kid around her age. I think the school had some sungka boards that people could borrow after class, and I played with the other kids until it was time to go home. I don't know if this is a game that I can bring to the playground. It'll probably be a challenge with sand and kids and lots of small pieces. I think this will just be a game for home and for us, but it's wonderful that I get to share it with her.
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:
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.
(defunmy-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:
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.
[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:
This is the code to make it:
(defunmy-minecraft-remove-markup (s)
(if (string-match "^[=~]\\(.+?\\)[=~]$" s)
(match-string 1 s)
s))
(defunmy-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))))
(defunmy-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:
I changed my server.properties to set enable-command-block=true.
In the game, I used /gamemode creative to switch to creative mode.
I used /give @p minecraft:command_block to give myself a command block.
I right-clicked an empty place to set the block there.
I right-clicked on the command block and pasted in the command.
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.
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!
We were playing MineClone 2 in the living room, as we often do these
evenings. I was tidying up the farm, and A+ was impatiently waiting
for me to finish because she wanted to pretend to be the village witch
and trade some potions for emeralds. She tried to clamber over me to
get to the other side, and she tripped on my Lenovo X220T laptop's
screen.
The screen glitched solid blue and didn't go back to normal even after
I rebooted. Aaaah! Big feelings! I took a few deep breaths. A+
immediately became defensive, blaming me angrily for having the laptop
there in the first place. (It was on my lap! I was sitting on the
couch!) I took a few more deep breaths. I reminded myself that this is
precisely the reason I have an "oops" fund, and that taking out my
frustration on her wouldn't solve the problem. I also reminded myself
that I didn't have to freak out about her not apologizing. First
things first. I SSHed in and started another backup, took a few more
breaths, and thought about things.
So the screen was probably broken. I still had lots of options. I
could use it with an external monitor. I could swap the SSD into the
other X220T, the one with the slightly broken screen (I had stepped on
it during the sleep-deprived days of early parenting) and the wobbly
power input that tended to lose contact. When my laptop screen
glitched dim in university, that got me to learn more about Emacspeak
and I ended up making that the basis for my senior project; perhaps
this was another opportunity along those lines.
If it was unrecoverable, I could buy another computer, as I've been
meaning to upgrade. Still can't have nice things, obviously, so
probably the Lenovo T480 for its upgradability. T480s seem to be
selling from between CAD 300-400 in our area. I've been waffling on
upgrading my computer for a few years now, so that might be a good
option.
It was already quite late at night, and I decided not to spend too
much more time on it. Things would be clearer with more sleep and more
space.
The next day, W- and A+ gave me enough space in the morning to
disassemble the X220T following the service manual, down to the LCD
panel and LCD cable. I disconnected and reconnected every component,
and then I turned the computer on again. It worked, hooray! And I only
had three screws left over. (Whoops! That's what I get for not
following the service manual closely on the way back up, and not using
lots of labelled containers for sorting the different screws for each
steps.)
I'm glad about how it all worked out. I'm glad I didn't lose my cool
and that I didn't catastrophize either the accident or A+'s response
to it. This was the most I'd disassembled my laptop so far, which was
pretty neat especially since I managed to get it working again. And it
works, which means I might be able to procrastinate deciding on a new
computer for another couple of years.
Hooray for this X220, and for learning how to be a better parent!
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.
It was interesting to read Zoe Chance's book Influence is Your
Superpower (2022) with a focus on influencing A-, who is 6 years old
and definitely more reachable via her Gator brain than her Judge
brain. Shining is easier because I have to connect with just one
person who really wants to connect with me. Creating space with the
"No" challenge is a little tougher, since she's pretty wise to the way
I try to soften nos. ("You always say later!") But I'm definitely
going to try to practise doing aikido with her mind, accepting her
resistance and exploring it with questions. I can work on using my
relaxed voice most of the time, especially since she's sensitive to my
tone. I also like the tip about using the Zeigarnik effect to invite
her curiosity and get her to ask, maybe by using things like "I might
know something that could help. Would you like to hear about it?"
instead of jumping in with advice. Paying attention to how we frame
things (monumental, manageable, mysterious?) and challenging ourselves
to do bigger and better might be fun, too. She's old enough that I
might even be able to ask her, "What would it take?" I'm sure she'll
pick up that behaviour quickly and ask me that when she wants
something, so I'd better be prepared for that!
I've been coming to terms with the idea that I might not get
appreciably more focus time over the next few years, if we decide to
either continue with virtual school or switch to homeschooling. It's
okay. A-'s going to grow more independent and disappear for long
stretches of time, so there's no need to rush or push her away just so
that I can do stuff on my computer. I'll miss these days soon enough.
So I just need enough me time to keep myself sane and to make better
use of interstitial time as the opportunities arise: waiting for her
to wake up, waiting for her to finish reading or playing, waiting for
her to go to sleep… I'm starting to be able to find 5 minutes here,
20 minutes there. Most of the time, I can't jump on my laptop. If I'm
on a screen, she'll want to be on a screen. Fortunately, my SuperNote
doesn't trigger that sense of unfairness, so I can draw or write as
long as I'm willing to let her use it if she wants to draw too.
I get some coding time here and there, too. I've shifted to more of an
advisory role for my consulting, helping a couple of other developers
via text chat on my phone throughout the day and sitting down to code
when A-'s watching a movie. Sometimes I work on personal projects
while A- watches a movie. She's very good at insisting we both take
eye breaks, and from all her questions, I get the feeling that her
brain is still very busy processing the Nth time through Frozen or the
LEGO Movie. Cool, cool. Might as well use that time to work on
continuous improvement. There's always more tidying to do, but it's
also good to play around with ideas and try to make things better.
So, what do I want to think about and work on when these opportunities
come up? How can I accelerate during those little sprints of thinking
time?
Drawing and writing: I can collect questions to reflect on or
thoughts to untangle, so I can quickly pick one and add to a sketch
or a handwritten draft of a blog post.
Book notes: I can keep a bookmark in a book and sketchnote a few
more pages when I have the chance. Bonus: she sees me reading. Good
time to learn more about parenting, education, psychology, and other
topics that might be useful.
Coding: I can work on setting up my server so that I can write and
publish blog posts from my phone, including referring to sketches
and converting hand-written drafts.
House: I can get rid of more clutter so that I can find things more
easily.
Tech: I can prepare ePubs and PDFs to read on my SuperNote so that
I can learn more about things that will make coding easier or more
fun.
What if I want to create more time? How can I get more focused time?
E-book reading time: A- quickly finishes books from the library, but
the tablet can be a portal to thousands more books. Besides,
sometimes she just wants to read, and that's okay.
More consistent bedtime: if I go to sleep at a reasonable time, I
can use some time in there morning to do stuff. I just have to be
ready to set it aside when she wakes up.
At the playground: if we're at a playdate, I like to still pay
attention to the kids and the other parents. I can bring a 3x3 cube
and my SuperNote to take advantage of spare time, though.
More books to lose herself in: I pick up lots of book
recommendations from Facebook, and the library's a great source.
It's a win all around: we get extra exercise walking to the library,
she learns about more things and more words, and I get time to focus
on something.
Take-out/convenience foods, preparing ahead: it takes me around an
hour to make dinner. I can occasionally swap some of that time for
thinking or coding time by using money. Hmm…
It'll be great. Sure, it's not the sudden jump in discretionary time
that I might have had if A- was going to go to in-person school, but
this way could be good too. I can grow into it just like A- will grow
into her own independence. It reminds me of the way my 5-year
experiment with semi-retirement started off with lots of consulting
and slowly ratcheted down until I felt comfortable using most of my
time for my own stuff. We can learn about time apart together.