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()
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:
- retrieve data
- change fields using standard setters
- 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(...)
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:
- RPC & Server-side Game Logic — handler pipeline and abort semantics used by entity extension methods
- Query Language & Data Retrieval — selection construction using
Where/WithbeforeUpdate/Delete