Magic Pockets Level Script Format

From ModdingWiki
Jump to navigation Jump to search

Authored entities and level events in Magic Pockets are stored in seven .pin files. These use an RNC method 1 wrapper. They are unrelated to sound-bank PIN files and driver modules.

File Use Decompressed bytes
level0.pin Attract-demo level events 5888
new1.pin World 1 16662
level2.pin World 2 13946
level3a.pin World 3 variant A 5744
level3b.pin World 3 variant B 7680
level3c.pin World 3 variant C 4882
level4.pin World 4 16662

File format

All multi-byte values are big-endian. The header is a sequence of 16-bit offsets into the same decompressed file. Read offsets until reaching a word greater than or equal to the file length; the shipped tables use the file length as a sentinel. There is no leading entry count.

Each offset starts a record stream. Entries can overlap: several starting points may lead into the same physical tail. Do not infer a room count from the number of header entries, or split streams at the next header offset.

Control records

Read a 16-bit marker before each record:

Marker Record size Meaning
0xAAAA 2 bytes End this stream; the engine also handles a particular world-1 cutscene at this terminal
0xBBBB 4 bytes Following UINT16BE selects a sublevel-position lookup
0xCCCC 4 bytes Following UINT16BE is a target for the event-stream wait counter
0xDDDD 2 bytes Start the attract demo and end the stream
Other value 6 bytes + payload Entity-spawn record; ordinary records use 0xEEEE

The ordinary marker is a discriminant, not an additional entity parameter; the original consumer checks the four special values, rather than requiring 0xEEEE.

Entity records

Data type Name Description
UINT16BE marker Any non-control marker
UINT16BE layout BX layout selector passed to the entity factory
UINT16BE type Entity type passed in AX
UINT16BE[words] payload Length selected by layout
Layout Payload words Generic fields
2 or 3 2 X, Y
4 3 X, Y, animation-set field at entity +0x14
5 4 As above, plus state/script-table selector
6 5 As above, plus entity field +0x10
7 6 As above, plus entity field +0x26
8 6 Same total length, but a different byte-level interpretation of the tail

The first two payload words represent signed 16-bit coordinates. Preserve their full bit patterns, including negative values. The layout number is not a literal word count. The later generic words select or initialise runtime fields; they are not independently stored animation scripts.

Special entity types

For type 0x1F with layout 7, the six words mean X, Y, Z, one discarded word, and two direction-setup arguments stored at DS:8C1F and DS:8C21. Type 0x1F with another layout falls back to the generic interpretation. Type 0x2B sets some fixed runtime fields before consuming the normal generic payload.

The entity factory also serves runtime spawn queues, including branches whose payload contains a live entity pointer. Those branches are not a general authoring format for static file records. Keep byte-length rules and entity-specific semantics separate when writing an editor.

Related data

Tile layout is in PAP files. Sprite-bank selection, frame composition and the runtime entity-script VM are in the executable. Runtime-generated pickups and projectiles need not have a record in this authored stream.

Source code

From re-magicpockets, the open-source browser port and reverse-engineering project:

Credits

This file format was reverse engineered by VorticonCmdr. Please credit this work in projects that use it; a link back to this wiki is appreciated.