Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

File Formats

All Flint data formats use TOML (session recordings are JSON Lines). This page is the reference for every file type the engine reads or writes. Procgen specs (.procgen.toml) and terrain files (.terrain.toml) are covered on their own pages: Procedural Generation and Terrain.

Scene Files (.scene.toml)

The primary data format. Each scene file contains metadata and a collection of named entities with their component data.

[scene]
name = "Scene Name"
version = "1.0"
description = "Optional one-line description"
input_config = "custom_input.toml"  # Optional input binding config
preload_audio = true                # Optional; false skips the blanket audio/ preload

[camera]                            # Optional authored framing
position = [0, 4, 12]
target = [0, 1, 0]

[entities.<name>]
archetype = "<archetype>"
parent = "<parent_name>"          # Optional parent entity

[entities.<name>.<component>]
field = value
[scene] keyTypeDefaultDescription
namestring(required)Human-readable scene name
versionstring"1.0"Format version
descriptionstring(none)Free-text description
input_configstring(none)Game-level input binding overlay (see Input Configuration)
preload_audiobooltrueWhen false, the player skips preloading every file under audio/ at scene load so a scene with a large audio folder starts instantly. Sounds named by audio_source components and music-session stems still load through their own paths; this only gates the convenience preload for script-triggered sounds.

Scenes may also include optional top-level [camera], [environment] and [post_process] blocks, and a [prefabs] section (see Prefab Templates).

[camera]

The authored framing. flint render starts from it when no camera flags are given, and the scene viewer seeds its orbit camera from it (Space returns to it). Absent, both fall back to an automatic framing.

[camera]
projection = "perspective"   # or "orthographic"
position = [0, 4, 12]
target = [0, 1, 0]
fov = 60.0                   # perspective only
near = 0.1
far = 500.0
# ortho_height = 10.0        # orthographic only: half-height in world units
KeyTypeDefaultDescription
projectionstring"perspective""perspective" or "orthographic"
ortho_heightf320Orthographic half-height in world units (orthographic only)
position[f32; 3](auto)Camera position
target[f32; 3](auto)Look-at point
fovf32(renderer default)Vertical field of view in degrees (perspective only)
nearf32(renderer default)Near clipping plane
farf32(renderer default)Far clipping plane

[environment]

Skybox and the scene-wide shading levers. Every lever is optional and its absence means “exactly the legacy shading” (see Lighting). Fog is not here; it lives in [post_process].

[environment]
skybox = "textures/dusk_panorama.png"
ambient_sky = [0.35, 0.40, 0.50]
ambient_ground = [0.18, 0.14, 0.10]
diffuse_wrap = 0.3
oren_nayar = 0.7
sheen_color = [1.0, 0.9, 0.8]
sheen_strength = 0.15
KeyTypeDefaultDescription
skyboxstring(none)Equirectangular panorama image for the skybox
ambient_sky[f32; 3]renderer defaultHemisphere ambient colour from above (linear)
ambient_ground[f32; 3]renderer defaultHemisphere ambient colour from below (linear)
diffuse_wrapf320Diffuse terminator wrap; 0 = physically sharp, 0.20.5 = soft matte
oren_nayarf320Blend from Lambert toward Oren-Nayar diffuse (0–1); sigma comes from material roughness
sheen_color[f32; 3][1, 1, 1]Charlie-sheen rim tint (linear); only matters with a non-zero strength
sheen_strengthf320Charlie-sheen rim strength; keep at or below about 0.3

[post_process]

Configures the HDR post-processing pipeline. Every key is optional. See Post-Processing for what each effect does and the matching flint render flags.

