Components from Luau: AddComponent, GetComponent, GetComponents, Destroy (#75) #83

Closed
opened 2026-09-06 01:25:28 +00:00 by crowmaki · 0 comments
Owner

Parent

#75

What to build

Scripts compose GameObjects at runtime. go:AddComponent(Mover) attaches a Component, runs Awake, and returns the instance. go:GetComponent(Mover) and self:GetComponent(Mover) return the first Component of that class on the GameObject or nil; go:GetComponents(Mover) returns every one. Both accept a class table or a Schema name string, so go:GetComponent("cinnabar.rigidbody") finds an Odin-registered Component. A Component that is not Script-defined comes back as a generic userdata with gameObject, IsAlive, Destroy and no field access. Destroy(component) and component:Destroy() queue removal for the next Structural Flush.

A GameObject or Component created inside Update receives its first Update on the next frame: it lies beyond the count captured at the start of that class's walk.

Acceptance criteria

  • go:AddComponent(Mover) returns an instance whose Awake has already run, and Odin sees the Component via gameobject_component_count
  • GetComponent returns the first instance of the class or nil; GetComponents returns all of them in on-object order
  • GetComponent by Schema name string finds an Odin-registered Component and returns a generic userdata; reading a field on it raises an error
  • Destroy(component) and component:Destroy() leave the Component alive until the next Structural Flush; component_is_alive is false after it
  • go:Destroy() from inside Update completes: every instance alive at the start of the frame still updates that frame, and the destroyed set is gone after the flush
  • A Component added from inside Update receives no Update that frame and its first Start and Update the next
  • Two GetComponent calls for the same Component in one frame compare equal with ==

Blocked by

## Parent #75 ## What to build Scripts compose GameObjects at runtime. `go:AddComponent(Mover)` attaches a Component, runs `Awake`, and returns the instance. `go:GetComponent(Mover)` and `self:GetComponent(Mover)` return the first Component of that class on the GameObject or `nil`; `go:GetComponents(Mover)` returns every one. Both accept a class table or a Schema name string, so `go:GetComponent("cinnabar.rigidbody")` finds an Odin-registered Component. A Component that is not Script-defined comes back as a generic userdata with `gameObject`, `IsAlive`, `Destroy` and no field access. `Destroy(component)` and `component:Destroy()` queue removal for the next Structural Flush. A GameObject or Component created inside `Update` receives its first `Update` on the next frame: it lies beyond the count captured at the start of that class's walk. ## Acceptance criteria - [ ] `go:AddComponent(Mover)` returns an instance whose `Awake` has already run, and Odin sees the Component via `gameobject_component_count` - [ ] `GetComponent` returns the first instance of the class or `nil`; `GetComponents` returns all of them in on-object order - [ ] `GetComponent` by Schema name string finds an Odin-registered Component and returns a generic userdata; reading a field on it raises an error - [ ] `Destroy(component)` and `component:Destroy()` leave the Component alive until the next Structural Flush; `component_is_alive` is false after it - [ ] `go:Destroy()` from inside `Update` completes: every instance alive at the start of the frame still updates that frame, and the destroyed set is gone after the flush - [ ] A Component added from inside `Update` receives no `Update` that frame and its first `Start` and `Update` the next - [ ] Two `GetComponent` calls for the same Component in one frame compare equal with `==` ## Blocked by - #81 - #82
Sign in to join this conversation.
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#83
No description provided.