Files
forma-engine/docs/2_5D_PRESENTATION.md

50 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fixed-camera games and runtime presentation
Forma supports fixed orthographic scenes that combine 3D geometry and transparent GLB sprite planes. This is optional: projects without these settings retain the existing camera, controls, and player UI.
## Camera and rendering
An entity can have `camera: { mode: "fixed", lookAt: [0, 0, 0], projection: "orthographic", orthoWidth: 24, aspect: 16 / 9 }`. The camera uses the entity's world position, faces `lookAt`, and preserves the specified aspect ratio with letterboxing. Omit `aspect` to fill the current viewport. The inspector exposes fixed mode, projection, width and look-at position. Perspective and follow/first-person cameras remain supported.
`settings.rendering` accepts `toneMapping`, `exposure`, `contrast` and `defaultLights`. Set `defaultLights: false` to use only authored lights, for example in an imported Blender scene. Disabling tone mapping is useful for artwork that already contains lighting. Generated mesh materials accept `unlit`, `alpha` (01) and `doubleSided`; scripts can update them through `api.patch`. Imported GLB materials retain their authoring settings unless a material override is requested.
## Controls
`settings.controls` optionally maps `attack`, `jump`, `dash`, `sprint` and `reset` to arrays of browser `KeyboardEvent.code` values. Empty arrays disable a keyboard action. Mouse attack and pointer aiming retain the existing runtime input API. Movement remains WASD/arrows; a project's script may transform those axes into its camera basis. Dash/jump/reset also have one-frame pressed events.
## Presentation
Optional `settings.presentation` enables the same lightweight overlay in the editor and exported standalone player:
```json
{
"title": "Example game",
"accent": "#d74732",
"instructions": "WASD — move · J — attack · Space — dash",
"start": { "title": "Example game", "body": "Reach the exit." }
}
```
The start screen pauses simulation until the player continues. The overlay supplies pause/resume, fullscreen, sound, touch movement/attack/dash and keyboard restart. On restart it emits `resetPressed`; the project script owns resetting its gameplay state. Stop in the editor restores the original scene document.
Scripts can emit these presentation events:
```js
api.emit("hud", {
objective: "Wave 1 / 3",
counters: ["Enemies: 4", "Defeated: 0"],
meters: [
{ id: "life", label: "Health", value: 4, max: 5, style: "hearts" },
{ id: "dash", label: "Dash", value: 0.7, max: 1, style: "bar" }
]
});
api.emit("hud", { overlay: { title: "Victory", body: "You reached the exit.", button: "Play again" } });
api.emit("hud", { overlay: null }); // Clear an outcome overlay when resetting.
api.emit("feedback", {}); // Brief damage vignette.
api.emit("sound", { frequency: 520, endFrequency: 90, duration: 0.1, type: "triangle", gain: 0.025 });
```
Outcome overlays pause simulation. HUD text is assigned as text content, meter values and list lengths are bounded. Audio starts after a user gesture and can be muted. Runtime callbacks continue receiving these events, including during headless tests.
The concrete arena, artwork, combat, enemy AI and wave progression live in `projects/InfernalCourtyard`, not in the engine or default project templates.