Scene requirements

This document defines the target requirements for new Vrata scenes. It is based on the current Scene Bundle v1 runtime contract and on diagnostics from the legacy exported staging scenes. The legacy scenes are useful only as technical probes. New scenes must be original or properly licensed and must not copy their meshes, textures, layouts, names, trade dress, or distinctive visual composition.

The default project-authored workflow is defined by docs/arch/2026-08-29-agentic-deterministic-scene-authoring.md. These requirements validate the resulting scene and remain independent of the LLM, agent orchestrator, DCC, or repository topology used during authoring.

Goals

Every scene also follows the shared quality contract and task packet. Technical compatibility, reproducibility and image-regression thresholds cannot close its User/Builder/Physics or visual-quality gates. Inherit those requirements for every room type.

Human Requirements

Originality And Rights

User Experience

Runtime Fit

Bundle Layout

Production bundles should use this layout:

assets/scenes/<scene-id>/
  scene.json
  scene.glb
  preview.webp
  LICENSES.md

Rules:

Manifest Requirements

The runtime currently parses Scene Bundle v1. Validators for new scenes should be stricter than the runtime parser.

Field Severity Requirement
schemaVersion fail Must equal 1 until a new runtime schema is shipped.
sceneId fail Lower-kebab ID, stable and immutable for a published version, matching the bundle directory.
label fail Human-readable name, 3-60 characters, no internal codenames or third-party brands unless licensed.
source fail Public-safe provenance string, not a local absolute path.
glbPath fail Relative path to .glb; no absolute URLs for production bundles.
renderMode warn Must be default or clean; prefer clean only when the asset was checked under clean runtime lighting.
spawnPoints fail Non-empty array; first entry must be main and must be usable.
bounds fail Required for product scenes; must describe the intended navigable room, not exporter/helper extents.
anchors.teleportFloorY warn Required when teleport/seating is expected; usually 0.
anchors.seatAnchors warn/fail Required if visible seats are part of the scene promise; optional for empty gallery/stage scenes.
materialOverrides warn Should be absent. Up to 5 targeted overrides may be allowed temporarily with a ticket and expiry.
preview fail Required for product scenes and must point to an existing preview image.
rights fail Required by validators even though runtime ignores it today.

Recommended rights block:

{
  "rights": {
    "owner": "vrata",
    "license": "internal-original",
    "clearedFor": ["staging", "production", "web-runtime", "screenshots", "optimization"],
    "sourceAssets": [
      {
        "id": "asset-library-or-ticket-id",
        "type": "mesh|texture|hdr|audio|font",
        "author": "Vrata",
        "licenseRef": "LICENSES.md"
      }
    ]
  }
}

Coordinate And Scale Requirements

Spawn Requirements

The first spawn point is the runtime entry point today.

Check Severity Requirement
spawnPoints[0].id fail Must be main.
Position finite fail x, y, and z must be finite numbers.
On floor fail abs(position.y - teleportFloorY) <= 0.1 unless the room intentionally starts on a platform.
Inside bounds fail Spawn must be inside manifest bounds with at least 0.5m margin from walls/edges.
Head clearance fail At least 2.0m clear vertical space above spawn.
Open radius fail At least 0.75m free radius around the player root.
First view readability fail Runtime screenshot from spawn must pass the visual thresholds below.
Future yaw warn Add yaw when schema/runtime support lands; until then author the room so default yaw is usable.

Spawn staging checks must use ?debug=1&scenefit=0. Debug auto-fit is enabled by default with ?debug=1 and replaces the manifest spawn, so a screenshot or pose captured without scenefit=0 is not spawn evidence.

Seating And Interaction Anchors

Seat anchors are domain metadata, not decorative mesh names.

Geometry Requirements

Material And Lighting Requirements

Texture Requirements

Performance Budgets

Budgets are per scene bundle profile. Validators should support profile selection and default to desktop-standard for staging rooms.

