diff --git a/docs/home/100-state-machine/325-creating-events/100-events/100-general-interface.md b/docs/home/100-state-machine/325-creating-events/100-events/100-general-interface.md index 3fc55ce6..596a5efe 100644 --- a/docs/home/100-state-machine/325-creating-events/100-events/100-general-interface.md +++ b/docs/home/100-state-machine/325-creating-events/100-events/100-general-interface.md @@ -34,14 +34,14 @@ const QuestCompletionEvent = genEvent({ In order for Paima Engine to be able to use the events, these need to be exported through a module in the packaged files. This can be generated by having an `events` package in the game's directory, where the result of -`generateAppEvents` is exported: +`registerEvents` is exported: ```ts -const eventDefinitions = [ +const eventDefinitions = { QuestCompletionEvent, -] as const; +} as const; -export const events = generateAppEvents(eventDefinitions); +export const events = registerEvents(eventDefinitions); ``` # Listening to events @@ -55,10 +55,11 @@ A few things to note: ```ts import { PaimaEventManager } from '@paima/sdk/events'; +import { events } from '@game/events'; const unsubscribe = await PaimaEventManager.Instance.subscribe( { - topic: QuestCompletionEvent, + topic: events.QuestCompletionEvent, filter: { playerId: undefined }, // all players }, event => { @@ -76,9 +77,9 @@ You can publish messages from your game's state machine at any time. You need to provide *all* fields (both those indexed and those that aren't). This is done by returning the new events as a part of the state transition function's result, alongside the SQL queries that change the state. If all the changes to the -database state are applied correctly for a particular input, then Paima Engine -will take care of only sending these events to the clients that -need them. +database state are applied correctly for that transaction, then Paima Engine +will take care of sending these events *only* to the clients that need them. +Under the hood, the engine uses the following API for this. ```ts import { PaimaEventManager } from '@paima/sdk/events'; @@ -86,7 +87,7 @@ import { PaimaEventManager } from '@paima/sdk/events'; await PaimaEventListener.Instance.sendMessage(QuestCompletionEvent, { questId: 5, playerId: 10 }); ``` -## Typed helpers +## State transition function From Paima Engine's point of view, the type of the `stateTransitionFunction` looks something like this. @@ -135,11 +136,15 @@ return { ``` However, this doesn't leverage the typescript's type system at all, which makes -it error prone. Instead, the recommended approach is to use the typed helpers -provided in the SDK. +it error prone. + +## Typed helpers + +Instead, the recommended approach is to use the typed helpers provided in the +SDK. -The main one is the `EventQueue` type, which can be used to statically guarantee -that the emitted events are part of the exported events. For example: +The first one is the `EventQueue` type, which can be used to statically +guarantee that the emitted events are part of the exported events. For example: ```ts type Events = EventQueue; @@ -156,18 +161,19 @@ async function stateTransitionFunction ( ``` This prevents you from emitting events that are not part of the -`eventDefinitions` array. +`eventDefinitions` object. The second helper is the `encodeEventForStf` function, which can be used to rewrite the previous code like this: ```ts +import { events } from '@game/events'; return { stateTransitions: [], events: [ encodeEventForStf({ from: precompiles.foo, - topic: QuestCompletion, + topic: events.QuestCompletion, data: { questId: 5, playerId: 10, @@ -227,10 +233,10 @@ return { }; ``` -Using `encodeEventForStf` also has the secondary advantage of providing slightly -better error messages and editor support in the case of overloads, since once -the topic argument is fixed, the type of the data can be fully computed instead -of having to compare to the full union of possible values. +Using `encodeEventForStf` also has the secondary advantage of providing better +error messages and editor support, particularly with overloaded events, since +once the topic argument is fixed, the type of the data can be fully computed +instead of having to compare to the full union of possible values. # Signature hash