Best Practices¶
Recommended practices for building with Trecs.
Systems¶
- Declare system dependencies explicitly. Use
[ExecuteAfter]/[ExecuteBefore]instead of relying on registration order. - Pick the right phase.
Fixedfor simulation,Inputfor queueing inputs,EarlyPresentation/Presentation/LatePresentationfor rendering and transform sync. The phase determines which Accessor Role you get and what you're allowed to do in it. - Keep fixed-update objects stateless. Includes systems and service classes used by fixed-update systems. Constructor parameters with immutable configuration are fine. Mutable state belongs in components or heap pointers, where it's serialized, deterministic, and visible to tooling. Otherwise state diverges between record and replay. Variable-update systems don't have this constraint (desyncs aren't possible there), though it's still convenient to use components to co-locate data with entities.
Components¶
- Data only, no logic. Components are unmanaged structs with fields. Put logic in systems.
- Keep components small and focused. Prefer
Health { Current, Max }over a 20-fieldCharacterStats. Many components often hold just a single field — use[Unwrap]with Aspects to skip the outer struct. - Unmanaged only. No classes, strings, arrays, or reference types. Use heap pointers for managed/dynamically-sized data and
FixedList<N>for inline lists.
Entities & Templates¶
- Templates describe design concepts.
Bullet,Player,Enemy— notEntityWithHealthAndPosition.
General¶
- Prefer
World.Rng, notUnityEngine.Random. External RNG breaks replay.FixedRngandVariableRngare independent streams. - Prefer
World.DeltaTime/World.ElapsedTime, notUnityEngine.Time.deltaTime,UnityEngine.Time.timeorDateTime/Stopwatch
See also¶
- Gotchas — common mistakes, edge cases, and surprises with the symptom / cause / fix for each.