Metric mobile-lite fail desktop-standard warn desktop-standard fail xr fail
Bundle size >15 MB >25 MB >40 MB >25 MB
Main GLB size >15 MB >25 MB >40 MB >25 MB
Runtime triangles >90000 >150000 >220000 >120000
Runtime object count >500 >600 >1000 >500
Runtime mesh count >250 >300 >600 >300
Runtime material count >96 >128 >256 >128
Runtime texture count >48 >64 >96 >64
Cold load on staging desktop >20000 ms >15000 ms >30000 ms >20000 ms

Notes:

Runtime Visual Acceptance

Runtime acceptance must be measured in the real Vrata browser runtime, not only through static GLB inspection.

Required command shape for automated checks:

open /rooms/<room-id>?debug=1&scenefit=0
wait until window.__VRATA_DEBUG__.sceneBundleState is loaded or failed
read window.__VRATA_DEBUG__.sceneDebug

Hard failures:

Warnings:

Intentional dark scenes:

Supported glTF Features

Allowed for product scenes:

Warnings for product scenes:

Failures for product scenes:

Validator Rule IDs

Agents and validators should report stable rule IDs. Suggested IDs:

Rule ID Severity Check
SCENE_RIGHTS_001 fail rights metadata exists and clears staging/production/web-runtime.
SCENE_RIGHTS_002 fail No prior-company paths, names, brands, or unlicensed asset references.
SCENE_MANIFEST_001 fail schemaVersion === 1.
SCENE_MANIFEST_002 fail sceneId is lower-kebab and matches bundle directory.
SCENE_MANIFEST_003 fail glbPath is relative .glb with no traversal.
SCENE_MANIFEST_004 fail preview exists for product scenes.
SCENE_MANIFEST_005 fail bounds exists and all axes are positive finite numbers.
SCENE_ASSET_001 fail Main GLB exists and size is within selected profile fail budget.
SCENE_ASSET_002 fail All GLB/bundle resource references resolve.
SCENE_GLTF_001 fail GLB is valid glTF 2.0 and has exactly one default scene or documented scene selection.
SCENE_GLTF_002 fail No unsupported required extensions.
SCENE_GLTF_003 warn Deprecated or ignored extensions are present.
SCENE_SCALE_001 fail Runtime bounds are finite and no normal indoor axis exceeds 200m.
SCENE_SCALE_002 fail Runtime bounds are not more than 3x manifest bounds without approved world profile.
SCENE_SPAWN_001 fail First spawn is main, finite, inside bounds, on floor, and has clearance.
SCENE_SEAT_001 fail Seat anchors have unique IDs, finite position, valid yaw, positive radius.
SCENE_SEAT_002 warn Visible seating lacks anchors or anchors are too close/inside geometry.
SCENE_MATERIAL_001 warn Unconverted placeholder material names are present.
SCENE_MATERIAL_002 fail Broad material overrides are required to make the scene readable.
SCENE_VISUAL_001 fail Runtime scene does not reach loaded.
SCENE_VISUAL_002 fail Runtime missing assets are non-empty.
SCENE_VISUAL_003 fail Spawn screenshot is black/transparent/unreadable.
SCENE_PERF_001 warn Runtime metrics exceed profile warning budget.
SCENE_PERF_002 fail Runtime metrics exceed profile fail budget.

Machine-Readable Profile

The following JSON is the initial validator profile. It is intentionally stricter than the legacy staging corpus.

