Appearance
Appearance
DANGER
This document is a stub.
The Game Backend is a distributed actor system where the game logic is implemented using Entities. The Entity lifecycles come in two flavors, as Ephemeral and Persisted entities.
Create ---> ( Starting ) --> ( Running ) --> ( Stopping ) ---> removed from system
An Ephemeral Entity is an Entity that lives only as long as it is running. Its state will be forgotten and EntityId will become unused when the entity instance stops. This is often used for service entities that do not need to store state over server node reboots and for helper entities that only live for a moment. For example, InAppPurchaseValidatorActor
is an ephemeral entity. If this entity is lost, the ongoing validation operations will be lost, but only temporarily as the validation will be retried.
.------- crash recovery ----------.
| v
Create --> ( Starting ) --> ( Running ) --> ( Stopping ) --> ( Persisted )
^ |
'-------- Wake up on demand -----------------------'
A persisted entity is an entity whose state is stored into a persisted storage when it is not running. When it is created for the first time, it is given an immutable EntityId, and from this point onward the EntityId will always refer to this particular entity. The next time the entity is needed and the state of the entity is restored from the database. Hence, persisted entities are eternal.
Entities communicate by sending messages to each other. When sending a message, the sender specifies a destination entity id and a payload. The system will deliver the message to the destination entity if such exists, waking it up if necessary. Communication is fundamentally unreliable. If the destination entity does not exist or an error occurs, the message is dropped and no retries are attempted. If the sender needs to know whether the message was processed, the recipient must send an acknowledgment message back to the sender. This pattern is available thru EntityAsk<>
method.
In addition to raw messaging and EntityAsk<>
, Metaplay provides a PubSub system in which an entity may Subscribe to a topic of another Entity. When the subscribed entity publishes a message to a given topic, the message is delivered to the entities subscribing to that topic on that entity.
All participants in a PubSub must be in a Running state. When an entity shuts down or crashes, all subscribers and subscribees are notified and the shutdown entity is unsubscribed. However, the communication is fundamentally unreliable and no timely lifecycle notifications can be guaranteed. Only the order of the messages and the delivery of preceding messages in a single PubSub topic is guaranteed; for anything more sophisticated, an EntityAsk<>
-like acknowledgment mechanism needs to be used.
For more details, see Deep Dive: Entity-to-Entity Communication.
As entities use memory, CPU, and potentially other resources when running, it is important to shut down entities as they are no longer needed. As such, the developer must choose a suitable EntityActor.ShutdownPolicy
for each entity type in the game.
The most straightforward ShutdownPolicy
is AutoShutdownPolicy::ShutdownNever
. As its name implies, the entity will not be automatically shut down. In this mode, the developer must manually call RequestShutdown()
where appropriate. This is most commonly used for long-lived service entities.
For automatic shutdown, the developer may use AutoShutdownPolicy::ShutdownAfterSubscribersGone
. In this mode, the entity lives only as long there has been recently a PubSub subscriber to the entity. After the last subscriber is lost and the specified time has passed with no new subscribers appearing, the entity will be shut down. This is the most commonly used for persisted entities.