数据修改与 Model 扩展
最后更新:2026 年 7 月 16 日
本页讲两件相关的事:通过 Update() 和 Delete() 修改游戏数据,以及把领域行为作为具名的 RPC 方法扩展到 Model 上。
数据修改
何时使用
当你需要把游戏数据的改动作为状态持久化下来时,就使用数据修改:
- 修改查询返回的对象上的字段,再用
Update()保存 - 用
Update(handler)就地应用一次更新操作 - 用
Delete()删除选择集中包含的对象
信息
如果结果必须是一次可被存储、之后能取回、并在适用时可通过数据层观察到的状态变更,那么这就是标准做法。
基本规则
PlayServ 不需要任何特殊手法来修改数据。流程就是:
- 取回数据
- 用普通的 setter 修改字段
- 调用
Update()
备注
一次写入是否被允许,取决于调用方和这张 Table。默认情况下游戏客户端不能写;在归属于某个 Player 的 Table 上,客户端只能写自己的行。如果 Update() 或 Delete() 被拒绝,请看 Access Control。
更新一个选择集
选出一组对象,修改它们,然后持久化这些改动。
var players = PlayServ.Model<Player>()
.Where(player => player.Level >= 10);
// modify every selected object
players.Map(p => {
p.Coins += 100;
});
// modify a single object in the selection
players[0].Coins += 500;
// persist changes
players.Update();
用 Handler 更新
你也可以只用一次 Update(...) 调用配上就地写的 Handler 来更新。
players.Update(p => {
p.Coins += 100;
});
Delete
要删除选择集中包含的所有对象:
players.Delete();
Model 扩展
何时使用
当你需要把领域行为挂到某个 Model 类型上、并作为 RPC 方法来执行时,就使用 Model 扩展:
- 通过 RPC Handler API,把行为定义成 Model 上的扩展方法
- 在客户端代码中对已取回的 Entity 调用这个行为 —— 例如
player.Shoot(...)
信息
Model 扩展让 gameplay 操作能够表达为一个明确的动作 —— 一个方法 —— 并通过 RPC Handler 的 Pipeline 执行,其中也包括中止行为。
工作方式
Model 可以扩展出与某个 Entity 类型绑定的自定义 RPC 方法 —— 比如 NPC 生成、Player 开枪、宝箱打开。这些 RPC 方法执行时,Model 的数据就是它们的上下文。
当某个操作代表的是与 Entity 类型相关联的具名动作,而不是直接改一个字段时,走这条路才合适。
服务端:定义扩展方法
PlayServ.Server.Model<Player>()
.DoShoot(vector => {
return false; // abort pipeline
});
客户端:调用扩展方法
var player = await PlayServ.GetPlayer(playerId);
player.Shoot(vector3d);
下一步
- Query Language & Data Retrieval —— 在
Update/Delete之前,用Key/Where/With构造选择集 - RPC & Server-side Game Logic —— Entity 扩展方法所用的 Handler Pipeline 与中止语义