docs(game-runtime): U1 运行时约定文本 runtime-api-2d.md(交 U3 prompt 嵌入)
plan 2026-06-18-001 U1 交付物「约定文字同步喂进 prompt → 交 U3 落 SaaPrompts 新 SYSTEM」。
新增 game-runtime/src/host/runtime-api-2d.md——写 gameDefinition behavior 逻辑时能用的全部 rt 面
的人/模型可读契约:gameDefinition 结构 / behavior 代码契约(new Function('rt','self','dt',code)+
trigger 语义+四条硬约束)/ rules / rt 面全 API 参考 / 组件 / 4 原型 few-shot / 常见坑(治真实模型
漂移:禁约定外 helper、禁 Math.random、终态置 latch、behavior 不画图、关键事件挂 fx)。
U3 的 GAMEDEF_SYSTEM prompt 直接嵌入本文。状态 v0(已过 4 类原型表达力证),保留补 idiom 余量。
落点同 game-host.d.ts 之理(内部宿主↔behavior 接线面 → game-runtime/src/host/);
是否升格 contracts/ 跨仓契约由 6c6g(contracts owner)定。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4292f4e793
commit
c8526f1dd6
120
game-runtime/src/host/runtime-api-2d.md
Normal file
120
game-runtime/src/host/runtime-api-2d.md
Normal file
@ -0,0 +1,120 @@
|
||||
# 运行时访问约定(2D 适配器 · behavior 侧 API)—— runtime-api-2d v0
|
||||
|
||||
> plan 2026-06-18-001 U1 交付物。本文件是「写 gameDefinition 的 behavior 逻辑时能用的全部 `rt` 面」的**人/模型可读契约**,
|
||||
> U3 的 `GAMEDEF_SYSTEM` prompt 直接嵌入本文(+ 末尾 few-shot)。实现见 `gd-runtime.js`,类型雏形随后正式化为 `runtime-api-2d.d.ts`。
|
||||
>
|
||||
> **状态 v0(plan「别冻早」)**:已过 4 类原型表达力证(见 `gd-archetypes.test.mjs`),接口稳定但保留随真实模型输出补 idiom 的余量。
|
||||
> **落点说明**:与 `game-host.d.ts`(第 9 类契约)同理,本约定是 game-runtime 内部「宿主↔游戏 behavior」接线面,故落 `game-runtime/src/host/`;
|
||||
> 是否升格为 `contracts/` 跨仓契约由 6c6g(大脑线/contracts owner)定。
|
||||
|
||||
---
|
||||
|
||||
## 1. 游戏 = 声明式 gameDefinition(改源不改打包产物)
|
||||
|
||||
一个游戏 = 一份 `gameDefinition` JSON(结构见 `contracts/agent-loop/source-project.schema.json`):
|
||||
|
||||
| 字段 | 含义 |
|
||||
|---|---|
|
||||
| `entities[]` | 实体:`{id, transform:{position:{x,y}}, components:[组件id...]}`(可带 `vx/vy/tags` 供运行时用) |
|
||||
| `components[]` | 组件定义:`{id, kind, ...}`,`kind ∈ render/collision/physics/custom` |
|
||||
| `behaviors[]` | 行为模块:`{id, trigger, code}`——`code` 是一段 **JS 逻辑字符串**,运行期编译执行 |
|
||||
| `scenes[]` | 场景:`{id, entityRefs:[实体id...]}`(v0 取 `scenes[0]` 决定初始实例化哪些实体;缺省全量) |
|
||||
| `rules[]` | 胜负规则:`{id, condition, outcome}`——`condition` 是 JS 布尔表达式串,`outcome ∈ win/lose/score/advance` |
|
||||
|
||||
**核心范式**:实体/组件/场景/规则是**声明式数据**;唯一的「逻辑代码」是 `behaviors[].code` 和 `rules[].condition`,
|
||||
它们经受控的 `rt` 面操作世界。**behaviors 只写逻辑、不写画**(出图由声明式渲染器据 render 组件自动完成)。
|
||||
|
||||
---
|
||||
|
||||
## 2. behavior 代码契约
|
||||
|
||||
每个 behavior 的 `code` 被编译为 `new Function('rt', 'self', 'dt', code)`,每次调用注入三参:
|
||||
|
||||
- **`rt`** — 运行时访问面(见 §4),操作世界的唯一入口。
|
||||
- **`self`** — 本 behavior 的**持久局部态**(普通对象 `{}`,跨帧保留)。存计时器/累加器:`self.t = (self.t||0) + dt;`
|
||||
- **`dt`** — 本帧时间步(秒)。
|
||||
|
||||
**trigger 语义**:
|
||||
- `init`:世界建好后**跑一次**(布初始实体/初值)。
|
||||
- `update` / `input` / `collision` / `timer`:**每帧跑一次**(输入经 `rt.input` 轮询;碰撞/计时在 behavior 内自查)。
|
||||
|
||||
**硬约束(违反 = 生成缺陷)**:
|
||||
1. **确定性**:随机一律 `rt.random/rt.randRange/rt.randInt`,时间一律 `rt.time.now()`/`dt`——**禁 `Math.random` / `Date.now` / `performance.now`**。
|
||||
2. **只用 `rt` 面**:禁自造约定外 helper(如 `rt._spawnFood`)、禁 `document`/`window`/裸引擎/`requestAnimationFrame`/`addEventListener`。要生成实体用 `rt.spawn`。
|
||||
3. **终态置 latch**:胜负用 `rt.win()`/`rt.lose()`(置不可逆终态),**不要**用计分或自定义 flag 表达「游戏结束」。
|
||||
4. **特效经 `rt.fx`**:碰撞/得分等关键事件调 `rt.fx.burst(...)` / `rt.fx.beep(...)`(真接引擎粒子/音频)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 规则(rules)
|
||||
|
||||
`condition` 是 JS 布尔表达式串,作用域内有 `rt`(与 `self`)。每帧求值;为真时按 `outcome`:
|
||||
|
||||
- `win` / `lose` → 置 latch 终态(一次性,不可逆)。
|
||||
- `score` → 上升沿 +1 分(防每帧重复加)。
|
||||
- `advance` → 场景推进(v0 占位)。
|
||||
|
||||
例:`{ "id":"win", "condition":"rt.score >= 10", "outcome":"win" }`
|
||||
|
||||
---
|
||||
|
||||
## 4. `rt` 面参考(全部可用 API)
|
||||
|
||||
### 实体
|
||||
- `rt.getEntity(id)` → 实体或 null(仅活实体)
|
||||
- `rt.entities()` → 全部活实体数组
|
||||
- `rt.query(name)` → 按 tag 或组件 id/kind 过滤的活实体数组
|
||||
- `rt.spawn({x, y, vx?, vy?, tags?, components?})` → 新实体(`components` 可内联组件对象);返回实体引用
|
||||
- `rt.destroy(entity)` → 标记死亡(帧末回收)
|
||||
- 实体字段:`.x .y .vx .vy .alive .tags(Set) .components(数组)`;方法 `.get(k)` / `.set(k,v)` / `.destroy()`;可直接读写任意属性(`e.hp = 3`)
|
||||
|
||||
### 输入(轮询)
|
||||
- `rt.input.isDown(key)` → 是否按住(如 `'ArrowLeft'`/`'Space'`)
|
||||
- `rt.input.justPressed(key)` → 本帧是否刚按下
|
||||
- `rt.input.justTapped()` → 本帧是否发生指针按下
|
||||
- `rt.input.pointer` → `{x, y, down}`
|
||||
|
||||
### 时间 / 随机(确定性)
|
||||
- `rt.time.now()` → 相对游戏时间(秒,从 0 累加;**用这个**,非绝对钟)
|
||||
- `rt.dt` → 本帧步长(秒,= 注入的 `dt`)
|
||||
- `rt.random()` → `[0,1)`;`rt.randRange(a,b)` → `[a,b)`;`rt.randInt(a,b)` → `[a,b]` 整数
|
||||
|
||||
### 分数 / 胜负
|
||||
- `rt.score`(读)/ `rt.addScore(n=1)` / `rt.setScore(n)`
|
||||
- `rt.win()` / `rt.lose()` → 置 latch 终态
|
||||
|
||||
### 工具 / 特效
|
||||
- `rt.clamp(v,lo,hi)` / `rt.dist(ax,ay,bx,by)` / `rt.overlap(a,b)`(AABB,`a/b={x,y,w?,h?}`,缺省半尺寸 16)
|
||||
- `rt.fx.burst(x,y,color)` → 引擎粒子(color 接 `'#rrggbb'` 或 `{r,g,b,a}`)
|
||||
- `rt.fx.beep(kind)` → 引擎音效(kind ∈ `score/hit/lose/win/default`)
|
||||
- `rt.view` → `{w:390, h:844}`(视口;边界判断用)
|
||||
|
||||
---
|
||||
|
||||
## 5. 组件(components)
|
||||
|
||||
- **render**:`{id, kind:'render', shape, color, ...}`
|
||||
- `shape:'rect'` + `w,h`(以实体 transform 为中心)
|
||||
- `shape:'circle'` + `r`
|
||||
- `shape:'fill'` + `color`(铺满视口,作背景)
|
||||
- **physics**:`{id, kind:'physics', gravity?}`——挂此组件的实体每帧自动 `x+=vx*dt; y+=vy*dt`(有 `gravity` 则先 `vy+=gravity*dt`)。不挂则位置全由 behavior 控制。
|
||||
- **collision / custom**:声明式标记,由 behavior 自行 `rt.overlap` 判定 / 读取。
|
||||
|
||||
---
|
||||
|
||||
## 6. 原型范式(few-shot · 见 `gd-archetypes.test.mjs` 完整可跑版)
|
||||
|
||||
- **paddle-intercept(打砖块/pong)**:板 entity + 球 entity(`vx/vy`);update behavior 里键/指针控板、球积分+墙反弹、`rt.overlap` 板拦截 `rt.addScore`+`rt.fx.burst`、落底 `rt.lose()`。
|
||||
- **event-clicker(点击器/放置)**:按钮 entity;input behavior 里 `if(rt.input.justTapped()) rt.addScore(1)`;rule `rt.score>=N → win`。
|
||||
- **dodge-spawn(躲避)**:玩家 entity;update behavior 里键控玩家、定时 `rt.spawn` 随机位敌人(`rt.randRange`)、遍历 `rt.query('enemy')` 下落+出界 `rt.destroy`+`rt.overlap` 撞玩家 `rt.lose()`。
|
||||
- **runner(跑酷)**:玩家挂 `physics{gravity}`;update behavior 里 `rt.input.justTapped()` 起跳(置 `vy`)、落地复位、定时 `rt.spawn` 障碍(`vx`)、`rt.overlap` 撞障碍 `rt.lose()` / 出界 `rt.addScore`。
|
||||
|
||||
---
|
||||
|
||||
## 7. 常见坑(治真实模型漂移)
|
||||
|
||||
- ❌ 自造 `rt._spawnFood` 等约定外 helper → ✅ 用 `rt.spawn(...)`。
|
||||
- ❌ `Math.random()` / `Date.now()` → ✅ `rt.random()` / `rt.time.now()`(确定性,否则取证不可复现 + 静态门拒)。
|
||||
- ❌ 用分数/flag 表达「结束」 → ✅ `rt.win()`/`rt.lose()` 置 latch。
|
||||
- ❌ 在 behavior 里画图(`ctx.fillRect`)→ ✅ 给实体加 render 组件,渲染器自动出图。
|
||||
- ❌ 关键事件无特效 → ✅ 碰撞/得分调 `rt.fx.burst`/`rt.fx.beep`(满「真接线」门)。
|
||||
Loading…
x
Reference in New Issue
Block a user