Skip to content

SCP scene tables

Robomodo RMEWorld and streamingApplies toSHRED

The SCP of a model quartet is the scene file. Its first table lists the mesh placements; the rest describes what a level is made of apart from geometry: a tree of nodes, a table of their world matrices, a joint table, and a blob, a chain of typed sections that hold the spot chunks, splines, lights and other scene objects. Every level PAK holds one or more SCPs, 547 in all. Proven · all 547 SCPs

All numbers are big-endian. Pointers inside an SCP are stored as offsets from its start; 0xFFFFFFFF is a null. The loader turns them into pointers when it loads the file, so a stored 0 is a valid offset, not a null. Observed · static reading of the executable

SCP header72 bytesSHRED61% known

Each table is a count and an offset from the start of the file. The loader relocates the offsets named in the last column of the table below.

ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x04u32 = 0xBABF003CmagicProven
0x44u32unknownUnknown
0x82u16 = 0x0048header_sizeObserved
0xA2u16load_flagsObservedbit 1 borrowed storage, bit 4 relocated; 0 on disc
0xC4u32unknownUnknown
0x104u32placement_countProven
0x144u32placement_offsetProvenrecords of 0x30 bytes
0x184u32node_countProven
0x1C4u32node_offsetProvenrecords of 0x70 bytes
0x204u32joint_countProven141 in the 505 level SCPs with joints
0x244u32joint_offsetProvenrecords of 16 bytes
0x288u32[2]table_28Unknowna table of 0x38-byte records the loader relocates; 0 in every file read
0x308u32[2]table_30Unknowna table of 0x200-byte records the loader relocates; 0 in every file read
0x384u32matrix_countProvenequals node_count in all 547 files
0x3C4u32matrix_offsetProvenrecords of 8 bytes
0x404u32unknownUnknown0
0x444u32blob_offsetProven0xFFFFFFFF or 0 when there is no blob (136 SCPs); the chain starts here

A node is 112 bytes. The scene is a tree of nodes; each node lists its children and the placements it owns.

SCP node112 bytesSHRED86% known

Two sets of five (count, pointer) pairs; only the first pair of each set is ever used.

ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x016f32[4]sphereInferreda bounding sphere (centre xyz, radius) on some nodes, zero on the rest
0x104u32idProvensdbm of the node's name; 1 of 106 in CHARLIE resolves (Main)
0x1412u32[3]editor_leftoversObservedheap-like addresses of the authoring session; not data
0x2020u32[5]child_countsProvenonly the first is ever nonzero
0x3420u32[5]child_offsetsProven0xFFFFFFFF when unused; each element is the offset of a node record
0x4820u32[5]placement_countsProven
0x5C20u32[5]placement_offsetsProveneach element is the offset of a placement record

Of the ten (count, offset) pairs only the first of each set occurs: 165,525 child links and 155,292 placement links over the disc’s 166,089 nodes, and every link lands on the start of a record. Proven · all 547 SCPs 564 nodes are never a child (the 547 file roots and 17 others), and 12,211 of the 167,503 placements are owned by no node. Proven · all 547 SCPs The leftovers have no use. Node names are not stored, and a node’s id resolves to a name only in rare cases (Main in CHARLIE). Observed

The matrix table has one 8-byte record per node, in node order: a name or model hash and the offset of a 64-byte row-major matrix with the translation in floats 12 to 14 (the row-vector convention of Placements).

Node matrix record8 bytesSHRED100% known
ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x04u32hashObservedthe group's name hash (NavSplines, CHALLENGE, AI, Audio, ...) or, for a node of one mesh, the model hash; else 0
0x44u32matrix_offsetProven

For 63 of CHARLIE’s 85 placements the node’s matrix equals the placement’s own. The group and root matrices are diag(−1, 1, 1), the export mirror; a spot chunk’s matrix is not composed with it. Observed

The joint table has 141 records of 16 bytes in each of the 505 level SCPs, byte for byte the same: the rig of the player’s skater and board (Hips, Spine, Spine1, …, BoardTruck, BoardNose, Hair*). The two actor SCPs (male, female) have 40-joint variants. Proven · all 547 SCPs It is the table that skinned meshes take their bone names from.

At blob_offset is a chain of sections, each starting with four words and ending where the next begins.

SCP blob section header16 bytesSHRED100% known

The data starts data_offset bytes into the section. The chain ends with a 16-byte record {junk, 8, 0, 0}.

ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x04u32flagsProventhe high 16 bits are the type; the low 16 are junk for splines and vary for the other types (an occluder's low half is its shape)
0x44u32sizeProvenbytes of the section, header included
0x84u32countProven
0xC4u32data_offsetProven0x10, or 0x20 to 0x40 for type 0xE

The 411 SCPs that have a blob all walk to the end record; the data_offset of 0x20 to 0x40 in type 0xE sections is what makes the chain continuous (reading it as 0x10 stops it early in 35 files). Proven · all 411 chains

The engine keeps a registry of section types: a loader and an unloader per type, registered at start-up, each receiving the section’s pointer. Types 2, 3, 5 and 10 have a loader of their own; types 0, 1, 9, a and c share the spline manager, one class each. Types 4, 6, b, d, e and f have no registry entry. Observed · static reading of the executable

Type Content Sections Read
2 spot chunks 387 Proven
0, 1, 9, a, c splines, one class per type 231 Proven
3 spot cameras: 48-byte records of a spot name and two frames 10 Proven
4 lights 55 Proven
5 locators: one record in echo, a waypoint 1 Proven
b occluders: 16-byte records of a name, a matrix and a line outline 9 Proven
d lighting layers: names of specular cube textures (spec_locator_N) 23 Observed
f records of 240 bytes starting with a position (w = 1): probe or ambient volumes 23 Inferred
6 small trailer sections of 32 to 432 bytes whose count word is a leftover address and whose bytes are small-integer arrays 175 Unknown
e 128-byte records of a 64-byte matrix, an id and a parent hash, then zeros; data offset 0x20 to 0x40; no consumer found 38 Observed
10 2,096 records of a 64-byte matrix, a radius, an entity index, a box of 24 f32 (corners at ±4) and named sub-records (snow_timebane_fence_dest, distancemarker_01, vfx_skt_cae_a_debristrash_m.ice); the records tile every section 40 Observed

The section counts are over the disc’s SCPs. Observed The reading of type 10 as breakable props comes from the names and the engine’s loader for the type, whose function was not read in full. Inferred

Counted by a strict reader over the SCPs of each level’s PAKs (base and layers); every chain complete. Proven · all 547 SCPs

Level PAKs Nodes Placements Spot chunks Teleport chunks
Charlie 41 35,820 49,820 3,217 30
Delta 19 12,050 13,323 1,344 22
Echo 17 8,382 8,472 4,714 57
Foxtrot 17 13,252 9,394 7,375 48
India 17 11,403 9,749 6,458 87
Juliet 17 41,184 39,467 7,695 60
Mike 40 11,401 8,944 7,637 15
November 17 13,576 9,764 7,194 63
Oscar 17 7,746 7,608 4,012 75
Papa 17 11,275 10,962 3,369 81
All 166,089 167,503 53,015 538
What are the remaining header tables and section types?

The tables at header offsets 0x28 and 0x30 are relocated by the loader but empty in every SCP read. What the sections of types 6, e and 10 are for (and what consumes e and f) is not established.