02 maps and tiles - HoraceAndTheSpider/New-Zealand-Story-Editor GitHub Wiki
P09 β Transition marker coordinate interpretation
The new source-backed transition table is not part of the 64Γ64 tile grid. It contains a one-byte X and one-byte Y per source stage; game code compares these bytes with active-object positions shifted right four (ASR.W #4). These two bytes can be displayed on the native map as tile-like source positions, independent of map tile IDs, first placement record, $03 generators and header words. The destination X/Y values are raw 16-bit words written to runtime $027C(A6); visually plotting them as pixels is a provisional coordinate conversion until validated on Amiga. Maps in P09 visuals/ use Disk.1-extracted tile sheets and label approximate arrivals appropriately. No tile-bank data has been edited.
P08 β Distinct 4-4 / 4-4b tile-classification tables (13 October 2026)
The original 4-4 level and the distinct 4-4b special-area have different tile-classification word tables, not merely different map artwork. The original setup routine RAM $0C7E2 tests special-area flag +$26(A6) and overrides the normal catalogue classification pointer with $0000CFC2 in special mode. This program window exactly matches original disk $8C6AF...; see Game Code.
- 4-4 ordinary classification: RAM
$0CF98has 20 big-endian word values, followed by$AAAAterminator at RAM$0CFC0. The complete 42 bytes are identical to original disk$8CD47..$8CD70. - 4-4b special classification: RAM
$0CFC2has 56 big-endian word values, followed by$AAAAat$0D032. The first 54 bytes match disk$8CD71...; the source stream then contains$95coding and differs from the expanded RAM array, so the remaining original source cannot be patched as an uncompressed 56-word disk table without tracing the loader/expander.
The original map/property expansion routine uses each 16-bit word as four 4-bit nibbles when creating its derived 2Γ2 collision/property grid; it has a bounded tile-ID lookup and a fallback value for indices beyond the table. The meanings of class codes $0/$1/$F (and any others) are still unknown. These are classification codes, not enemy species, warp IDs or verified visual tile IDs. The size difference (20 vs 56 classifications) is a further reason 4-4b has distinct gameplay data rather than being a copied tile map.
New audit CSVs: research/P08_4_4_tile_classification_nibbles.csv and P08_4_4b_tile_classification_nibbles.csv. For mobile review, source-accurate 2Γ2 nibble matrices: visuals_P08/09_4_4_tile_classification.png and 09_4_4b_tile_classification.png. Do not enable collision/property editing or expand these tables until native source length, encoding and consumers are proved.
P05 β Palette register conversion independently verified in UAE save state
The former provisional display conversion is now corroborated by the original game's live chipset state. The Stage 1_1.uss file contains a CHIP section beginning at file $018C (payload at $019C). The sixteen 16-bit big-endian colour values starting at save-state file $027C are:
0000 060E 0222 0A42 0C80 0860 0060 0AAA 0600 000E 0E00 02AE 0E80 0CC4 00E0 0EEE
They correspond exactly to the sixteen original native tile-palette words extracted from all sixteen compressed graphics banks:
0000 0307 0111 0521 0640 0430 0030 0555 0300 0007 0700 0157 0740 0662 0070 0777
Every component is doubled independently from 3-bit 0..7 to 4-bit 0..14. The match holds for 16/16 registers and agrees with the existing browser conversion of each 3-bit component to 8-bit intensity 34Γn. P05 visuals/10_original_palette_disk_vs_saved_chipset.png illustrates all sixteen exact pairs. This demonstrates the source palette conversion in the captured state; it does not prove separate live sprite colour-bank assignments or all palette changes in every level. The next sixteen register words in this save snapshot are mostly zero, with $FFF at index 17 and 22, so there is no evidence here for a complete independent 16-colour moving-character palette.
The scenery tile bitplanes remain verified as interleaved by scanline. Do not use their correct palette to validate unconfirmed hero/enemy RAM contact sheets: source sprite bank, actual pixel encoding and transparency/mask may differ. The P04 creature-looking frames remain candidate graphics only; P05 comparison notes repeated $FE-spaced motifs that undermine an assumed fixed $80-byte sprite-frame stride.
Maps and Tiles
P03, 12 October 2026 β native graphics, embedded palette words, and level headers analysed against user-supplied Disk.1. Baseline SHA-256 fec7ce66934497b65745aa658599bdc697cf0ea0111d77d211fce3f48e27b416.
Native maps
- 21 observed 64Γ64 tile maps; 4,096 bytes/map; each cell an unsigned tile ID (0β255); tile graphics are 16Γ16 pixels (1,024Γ1,024 complete map).
- Disk storage is bottom-up:
offset + 64*storedY + X, stored Y=0 at bottom. On a top-down browser canvas, map cell(X, screenY)isdisk[offset+64*(63-screenY)+X]. - The AMOS viewer's level offset formula contains a genuine error: 3_4 is
$46280, not$4BA80.$46280renders a coherent map using the game's matching native 3_4 tile bank;$4BA80produces visually scrambled data and has much poorer horizontal/vertical tile adjacency. P01's incorrect offset is superseded for preview, import and export. - 5_3 remains at
$79080. Its P01 sheet was in the wrong sequence for this map; the actual bank 14 native ordering fixes its graphics.
Level addresses, graphics assignments and out-of-bank references
Absolute hexadecimal file offsets (not runtime RAM addresses). Map occupies [offset, offset+$1000). Native tile counts come from Disk.1's actual decoded graphics banks; remaining IDs must be preserved even if they have no corresponding native image.
| # | Level | Map offset | Tile bank | Native tiles | Map cells outside bank |
|---|---|---|---|---|---|
| 1 | 1_1 | $18C80 |
0 | 173 | 971 |
| 2 | 1_2 | $1A280 |
1 | 198 | 132 |
| 3 | 1_3 | $1B880 |
2 | 134 | 565 |
| 4 | 1_4 | $1CE80 |
3 | 189 | 0 |
| 5 | 2_1 | $22680 |
4 | 107 | 0 |
| 6 | 2_2 | $23C80 |
4 | 107 | 0 |
| 7 | 2_3 | $25280 |
4 | 107 | 0 |
| 8 | 2_4 | $26880 |
4 | 107 | 0 |
| 9 | 3_1 | $42080 |
5 | 219 | 0 |
| 10 | 3_2 | $43680 |
6 | 205 | 0 |
| 11 | 3_3 | $44C80 |
7 | 219 | 0 |
| 12 | 3_4 | $46280 |
8 | 192 | 0 |
| 13 | 4_1 | $4D080 |
9 | 158 | 0 |
| 14 | 4_2 | $4E680 |
9 | 158 | 0 |
| 15 | 4_3 | $4FC80 |
9 | 158 | 0 |
| 16 | 4_4 | $5D880 |
10 | 157 | 346 |
| 17 | 4_4b | $5EE80 |
11 | 256 | 0 |
| 18 | 5_1 | $6CA80 |
12 | 191 | 0 |
| 19 | 5_2 | $6E080 |
13 | 219 | 0 |
| 20 | 5_3 | $79080 |
14 | 117 | 0 |
| 21 | 5_4 | $7A680 |
15 | 200 | 0 |
Out-of-bank references occur in levels 1_1, 1_2, 1_3 and 4_4. P03 demonstrates that every out-of-bank cell lies outside the corresponding level header's declared dimensions. Whether the retail renderer ever reads those stored rows still awaits 68000 verification. P02 uses non-destructive placeholders for those indices.
Native graphics: proven compressed format
Sixteen banks have been identified in Disk.1; several levels intentionally share a graphics bank. Every bank is independently verifiable by decoding and checking the expected total output length and image geometry.
At each header offset H:
| Disk location | Type | Meaning |
|---|---|---|
H+$00 |
big-endian long | Decoded byte count β 1 |
H+$04 |
big-endian long | Packed record byte count β 1, including this 9-byte envelope |
H+$08 |
unsigned byte | RLE escape token (varies by bank) |
H+$09..H+packedLength |
byte stream | RLE-compressed contents; end-exclusive H + packedLength |
Decoder: Read a byte. If it is not the escape, output it literally. If it is the escape, read value, countMinusOne and output value repeated countMinusOne + 1 times. Stop precisely at the bank's packed end. Validate decompressed length; reject an overflow or truncated triplet. Examples: in bank 0 escape $2C, the triplet 2C 00 0F produces sixteen zero bytes; 2C FF 07 produces eight $FF bytes.
Decoded layout: The first $80 bytes form a shared metadata preamble, starting 30 31 00 00 03 07 01 11. The first two bytes are a signature and the next 32 bytes are 16 original colour words (P03); the remaining fields still need investigation. After that are N consecutive $80-byte tile images (16Γ16 pixels Γ 4 bitplanes). Each scanline has four consecutive big-endian 16-bit plane words, low-to-high bit significance. The most significant bit of each plane word corresponds to the leftmost pixel. For colour index at (x,y):
sum( ((be16(tile+8*y+2*plane) >>> (15-x)) & 1) << plane, plane=0..3 ).
The 21 level-to-bank assignments below were cross-checked against the reference graphics and map appearance; an emulator save-state includes a byte-for-byte run of unpacked 1_1 tile records that matches this format. This validates the extraction but does not establish the 68000 decompression routine address or in-game graphics palette registers.
| Bank | Disk.1 header | Packed length | Decoded length | Native tiles | Escape |
|---|---|---|---|---|---|
| 0 | $02C00 |
$513C |
$5700 |
173 | $2C |
| 1 | $08400 |
$5A7C |
$6380 |
198 | $25 |
| 2 | $0F200 |
$3E90 |
$4380 |
134 | $15 |
| 3 | $13400 |
$540F |
$5F00 |
189 | $53 |
| 4 | $1E400 |
$318E |
$3600 |
107 | $4D |
| 5 | $27E00 |
$6301 |
$6E00 |
219 | $2B |
| 6 | $2EC00 |
$5C28 |
$6700 |
205 | $B1 |
| 7 | $35A00 |
$6406 |
$6E00 |
219 | $4B |
| 8 | $3C800 |
$5640 |
$6080 |
192 | $96 |
| 9 | $47800 |
$4556 |
$4F80 |
158 | $89 |
| 10 | $51200 |
$43DB |
$4F00 |
157 | $28 |
| 11 | $56A00 |
$6DFB |
$8080 |
256 | $25 |
| 12 | $60400 |
$5631 |
$6000 |
191 | $2B |
| 13 | $65C00 |
$6987 |
$6E00 |
219 | $34 |
| 14 | $6F600 |
$2F5F |
$3B00 |
117 | $14 |
| 15 | $73800 |
$5723 |
$6480 |
200 | $35 |
Colour fidelity and remaining graphics questions
Pixel indices and all tile graphics are now extracted directly from Disk.1, and P02's built-in atlas PNGs are generated from these decoded disk pixels (not copied from supplied Tiles PNG.zip). When an actual Disk.1 is loaded, the browser decodes those same native banks afresh rather than relying on its bundled preview PNGs. P03 has recovered the original 16 colour words from bank metadata and renders them using provisional twofold nibble expansion. The actual hardware colour-register setup remains to be demonstrated by tracing the 68000 palette code. Do not describe the 16 display RGB values as proven recovered disk palette data.
These are background tile banks, not a verified complete sprite library. Identifying moving player/enemy sprite banks, animation frames, transparency and any other graphics resources remains open; see Further Investigations.
P02 regression evidence
- The header/payload decoder emits all 16 native banks with exact expected counts and an end-aligned output; automated tests check byte-level pixel-index hashes for every bank.
- Native levels 3_4 and 5_3 render coherent complete maps after correcting the offset/atlas selection respectively. Unchanged Disk.1 remains byte-for-byte identical on export, and map edits only update the selected
$1000-byte map slice. - Graphics decoding is read-only. No new game-binary graphics writer has been authorised or proved. The editor may view original tiles, but tile-pixel editing/exporting native compressed banks is not yet implemented.
Original AMOS viewer discrepancy
The legacy AMOS routine selects map offsets by adding $18C80 + (levelβ1)*$1600 plus a group-specific correction. It uses $23C00 for levels 12β15; the formula thus puts 3_4 at $4BA80 rather than the validated $46280. Treat those inherited constants as leads, not authoritative. Because the corrected graphics/map alignment is compelling but the 68000 map pointer table has not yet been disassembled, distinguish binary/visual verified from runtime code verified.
P03 β original level headers, playable extent and position candidates
A $80-byte binary header precedes each map at disk file offset mapOffset - $80. The header begins 30 31 (ASCII 01) and has the following reproducible fields:
| Header relative byte | Width | Observed meaning | Confidence |
|---|---|---|---|
+$00 |
2 | 30 31 signature on all 21 levels |
verified |
+$02 |
big-endian 16-bit | Declared width: always 64 tile cells | verified structural |
+$04 |
big-endian 16-bit | Declared height: 14, 32, 48 or 64 tile cells | verified structural |
+$0E |
big-endian 16-bit | X-like value, in range 0β63 | provisional role |
+$10 |
big-endian 16-bit | Y-like value, always less than this level's declared height | provisional role |
| Remaining bytes | β | Present and predominantly zero; field roles unclassified | unknown |
The storage grid remains 64Γ64, bottom-up; the declared active rows are stored Y 0..heightβ1, corresponding to editor screen Y 64βheight..63. The out-of-bank references previously reported for 1_1, 1_2, 1_3 and 4_4 are all outside those declared rows. No level references a missing native tile within its declared rectangle. This settles the binary-data explanation for P02's missing-art warnings. The game code's clipping behaviour still needs a runtime trace; the editor does not delete or rewrite rows outside the declared height.
The two unclassified coordinate words may describe initial position, camera starting position, an exit/warp, or something else. They are not currently identified as hero spawn, enemy spawn or warp destinations. P03 permits an optional read-only marker for user/runtime comparison; the editor never writes them.
| Level | Header at Disk.1 | Width Γ height | +$0E | +$10 | Out-of-bank refs inside / outside header height |
|---|---|---|---|---|---|
| 1_1 | $18C00 |
64Γ14 | 0 | 0 | 0 / 971 |
| 1_2 | $1A200 |
64Γ32 | 0 | 0 | 0 / 132 |
| 1_3 | $1B800 |
64Γ32 | 33 | 10 | 0 / 565 |
| 1_4 | $1CE00 |
64Γ64 | 0 | 38 | 0 / 0 |
| 2_1 | $22600 |
64Γ64 | 0 | 11 | 0 / 0 |
| 2_2 | $23C00 |
64Γ64 | 44 | 24 | 0 / 0 |
| 2_3 | $25200 |
64Γ64 | 0 | 43 | 0 / 0 |
| 2_4 | $26800 |
64Γ64 | 30 | 55 | 0 / 0 |
| 3_1 | $42000 |
64Γ64 | 0 | 52 | 0 / 0 |
| 3_2 | $43600 |
64Γ64 | 25 | 17 | 0 / 0 |
| 3_3 | $44C00 |
64Γ64 | 44 | 55 | 0 / 0 |
| 3_4 | $46200 |
64Γ64 | 42 | 24 | 0 / 0 |
| 4_1 | $4D000 |
64Γ64 | 44 | 55 | 0 / 0 |
| 4_2 | $4E600 |
64Γ64 | 44 | 39 | 0 / 0 |
| 4_3 | $4FC00 |
64Γ64 | 7 | 7 | 0 / 0 |
| 4_4 | $5D800 |
64Γ48 | 0 | 0 | 0 / 346 |
| 4_4b | $5EE00 |
64Γ48 | 0 | 39 | 0 / 0 |
| 5_1 | $6CA00 |
64Γ64 | 44 | 55 | 0 / 0 |
| 5_2 | $6E000 |
64Γ64 | 38 | 47 | 0 / 0 |
| 5_3 | $79000 |
64Γ64 | 44 | 0 | 0 / 0 |
| 5_4 | $7A600 |
64Γ64 | 44 | 0 | 0 / 0 |
P03 β original embedded colour words
All sixteen successfully decoded graphics banks start their 128-byte decompressed preamble with the ASCII 30 31 signature, followed by sixteen big-endian colour words at decompressed offsets +$02..+$21. The same sixteen values appear in every bank:
0000 0307 0111 0521 0640 0430 0030 0555 0300 0007 0700 0157 0740 0662 0070 0777
Every RGB nibble fits 0..7; assigning the 16 words to the 16 pixel indices produces a direct match to the general red/purple/green/blue colour relationships of the previous reference palette. This is verified disk-sourced palette data, rather than a palette guessed from reference PNG artwork. The browser currently expands each 3-bit component n to 4-bit channel 2n, then to an 8-bit value 34n; whether the retail renderer uses precisely this channel expansion is provisional until the palette/Copper register-writer is traced. P03's 21 bundled atlas previews have been regenerated from the source palette words and raw native tile pixels, and opening Disk.1 reads these words from the loaded bank metadata. No bytes in the game image are altered by palette display.
The remaining part of each 128-byte decoded bank preamble (after +$22) has not been fully decoded. It can contain varying level/bank-specific values and should be investigated alongside objects and graphical bank configuration, not silently ignored.
P04 β visual validation package
Twenty-one disk-derived level previews have been rendered from the P03 native graphics banks, with the header +$0E/+$10 pair superimposed solely as a candidate (yellow cross). Levels with a declared height under 64 are cropped to their header-declared bounds in the overview; full individual level images shade the unused stored rows and retain their bytes. The files are supplied as PNGs in P04 visuals/ (01_all_21_header_points.png and 02_map_*_header_point.png). These are review drawings, not positions of proven spawns or warps.
P04 also found 16Γ16 four-bitplane plane-major character-like images in the supplied UAE Chip RAM, which are separate from the already-proven row-interleaved native background tile bank format. See Game Code and Runtime for exact address/formula and evidential limits. The Disk.1 sprite resource, runtime sprite-object table and exact sprite palette remain open; do not substitute these provisional RAM images for native disk graphics in the production editor yet.
P10 β Moving graphics are separate from verified tile decoding (13 October 2026)
The 16 original tile banks and RGB palette extraction are verified, but the new actor investigations must not inherit those decoder assumptions. Animation indices $B0..$C9, $CA..$CF and $6F..$84 appear in actor-associated native word streams; these references do not indicate a physical offset into the 16 tile banks. The RAM $51030 graphics contact sheets in visuals/05_graphics_RAM_probe_*.png are layout tests only, using the known background palette for comparison. Their frame dimensions, offsets, masks, sprite palette, and connection to actor IDs are unproved. Only the source-verified tile atlases are suitable for literal paint/preview in the current app. A future sprite editor needs a separately proven image index resolver and safe encoder, not reuse of tile bank RLE writes by assumption.
Canonical illustrated evidence (P11 handover curation)
The images in this section are stored inside wiki/images/; they remain available when temporary research/ and visuals/ directories are removed. Labels show original binary evidence or candidates, not invented gameplay identities. Graphics presented here as object markers are not authentic moving-sprite artwork. The user reports that position markers appear approximately one tile too low in earlier overlays; do not use these images as proof of pixel-exact entity origins until the native sprite anchoring is traced.
