# tecs.events
Typed events and address-based message buses.
Define a record, initialize it in place, and register it once:
```teal
local record Damaged is tecs.events.Event
amount: number
metamethod __call: function(self, amount: number): Damaged
end
Damaged.init = function(event: Damaged, amount: number)
event.amount = amount
end
tecs.events.newEvent(Damaged)
```
Worlds use the same event definitions and address routing as a standalone
[`MessageBus`](/modules/events/#tecs.events.MessageBus). Address `0` conventionally
names a whole world, while entity IDs address individual entities.
Event delivery is synchronous. The emitter owns an event instance during
dispatch, so observers treat its fields as read-only and copy values they need
to retain. A table event constructed directly, such as `Damaged(10)`, is an
independent value the caller may keep.
## Module contents
### Constructors
| Constructor | Description |
| --- | --- |
| [`newEvent`](/modules/events/#tecs.events.newEvent) | Configures a table event with a callable constructor. |
| [`newFFIEvent`](/modules/events/#tecs.events.newFFIEvent) | Configures an FFI event with a callable constructor. |
| [`newMessageBus`](/modules/events/#tecs.events.newMessageBus) | Creates an independent address-based event message bus. |
### Types
| Type | Kind | Description |
| --- | --- | --- |
| [`Event`](/modules/events/#tecs.events.Event) | interface | Event names a registered event definition or one of its instances. |
| [`EventInit`](/modules/events/#tecs.events.EventInit) | type | EventInit initializes an event instance from constructor arguments. |
| [`EventListener`](/modules/events/#tecs.events.EventListener) | type | EventListener synchronously receives an event of its declared type. |
| [`MessageBus`](/modules/events/#tecs.events.MessageBus) | interface | MessageBus routes typed events by integer address. |
## Constructors
### tecs.events.newEvent Static
Configures a table event with a callable constructor.
Registration mutates the supplied definition by assigning its event ID
and constructor metatable. Register each definition once.
```teal
function tecs.events.newEvent(event: E)
```
#### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `event` | `E` | The caller supplies the event record to configure in place. |
#### Returns
None.
### tecs.events.newFFIEvent Static
Configures an FFI event with a callable constructor.
Registration mutates the supplied definition. Field names must be
unique C identifiers. `eventId` and `typeId` are reserved. Use
`double` for entity IDs so their packed slot and generation remain
exact.
```teal
function tecs.events.newFFIEvent(
event: E, fields: {{string, string}}, structName: string
)
```
#### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `event` | `E` | The caller supplies the event record to configure in place. |
| `fields` | `{{string, string}}` | The caller supplies each field name and C type in constructor order. |
| `structName` | `string` | The caller supplies a shared C struct name or omits it to generate one. |
#### Returns
None.
### tecs.events.newMessageBus Static
Creates an independent address-based event message bus.
```teal
function tecs.events.newMessageBus(): MessageBus
```
#### Arguments
None.
#### Returns
| Type | Description |
| --- | --- |
| [`MessageBus`](/modules/events/#tecs.events.MessageBus) | Returns an empty message bus with no observers. |
## Types
### tecs.events.Event interface
`Event` names a registered event definition or one of its instances.
```teal
interface tecs.events.Event
eventId: integer
end
```
#### tecs.events.Event.eventId field
Read-only. The unique ID of the event.
```teal
tecs.events.Event.eventId: integer
```
### tecs.events.EventInit type
`EventInit` initializes an event instance from constructor arguments.
```teal
type tecs.events.EventInit = function(E, ...: any)
```
### tecs.events.EventListener type
`EventListener` synchronously receives an event of its declared type.
```teal
type tecs.events.EventListener = function(E)
```
### tecs.events.MessageBus interface
`MessageBus` routes typed events by integer address.
```teal
interface tecs.events.MessageBus
emit: function(MessageBus, integer, E)
hasObservers: function(MessageBus, integer, E): boolean
observeOnce: function(
MessageBus, integer, E, function(E)
)
stopObserving: function(
MessageBus, integer, E, function(E) | string
)
clearAddress: function(self, integer)
clearEntityObservers: function(self)
observe: function(
self,
address: integer,
eventType: E,
observer: function(E),
id: string
)
reset: function(self)
end
```
#### tecs.events.MessageBus.emit Static
Emit an event to all observers at the specified address.
```teal
function tecs.events.MessageBus.emit(MessageBus, integer, E)
```
##### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `#1` | [`MessageBus`](/modules/events/#tecs.events.MessageBus) | |
| `#2` | `integer` | |
| `#3` | `E` | |
##### Returns
None.
#### tecs.events.MessageBus.hasObservers Static
Check if any observers exist for an event type at an address.
```teal
function tecs.events.MessageBus.hasObservers(
MessageBus, integer, E
): boolean
```
##### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `#1` | [`MessageBus`](/modules/events/#tecs.events.MessageBus) | |
| `#2` | `integer` | |
| `#3` | `E` | |
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | |
#### tecs.events.MessageBus.observeOnce Static
Observe an event type at a specific address, at most once.
```teal
function tecs.events.MessageBus.observeOnce(
MessageBus, integer, E, function(E)
)
```
##### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `#1` | [`MessageBus`](/modules/events/#tecs.events.MessageBus) | |
| `#2` | `integer` | |
| `#3` | `E` | |
| `#4` | `function(E)` | |
##### Returns
None.
#### tecs.events.MessageBus.stopObserving Static
Stop observing an event type at a specific address.
```teal
function tecs.events.MessageBus.stopObserving(
MessageBus, integer, E, function(E) | string
)
```
##### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `#1` | [`MessageBus`](/modules/events/#tecs.events.MessageBus) | |
| `#2` | `integer` | |
| `#3` | `E` | |
| `#4` | function(E) | string | |
##### Returns
None.
#### tecs.events.MessageBus:clearAddress Instance
Clear all observers for an address (used on entity despawn).
```teal
function tecs.events.MessageBus.clearAddress(self, integer)
```
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `MessageBus` | |
| `#2` | `integer` | |
##### Returns
None.
#### tecs.events.MessageBus:clearEntityObservers Instance
Clear per-entity observers (every address except the global
address 0), preserving global subscriptions. Used by
world:clearEntities so query infrastructure stays subscribed.
```teal
function tecs.events.MessageBus.clearEntityObservers(self)
```
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `MessageBus` | |
##### Returns
None.
#### tecs.events.MessageBus:observe Instance
Observe an event type at a specific address.
Address 0 is for world-level events, entity IDs for entity events.
```teal
function tecs.events.MessageBus.observe(
self,
address: integer,
eventType: E,
observer: function(E),
id: string
)
```
##### Type Parameters
| Name | Constraint | Description |
| --- | --- | --- |
| `E` | [`Event`](/modules/events/#tecs.events.Event) | |
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | [`MessageBus`](/modules/events/#tecs.events.MessageBus) | The message bus that owns the subscription. |
| `address` | `integer` | Use 0 for world-level events or an entity ID for entity events. |
| `eventType` | `E` | The registered event type to observe. |
| `observer` | `function(E)` | Called synchronously with each matching event. |
| `id` | `string` | An optional stable name accepted by `stopObserving`. |
##### Returns
None.
#### tecs.events.MessageBus:reset Instance
Reset the entire message bus.
```teal
function tecs.events.MessageBus.reset(self)
```
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `MessageBus` | |
##### Returns
None.