[post_process]
bloom_enabled = true
bloom_intensity = 0.04
ssao_samples = 16
dof_strength = 0.5
dof_focus_distance = 8.0
film_grain = 0.03
grade_gain = [1.04, 1.0, 0.94]
fxaa = false
KeyTypeDefaultDescription
bloom_enabledbooltrueBloom pass
bloom_intensityf320.04Bloom strength
bloom_thresholdf321.0Brightness above which pixels bloom
vignette_enabledboolfalseEdge darkening
vignette_intensityf320.3Vignette strength
vignette_smoothnessf322.0Vignette falloff curve
exposuref321.0Exposure multiplier before tone mapping
ssao_enabledbooltrueScreen-space ambient occlusion
ssao_radiusf320.5SSAO sample radius (world units)
ssao_intensityf321.0SSAO darkening strength
ssao_samplesu3264Hemisphere samples per pixel, 1–64. The heaviest per-pixel cost in the stack; 16 is ~4x cheaper and usually indistinguishable on matte scenes
fog_enabledboolfalseDistance fog
fog_color[f32; 3][0.7, 0.75, 0.82]Fog colour
fog_densityf320.02Exponential fog density
fog_startf325.0Distance at which fog begins
fog_endf32100.0Distance at which fog saturates
fog_height_enabledboolfalseHeight-based fog
fog_height_fallofff320.1How quickly height fog thins with altitude
fog_height_originf320.0World Y where height fog is densest
dither_enabledboolfalseOrdered dither
dither_intensityf320.03Dither strength
volumetric_enabledboolfalseVolumetric light (god rays)
volumetric_samplesu3232Ray-march steps
volumetric_densityf321.0Scattering density
volumetric_max_distancef32100.0Ray-march cut-off
volumetric_decayf320.98Per-step energy decay
chromatic_aberrationf320Colour-fringe amount at the frame edge
radial_blurf320Zoom-blur amount from the frame centre
desaturatef320Drain toward ash-grey; 0 = full colour, 1 = fully drained
dof_strengthf320Depth-of-field defocus; 0 = sharp
dof_focus_distancef3210.0Focus plane distance in view metres
dof_focus_rangef325.0Half-width of the in-focus band in view metres
kuwahara_enabledboolfalseAnisotropic Kuwahara (painterly) pre-pass
kuwahara_radiusu324Filter radius in pixels
kuwahara_sharpnessf328.0Sector weighting sharpness
kuwahara_hardnessf328.0Sector edge hardness
kuwahara_anisotropyf321.00 = isotropic, 1 = fully anisotropic
film_grainf320Animated grain; 0.020.05 is subtle
grade_lift[f32; 3][0, 0, 0]Per-channel add after ACES tone mapping
grade_gamma[f32; 3][1, 1, 1]Per-channel midtone curve
grade_gain[f32; 3][1, 1, 1]Per-channel multiply
fxaaboolfalseFXAA pass on the final composite. Off by default so headless pixel-diff gates stay single-path

Scenes are loaded by flint-scene and can be edited with flint entity create, flint entity delete, or by hand. At load, each authored component is validated against its schema (warnings only) and any schema field with a default that the entity did not set is filled in (see Scenes). The flint edit --watch viewer reloads automatically when the file changes.

