Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/concepts/entity-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ projections. They are not a second room protocol. Generic subscriptions, changin
permissions during a connection, AOI, cross-root transactions, fragmentation,
persistence and ACK/replay history remain outside this delivery. The
[replication design](../project/entity-replication-design.md) records these boundaries.
Its [planned subscription model](../project/entity-replication-design.md#configuration-driven-subscriptions-planned)
derives scopes, visibility, data selections and scene visibility from game configuration;
it does not make those orchestration features available in the current runtime.
2 changes: 2 additions & 0 deletions docs/concepts/entity-sync_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ Kernel 在所有者线程捕获拥有型值,带修订号的发布通过[通用
可复用的 C++ 标量接口仍可用于应用中的纯标量投影,它们不是第二套房间协议。
通用订阅、连接内变更权限、AOI、跨根事务、分片、持久化及 ACK/重放历史不在本轮范围内。
[复制设计](../project/entity-replication-design_CN.md)记录这些边界。
[计划中的订阅模型](../project/entity-replication-design_CN.md#配置驱动的订阅计划)由游戏配置决定范围、
可见条件、数据选择及场景可见性;当前运行时尚未提供这些编排能力。
57 changes: 57 additions & 0 deletions docs/project/entity-replication-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,63 @@ The diagram below describes semantic keys; the [protocol reference](../reference

Authorize root access, each table/column, each relationship and each child field separately. `sync_self` / `sync_view` are policy inputs, not session authentication; deny missing bindings/policy. Parent visibility grants no child-field access. Hidden changes do not advance that recipient's projected revision. Keep recipient progress separate from Kernel dirty flags and from other recipients.

## Configuration-driven subscriptions (planned)

The next layer derives subscriptions from game configuration and current business state. **Scopes, visibility conditions and the allowed scalar fields, table columns and child projections are configurable.** The framework must not hardcode owner, party, equipment or appearance field sets. Existing mask names can seed defaults; they do not limit the names or number of game-defined groups.

| Input | Responsibility |
| --- | --- |
| Scope | Find candidates using a registered provider: grid neighborhood, circle, party members, self or another business-defined range. Entity definitions select a profile and expose its parameters; map/game configuration selects the spatial implementation. |
| Visibility condition | Evaluate current observer/target facts. Party or guild membership can filter a spatial scope, while a separate relationship scope can explicitly allow tracking outside vision. |
| Data view | Select named fields, table columns and nested child views from Entity definitions. Games choose both names and member sets; adding a group must not require a framework enum or handwritten C++/C# field list. |
| Scene visibility | Decide whether this recipient presents a world actor. A position-only subscription may remain after the actor leaves vision. |

Each rule combines a scope, condition, one or more data views and scene visibility. Conditions within a rule must all pass. Matching rules merge their allowed members into one effective projection for each recipient/root, with scene visibility enabled only by an eligible rule. No matching grant means no data. Position-only tracking grants neither world appearance nor equipment inspection.

The following JSON is a **logical configuration draft**, using guest-room member names. It is not accepted by the current Entity JSON v1 parser or runtime. Its file layout and spreadsheet/export representation remain to be specified.

```json
{
"views": {
"nearby_actor": {
"class": "GuestPlayer",
"fields": ["name", "x", "y", "hp"],
"containers": {"equipment": {"view": "equipped_item"}}
},
"party_position": {"class": "GuestPlayer", "fields": ["x", "y"]},
"personal_state": {
"class": "GuestPlayer",
"fields": ["mp"],
"tables": {"inventory": {"columns": ["item_id", "quantity"]}}
},
"equipped_item": {"class": "GuestEquipment", "fields": ["item_id", "power"]}
},
"rules": [
{"scope": "vision", "condition": "can_observe", "views": ["nearby_actor"], "scene_visible": true},
{"scope": "party", "condition": "outside_vision", "views": ["party_position"], "scene_visible": false},
{"scope": "self", "condition": "is_owner", "views": ["nearby_actor", "personal_state"], "scene_visible": true}
]
}
```

These names and selections are game choices. Removing the party rule hides out-of-vision party members; selecting another view changes their allowed data. Scope/condition names refer to registered implementations, without requiring an expression language. The existing native exporter should resolve class/member references and produce server selections and trusted client type catalogs from the same configuration. Unknown references, incompatible class/type selections and recursive view definitions must fail validation. Container access does not implicitly include every child field.

Equipment and appearance use the same equipment Entity state; clients render that state. Equipment inspection remains a separate business request, permitted through the current friends list or an authorized in-vision relationship. Initially return an authorized snapshot rather than create a permanent inspection subscription.

| Runtime change | Planned subscription result |
| --- | --- |
| Enter vision | Install a complete allowed baseline and enable the world actor. |
| Leave vision but retain configured party tracking | Remove fields no longer granted, retain only the selected tracking data and disable the world actor. |
| Party/guild membership, visibility or selected profile changes | Recompute affected grants; replace the subscription binding/baseline when its projection changes. This does not imply configuration-file hot reload. |
| Lose every grant | End the subscription and remove its replica; the server Entity can remain alive. |
| Destroy the root | Retire all subscriptions for that Entity lifetime. |

Projection replacement must clear formerly visible members and retire unadmitted old publications; it requires an explicit connection-local subscription reset, not a root-destruction tombstone. Current room recovery still closes/reconnects and does not implement this reset. Field structure stays constrained by trusted definitions while authorized table rows and child memberships can change.

For the planned revision semantics, the server supplies final changed values and may publish a transition such as `base=10, revision=15`. The patch must cover the complete selected transition from the receiver's base; target revisions need not increase by one. Missing structural prerequisites still require a fresh baseline. Clients render interpolation, HP/MP transitions and equipment effects from committed authoritative state. The current publisher/codec/replicas still require consecutive revisions; changing this rule needs coordinated C++/Protobuf/C# validation.

Acceptance must cover configurable field/table/child selections, spatial and relationship transitions, hidden versus position-only party tracking, grant union and removal, inspection eligibility, connection-local baseline replacement, and valid revision jumps versus mismatched bases. One-root atomicity, owning values, lifetime checks and resource limits remain required. These are planned checks, not completed acceptance.

## One ordered root commit

The consistency boundary is one selected root tree per recipient. A baseline is its complete authorized state, including empty tables/slots and type-correct zero values. Freeze it at revision R on the owner thread after initialization and business mutations; later mutations belong to the next capture. Do not publish a partially initialized Entity or infer flush order from module registration order.
Expand Down
57 changes: 57 additions & 0 deletions docs/project/entity-replication-design_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,63 @@

分别授权根访问、表格/列、每条关系及每个子字段。`sync_self`/`sync_view` 是策略输入,不是会话认证;绑定/策略缺失时拒绝。父可见性不授予子字段访问权。隐藏变化不推进该接收者的投影修订号。接收者进度与 Kernel 脏标记、其他接收者进度分开维护。

## 配置驱动的订阅(计划)

下一层根据游戏配置与当前业务状态推导订阅关系。**范围、可见条件,以及允许同步的标量字段、表格列和子实体投影,全部可配置。** 框架不写死个人、小队、装备或外观的字段集合。已有 mask 名称可以生成默认分组,但不限制游戏自定义分组的名称与数量。

| 输入 | 职责 |
| --- | --- |
| 范围 | 通过注册的实现获取候选:九宫格、圆形、小队成员、自己或业务定义的其他范围。Entity 定义选择配置并提供参数,地图/玩法配置选择空间算法。 |
| 可见条件 | 根据观察者与目标的实时状态判断。小队/公会关系可以过滤空间范围;独立的关系范围也可明确允许视野外追踪。 |
| 数据视图 | 从 Entity 定义中选择具名字段、表格列及嵌套子视图。名称与成员集合均由游戏配置,新增分组不要求修改框架枚举或手写 C++/C# 字段列表。 |
| 场景可见性 | 决定接收方是否显示场景角色;目标离开视野后,仍可保留仅坐标订阅。 |

每条规则组合范围、条件、一个或多个数据视图及场景可见性。同一规则内条件全部通过才生效;命中规则合并允许的成员,形成每个接收者/根的最终投影。只有生效规则才能允许场景角色显示。没有授权规则就不发数据;坐标追踪不会同时授予外观或装备查看权限。

以下 JSON 仅为使用房间字段名的**逻辑配置草案**,当前 Entity JSON v1 解析器与运行时不接受它。文件组织与表格/导出表示仍需确定。

```json
{
"views": {
"nearby_actor": {
"class": "GuestPlayer",
"fields": ["name", "x", "y", "hp"],
"containers": {"equipment": {"view": "equipped_item"}}
},
"party_position": {"class": "GuestPlayer", "fields": ["x", "y"]},
"personal_state": {
"class": "GuestPlayer",
"fields": ["mp"],
"tables": {"inventory": {"columns": ["item_id", "quantity"]}}
},
"equipped_item": {"class": "GuestEquipment", "fields": ["item_id", "power"]}
},
"rules": [
{"scope": "vision", "condition": "can_observe", "views": ["nearby_actor"], "scene_visible": true},
{"scope": "party", "condition": "outside_vision", "views": ["party_position"], "scene_visible": false},
{"scope": "self", "condition": "is_owner", "views": ["nearby_actor", "personal_state"], "scene_visible": true}
]
}
```

以上名称和字段集合均为游戏选择。移除小队规则即可隐藏视野外队友,改用其他视图即可改变允许的数据。范围/条件名称引用已注册实现,无需引入表达式语言。沿用原生导出工具,从同一配置解析类与成员引用,生成服务端选择信息和客户端可信类型目录。未知引用、不兼容的类/类型选择及递归视图定义必须校验失败;允许容器不隐含允许所有子字段。

装备和外观使用同一份装备 Entity 状态,客户端据此渲染。装备查看作为独立业务请求,按当前好友列表或已授权的视野内关系判断;首版返回允许的快照,不额外建立永久查看订阅。

| 运行时变化 | 计划中的订阅结果 |
| --- | --- |
| 进入视野 | 安装完整允许基线,显示场景角色。 |
| 离开视野但保留配置的小队追踪 | 移除不再允许的字段,仅保留选定追踪数据,不再显示场景角色。 |
| 小队/公会、可见状态或选用配置变化 | 重算受影响授权;投影变化时替换订阅绑定及基线。这不表示支持配置文件热加载。 |
| 失去全部授权 | 结束订阅并移除副本,服务端 Entity 可以继续存在。 |
| 根销毁 | 结束该 Entity 存续期的全部订阅。 |

投影替换须清除不再可见的成员,并退役尚未入队的旧发布;需要显式的连接内订阅重置,不能借用根销毁标记。当前房间仍通过断开重连恢复,尚未实现此重置。字段结构受可信定义约束,允许的表行及子实体成员仍可动态变化。

计划中的修订语义由服务端给出变化属性最终值,允许发布 `base=10, revision=15`。补丁必须完整覆盖接收端基准到目标版本的选定变化,不要求目标修订逐个加一;缺少结构前提时仍需新基线。客户端根据已提交权威状态表现插值、HP/MP 过渡及换装效果。当前发布端/编解码/接收端仍要求连续修订,修改须协调验证 C++/Protobuf/C#。

验收须覆盖可配置字段/表格/子实体选择、空间与关系变化、视野外队友隐藏或仅坐标同步、授权合并与撤销、装备查看条件、连接内基线替换,以及合法版本跳跃与错误基准。保留单根原子性、拥有型值、存续期检查和资源上限。这些是计划中的检查,不代表已通过验收。

## 一个根的有序提交

一致性边界为每个接收者的一棵选定根树。基线是完整授权状态,包括空表格/槽位和类型正确的零值。在初始化和业务修改结束后,于所有者线程冻结修订 R;后续修改进入下一次捕获。不能发布部分初始化的 Entity,也不能通过模块注册顺序推断刷新顺序。
Expand Down
Loading