Press "." to enter slideshow, once entered "PgUp" and "PgDn" to
navigate, "Esc" to leave slideshow again.
The Children Yearn for the Mines
Importing Ultima IV maps into Minecraft MinetestLuanti
Nick Moore
This is a presentation about copying the Ultima IV maps into
Minecraft, well not minecraft but a thing which was called Minetest
and is now called Luanti.
more stuff here
Procrastination
it's okay I'll fix that later
actually it's a talk about procrastination. Yesterday Ada gave a
lightning talk about procrastination and I wanted to show that
while students can procrastinate hard, senior devs can procrastinate
harder.
The Primordial Code
TODO:
- history of cool stuff
- 4 billion years of biology in 10 minutes
- even cooler stuff
- you are in a twisty maze of wikipedia articles, all different
- evolution wtaf are you don
- is everything a fish?
- XXX TODO finish todo list LOL
anyway I was working on yesterday's presentation about bioinformatics and
I'd gotten as far as a to-do list which had lots to do and it was a lot
of hard work but all I had to do was get on with it but ...
anyway so when I was a teenager I really loved this game called Ultima IV
which ran on the apple 2 and even though there you saw the world through this
tiny window ...
... there was a whole world there in your imagination. Places in games can seem really really even though they're just imaginary ...
Minecraft
Images of Minecraft are the intellectual property of Microsoft.
This is not a place of honor.
Do not fold, spindle or mutilate.
NO PICTURES.
Anyway, when Minecraft came out I thought about how cool it would be if I
could take the blocky maps from Ultima IV and put them into the blocky world
of Minecraft.
Several years later ...
Reading the Map
with open("dat/WORLD.MAP", "rb") as fh:
ultima_world = fh.read(256*256)
def get_block(x, y):
return ultima_world[(y//32)*8192+(x//32)*1024+(y%32)*32+(x%32)]
reading the Ultima IV map is really easy because computers were too
primitive to be difficult and so it's just a bunch of bytes in a file
but not in order of course because computers
Writing the Map
Minecraft
Minetest
Luanti
Instead of targeting Minecraft which is closed source and in Java `:-(`
I decided to target Luanti which is open source and in Lua `:-/`
def block_to_data(block):
# block is a binary array of node IDs in ZYX order.
assert len(block) == 4096
# headers
yield 14 # flags: generated, lighting expired, day_night_differs, NOT is_underground
yield from u16(0) # lighting needs recomputing in all directions
yield from u32(0xffffffff) # timestamp
# block mapping: only bother including blocks present in
# this sector.
present_blocks = set(block)
present_block_map = [ (k, v) for k, v in block_map.items() if v in present_blocks ]
yield 0 # mapping version
yield from u16(len(present_block_map)) # length of block map
for k, v in present_block_map:
yield from u16(v)
yield from u16(len(k))
yield from bytes(k, 'ascii')
the file format for this is documented. It's very weird but at least
it is documented. Well, more like "confessed".
I promised I'd show some python source code at this python conference
so here it is. There's no syntax highlighting. Git gud.
it builds a bunch of binary data ...
yield 2 # content_width (always 2)
yield 2 # params_width (always 2)
for b in block:
yield from u16(b) # param0
for b in block:
yield 0 # param1
for b in block:
yield 0 # param2
yield from u32(0)
yield 10 # timer record size (always 10)
yield from u16(0) # no timers
... and some metadata which I don't really understand but I just
set it mostly to 0 and it sort of works.
def block_to_binary(block):
yield 29 # chunk version number
yield from zstd.compress(bytes(block_to_data(block)))
db = sqlite3.connect('/home/nick/.minetest/worlds/x/map.sqlite')
def write_block(x, y, z, block):
pos = z * 4096 * 4096 + y * 4096 + x
data = bytes(block_to_binary(block))
db.execute("insert or replace into blocks (pos, data) values (?, ?)", (pos, data))
Then it writes it into sqlite as a zlib compressed blob.
Confession.
Now I could write 16x16x16 blocks of random crap into Luanti.
this is a bit of the Ultima IV map
here it is copied into Luanti, scaled up 1:12.
there's also towns and castles and stuff
... which have their own 32x32 maps so I just write them into
the map at the appropriate places, scaled 1:1.
that worked.
it all looked a bit square and ugly though
so I implemented a filter to round everything off
and that looked a lot better
Ultima IV in Luanti
- Mountains
- Trees
- Shrines
- Dungeons
- Moongates
- XXX TODO finish TODO list ROFLcopter
so now I had a whole list of other things to do: mountains needed
to grow up and oceans grow down and it needed trees and dungeons
and shrines and moongates and it was all a bit hard and tedious.
Procrastination
so i procrastinated
https://nick.zoic.org/PYCON25/