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 $0CF98 has 20 big-endian word values, followed by $AAAA terminator at RAM $0CFC0. The complete 42 bytes are identical to original disk $8CD47..$8CD70.
  • 4-4b special classification: RAM $0CFC2 has 56 big-endian word values, followed by $AAAA at $0D032. The first 54 bytes match disk $8CD71...; the source stream then contains $95 coding 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) is disk[offset+64*(63-screenY)+X].
  • The AMOS viewer's level offset formula contains a genuine error: 3_4 is $46280, not $4BA80. $46280 renders a coherent map using the game's matching native 3_4 tile bank; $4BA80 produces 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.

original palette disk vs saved chipset β€” P06 visual evidence