More feasibility on ZIL: matrix/grid arrays

Hi there,

I keep on studying ZIL. It is being an enlightment process as it requires a totally different approach from my stone-carved table orientation learnt with other engines. And the somewhat unsemantic and cryptic nature of some language specifics (function names and routines, the old school programmer lingo…) is adding up to the difficulty. But.

I endure with the design of my little game and I’ve learnt to appreciate how the old programmers exceled in creating incredible games with assembler, machine code and just a handful of bytes in the old retro machines. I’ve reviewed many other and more modern (text adv) engines but it all ends up in coming back to ZIL since can’t find how to implement certain features thet, while simple enough, are beyond their capabilities (or mine, most probably).

In my game, the player does not move but merely gives commands to 7 npcs to move throughout the map. To do so, npcs must be able to know how locations are connected, as the player’s command “goto laboratory” must result in the npc moving from room to room, one movement per turn, as things happen when e.g. two npcs convene in a same room. I’ve considered the option of creating a matrix/grid array of 64x64 (columns and lines are the list of rooms) and storing in each pair of coordinates the list of movements from the room x to room y. This approach is nice on paper but takes 4.096 room pairs and too much memory, I guess.

I’m turning to simple maths instead and considering a different approach, using a numeric attribute “room-index-code”. Lower level rooms have a 1000 based vlue, level 2 a 2000, etc. Now, if an npc must move east, the code simply adds +1 to the room number and describe. To the west, -1. To the nort, +10. To the south, -10. Up, +1000. Down, -1000. With room index codes, npcs need not be intelligent or store info, as the system takes care using maths. An inmense grid array is not necessary anymore and implementation is easier.

Question: can ZIL variables hold values larger than 256? I’ve tested this approach with other 8biters but, for 110 rooms, numeric intervals are very limited and a handful of rooms must be left out of the routine for the lack of remaining intervals.

Thanks in advance, ideas welcome!

1 Like

Don’t know if this answers your question but variables are 16-bit wordsand can therefore hold values 0-65535 or -32768-32768 if signed.

2 Likes

You have read the source of Suspended ? Infocom dodged your issues through feelies (a mapboard and six pawns representing the NPCs, so the player can see at glance where the NPC are, and see the path they have to follow) but Suspended is a 104k z3 story file, you can build up to 512k z8 story file, so I think that you can successfully implement NPCs capable of autonomously reaching locations, but I think that you should use pathfinding algorithms instead of an huge precalculated table. (there’s plenty of prior debates on NPC pathfinding in this very forum…)

HTH and
Best regards from Italy,
dott. Piergiorgio.

Yes, Suspended is the right place to look for inspiration here. Specifically, look at goal.zil, which implements the “ROBOT, GO TO PLACE” action. This is handled with a series of “lines” (think like a bus line or a subway line): regions of the map where the robot knows how to get from any room to any adjacent room. Then the “transfer table” tells the robot how to transfer from one line to another. The FOLLOW-GOAL routine ties this all together.

Whether this works for your purposes depends on how the map is laid out. I have to admit, I’m having a great deal of trouble understanding how exactly the Suspended code actually works, though some of that is due to my lack of ZIL experience.

If you do want to use a big hand-calculated table, though, you could follow this model: divide your map into zones, then have a matrix showing the route from any zone to any other, and a matrix for routing within each zone. This would cut down the memory requirements significantly, but only if you have “bottlenecks” in the map that give you easy zone-change points.

Curses! do this for the mazes:

Array mouse_maze string "111111111110010011111001011111100001111001111111100111111111111";

This is a TABLE of bytes (characters) in ZIL lingo. This is actually a map over the rooms. If you reorganize the data in a grid (7x9):

111111111
110010011
111001011
111100001
111001111
111100111
111111111

Where 0 is an enterable room and 1 is a wall. This could quite easily be redone with bits and a table 512 bytes to map a grid 64x64 (4096 rooms).

For Hadean Lands I set up a function which basically hard-coded all the pathfinding.

(Okay, it was an I7 rulebook, but a function would have done the same job.)

It basically looked like:

    if currentroom is X:
        if destination is A or B or C or D:
            return A
        else if destination is Y or Z:
            return Y
        else
            return E
    if currentroom is Y:
        if destination is Z:
            return Z
        else
            return X
    ....

This was a headache to write, and I had to test it very carefully. But once it was written, it solved the problem efficiently and with no use of RAM.

(Depending on your needs, you might want a function that returned a next-direction rather than a next-room.)

2 Likes

For completeness, the map for the above example:

E--F--G...
|
X--Y--Z
|
A--B
|  |
C--D
1 Like

If you want to go this route, ZIL does have Lisp-inspired macros; in theory you could set up the room-defining macro such that it could generate a routine like this automatically for you, running a pathfinding algorithm at compile-time.

In practice that’s going to be a pain in the ass, so you might want to start with a run-time pathfinding algorithm and then try to shift it to compile-time if the slowness becomes unacceptable.

A very important consideration here is what target machines you’re aiming at.

Infocom found cheap ways to implement pathfinding, because they had to, or it wouldn’t run on the 1 MHz, 48 KB RAM computers they wanted to sell the games for.

If you’re aiming for somewhat modern computers, you can do a breadth-first search without too much hassle. If you’re aiming for 8-bit targets, this will be too slow, unless the map is tiny.