Skip to content

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.

Each entry has:

FieldWhat it does
keyDotted lowercase key like player.moveSpeed. Validated as ^[a-z][a-zA-Z0-9_.]*$.
typeOne of int, float, bool, string, color, vec2, vec3, curve.
defaultThe value. Type depends on type.
rangeOptional { min, max } for numeric types. Drives slider bounds in any designer UI you build.
hintOptional helper text. Shows in the editor row and can surface in your game’s debug overlay.
typeDefault shapeExample
intnumber (integer)100
floatnumber220.0
boolbooleantrue
stringstring"Smith"
colorhex string"#d77757"
vec2[x, y][100, 200]
vec3[x, y, z][0, 5, -10]
curvearray 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.

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:

KeyDefaultWhat it does
player.moveSpeed220Walk velocity in px/s
player.runSpeed320Sprint velocity
player.jumpVelocity480Initial upward velocity
player.maxFallSpeed720Terminal fall velocity
player.coyoteMs100Window after leaving a platform where a jump still counts
player.jumpBufferMs120Window before landing where a queued jump auto-fires
player.variableJumpReleaseFactor0.5Multiplier 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.

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.

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.