Component Schemas (schemas/components/*.toml)

Define the fields, types, and defaults for each component kind. Components are dynamic — they exist as schema TOML, not compiled Rust types.

[component.<name>]
description = "Human-readable description"

[component.<name>.fields]
field_name = { type = "<type>", default = <value>, description = "..." }

Supported field types: bool, i32, i64, f32, f64, string, vec2, vec3, vec4, color, transform, enum, entity_ref, array. vec2 and vec4 are validated as float arrays. Schema default values are applied at scene load for every listed component that omits the field (see Schemas).

Key component schemas: transform, material, door, bounds, rigidbody, collider, character_controller, audio_source, audio_listener, audio_trigger, animator, skeleton, script, interactable, sprite, asset_def.

Archetype Schemas (schemas/archetypes/*.toml)

Bundle components together with sensible defaults for common entity types.

[archetype.<name>]
description = "..."
components = ["comp1", "comp2"]

[archetype.<name>.defaults.<component>]
field = value

Constraint Files (schemas/constraints/*.toml)

Declarative validation rules checked by flint validate. Each file can contain multiple [[constraint]] entries.

[[constraint]]
name = "rule_name"
description = "What this constraint checks"
query = "entities where archetype == 'door'"
severity = "error"                 # "error" or "warning"
message = "Door '{name}' is missing a transform component"

[constraint.kind]
type = "required_component"        # Constraint type
archetype = "door"
component = "transform"

Constraint kinds: required_component, required_child, value_range, reference_valid, query_rule.

Animation Clips (animations/*.anim.toml)

TOML-defined keyframe animation clips for property tweens. Loaded by scanning the animations directory at startup.

name = "clip_name"
duration = 0.8

[[tracks]]
interpolation = "Linear"           # "Step", "Linear", or "CubicSpline"

[tracks.target]
type = "Rotation"                  # "Position", "Rotation", "Scale", or "CustomFloat"
# component = "material"           # Required for CustomFloat
# field = "emissive_strength"      # Required for CustomFloat

[[tracks.keyframes]]
time = 0.0
value = [0.0, 0.0, 0.0]           # [x, y, z] (euler degrees for rotation)

[[tracks.keyframes]]
time = 0.8
value = [0.0, 90.0, 0.0]
# in_tangent = [...]               # Optional, for CubicSpline
# out_tangent = [...]

[[events]]                         # Optional timed events
time = 0.0
event_name = "door_start"

CubicSpline tracks read in_tangent / out_tangent on each keyframe; the glTF importer fills them from CUBICSPLINE samplers.

Animation Sequences (animations/*.sequence.toml)

An ordered list of timestamped animator events: crossfade the base clip, set a layer, change speed, or raise a named cue for the entity’s script. The player loads every sequence in the scene’s animations/ directory; scripts start one with play_sequence(entity, name), and the model previewer plays one with flint edit model.glb --sequence <file>. See Animation: Sequences.

name = "intro_bow"
loop = false                       # Optional; default false
# duration = 6.0                   # Optional; default = last event time + its transition

[[events]]
time = 0.0
kind = "blend"                     # blend | layer | speed | cue
clip = "walk"
duration = 0.3                     # Crossfade seconds; 0 = hard cut

[[events]]
time = 1.0
kind = "layer"
index = 0                          # Layer slot (0..254)
clip = "wave"                      # Omitted fields keep their current value
weight = 1.0
fade = 0.25                        # Ramp the weight over this many seconds
mode = "additive"                  # additive | override
mask = "spine"                     # Root joint of the affected subtree

[[events]]
time = 2.5
kind = "speed"
value = 0.5

[[events]]
time = 4.0
kind = "cue"
name = "done"                      # Delivered to on_sequence_cue(sequence, cue)
KeyTypeDescription
namestringSequence name, as used by play_sequence
loopboolWrap at duration and fire events again from t = 0
durationf64Explicit length in seconds. A looping sequence whose resolved duration is 0 is a load error
events[].timef64Seconds from the start
events[].kindstringblend (clip, duration), layer (index, clip, weight, fade, mode, mask), speed (value), cue (name)

Asset Sidecars (assets/**/*.asset.toml)

Metadata files stored alongside imported assets in the catalog.

[asset]
name = "asset_name"
type = "mesh"                      # mesh, texture, material, audio, script
hash = "sha256:a1b2c3..."
source_path = "models/chair.glb"
format = "glb"
tags = ["furniture", "medieval"]

[asset.properties]                 # Optional provider-specific metadata
prompt = "wooden tavern chair"
provider = "meshy"

