Script fields of MonoBehaviours
A game’s own components are MonoBehaviours (class id 114). Their type tree covers only the base fields; the fields the game’s script declares follow in the object’s bytes. A player build strips the script’s tree, so these bytes have no description in the file: the layout comes from the script’s source or from measuring the data. Observed
The serialization rules are Unity’s: fields in declaration order, every value its type’s size, the position padded to 4
bytes after a bool field that ends the object or precedes a wider one (a ResetPosition’s one flag is followed by three
zero bytes), a string a 32-bit length then the bytes and padding to 4, an object reference 12 bytes (i32 file id, i64
path id; a path id of 0 is null). Observed · SkateBIRD, Sledding
A layout read from measured bytes belongs to the Unity version and game build it was measured on. A reader that refuses bytes of another length, a bool that is neither 0 nor 1, or padding that is not zero fails loudly instead of guessing. Inferred
SkateBIRD’s scripts
Section titled “SkateBIRD’s scripts”Measured on SkateBIRD’s Unity 2019.4.20f1 files: 134 ResetPosition scripts and the MissionGiver scripts of levels 1 to
5, 7, 12 and 13. Observed · SkateBIRD
The bytes after the MonoBehaviour base fields.
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 1 | bool | startingPosition | Proven | 1 on the point where the level starts; each level stores at most one such point, level7 none |
| 0x1 | 3 | u8[3] | padding | Proven | zero in every script read |
MissionGiver’s first field is the mission’s title: a string (a 32-bit length, that many UTF-8 bytes, zero padding to a
multiple of 4); the fields after it are not decoded. Observed · SkateBIRD An empty title means the giver has none.
Observed · SkateBIRD
One node of a rail; nodes are chained by their references. Measured over the 540 nodes of level1.
| Offset | Size | Type | Field | Confidence | Notes |
|---|---|---|---|---|---|
| 0x0 | 12 | PPtr | prev | Observed | previous node of the chain; a path id of 0 is none |
| 0xC | 12 | PPtr | next | Observed | next node of the chain |
| 0x18 | 12 | PPtr | reference 3 | Unknown | a reference to another object; its target and meaning are not established |
| 0x24 | 12 | PPtr | reference 4 | Unknown | a reference to another object; its target and meaning are not established |
| 0x30 | 8 | u8[8] | flags | Unknown | eight bytes, each 0 or 1 in every node read; meaning not established |
A chain of nodes is a rail: start at a node with no prev, follow next. A chain with no such node is closed.
Observed · SkateBIRD Chains of a single node carry no curve; a node whose next has a prev pointing elsewhere
makes the chain follow next; two nodes naming the same next end the second chain there. Observed · SkateBIRD
The Universal Render Pipeline asset
Section titled “The Universal Render Pipeline asset”URP’s settings live in a UniversalRenderPipelineAsset MonoBehaviour per quality level. Its fields are stored in the
class’s declaration order, 4 bytes per value (a bool padded to 4), an object reference 12 bytes and an array its count and
elements. The layout is verified for k_AssetVersion 13: the three assets of Sledding Game (452 bytes each as read) give
settings equal to the keywords of the shader variants the build keeps for them. Observed · Sledding
| Field group (in order) | Stored as | Confidence |
|---|---|---|
k_AssetVersion, k_AssetPreviousVersion |
i32, i32 (13) |
Observed · Sledding |
m_RendererType, m_RendererData |
i32, reference |
Observed · Sledding |
| renderer list | count, then 12 bytes per reference | Observed · Sledding |
| default renderer, depth and opaque texture, downsampling, terrain holes, HDR and its precision, MSAA, render scale, upscaling filter, FSR sharpness | 4 bytes each | Observed · Sledding |
| LOD cross fade (bool), dithering type, SH evaluation mode, light probe system, probe volume budgets, flags and SH bands | 4 bytes each | Observed · Sledding |
| main light mode (0 disabled, 1 per pixel, 2 per vertex), main light shadows, shadow map resolution | 4 bytes each | Observed · Sledding |
| additional lights mode, per-object limit, additional light shadows and its resolution tiers | 4 bytes each | Observed · Sledding |
| reflection probe blending, box projection, atlas | bool each, 4 bytes | Observed · Sledding |
shadow distance (f32), cascade count (1 to 4), cascade splits and border, depth and normal bias |
4 bytes each, splits 4 + 8 + 12 | Observed · Sledding |
| soft shadows, enclosing sphere, soft quality, cookie resolution and format, SRP batcher, dynamic batching | 4 bytes each | Observed · Sledding |
| mixed lighting, light cookies, light layers | bool each | Observed · Sledding |
The later fields (batching, post-processing, the GPU resident drawer) follow in URP 17.3’s declaration order: PEAK’s asset and Sledding Game’s read in that order to their last byte. Observed · Sledding, PEAK Another asset version has another layout and is refused. Inferred
Big Walk’s asset, of the same asset version, departs from that order: it holds the same fields through the reflection probe blending (offset 184), and then two integers (6, 6) and a float 100.0 where 17.3 has the box projection. Observed · Big Walk Big Walk is an IL2CPP build, so the class it was built with is not traced. Unknown · Big Walk
A renderer’s m_RendererFeatureMap need not match its m_RendererFeatures: Big Walk’s renderer (globalgamemanagers.assets
object 4550) stores no feature and a map of one entry. Observed · Big Walk Only the editor maintains the map; PEAK’s
decompiled URP runtime has no reader of it. Observed · PEAK So a reader reads it as stored and does not check its length
against the features. Inferred
Global settings
Section titled “Global settings”GraphicsSettings’ m_CurrentRenderPipelineGlobalSettings names a UniversalRenderPipelineGlobalSettings MonoBehaviour in
globalgamemanagers.assets. It decodes in declaration order to its last byte, including its [SerializeReference] registry
(version 2; each entry a 64-bit id, the class, namespace and assembly names, then the data): 16 graphics-settings entries in PEAK
(3,448 bytes) and 16 in Sledding Game (3,452 bytes). Observed · PEAK, Sledding Sledding Game’s include the screen-space
ambient occlusion resources and no GPU resident drawer or STP resources; Big Walk’s hold a class of the game’s own,
MA.Flora.FloraRuntimeSettings. Observed · Sledding, Big Walk UniversalRendererResources holds m_CopyDepthPS and
m_DBufferClear, shader references. Observed · PEAK, Sledding
RenderGraphSettings.m_EnableRenderCompatibilityMode is false in PEAK and true in Sledding Game. Observed · PEAK, Sledding
The pipeline reads it only when URP is built with URP_COMPATIBILITY_MODE, using the render graph when it is false and logging
RenderGraph is now enabled. or disabled. in a player. Sourced · Universal Render Pipeline source (Unity-Technologies/Graphics)
PEAK’s URP assembly is built without it (the getter returns false, UniversalRenderer.Setup is empty), so PEAK always draws through
the render graph. Observed · PEAK Sledding Game’s IL2CPP metadata holds the compatibility path’s strings and its player log
reads RenderGraph is now disabled.: Sledding Game draws URP in Compatibility Mode. Observed · Sledding Big Walk’s metadata
does not hold that string. Observed · Big Walk
PEAK’s pipeline
Section titled “PEAK’s pipeline”PEAK has one pipeline asset, URPAsset (asset version 13, in globalgamemanagers.assets), used by the graphics settings and every
quality level: depth texture and opaque texture required, MSAA 1, and two renderers, URP_Renderer (the default, index 0) and
URP_RenderTexture. Observed · PEAK Both are UniversalRendererData of asset version 3 in URP 17.3’s layout, which
ends at m_IntermediateTextureMode (17.6 adds m_TileOnlyMode), the deprecated shader references coming before the feature
list; both renderers’ bytes are consumed exactly. Observed · PEAK
| Setting | URP_Renderer |
URP_RenderTexture |
Confidence |
|---|---|---|---|
| Rendering mode | 2, Forward+ | 2, Forward+ | Observed · PEAK |
| Depth priming | 0, disabled | 0, disabled | Observed · PEAK |
| Copy depth | 1, after transparents | 1, after transparents | Observed · PEAK |
| Prepass layer mask | 0x8A309437 |
0x82318437 |
Observed · PEAK |
| Opaque layer mask | 0x8A31D437 (adds layers 14, Hazard, and 16) |
0x82318437 |
Observed · PEAK |
| Depth formats, accurate G-buffer normals | default, on | default, on | Observed · PEAK |
URP_Renderer has 15 renderer features, of which the stored active ones are an SCPE EdgeDetectionRenderer, a
DecalRendererFeature (technique 1, DBuffer, maximum draw distance 500, surface data 2: albedo, normal and MAOS, the
_DBUFFER_MRT3 keyword) and two of its five FullScreenPassRendererFeatures; HBAO and the other SCPE effects are stored
inactive. Observed · PEAK The cameras of the scenes (MainCamera in level0, level1, level2 and level4) use the
default renderer (index −1) with the depth option 2, the pipeline’s setting; HeroCamera (renderer 1) and PassportCamera render
into textures. Observed · PEAK
So the frame has a full depth-normals prepass: in the game’s own URP code (Unity.RenderPipelines.Universal.Runtime.dll), the
DBuffer pass asks for depth and normals, a forward renderer then runs a whole prepass (the partial one is for deferred), and with
depth priming off the depth copy is scheduled during the prepass, which renders into _CameraDepthTexture and sets it globally.
An opaque UniversalForward or UniversalForwardOnly program that samples _CameraDepthTexture therefore reads the prepass’s
depth, which holds the opaque-queue renderers of the prepass layer mask drawn through their DepthNormals or
DepthNormalsOnly pass. Inferred · PEAK · from the game’s URP code, decompiled PEAK’s W/Peak_* shaders have
UniversalForwardOnly, ShadowCaster, DepthOnly, DepthNormalsOnly and MotionVectors passes. Observed · PEAK
The stored asset is not what PEAK draws with: its settings handler loads and applies every setting when it is constructed at start-up, before any level draws, and rewrites the asset. Inferred · PEAK · from the game’s scripts, decompiled
| Setting | Default on a desktop | Default on the Steam Deck | Confidence |
|---|---|---|---|
| Render scale | Native: scale 1, upscaling filter Linear | Medium: 0.4, STP | Inferred · PEAK · the scripts |
| Shadow distance | Medium: 150, 2 cascades | Low: 75, 1 cascade | Inferred · PEAK · the scripts |
| Level of detail | Medium: QualitySettings.lodBias 0.85 |
Inferred · PEAK · the scripts | |
| Texture quality | Native: globalTextureMipmapLimit 0 |
Inferred · PEAK · the scripts |
The stored render scale, 0.8 with STP, is neither default. Observed · PEAK The ambient occlusion setting toggles an HBAO
volume component, while the HBAO renderer feature is stored inactive. Observed · PEAK level4’s gameplay cameras store
anti-aliasing 3 (temporal) with post-processing on, so at scale 1 URP 17.3 jitters the projection by Halton(2, 3) − 0.5 at index
(frame & 1023) + 1 times the jitter scale and draws motion vectors after the prepass. Inferred · PEAK · the stored cameras and URP’s code
The asset enables the GPU resident drawer (mode 1, small-mesh culling 0.5 %, occlusion culling off); URP supports it here because
every renderer is Forward+ (IsGPUResidentDrawerSupportedBySRP checks the cluster light loop) and Direct3D 11 uses raw buffers.
Inferred · PEAK · the stored asset and URP’s code level4’s skybox material uses the shader GD/Lit Clouds Sky, drawn by
URP’s skybox pass over Unity’s built-in skybox mesh. Observed · PEAK
PEAK’s and Big Walk’s scripts are not decoded here. The IL2CPP games’ script classes can be recovered from the generated managed stubs, see scripting backends; the field order recovered that way is 4 bytes short on types with serialized fields the stubs lack.