ProjectConfig
The ProjectConfig system is the table of typed constants every other system reads from. Player walk speed, jump height, day-cycle length, typewriter speed: anything a designer might want to tune without opening source code.
Open it from Inspector → Systems → ProjectConfig → Open. The editor renders a table you can add rows to, edit values in place, and save back to the descriptor.
Schema
Section titled “Schema”Each entry has:
| Field | What it does |
|---|---|
key | Dotted lowercase key like player.moveSpeed. Validated as ^[a-z][a-zA-Z0-9_.]*$. |
type | One of int, float, bool, string, color, vec2, vec3, curve. |
default | The value. Type depends on type. |
range | Optional { min, max } for numeric types. Drives slider bounds in any designer UI you build. |
hint | Optional helper text. Shows in the editor row and can surface in your game’s debug overlay. |
Type cheatsheet
Section titled “Type cheatsheet”type | Default shape | Example |
|---|---|---|
int | number (integer) | 100 |
float | number | 220.0 |
bool | boolean | true |
string | string | "Smith" |
color | hex string | "#d77757" |
vec2 | [x, y] | [100, 200] |
vec3 | [x, y, z] | [0, 5, -10] |
curve | array of [t, value] pairs | [[0, 0], [0.5, 0.8], [1, 1]] |
Range hints make sense for numeric types only and are ignored for the others. A curve is parameterised on t in [0, 1] and is typically used for damage falloff, ease curves, day-length brightness.
Hot-tuning workflow
Section titled “Hot-tuning workflow”Bundles ship most player feel constants through ProjectConfig so the values are visible in one place and tweakable from the editor. The Platformer bundle’s defaults:
| Key | Default | What it does |
|---|---|---|
player.moveSpeed | 220 | Walk velocity in px/s |
player.runSpeed | 320 | Sprint velocity |
player.jumpVelocity | 480 | Initial upward velocity |
player.maxFallSpeed | 720 | Terminal fall velocity |
player.coyoteMs | 100 | Window after leaving a platform where a jump still counts |
player.jumpBufferMs | 120 | Window before landing where a queued jump auto-fires |
player.variableJumpReleaseFactor | 0.5 | Multiplier when jump is released mid-rise |
Save in the editor and the dev server hot-reloads. You can tune until it feels right without ever touching the level scene’s source.
For systems that need polish constants specific to character feel (coyote time, jump buffer, air control), CharacterController owns those directly with the same hot-reload behavior. Use ProjectConfig for game-level constants that multiple systems read.
Why one table
Section titled “Why one table”Two reasons:
- Discoverability. Designers know where to look. New collaborators can scan one file and learn the levers of the game.
- Round-trip with editors. The ProjectConfig editor knows the type system, validates inputs, and previews defaults. Custom UI built on top can read the same descriptor without re-defining the schema.
If a value doesn’t need designer tuning (a CSS class name, a font family) keep it inline in source. ProjectConfig is for things you’d want to twiddle live.
Editing the config by hand
Section titled “Editing the config by hand”The descriptor entry looks like:
[systems.ProjectConfig.config]entries = [ { key = "player.moveSpeed", type = "float", default = 220.0, range = { min = 0, max = 800 }, hint = "Walk velocity in px/s" }, { key = "player.coyoteMs", type = "int", default = 100, range = { min = 0, max = 500 }, hint = "Grace window after walking off a ledge" }, { key = "world.dayLengthMs", type = "int", default = 90000, range = { min = 10000, max = 600000 }, hint = "Full day/night cycle in ms" },]Validation: keys are unique, names match the dotted-lowercase pattern, defaults match their declared type.