Style Guides (styles/*.style.toml)

Define visual vocabulary for consistent AI asset generation. Searched in styles/ then .flint/styles/.

[style]
name = "medieval_tavern"
description = "Weathered medieval fantasy tavern"
prompt_prefix = "Medieval fantasy tavern style, low-fantasy realism"
prompt_suffix = "Photorealistic textures, warm candlelight tones"
negative_prompt = "modern, sci-fi, neon, plastic"
palette = ["#8B4513", "#A0522D", "#D4A574", "#4A4A4A"]

[style.materials]
roughness_range = [0.6, 0.95]
metallic_range = [0.0, 0.15]
preferred_materials = ["aged oak wood", "rough-hewn stone", "hammered wrought iron"]

[style.geometry]
max_triangles = 5000
require_uvs = true
require_normals = true

Semantic Asset Definitions (schemas/components/asset_def.toml)

The asset_def component schema describes what an entity needs in terms of assets, expressed as intent. Used by the batch resolver to auto-generate missing assets.

[entities.tavern_wall.asset_def]
name = "tavern_wall_texture"
description = "Rough stone wall with mortar lines"
type = "texture"
material_intent = "rough stone"
wear_level = 0.7
size_class = "large"
tags = ["wall", "interior"]

Prefab Templates (prefabs/*.prefab.toml)

Reusable entity group templates with variable substitution. Prefabs define a set of entities that can be instantiated multiple times in a scene with different prefixes and per-instance overrides.

[prefab]
name = "template_name"
description = "Optional description"

[entities.body]

[entities.body.transform]
position = [0, 0, 0]

[entities.body.model]
asset = "model_name"

[entities.child]
parent = "${PREFIX}_body"

[entities.child.transform]
position = [0.5, 0, 0]

All string values containing ${PREFIX} are replaced with the instance prefix. Entity names are prepended with the prefix (e.g., body becomes player_body with prefix "player").

Scenes instantiate prefabs in a [prefabs] section:

[prefabs.player]
template = "template_name"
prefix = "player"

[prefabs.player.overrides.body.transform]
position = [0, 0, 0]

[prefabs.ai1]
template = "template_name"
prefix = "ai1"

[prefabs.ai1.overrides.body.transform]
position = [5, 0, -3]

Overrides are deep-merged at the field level — specifying one field in a component preserves all other fields from the template.

See Scenes: Prefabs for usage details.

Spline Files (splines/*.spline.toml)

Define smooth 3D paths using Catmull-Rom control points. Used for track layouts, camera paths, and procedural geometry generation.

[spline]
name = "Track Name"
closed = true             # true for closed loops, false for open paths

[sampling]
spacing = 2.0             # Distance between sampled points (meters)

[[control_points]]
position = [0, 0, 0]
twist = 0.0               # Banking angle in degrees

[[control_points]]
position = [0, 0, -50]
twist = 0.0

[[control_points]]
position = [50, 0, -100]
twist = 5.0               # Banked turn
FieldTypeDescription
spline.namestringHuman-readable name
spline.closedboolWhether the spline forms a closed loop
sampling.spacingf32Distance between sampled points along the curve
control_points[].position[f32; 3]3D position [x, y, z]
control_points[].twistf32Banking angle in degrees (interpolated with C1 continuity via Catmull-Rom)

The engine samples the control points into a dense array using Catmull-Rom interpolation, stored as the spline_data ECS component. Scripts can query this data via spline_closest_point() and spline_sample_at().

UI Layouts (ui/*.ui.toml)

Data-driven UI element trees. Loaded by scripts via load_ui(). Each layout file references a companion style file.

[ui]
name = "Race HUD"
style = "ui/race_hud.style.toml"

[elements.<id>]
type = "panel"                     # panel, text, rect, circle, image
anchor = "bottom-center"           # Screen anchor (root elements only)
class = "hud-panel"                # Style class from .style.toml
parent = "parent_id"               # Optional parent element
text = "Default text"              # For text elements
src = "logo.png"                   # For image elements
visible = true

Element types: panel (container with background), text (styled text), rect (filled or outlined rectangle), circle (filled circle), image (sprite).

Anchor points: top-left, top-center, top-right, center-left, center, center-right, bottom-left, bottom-center, bottom-right.

See Scripting: Data-Driven UI for the full layout/style/API reference.

UI Styles (ui/*.style.toml)

Named style classes for UI elements. Referenced by .ui.toml layout files.

[styles.<class-name>]
width = 200
height = 60
color = [1.0, 1.0, 1.0, 1.0]     # Primary color (RGBA)
bg_color = [0.0, 0.0, 0.0, 0.6]  # Background color
font_size = 24
text_align = "center"              # left, center, right
rounding = 8
opacity = 1.0
padding = [12, 8, 12, 8]          # [left, top, right, bottom]
layout = "stack"                   # stack (vertical) or horizontal
layer = 0                          # Render depth ordering
width_pct = 100                    # Percentage of parent width
margin_bottom = 4                  # Spacing in flow layout

Style properties support float, color ([r,g,b,a]), string, and boolean values. See Scripting: Style Properties for the complete property table.

Rhai Scripts (scripts/*.rhai)

Game logic scripts written in Rhai. Attached to entities via the script component. See Scripting for the full API reference.

#![allow(unused)]
fn main() {
fn on_init() {
    log("Entity initialized");
}

fn on_update() {
    let dt = delta_time();
    // Called every frame — use delta_time() for frame delta
}

fn on_interact() {
    // Called when the player interacts with this entity
    play_sound("door_open");
}
}

Input Configuration (config/input.toml, ~/.flint/input_{game_id}.toml)

Define action-to-binding mappings for keyboard, mouse, and gamepad input. Loaded with layered precedence: engine defaults → game config → user overrides → CLI override.

version = 1
game_id = "doom_fps"

[actions.move_forward]
kind = "button"
[[actions.move_forward.bindings]]
type = "key"
code = "KeyW"
[[actions.move_forward.bindings]]
type = "gamepad_axis"
axis = "LeftStickY"
direction = "negative"
threshold = 0.35
gamepad = "any"

[actions.fire]
kind = "button"
[[actions.fire.bindings]]
type = "mouse_button"
button = "Left"
[[actions.fire.bindings]]
type = "gamepad_button"
button = "RightTrigger"
gamepad = "any"

[actions.look_x]
kind = "axis1d"
[[actions.look_x.bindings]]
type = "mouse_delta"
axis = "x"
scale = 2.0
[[actions.look_x.bindings]]
type = "gamepad_axis"
axis = "RightStickX"
deadzone = 0.15
scale = 1.0
invert = false
gamepad = "any"

Binding types: key, mouse_button, mouse_delta, mouse_wheel, gamepad_button, gamepad_axis. Action kinds: button (discrete), axis1d (analog). Gamepad selector: "any" or a numeric index. User overrides are written automatically when bindings are remapped at runtime.

Music Session Files

The rhythm system (Music Sessions) has its own family of files. All carry schema_version = 0. The full grammar lives with the flint-music crate; this is the map.

FilePurpose
*.suite.tomlSuite manifest: [suite] id and title, [audio] sample_rate, [[tempo]] anchors (sample, bpm, time_signature), [[sections]] (name, start_sample, pulse_window_ms), [reintegration] (re_entry_sections, lead_bus, reassembly_bars), and one [buses.<name>] per fixed bus (foundation, harmony, world_voice, home_theme, child_motif, texture) with file or silent = true. Optional [[degraded_alternates]]. Checked by flint validate-suite.
*.chart.tomlBeatmap: suite id, [[curves]] (channellean, sway, pressure_l, pressure_r; beat; value; interplinear, hold, smooth), [[pulses]] (beat, kindpulse, press, flick, optional window_ms, strength, direction), [[cues]] (beat, cue, optional params), [[intensity]] (beat, value).
*.events.tomlOffline event script for flint render-suite: [[events]] with at = "bar:N" or "beat:N", bus, actionset_gain (db, ramp_ms), set_lpf (hz, ramp_ms), set_detune (semitones, ramp_ms), marker (label).
*.session.jsonlRecorded input session (flint play-chart --record): one JSON object per line, a header (suite, chart, sample rate, latency and calibration offsets, config snapshots) followed by lean (sample, x, y) and pulse (sample, kind) events stamped in suite samples. Replayed by flint replay-chart --session.
config/coherence.tomlCoherence integrator tuning (--config)
config/ladder.tomlDisintegration ladder: rungs, hysteresis, per-rung audio and visual params, and the [seam] table (lead_in_beats 0–8, default 0) (--ladder)
config/gradient.tomlError-driven audio gradient (--gradient)
config/haptics.tomlRumble entrainment (--haptics)
logs/latency/calibration-*.tomlWritten by flint calibrate; the median tap offset feeds later sessions. flint spike-rumble writes its timing report beside it
logs/sessions/*.session.jsonl, logs/judgment/*.jsonlDefault locations for recorded sessions and replay judgment logs

Configuration (~/.flint/config.toml, .flint/config.toml)

Layered configuration for API keys and generation settings. Global config is merged with project-level config; environment variables override both.

[providers.flux]
api_key = "your-api-key"
enabled = true

[providers.meshy]
api_key = "your-api-key"
enabled = true

[providers.elevenlabs]
api_key = "your-api-key"
enabled = true

[generation]
default_style = "medieval_tavern"

Environment variable overrides: FLINT_FLUX_API_KEY, FLINT_MESHY_API_KEY, FLINT_ELEVENLABS_API_KEY.