Publishers
Publishers describe a service that receives and processes events generated server-side by various Hiro systems, such as achievements, economy, teams, and more. They act as listeners that respond to events, enabling you to implement workflows like custom analytics tracking, custom rewards, or integrating with external services.
Use cases #
Publishers can be used to extend the capabilities of existing Hiro systems with custom workflows that go beyond the standard mechanisms.
Extending existing Hiro systems #
The Rewards system grants players currencies, energies, and items. Publishers handle scenarios it doesn’t cover, like updating player stats when events occur.
This Publisher grants experience points when a player claims an achievement:
| |
Register the publisher after initializing your Hiro systems:
| |
Analytics and LiveOps #
Publishers can be used for sending gameplay events to analytics platforms. Hiro’s built-in SatoriPersonalizer handles this for Satori, publishing events like achievement claims, purchases, and energy usage that Satori uses for player segmentation and targeting. You can register additional Publishers to send events to your own analytics backend or third-party services alongside SatoriPersonalizer.
Built-in publishers #
SatoriPersonalizer #
SatoriPersonalizer is Hiro’s built-in Publisher implementation. It implements both the Publisher and Personalizer interfaces, creating a bidirectional adapter between Hiro and Satori:
| Role | Direction | Purpose |
|---|---|---|
| Publisher | Writes to Satori | Sends analytics events |
| Personalizer | Reads from Satori | Fetches remote config and live event data to customize gameplay configs |
This two-way flow is key to Satori’s LiveOps capabilities. As a Publisher, it sends player events (achievements claimed, purchases made, etc.) to Satori. Satori can then use this behavioral data to segment players and deliver targeted configuration back through feature flags, which SatoriPersonalizer reads as a Personalizer.
When you initialize SatoriPersonalizer, you must specify which events you want to publish by passing them in. For example, to publish authenticate, achievements, economy, and energy events:
| |
To publish all events, pass in hiro.SatoriPersonalizerPublishAllEvents(). This uses the “no session” option for authentication by default. If you don’t want to publish any events (that is, to use SatoriPersonalizer solely for its Personalizer functionality), pass in ctx alone.
SatoriPersonalizer to AddPersonalizer() to instruct Hiro to automatically register it as both a Personalizer and Publisher. Use AddPublisher() to register your own custom publisher implementations. You can register multiple publishers; events are sent to all of them.Authentication options #
There are two options for publishing authentication events to Satori:
| Option | Parameter | Behavior |
|---|---|---|
| no session | SatoriPersonalizerPublishAuthenticateEvents() | Authenticates without creating a server-side session (recommended) |
| with session | SatoriPersonalizerPublishAuthenticateEventsWithSession() | Creates a new random session ID for each authentication |
These options authenticate the player to Satori immediately after Nakama authentication, creating them in Satori if they don’t already exist. This is essential if you want to fetch feature flags for new players — without one of these options, SatoriPersonalizer cannot retrieve flags for players who haven’t been created in Satori yet.
If your game client also authenticates with Satori directly, use SatoriPersonalizerPublishAuthenticateEvents(). Using SatoriPersonalizerPublishAuthenticateEventsWithSession() will generate two _sessionStart events (one from the client, one from Nakama) with two different session IDs.
With the “no session” option, Nakama authenticates with Satori without creating a new session ID; instead, all server-side events are automatically associated with the client’s session when they reach Satori.
Read more about Sessions.
Publisher interface #
The Publisher interface defines two methods that must be implemented:
| |
PublisherEvent structure #
The PublisherEvent structure contains information about an event:
| |