{
  "sceneRequirementsVersion": 1,
  "defaultProfile": "desktop-standard",
  "format": {
    "schemaVersion": 1,
    "productionAssetExtensions": [".glb"],
    "fixtureAssetExtensions": [".glb", ".gltf"],
    "legacyOnlyExtensions": [".fbx"],
    "requiredProductFiles": ["scene.json", "scene.glb", "preview.webp|preview.jpg"],
    "forbiddenPathPatterns": ["..", "^/", "^[A-Za-z]:", "\\\\"]
  },
  "rights": {
    "required": true,
    "requiredClearedFor": ["staging", "production", "web-runtime", "screenshots", "optimization"],
    "forbidUnlicensedThirdPartyAssets": true,
    "forbidPriorCompanyTradeDress": true
  },
  "profiles": {
    "mobile-lite": {
      "maxBundleMb": 15,
      "maxGlbMb": 15,
      "maxRuntimeTriangles": 90000,
      "maxRuntimeObjects": 500,
      "maxRuntimeMeshes": 250,
      "maxRuntimeMaterials": 96,
      "maxRuntimeTextures": 48,
      "maxLoadMs": 20000
    },
    "desktop-standard": {
      "warnBundleMb": 25,
      "maxBundleMb": 40,
      "warnRuntimeTriangles": 150000,
      "maxRuntimeTriangles": 220000,
      "warnRuntimeObjects": 600,
      "maxRuntimeObjects": 1000,
      "warnRuntimeMeshes": 300,
      "maxRuntimeMeshes": 600,
      "warnRuntimeMaterials": 128,
      "maxRuntimeMaterials": 256,
      "warnRuntimeTextures": 64,
      "maxRuntimeTextures": 96,
      "warnLoadMs": 15000,
      "maxLoadMs": 30000
    },
    "xr": {
      "maxBundleMb": 25,
      "maxGlbMb": 25,
      "maxRuntimeTriangles": 120000,
      "maxRuntimeObjects": 500,
      "maxRuntimeMeshes": 300,
      "maxRuntimeMaterials": 128,
      "maxRuntimeTextures": 64,
      "maxLoadMs": 20000
    }
  },
  "scale": {
    "unit": "meter",
    "floorYDefault": 0,
    "floorYTolerance": 0.05,
    "normalIndoorMaxAxisM": 200,
    "manifestBoundsWarnRatio": 1.5,
    "manifestBoundsFailRatio": 3.0,
    "normalIndoorMinWidthDepthM": 4,
    "normalIndoorMaxWidthDepthM": 80,
    "normalIndoorMinHeightM": 2.4,
    "normalIndoorMaxHeightM": 20
  },
  "spawn": {
    "mainSpawnRequired": true,
    "floorToleranceM": 0.1,
    "wallMarginM": 0.5,
    "freeRadiusM": 0.75,
    "headClearanceM": 2.0
  },
  "seating": {
    "idPattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
    "yawMin": -3.141593,
    "yawMax": 3.141593,
    "radiusMinM": 0.35,
    "radiusMaxM": 0.8,
    "seatHeightMinM": 0,
    "seatHeightMaxM": 0.8,
    "minDistanceMultiplier": 1.5
  },
  "visual": {
    "requireLoadedState": true,
    "requireNoFailureReason": true,
    "maxMissingAssets": 0,
    "minAverageAlpha": 250,
    "warnDarkPixelRatio": 0.35,
    "maxDarkPixelRatio": 0.70,
    "warnAverageLuminance": 55,
    "minAverageLuminance": 40,
    "intentionalDarkRequiresHumanReview": true
  },
  "gltf": {
    "allowedExtensions": [
      "KHR_texture_transform",
      "KHR_materials_unlit",
      "KHR_materials_emissive_strength",
      "KHR_lights_punctual",
      "KHR_draco_mesh_compression",
      "EXT_meshopt_compression",
      "KHR_texture_basisu"
    ],
    "warnExtensions": [
      "KHR_animation_pointer",
      "KHR_materials_pbrSpecularGlossiness"
    ],
    "forbidUnsupportedRequiredExtensions": true
  }
}

Acceptance Flow

  1. Static manifest validation: fields, paths, rights metadata, bundle layout.
  2. Static asset validation: GLB parse, resource references, extension support, sizes, texture dimensions, materials, node transforms, raw stats.
  3. Runtime local validation: load through Vrata runtime with ?debug=1&scenefit=0, assert loaded state, screenshot readability, runtime stats, missing assets.
  4. Staging validation: publish immutable bundle URL, bind a test room, run the same runtime checks against staging.
  5. Human review: confirm the scene is original, readable, socially usable, and not visually derived from the legacy copyrighted scenes.

Definition Of Ready For A New Scene

Source: docs/scene-technical-requirements.md in vrata-labs/platform at revision 380b2e7ff1dd, license Apache-2.0. GitHub