Skip to main content

Data Mutation & Model Extending

This page covers two related topics: mutating game data through Update() and Delete(), and extending models with domain behaviour as named RPC methods.


Data mutation

When to use

Use mutation when you need to persist changes to game data as state:

  • updating fields on objects returned by a query and saving them with Update()
  • applying a single inline update operation with Update(handler)
  • removing objects included in a selection with Delete()
info

This is the standard path when the outcome must be a stored state change that can later be retrieved and, where applicable, observed through the data layer.

Baseline rule

PlayServ does not require special techniques to modify data. The flow is:

  1. retrieve data
  2. change fields using standard setters
  3. call Update()

Update a selection

Select a set of objects, modify them, then persist the changes.

var women = PlayServ.Model<Player>()
.Where(player => player.Age > 18)
.Where(player => player.Gender == "Woman");

// update data
women.Map(girl => {
girl.Age = 18;
});
women[0].Age = 21;

// persist changes
women.Update();

Update with a handler

You can also update using a single Update(...) call with an inline handler.

women.Update(girl => {
girl.Age = 18;
});

Delete

To delete all objects included in the selection:

women.Delete();

Model extending

When to use

Use model extending when you need to attach domain behaviour to a model type and execute it as an RPC method:

  • defining behaviour as an extension method on a model via the RPC handler API
  • invoking that behaviour from client code on a retrieved entity — for example, player.Shoot(...)
info

Model extending allows gameplay operations to be expressed as an explicit action — a method — executed through the RPC handler pipeline, including abort behaviour.

How it works

A model can be extended with custom RPC methods tied to an entity type — for example, NPC spawns, player shoots, chest opens. When these RPC methods execute, the model data acts as their context.

This path is appropriate when the operation represents a named action associated with an entity type, rather than a direct field update.

Server: define an extension method

PlayServ.Server.Model<Player>()
.DoShoot(vector => {
return false; // abort pipeline
});

Client: call the extension method

var player = await PlayServ.GetPlayer(playerId);
player.Shoot(vector3d);

Next step

Continue with Query Language & Data Retrieval to understand how selections are constructed before mutation.

For related topics: