跳到主要内容

数据修改与 Model 扩展

最后更新:2026 年 7 月 16 日

本页讲两件相关的事:通过 Update() 和 Delete() 修改游戏数据,以及把领域行为作为具名的 RPC 方法扩展到 Model 上。


数据修改​

何时使用​

当你需要把游戏数据的改动作为状态持久化下来时,就使用数据修改:

  • 修改查询返回的对象上的字段,再用 Update() 保存
  • 用 Update(handler) 就地应用一次更新操作
  • 用 Delete() 删除选择集中包含的对象
信息

如果结果必须是一次可被存储、之后能取回、并在适用时可通过数据层观察到的状态变更,那么这就是标准做法。

基本规则​

PlayServ 不需要任何特殊手法来修改数据。流程就是:

  1. 取回数据
  2. 用普通的 setter 修改字段
  3. 调用 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 类型相关联的具名动作,而不是直接改一个字段时,走这条路才合适。

客户端player.Shoot(...)RPC 调用服务端 HandlerDoShoot —— 以 Model 为上下文return truereturn falsePipeline 继续动作被执行Pipeline 中止动作被拒绝

服务端:定义扩展方法

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

客户端:调用扩展方法

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

下一步​