Appearance
Lighting & shadows
Every map is lit by up to two kinds of light source:
- The environment sun — a built-in directional light configured in Scene Settings ▸ Sun. It is not an entity and never appears in the Hierarchy. Every map has one unless you turn it off.
- Light entities — game objects with a
directionalLight,pointLight, orspotLightcomponent, placed like any other object and freely scripted.
One sun = one shadow
If you place your own Directional Light entity, turn the environment sun off (Scene Settings ▸ Sun ▸ Enabled) — two suns mean doubled lighting and two overlapping shadow passes. New maps start with the environment sun off.
Scene Settings ▸ Shadows
Shadows are controlled per map in Scene Settings ▸ Shadows (also settable by the AI and scripts through setSceneSettings, or directly in the map JSON). These are scene-wide settings, like Unity's quality shadows: they drive the environment sun and act as the defaults for every Directional Light entity — so they work no matter which kind of sun lights your map.
| Setting | JSON key | Default | What it does |
|---|---|---|---|
| Enabled | shadowsEnabled | true | Master switch — gates the environment sun and every Directional Light entity. |
| Type | shadowType | 'soft' | Unity's Hard/Soft shadows. soft = smooth, filtered edges (PCFSoft); hard = crisp single-tap edges — cheaper, a stylized look. Renderer-wide. |
| Map Size | shadowMapSize | 2048 | The environment sun's shadow texture resolution: 512, 1024, 2048, 4096. Higher = crisper edges, more GPU memory. |
| Distance | shadowCameraSize | 30 | Unity's Shadow Distance: how far from the camera shadows render, clamped 10–200. Every directional light's shadow box follows the active camera at this radius. Bigger = shadows reach further but each shadow gets softer/blurrier, because the same texture is stretched over more ground. Raise Map Size to compensate. |
| — | shadowCameraNear | 0.5 | Start of the env sun's shadow depth range. JSON/AI only. |
| — | shadowCameraFar | 4 × Distance | End of the env sun's shadow depth range. JSON/AI only. Runtimes keep it at least 3 × Distance — smaller values would put the viewer outside the range and turn shadows off entirely. |
Shadows follow the camera — for every directional light
Directional lights are infinite suns, so — exactly like Unity — where the light entity sits is irrelevant: only its rotation (the light direction) matters. Each directional light's shadow frustum is a box of ±Distance units centred on the active camera and re-centred every frame — in the editor, the play-test, exported standalone games, and published multiplayer alike. Walk, drive, or fly anywhere and shadows come with you; objects further than Distance from the camera simply stop casting, which is what the setting means.
That makes Distance a quality dial as much as a reach dial: it decides how much ground around the viewer shares the shadow texture. 30 suits most maps; racing maps with long sight lines might use 100–200 with a 4096 map.
Shadows from light entities
| Component | Casts shadows | Coverage |
|---|---|---|
directionalLight | castShadow (per entity, gated by the scene's Shadows ▸ Enabled) | Camera-following box (see above). The box half-size is the scene's Distance; the light's own shadowCameraSize (Inspector: Shadow Size, clear the field to reset) can only shrink it for crisper shadows over less ground — the scene Distance is always the outer cap. |
spotLight | always | The spotlight's own cone. |
pointLight | castShadow, default off | Omnidirectional; the most expensive — use sparingly. |
ts
// A scripted lamp: warm spot shadows over a doorway
setComponent('spotLight', { color: '#ffcc88', intensity: 3, angle: 0.6, penumbra: 0.4 })
// A sun with a TIGHTER shadow box than the scene Distance — crisper shadows over less ground
setComponent('directionalLight', { color: '#ffffff', intensity: 1.2, castShadow: true, shadowCameraSize: 20 })
// Longer shadow reach is a SCENE setting (the cap for every light):
scene.setEnvironment({ shadowCameraSize: 120 })Changing shadows from a script
Every Shadows setting is also live-settable at runtime through scene.setEnvironment — the same call that drives sky, fog, and lighting changes. It merges (send only what you change), applies instantly, and in multiplayer broadcasts to every client:
ts
// Nightfall when the boss spawns: darker world, tighter but crisper shadows
scene.setEnvironment({
skyColor: '#0a0a14', ambientIntensity: 0.15, sunIntensity: 0.4,
shadowCameraSize: 40, shadowMapSize: 4096,
})
// Cutscene over the whole arena — trade sharpness for reach, then restore
scene.setEnvironment({ shadowCameraSize: 200 })
scene.setEnvironment({ shadowCameraSize: 30 })
// Turn shadows off for a low-spec mode toggle
scene.setEnvironment({ shadowsEnabled: false })Troubleshooting
- No shadows at all in the editor, and no shadow setting does anything — check Editor Settings ▸ Shadow Quality:
offdisables shadow rendering for your editor only (a per-user preference saved in the browser — the Scene Settings panel shows a warning when it's active). Exports and multiplayer are unaffected by it. - No shadows at all — check Scene Settings ▸ Shadows ▸ Enabled, and that the environment sun is on (Sun ▸ Enabled) or an entity light has
castShadow: true. - Shadows look soft/blocky — raise Map Size, or lower Distance (the texture covers less ground, so each shadow gets more pixels).
- Striped or splotchy surfaces (shadow acne) — the engine ships tuned bias defaults; if you see acne on custom content, raise Map Size or reduce Distance rather than pushing intensity.
See also
- Scripting basics —
setSceneSettingsandsetComponentfrom scripts.