User Tools

Site Tools


sd:writing_games_in_assembly_language

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
sd:writing_games_in_assembly_language [2026/05/04 07:26] appledogsd:writing_games_in_assembly_language [2026/05/04 07:50] (current) appledog
Line 1849: Line 1849:
 It's worth taking a moment to pause here and look, really look, at the data struct-ures we have so far and think carefully about how we want to proceed. Ideally what we **want** is an easy pointer from where we stand to a list of items. That's easy to do in a flat structure or with an insque. Let's say we want to have a map as data. Each square takes up space. A 58x23 map that fits on the screen will take 41,354 bytes if we try to store each tile as an object -- barely manageable. But a 256x256 world map would take more memory than the system has available. How did games like Ultima 4, 5 and 6 have such large world maps? There can be a few answers. It's worth taking a moment to pause here and look, really look, at the data struct-ures we have so far and think carefully about how we want to proceed. Ideally what we **want** is an easy pointer from where we stand to a list of items. That's easy to do in a flat structure or with an insque. Let's say we want to have a map as data. Each square takes up space. A 58x23 map that fits on the screen will take 41,354 bytes if we try to store each tile as an object -- barely manageable. But a 256x256 world map would take more memory than the system has available. How did games like Ultima 4, 5 and 6 have such large world maps? There can be a few answers.
  
-First, for Ultima 6, it was intended for computers with more memory. If you stored the Ultima 6 world map as an array of bytes, it would be 1 megabyte in size. The dungeon areas were just as large. Ultima 4 and 5 had a 256x256 world map -- just large enough to be byte-addressable. But since it couldn't fit in memory how did they do it? They pared it down and removed things from the game. We could probably do a better port of Ultima 6, but Ultima 6 is not going to be a realistic goal with under 200k usable memory for graphisc and data.+First, for Ultima 6, it was intended for computers with more memory. If you stored the Ultima 6 world map as an array of bytes, it would be 1 megabyte in size. The dungeon areas were just as large. Ultima 4 and 5 had a 256x256 world map -- just large enough to be byte-addressable. But since it couldn't fit in memory how did they do it? The answer is that they didn't load it into memory all at once. They kept it on disk or on the cartridge (or CD) and read only the parts they needed to display.
  
-One technique is swapping to disk. In the case of a world mapusing map chunks. The map was chopped up into areas and/or read in small chunks. We can do this with one map file and FSEEK. Chunks can be stored as rows and read in all at once at certain well-known positions of the file. For example, every 256 bytes can be considered one 16x16 chunk. This lets us FSEEK to the chunk and read it very quickly during play.+If the PLAY window has 11x11 tileswe can store the map and nine nearby tile regions in just 1089 bytes. 
  
-Another technique is one we have mentioned before. If the PLAY window has 11x11 tiles, we can store the entire displayable map in under 4k. If we store the 9 regions around the player, reloading when he changes regions (chunks), this will take just over half a bank of memory.If we merely preload the chunks he is likely to enter next (such as the three chunks next to the zone he is in, we can do it in less than 15k.+A roguelike game has a few more tiles, however. A normal roguelike has just one screen's worth of data -- no more than 80x25 squares. If we keep an array of INSQUE ''HEAD'' nodes and objects, this will amount to 86,000 bytes of data. If we can get this down to 32,000, maybe -- just maybe -- the system can be usable. 
 + 
 +The first thing we can do is remove 4 bytes for the X and Y position of an object. The X and Y position is now to be derived from it's location in the grid structure. 
 + 
 +Every object needs an ID, a TYPE, a GLYPH and a VIS. But not DATA1 or DATA2; and 17 bytes for a name is wasteful. Lets remove these 21 bytes and include 3 bytes for a DATA address; these 3 bytes are the data address of the first (data bearing) node in a list of data such as items contained inside this object, the object's string name, and so forth. This removes 21 bytes per object, since most objects will have a default name based on their type, but over-rides can be scanned from it's DATA list. 
 + 
 +.equ TILE_ID         ; Tile ID 
 +.equ TILE_TYPE       ; 2 bytes; ex. 0 = nothing, 1 = wall, 2=gold, etc. 
 +.equ TILE_GLYPH  2     ; 1 byte; what it looks like (char) 
 +.equ TILE_VIS    3     ; 1 byte; what it looks like on the map (char) 
 +.equ OBJ_SIZE    7     ; 7 bytes 
 + 
 +This short struct tells us what kind of tile is on any square, and then it has a poitner (it's ID) that can help us find any items that belong on this tile. 
 + 
 +// more to come // 
 + 
 + 
 + 
 + 
 +entire displayable map in memory under 4k. If we store the 9 regions around the player, reloading when he changes regions (chunks), this will take just over half a bank of memory. If we merely preload the chunks he is likely to enter next (such as the three chunks next to the zone he is in, we can do it in less than 15k.
  
 * a. If the player is in the top third of the chunk, load the chunk north of him into memory. * a. If the player is in the top third of the chunk, load the chunk north of him into memory.
sd/writing_games_in_assembly_language.txt · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki