Jump to content

Karl's Blog

  • entries
    18
  • comments
    43
  • views
    5,045

Penult Maps


Karl G

799 views

I have enjoyed @SpiceWare's blog entries about the making of his games, so I thought I'd try my hand at it for my upcoming game Penult.

 

My first demo was pretty much just a map viewer for the Ultima 3 world map. I chose Ultima 3 because it actually has the smallest world map: only 64x64 tiles. Converting the Ultima 3 map to data I could use in my initial demo wasn't difficult, but the first problem was that it was still too big: 64x64 bytes equals 4096 bytes, or exactly the size of one bank. This doesn't account for the 256 bytes I lose by using SuperChip RAM, nor does it leave any room for code to access the data.

 

Since there were less than 16 unique glyphs in the map data, I was able to convert each tile to a nybble, so that one byte contained the data for two adjacent tiles. This gave me plenty of space to contain the entire Ultima 3 world map. When I switched to my own world map, I made the size a bit bigger: 80x64 tiles.

 

Town maps were another issue. Each of these in Ultima 3 are also 64x64 tiles, and they have many more than 16 unique glyphs, so my compression trick would not work. Furthermore, even if it did fit, having each castle and town take up one bank each would cause me to quickly run out of space. Instead, my castle/town maps are 48x34 tiles in size, and I can fit two of these maps along with the code to access them per bank.

 

For making my own maps, I use the Tiled app. I'll show how the current version of Queen Avaline's castle looks in the Tiled editor. I'm picking that one because it's likely to change greatly before the final version - it has unused areas and hidden areas that I'll alter before the final version. Just to be sure, though, I'll put the screenshot in a spoiler tag:

Spoiler

 

1169685285_ScreenShot2019-10-02at6_38_09PM.thumb.png.28a0cb7d47ce896c5438aad1fff9b966.png

 

 

The game uses whatever tile is in the upper-left corner (grass, in this case) as a "filler" tile to fill in the edges of the map as the character comes to the edges of the map:

 

penult_60.png.3488674623827a3666dcfab68a1e1889.png

 

I export the map to CSV format, and I have a custom script that converts this data to data I can include in my source file:

Spoiler

 

#!/bin/bash
echo "castle_map" >castle-map.txt
cat castle.csv | while read line; do echo " .byte $line"; done >>castle-map.txt

 

 

 

The script to convert the world map is more complicated. Unlike the town maps, the world map wraps, so there is some redundant data to make the loading of the map quicker. Additionally, the data is compressed by converting to nybbles as described above. Here is the script I use to convert the CSV export of the world map to the format I need:

 

Spoiler

 

#!/bin/bash
cat world.csv | sed 's/10/A/g' | sed 's/11/B/g' | sed 's/12/C/g' | sed 's/13/D/g' | sed 's/14/E/g' | sed 's/15/F/g'| tr -d ','  >world-bare.txt
cat world-bare.txt | cut -c 1-12 >world-append.txt
paste -d '\0' world-bare.txt world-append.txt >world-tmp.txt
cat world-tmp.txt | head -n 6 >world-appendix.txt
cat world-tmp.txt world-appendix.txt >world-full-bare.txt
echo "world_map" >world-map.txt
cat world-full-bare.txt | sed 's/.\{2\}/&$/g' | sed 's/.$//' | sed 's/\$/,\$/g' | sed 's/^/ .byte $/' | cut -c 1-190 >>world-map.txt

 

 

 

 

Still left to do on the map front is figure out if I want smaller "village" maps to save space for remaining towns, and I need to figure out how I want to handle dungeon maps.

  • Like 3

2 Comments


Recommended Comments

Have you though about further compressing your maps. I suppose both, Run-Length-Encoding and Huffman encoding would give very good results here. Problem is, that you would have to do this on-the-fly, because you have very little RAM to decode into. But maybe it is worth thinking about it, if you should run out of ROM.

 

 

  • Like 1
Link to comment

Yeah, the city maps could be compressed quite a bit with either of these methods, I think, but running out of cycles would be an issue. It's further complicated by the fact that I'm only reading the currently-visible portion of a larger map into 84 bytes of RAM, fill in the potion off the map with a fill character, and then run the visibility code to blank out non-visible tiles all before the next visible screen. I'll definitely revisit how I do this to see if it would be feasible if I run out of ROM space, though.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...