Files
forma-engine/docs/2_5D_PRESENTATION.md
T

3.1 KiB
Raw Blame History

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 and contrast. 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:

{
  "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:

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.