Skip to content

2D scene format

VGAI Reference 0.3

Planned versioned generated-schema truth covering First-party PixiJS worlds and 2D authoring.

planned · generated · immutable Reference 0.3

Lifecycle and constraints

Detailed constraints will publish with the generated or reviewed entry.

Runnable Learn material

Generated format inventory

Inventory only — AC-REF-002 is not passed. Valid parser-verified examples, narrative guidance, complete cross-field/runtime constraints, and version history remain deferred. This page must not be treated as a complete format contract.

Source: packages/engine/schemas/scn2d.schema.json · 101 branch-sensitive field records · 63 source-described. This source intentionally supersedes the frozen study boundary.

scene-2d · file · 101 fields
Field / branchTypeRequiredDefaultConstraintsDescription
# $ object yes none {"additionalProperties":false} A world2d scene (PixiJS render surface)
# $.version number no none none Scene format version
# $.name string no none none Scene name shown in the native 2D document hierarchy and inspector
# $.surface const "world2d" no none {"const":"world2d"} Render surface. Always 'world2d'
# $.gravity array no none none World gravity [x, y] in px/s^2. Default [0, 9.8 * pixelsPerMeter] ([0, 980] at the default scale)
# $.gravity[0] number yes none none Missing source description
# $.gravity[1] number yes none none Missing source description
# $.pixelsPerMeter number no none {"exclusiveMinimum":0} Authored pixels per physics meter. Configures native Rapier World.lengthUnit and scales default gravity. Default 100
# $.background string no none none Background color hex string. Default '#10101a'
# $.entities array yes none none Root entities of the world2d scene
# $.entities[] ref #/$defs/__schema0 yes none none Missing source description
# $.entities[]ref:#/$defs/__schema0 object yes none {"additionalProperties":false} Missing source description
# $.entities[].idref:#/$defs/__schema0 string no none none Unique entity ID. Auto-generated if omitted
# $.entities[].nameref:#/$defs/__schema0 string yes none none Human-readable entity name (shown in hierarchy panel)
# $.entities[].surfaceref:#/$defs/__schema0 enum (2) no none {"enum":["world2d","world3d"]} Render surface that instantiates this entity. Default 'world2d' in a Scene2D file. The 'world3d' value is REJECTED at parse (T4.1): declared but has no runtime reader — authoring surface: 'world3d' throws. Do not author it ('world2d', the default, is fine).
# $.entities[].visibleref:#/$defs/__schema0 boolean no none none Whether the entity and its children are rendered
# $.entities[].lockedref:#/$defs/__schema0 boolean no none none Prevent selection and editing in the native 2D scene editor
# $.entities[].tagsref:#/$defs/__schema0 array no none none Arbitrary string tags for runtime queries. REJECTED at parse (T4.1): declared but has no runtime reader — authoring this field throws. Do not author.
# $.entities[].tags[]ref:#/$defs/__schema0 string yes none none Missing source description
# $.entities[].transform2dref:#/$defs/__schema0 object no none {"additionalProperties":false} Local 2D transform relative to parent
# $.entities[].transform2d.positionref:#/$defs/__schema0 array no none none Local position [x, y] in world2d pixels
# $.entities[].transform2d.position[0]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].transform2d.position[1]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].transform2d.rotationref:#/$defs/__schema0 number no none none Rotation in radians about the Z axis. Default 0
# $.entities[].transform2d.scaleref:#/$defs/__schema0 array no none none Scale per axis [x, y]. Default [1, 1]
# $.entities[].transform2d.scale[0]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].transform2d.scale[1]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].transform2d.pivotref:#/$defs/__schema0 array no none none Local pivot point [x, y] (center of rotation/scale)
# $.entities[].transform2d.pivot[0]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].transform2d.pivot[1]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].pivotref:#/$defs/__schema0 array no none none Local-space pivot point [x, y]
# $.entities[].pivot[0]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].pivot[1]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].spriteref:#/$defs/__schema0 object no none {"additionalProperties":false} 2D sprite appearance
# $.entities[].sprite.textureref:#/$defs/__schema0 string no none none Texture asset URL (loaded via PIXI.Assets). Omit for a tintable 1x1 white texture
# $.entities[].sprite.frameref:#/$defs/__schema0 string no none {"minLength":1} Spritesheet frame/sub-texture name when `texture` is a spritesheet atlas
# $.entities[].sprite.animationref:#/$defs/__schema0 string no none {"minLength":1} Named spritesheet animation from `texture` (PIXI.Spritesheet.animations); mutually exclusive with `frame`
# $.entities[].sprite.anchorref:#/$defs/__schema0 array no none none Normalized anchor [x, y] (0..1). Default [0.5, 0.5]
# $.entities[].sprite.anchor[0]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].sprite.anchor[1]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].sprite.tintref:#/$defs/__schema0 string no none none Tint color as hex string (e.g. '#ff8800'). Default white
# $.entities[].sprite.alpharef:#/$defs/__schema0 number no none {"minimum":0,"maximum":1} Opacity 0..1. Default 1
# $.entities[].sprite.widthref:#/$defs/__schema0 number no none none Explicit display width in pixels (overrides texture size)
# $.entities[].sprite.heightref:#/$defs/__schema0 number no none none Explicit display height in pixels (overrides texture size)
# $.entities[].sprite.blendModeref:#/$defs/__schema0 enum (4) no none {"enum":["normal","add","multiply","screen"]} PixiJS blend mode. Default normal
# $.entities[].sprite.interactiveref:#/$defs/__schema0 boolean no none none Enable federated pointer events (eventMode=static) so this sprite can be picked
# $.entities[].sprite.filterref:#/$defs/__schema0 enum (3) no none {"enum":["none","blur","desaturate"]} Apply a PixiJS filter (BlurFilter / ColorMatrix desaturate). Default none
# $.entities[].sprite.fpsref:#/$defs/__schema0 number no none {"exclusiveMinimum":0} AnimatedSprite playback speed in frames/sec. Default 8
# $.entities[].sprite.loopref:#/$defs/__schema0 boolean no none none Whether the named spritesheet animation loops. Default true
# $.entities[].textref:#/$defs/__schema0 object no none {"additionalProperties":false} World-space text label
# $.entities[].text.textref:#/$defs/__schema0 string yes none none The string to display
# $.entities[].text.fontSizeref:#/$defs/__schema0 number no none none Font size in pixels. Default 24
# $.entities[].text.fillref:#/$defs/__schema0 string no none none Text color as hex string. Default '#ffffff'
# $.entities[].text.anchorref:#/$defs/__schema0 array no none none Normalized anchor [x, y] (0..1). Default [0.5, 0.5]
# $.entities[].text.anchor[0]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].text.anchor[1]ref:#/$defs/__schema0 number yes none none Missing source description
# $.entities[].tilemapref:#/$defs/__schema0 object no none {"additionalProperties":false} 2D tilemap (CompositeTilemap)
# $.entities[].tilemap.framesref:#/$defs/__schema0 array yes none {"minItems":1} Ordered Pixi spritesheet frame names used as tile indices
# $.entities[].tilemap.frames[]ref:#/$defs/__schema0 string yes none {"minLength":1} Missing source description
# $.entities[].tilemap.textureref:#/$defs/__schema0 string yes none {"minLength":1} URL or project path to a Pixi spritesheet JSON asset
# $.entities[].tilemap.tileSizeref:#/$defs/__schema0 number yes none {"exclusiveMinimum":0} Positive square tile width/height in pixels
# $.entities[].tilemap.tilesref:#/$defs/__schema0 array yes none none Row-major grid of frame indices; -1 is an empty cell (each row is an array of tile indices)
# $.entities[].tilemap.tiles[]ref:#/$defs/__schema0 array yes none none Missing source description
# $.entities[].tilemap.tiles[][]ref:#/$defs/__schema0 integer yes none {"minimum":-9007199254740991,"maximum":9007199254740991} Missing source description
# $.entities[].physics2dref:#/$defs/__schema0 object no none {"additionalProperties":false} 2D physics rigid body + collider
# $.entities[].physics2d.bodyTyperef:#/$defs/__schema0 enum (4) yes none {"enum":["dynamic","fixed","kinematicVelocity","kinematicPosition"]} Rapier 2D rigid-body type. A body of any type nested below a dynamic or kinematic body is rejected: Rapier has no parent/child body relationship. Nesting below a fixed or physics-less transformed parent is supported for fixed bodies. Dynamic and kinematic bodies additionally require a conformal parent chain (uniform scale plus rotation/reflection), because later body rotation cannot round-trip through non-uniform parent scale without shearing the Pixi visual.
# $.entities[].physics2d.colliderref:#/$defs/__schema0 oneOf (3) yes none none Collider shape attached to the body. Its pose and dimensions use the composed parent transform at spawn. Cuboids support non-uniform scale; ball/capsule colliders reject non-uniform scale because Rapier cannot represent an ellipse.
# $.entities[].physics2d.colliderref:#/$defs/__schema0 oneOf[0] object yes none {"additionalProperties":false} Missing source description
# $.entities[].physics2d.collider.shaperef:#/$defs/__schema0 oneOf[0] const "cuboid" yes none {"const":"cuboid"} Box collider aligned to the rigid-body rotation
# $.entities[].physics2d.collider.halfExtentsref:#/$defs/__schema0 oneOf[0] array yes none none Half-width and half-height [hx, hy] in pixels
# $.entities[].physics2d.collider.halfExtents[0]ref:#/$defs/__schema0 oneOf[0] number yes none none Missing source description
# $.entities[].physics2d.collider.halfExtents[1]ref:#/$defs/__schema0 oneOf[0] number yes none none Missing source description
# $.entities[].physics2d.colliderref:#/$defs/__schema0 oneOf[1] object yes none {"additionalProperties":false} Missing source description
# $.entities[].physics2d.collider.shaperef:#/$defs/__schema0 oneOf[1] const "ball" yes none {"const":"ball"} Circle collider
# $.entities[].physics2d.collider.radiusref:#/$defs/__schema0 oneOf[1] number yes none none Radius in pixels
# $.entities[].physics2d.colliderref:#/$defs/__schema0 oneOf[2] object yes none {"additionalProperties":false} Missing source description
# $.entities[].physics2d.collider.shaperef:#/$defs/__schema0 oneOf[2] const "capsule" yes none {"const":"capsule"} Capsule collider (vertical)
# $.entities[].physics2d.collider.halfHeightref:#/$defs/__schema0 oneOf[2] number yes none none Half the straight segment length
# $.entities[].physics2d.collider.radiusref:#/$defs/__schema0 oneOf[2] number yes none none Cap radius
# $.entities[].physics2d.sensorref:#/$defs/__schema0 boolean no none none If true, a sensor (trigger) collider — overlaps fire onTriggerEnter/Exit, no solid response
# $.entities[].physics2d.densityref:#/$defs/__schema0 number no none none Collider density (drives mass). Default 1
# $.entities[].physics2d.frictionref:#/$defs/__schema0 number no none none Coefficient of friction. Default 0.5
# $.entities[].physics2d.restitutionref:#/$defs/__schema0 number no none none Bounciness 0..1. Default 0
# $.entities[].physics2d.linearDampingref:#/$defs/__schema0 number no none none Linear velocity damping. Default 0
# $.entities[].physics2d.gravityScaleref:#/$defs/__schema0 number no none none Per-body gravity multiplier. Default 1
# $.entities[].physics2d.lockRotationsref:#/$defs/__schema0 boolean no none none Lock the body so it cannot rotate. Default false
# $.entities[].componentsref:#/$defs/__schema0 object no none {"additionalProperties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}},{"type":"array","items":{"type":"boolean"}}]}},"propertyNames":{"type":"string"}} User-defined components (validated against the world2d component registry)
# $.entities[].components{key}ref:#/$defs/__schema0 object no none {"additionalProperties":{"anyOf":[{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},{"type":"array","items":{"type":"number"}},{"type":"array","items":{"type":"string"}},{"type":"array","items":{"type":"boolean"}}]},"propertyNames":{"type":"string"}} Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf (4) no none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[0] anyOf (3) no none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[0] anyOf[0] number no none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[0] anyOf[1] string no none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[0] anyOf[2] boolean no none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[1] array no none none Missing source description
# $.entities[].components{key}{key}[]ref:#/$defs/__schema0 anyOf[1] number yes none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[2] array no none none Missing source description
# $.entities[].components{key}{key}[]ref:#/$defs/__schema0 anyOf[2] string yes none none Missing source description
# $.entities[].components{key}{key}ref:#/$defs/__schema0 anyOf[3] array no none none Missing source description
# $.entities[].components{key}{key}[]ref:#/$defs/__schema0 anyOf[3] boolean yes none none Missing source description
# $.entities[].childrenref:#/$defs/__schema0 array no none none Child entities
# $.entities[].children[]ref:#/$defs/__schema0 ref #/$defs/__schema0 yes none none Missing source description