goldbox.geo¶
GEO map geometry for Pool of Radiance (C64).
A GEO file is four 256-byte planes over a 16x16 grid, not an array of
per-square records. Every square is indexed x + (y << 4) in each plane –
row-major, y increasing southward, origin top-left.
$000 high nibble = wall art north, low nibble = wall art east $100 high nibble = wall art south, low nibble = wall art west $200 square attributes; bit 7 = roofed / indoor $300 passability, two bits per direction: N=0-1, E=2-3, S=4-5, W=6-7
A wall and a barrier are two independent fields. Five readings of GEO failed because they conflated them. Wall art says what to draw; the two-bit field says whether you can walk through, and the game consults it only when there is wall art on that edge – an edge with no art is passable whatever its bits say.
Confirmed against simeonpilgrim/coab, a C# reimplementation of Curse of the
Azure Bonds reversed from the DOS overlays, and verified on our own 29 files:
adjacent squares agree about their shared edge 13793 times in 13920 (0.991).
reciprocity() recomputes that, so a mis-parsed file fails loudly.
On disk these are PRG files loading at $0400, so the payload is 1024 bytes after the two-byte load address.
Functions
|
Every GEO file on one game disk, keyed by its PETSCII name. |
Classes
One GEO file: a 16x16 grid of walls, doors and square attributes. |
Exceptions
A GEO payload that is not 1024 bytes. |
- class goldbox.geo.Geo[source]¶
Bases:
objectOne GEO file: a 16x16 grid of walls, doors and square attributes.
- classmethod from_bytes(data)[source]¶
Accept either the bare 1024 bytes or the PRG with its load address.
- Parameters:
- Return type:
- classmethod from_disk(disk, name)[source]¶
- Parameters:
disk (goldbox.d64.D64 | str)
- Return type:
- is_passable(x, y, direction)[source]¶
Can the party step this way?
No wall art means yes, whatever the bits hold – that is the engine’s own order of tests, and getting it backwards is what sank the earlier readings.
- reciprocity()[source]¶
(agreements, edges)on the raw barrier field between neighbours.Needs no ground truth: the east edge of a square is the west edge of its neighbour. Across all 29 files a correct parse scores 13793/13920 = 0.991; the readings that were tried and abandoned scored about 0.3. Run it before trusting anything else a file says.
It is deliberately the raw field and not
is_passable. Wall art is only 0.960 reciprocal, so the two sides of an edge genuinely disagree about whether a wall is drawn there – and that drags passability to 0.958. Those are one-way edges, not parse errors, and folding them in would blunt the diagnostic.
- script_id(x, y, mask=SCRIPT_ID)[source]¶
Which entry of the area’s ECL jump table this square runs, if any.
0 means no script. Pass the area’s own mask –
DUNGEON_FLOOR_MASKfor the dungeon-floor family, whose scripts use the two freed bits for encounter control instead.
- to_text(mark=None)[source]¶
An ASCII floor plan.
---a wall,-.-an opening,-+-a locked door,-*-wizard-locked; the same characters singly on vertical edges.markputs a character in the middle of named squares, for the party or a route.
- walkable_route(squares)[source]¶
True if every consecutive pair in
squaresis one legal step.- Return type:
- exception goldbox.geo.GeoError[source]¶
Bases:
ValueErrorA GEO payload that is not 1024 bytes.
- goldbox.geo.load_geo_files(disk)[source]¶
Every GEO file on one game disk, keyed by its PETSCII name.
- Parameters:
disk (goldbox.d64.D64 | str)
- Return type: