Proposal: a fuller type system for game programming — economy numbers (decimal/bigint), idle big-numbers, 2D math, containers & ergonomic wrappers #1
Labels
No labels
area:ci
area:docs
area:input
area:net
area:rendering
area:repo
area:stdlib
area:tooling
area:types
cleanup
dx
priority:high
priority:low
priority:medium
proposal
status:in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: workshopsoft/ludic#1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The current type surface is intentionally small (see the API Reference → Types):
int,fixed,bool,entity,str,ptr,byte, the typed bufferswords/fixeds/ptrs,[]Tslices,propertyrecords andenums.This is a revised, researched version of the first pass — informed by Go, C#, and Godot (a 2D engine), plus the number types tycoon and idle/incremental games depend on. Types are grouped by the job they do for a game developer. Each entry lists a precedent, the game use-case, and — because Ludic's anchor is a deterministic fixed-point runtime — an explicit determinism note.
A. Numbers for game economies (the part #1 got wrong)
decimaldecimal0.10; prices, balances, taxes add up exactlybigintBigInteger, Gomath/big.Inthuge(a.k.a.bignum)1e9e15u8i16u16u32i64u64@Sync/serializenetwork payloadsNotes:
decimalandbigintare the correct answer for money and exact large counts — the thing a tycoon game must never round wrong. Prefer them overfixedwhen the domain is currency, not physics.hugetargets idle games specifically: numbers grow past1e308, so games use a two-float (mantissa/exponent) representation. It should be its own type so its non-exact nature is explicit and it never sneaks into the deterministic sim.f32/f64— they break replay/lockstep determinism.B. 2D math & spatial types (from Godot, a 2D engine)
vec2(pair offixed) /ivec2(pair ofint)Vector2/Vector2i+ - * scalar,dot,length,normalized,floor -> ivec2rect/rectiRect2/Rect2icontains(point),intersects(other)transform2d(2×3)Transform2Danglefixedangle withsin/cos/rotate; avoids manual% TAUcolorColorrgb(),rgba(),lerp,darken;Color.*names already exist asintsvec2/ivec2is the single biggest ergonomic win — a 2D game touches vectors constantly, and today they are two loose fields. All of these lower to a couple ofi32s, so no new runtime.C. Containers
map<K,V>/ dictionarymap, C#Dictionaryset<T>[T; N]fixed arraysLANGUAGE.mdgrid<T>(or[T; W*H]sugar)Map.*is a fixed char grid)propertyD. Ergonomic & safety wrappers (make the developer's job easier)
option<T>/ maybe-1sentinelsresult<T, E>load, parse, net) without out-params or silent failureenum(payloads)matchon it — todayenumis only int constantshandle/ typed identityintduration/tickpercent/normalized[0,1]fixedfor health %, volume, lerptrune/charrunename/ interned stringStringNameSuggested phasing
vec2/ivec2+rect+color— daily 2D ergonomics, biggest win.decimal+bigint— economy/idle correctness (the money problem).option/result+ tagged-unionenums — safety and clean control flow.map/set+[T; N]— containers.huge(idle display), sized ints,angle/percent/handle/duration/rune/name— polish.All numeric/vector proposals lower to existing IR types (
i32pairs,i8/i16/i64, or a small struct), so most of this is front-end sugar + type checking, not new runtime.References
decimal,BigInteger,System.Numerics(Vector2, Complex, Half)rune,byte,complex,map,slice,channel) andmath/bigRect2,Vector2/Vector2i,Color,Transform2DRevised after researching Go, C#, and Godot; supersedes the initial sketch.
Proposal: richer built-in types for game programming (vectors, color, sized ints, fixed arrays)to Proposal: a fuller type system for game programming — economy numbers (decimal/bigint), idle big-numbers, 2D math, containers & ergonomic wrappersPhase 1 shipped —
IVec2+Rect(2c9f9ac)Landing the first phase of this proposal and decomposing the rest into tracked issues so the roadmap survives.
What shipped (phase 1 — the "biggest ergonomic win")
Phase 1 was vec2 / ivec2 + rect + color. Two of the four already existed, so this pass adds the two that were missing:
IVec2— an integer 2D vector, a pair ofintpacked into onei64(mirrors the existingVector, but whole-number). For tile/grid coordinates, cell offsets and integer sizes, where a fractional part would be a bug. Ops:make/zero/x/y/add/sub/scale/dot, the grid distancemanhattan,equal, andto_vector(widen into the fixed-pointVector).Rect— an axis-aligned rectangle, four Q16.16fixedcomponents packed into onei128. For HUD boxes, hitboxes and viewport regions. Ops:make/x/y/w/h, the derivedright/bottom/center, and thecontains(point) /intersects(overlap) tests.Both are true by-value types — they copy like scalars and never allocate — and every operation is exact and deterministic, bit-identical on every platform, exactly as the determinism policy requires.
Already present, so left as-is:
vec2is the existingVector(pair offixed), andcoloris the existing first-classColor(constants +Color.*withrgb/rgba/lerp/darken). Phase 1 is therefore complete.Wired end to end:
emit_corellty(IVec2→i64,Rect→i128),emit_calldispatch, the FRAGS list + reseeded C-free seed, a self-host test (types2d), per-symbol docs + type pages + inventory, and full vocabulary/editor sync (header, JetBrains, TextMate, LSP). All suites green:x test81/81,x test-tools30/30,x selfhost-test30/30 (incl. golden renders byte-identical and the bootstrap fixpoint), plusx check-impl/x check-vocabulary/x check-docs.Remaining phases — now tracked as their own issues
This proposal is an umbrella RFC spanning ~30 types; the rest is best tracked as focused issues rather than one giant ticket:
decimal+bigint)option/result+ tagged-unionenums)map/set+[T; N])huge, sized ints,angle/percent/handle/duration/rune/name)Closing this proposal as accepted and phase-1-delivered; follow the sub-issues above for the rest.