# L-R 编程范式（sapdon 存量类 Addon 通用骨架）

> 服务对象：`examples/digitCircuit`（数电）、`examples/fluid_pipe`（流体）、`examples/power_grid`（电力）——一个可复用的「装备类/生态类」Addon 编程范式。

这三类系统在玩法与数据形态上完全不同，但骨架高度一致：**都走一条"逻辑求解 → 渲染同步"的 L/R 分离流水线**，且都由 **连接(C₁)、源(S)、功能(F)、消费(Cc)、储量(R)** 五元组构成一个可更新的"资源网络"。

---

## 1. 五元组映射

| 元组 | digitCircuit 数电 | fluid_pipe 流体 | power_grid 电力 |
|---|---|---|---|
| **连接** C₁ | 导线 Net（逐面 `wire_connect:*` 手臂） | 段 Segment（逐面 `pipe_connect:*`） | 段（正交自动连通） |
| **源** S | on/off/switch 信号源 | 泵输出（+△） | 燃煤发电机 / 太阳能 |
| **功能** F | 门 / 分线器 / 合并器 | 阀门 / 三通 | 继电器（可控桥） |
| **消费** Cc | 显示灯（仅显示） | 罐纯吸收 / 空气汇 | 电力熔炉（真实熔炼） |
| **储量** R | 寄存器 store / 芯片 | 罐（32 格液位） | 电池（0..MAX 电量） |

> 关键洞察：F（功能块）本质是**受控的连接/变换器**——数电的门变换信号、流体的阀透传/断流、电力的继电器合并/分隔电网。绝大多数新生态系统只需把 F 当"可通断的耦合节点"即可起步。

## 2. 分层约束（铁的边界）

```
┌───────────────────────────────────────────────────────────┐
│  L 层 scripts/core/（纯逻辑，禁止 import @minecraft/server）│
│    graph.ts   建立"连接块图"：洪水填充成段/网，收设备端点     │
│    resource.ts/ settle.ts   资源在场上的传播/归并 + 逐 tick 结算│
│    → 把结果写进 seg.xxx（powered / front / covered / value） │
├───────────────────────────────────────────────────────────┤
│  R 层 scripts/engine/（MC 引擎，读世界方块）                 │
│    const/world/state/log/diag                              │
│    graph.ts   实现 L 层 FloodGraph 接口（世界实现）           │
│    rebuild.ts 放置/破坏/开关 → 重建段 + 加载后渐进重建         │
│    render.ts  只读 seg.xxx 同步写方块状态（发光/液位/带电）    │
│    persist.ts 只存小状态（设备表/连接位置），图=重建不落盘      │
│    tick.ts    主循环：L 结算 → R 渲染 → 设备存活检查          │
│  index.ts     注册：命令 / 自定义组件 / 事件 / 主循环          │
└───────────────────────────────────────────────────────────┘
```

铁律：
1. **L 层零 MC 依赖** → 可在 Node 直接镜像测试。
2. **L 写 `seg.*`，R 只读** → 状态单一来源，渲染层可缓存去重。
3. **连接块手臂/朝向 = 方块状态**（世界自动持久化），**图与传播场不落盘**，靠事件 + 加载后 `rebuildPending` 逐批（每 tick 64 个）渐进洪水重建。
4. **持久化只存小状态**：设备表（储量 level、源燃料、消费进度）+ 连接位置；液位/流动态只进内存 + 方块状态视觉兜底。
5. **写动态属性不可吞异常**（吞掉 = 重进世界静默丢存档）；用 `loaded` 门闩防启动早期空表覆盖存档。

## 3. 资源网络结算模板

```
每 tick（如 20t≈1s）:
  1. 连接图（L）   : 沿连接块洪水 → 段/网
  2. 场/结算（L）  : 若含共享设备的耦合（F/S/R 把邻段并网，F 用受控 open/closed 决定是否并）
                     → 网格级（或势场级）结算：源供给侧 vs 消费需求侧 + 储量缓冲
                     → 写 seg.powered / seg.covered 等
  3. 渲染（R）     : 读 seg.* → 写方块状态（电线发光、设备液位/燃烧/带电）
  4. 存量（R）     : 充电/放电/喂料扣除 → save（仅结构事件）
```

三种结算粒度的取舍：
- **网格级全局**（power_grid）：供/需对账 + 全有/全无。最简、稳压直觉，丢物理空间感。
- **势/距离场**（fluid_pipe）：源势沿图传播、衰减，决定"能不能到、到多高"。物理感强但复杂度高（需构思成本函数）。
- **布尔/位宽**（digitCircuit）：信号值 + 位宽固定点，天然适合布尔逻辑合成。

## 4. 镜像测试约束（母子同步）

L 层用 TS 写、Node 不能直接跑，因此采用**镜像副本**：`test/<name>.test.mjs` 复制 L 层纯逻辑（JS 版）。**改 L 层逻辑必须同步测试副本并跑绿**。这同时约束了 L 层必须保持"纯函数、可独立 import、无副作用"，否则镜像就同步不动。

## 5. 可复用工具箱（从三项目沉淀）

- `world.ts`：`blockKey / keyParts / getBlockByKey / getAdjacent` 一致性 key（`dim:x,y,z`）。
- `rebuildAround / rebuildPending / rebuildStale`：结构重建三件套（事件重建 + 加载渐进重建 + 失效重建）。
- `persist.ts`：动态属性分块读写通用骨架（单块/多块 `_chunks`）。
- 旋转设备：局部参考系语义面 + `ROT_FACE(facing, local)` 映射（见 fluid_pipe AGENTS），杜绝写死世界面。
- 诊断：`console.warn` ContentLog + 运行日志开关 + dump 就近转储。

## 6. 已知坑（三项目通用）

- 方块状态 **≤16 有效值**（整数范围 max-min ≤15）。
- 单元用普通立方体或命名材质 geo；同一方块所有 material instance 必须同一 `render_method`。
- Molang 变量名统一小写；粒子 `basic_*` 需传 `variable.direction`。
- 调试证据优先 ContentLog(`console.warn`)，`world.sendMessage` 不进日志。

---
> 新生态示例（如"供水系统""机械传动""雨洪管网"）建议直接套本范式：先定 L 层 graph+settle 并写镜像测试（绿后进 R），再补 R 层引擎与贴图。