Per-frame lifecycle: Update, FixedUpdate, Start, OnDestroy and Time (#81) #93

Merged
crowmaki merged 6 commits from issue-81-script-lifecycle into main 2026-09-06 03:29:47 +00:00
Owner

Closes #81. Part of #75.

What

A Script Component's Update(dt), FixedUpdate(dt), Start() and OnDestroy() run from the Plugin's Hooks and the Schema's Component Hooks.

  • update and fixed_update walk each Script class in Schema registration order and, within a class, walk component_storage by index, re-fetching storage every iteration. Instances on a GameObject that is not Active in Hierarchy, and instances already queued for removal, are skipped.
  • Start runs once per instance, immediately before its first frame method, behind a Transient Bool field the Plugin appends to every Script Schema. Its name is @started, which no Luau identifier can spell, so it never collides with a Script's own fields and never reaches a Scene Document.
  • OnDestroy runs from on_remove, so it runs exactly once whether the Component was removed directly, its owner destroyed, or its Scene unloaded.
  • A read-only Time global carries deltaTime, fixedDeltaTime and frameCount, refreshed at the top of each Hook from Frame Timing. Inside FixedUpdate, deltaTime is the fixed step, the Unity way.
  • Every method call goes through one pcall with a traceback handler. An error in one instance is logged and the rest of the frame continues.
  • Core: Component_Field_Desc gains flags, so a description can mark a field Transient. The struct stays 16 bytes.

One reading to confirm: Start runs before whichever of FixedUpdate or Update first reaches the instance in a Tick, which is Unity's ordering. The issue text names only Update.

Tests

tests/luau/lifecycle_test.odin covers every acceptance criterion from Luau source strings. tests/core/component_schema_test.odin covers the Transient flag on a description field.

The luau harness had a bug: capture_logger replaced the runner's logger, so no luau test could fail. It now forwards lines logged from _test.odin files to the runner. Every prior test still passes.

just check and just test pass (430 tests).

Closes #81. Part of #75. ## What A Script Component's `Update(dt)`, `FixedUpdate(dt)`, `Start()` and `OnDestroy()` run from the Plugin's Hooks and the Schema's Component Hooks. - `update` and `fixed_update` walk each Script class in Schema registration order and, within a class, walk `component_storage` by index, re-fetching storage every iteration. Instances on a GameObject that is not Active in Hierarchy, and instances already queued for removal, are skipped. - `Start` runs once per instance, immediately before its first frame method, behind a Transient `Bool` field the Plugin appends to every Script Schema. Its name is `@started`, which no Luau identifier can spell, so it never collides with a Script's own fields and never reaches a Scene Document. - `OnDestroy` runs from `on_remove`, so it runs exactly once whether the Component was removed directly, its owner destroyed, or its Scene unloaded. - A read-only `Time` global carries `deltaTime`, `fixedDeltaTime` and `frameCount`, refreshed at the top of each Hook from Frame Timing. Inside `FixedUpdate`, `deltaTime` is the fixed step, the Unity way. - Every method call goes through one `pcall` with a traceback handler. An error in one instance is logged and the rest of the frame continues. - Core: `Component_Field_Desc` gains `flags`, so a description can mark a field Transient. The struct stays 16 bytes. One reading to confirm: `Start` runs before whichever of `FixedUpdate` or `Update` first reaches the instance in a Tick, which is Unity's ordering. The issue text names only `Update`. ## Tests `tests/luau/lifecycle_test.odin` covers every acceptance criterion from Luau source strings. `tests/core/component_schema_test.odin` covers the Transient flag on a description field. The luau harness had a bug: `capture_logger` replaced the runner's logger, so no luau test could fail. It now forwards lines logged from `_test.odin` files to the runner. Every prior test still passes. `just check` and `just test` pass (430 tests).
crowmaki deleted branch issue-81-script-lifecycle 2026-09-06 03:29:47 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crowmaki/cinnabar!93
No description provided.