docs(game-runtime): U1 约定正式化 runtime-api-2d.d.ts(rt 接口 TS 契约 · 第10类契约 additive)
plan 2026-06-18-001 U1 正式化产物(plan「1-2 轮后正式化」已满足:4 轮迭代+跨品类 9/9 实证+clickable 基元,约定已稳)。 手写 TS 契约(同 api.d.ts/game-host.d.ts 范式),与 gd-runtime.js 同形: - gameDefinition 声明式模型:Render/Physics/Clickable/Marker 组件 + EntityDef/BehaviorDef(code)/RuleDef/SceneDef。 - rt 面(behavior 侧):实体 getEntity/entities/query/spawn/destroy + Entity 实例形 + input(轮询)/time(确定性,无 nowMs)/ dt/random/score-win-lose(latch)/clamp-dist-overlap/fx/view。 - ForensicsState:固定取证键 + 逐实体 id 投影命名位(ball.x…)+ tag=target → targets[]。 - createRuntime(boot,gameDefinition)→Runtime(init/update/render/state/destroy/errors)签名。 落 game-runtime/src/host/(同 game-host.d.ts 之理:内部宿主↔behavior 接线面,非跨仓 SSOT); additive 第 10 类契约,**不动现 8 契约**(故未改 source-project.schema.json;clickable 入其 kind 枚举=additive, 留 6c6g/创始人 决,contract-first 补正)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
80aaa116ab
commit
95b2572e65
217
game-runtime/src/host/runtime-api-2d.d.ts
vendored
Normal file
217
game-runtime/src/host/runtime-api-2d.d.ts
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
// runtime-api-2d.d.ts —— 运行时访问约定(2D 适配器 · behavior 侧 API)TS 契约 · core-runtime-v0
|
||||
// owner:本 session(引擎线 · plan 2026-06-18-001 U1 正式化产物) | 消费方:U2 build-from-source 装配器 + U3 GAMEDEF_SYSTEM prompt
|
||||
//
|
||||
// 【为什么手写 .d.ts、落 game-runtime/src/host/】
|
||||
// 与 game-host.d.ts(第 9 类契约)同理:发行版源 = ESM JS + JSDoc,对外「类型契约」手写。本约定是 game-runtime
|
||||
// 内部「宿主↔游戏 behavior」接线面(behaviors 经 rt 操作世界),与 api.d.ts(插件↔引擎面)正交、与 game-host.d.ts
|
||||
// (游戏工厂↔宿主面)相邻;故落 src/host/,不落 contracts/(避免跨仓 SSOT 反向 import)。是否升格 contracts/ 由 6c6g 定。
|
||||
//
|
||||
// 【与实现同形】本文件与 gd-runtime.js 的 createRuntime/rt 必须同形同步;人/模型可读版见同目录 runtime-api-2d.md。
|
||||
// 【状态】已过 4 轮迭代 + 跨品类 9/9 实证(含 clickable 基元),约定稳定,正式化为契约。后续演进只增不破已冻签名。
|
||||
|
||||
import type { PluginContext } from '../core/api.d.ts';
|
||||
import type { GameHostBootContext } from './game-host.d.ts';
|
||||
|
||||
/* ──────────────────────────────────────────────────────────────────────────
|
||||
* gameDefinition 声明式领域模型(source-project.schema.json#/properties/gameDefinition 的运行时消费视图)
|
||||
* ────────────────────────────────────────────────────────────────────────── */
|
||||
|
||||
/** 归一化颜色:'#rgb'/'#rrggbb' 或 {r,g,b,a}(0..1)。 */
|
||||
export type Color = string | { r: number; g: number; b: number; a?: number };
|
||||
|
||||
/** 渲染组件:声明式出图(behaviors 只逻辑不画,渲染器据此画)。 */
|
||||
export interface RenderComponent {
|
||||
id?: string;
|
||||
kind: 'render';
|
||||
/** rect(缺省,以 transform 为中心)/ circle / fill(铺满 390×844 视口作背景)。 */
|
||||
shape?: 'rect' | 'circle' | 'fill';
|
||||
color?: Color;
|
||||
w?: number; h?: number; // rect
|
||||
r?: number; // circle
|
||||
}
|
||||
|
||||
/** 物理组件(opt-in):挂此组件的实体每帧 x+=vx*dt; y+=vy*dt(有 gravity 则先 vy+=gravity*dt)。 */
|
||||
export interface PhysicsComponent {
|
||||
id?: string;
|
||||
kind: 'physics';
|
||||
gravity?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击组件(plan U3 离散点击声明式基元):运行时内置——本帧点中带此组件且 occupied!==true 的实体
|
||||
* → 自动翻 occupied=true + spawn mark 标记实体(可见变化) + 加 score + fx(粒子/音效)。
|
||||
* 离散点击类(井字棋/打地鼠/翻牌)声明它即可,免写易错 tap-handler。配 tags:["target"] 让九门 driver 逐个点。
|
||||
*/
|
||||
export interface ClickableComponent {
|
||||
id?: string;
|
||||
kind: 'clickable';
|
||||
/** 命中加分(缺省 1)。 */
|
||||
score?: number;
|
||||
/** 命中时 spawn 的标记实体的 render 形态(缺省黄色小圆)。 */
|
||||
mark?: { shape?: 'rect' | 'circle'; color?: Color; r?: number; w?: number; h?: number };
|
||||
/** 命中区半尺寸来源(缺省取 render 尺寸 / 80)。 */
|
||||
hitW?: number; hitH?: number;
|
||||
}
|
||||
|
||||
/** 碰撞/自定义组件:声明式标记,由 behavior 自行 rt.overlap 判定 / 读取。 */
|
||||
export interface MarkerComponent {
|
||||
id?: string;
|
||||
kind: 'collision' | 'custom';
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
export type Component = RenderComponent | PhysicsComponent | ClickableComponent | MarkerComponent;
|
||||
|
||||
/** 实体声明(schema entity):transform.position → 运行时 x/y;可带 vx/vy/tags + 任意数值字段(idx/occupied 等)。 */
|
||||
export interface EntityDef {
|
||||
id: string;
|
||||
transform: { position: { x: number; y: number; z?: number }; rotation?: number; scale?: number };
|
||||
/** 组件引用(components[].id 字符串)或内联组件对象(spawn 用)。 */
|
||||
components?: Array<string | Component>;
|
||||
vx?: number; vy?: number;
|
||||
tags?: string[];
|
||||
[k: string]: unknown; // 运行时可用的自定义数值/布尔字段(idx/occupied/…)
|
||||
}
|
||||
|
||||
/** 行为模块:code 是一段 JS 逻辑串,运行期编译为 function(rt,self,dt)。init 跑一次,其余每帧。 */
|
||||
export interface BehaviorDef {
|
||||
id: string;
|
||||
trigger: 'init' | 'update' | 'input' | 'collision' | 'timer';
|
||||
/** 逻辑代码(规范字段 code;js 为兼容别名)。受校验边界静态扫描(禁 Math.random/Date/process/while(true)…)。 */
|
||||
code?: string;
|
||||
js?: string;
|
||||
}
|
||||
|
||||
/** 规则:condition 是无副作用 JS 布尔表达式(rt/self 在作用域),为真按 outcome。 */
|
||||
export interface RuleDef {
|
||||
id: string;
|
||||
condition: string;
|
||||
outcome: 'win' | 'lose' | 'score' | 'advance';
|
||||
}
|
||||
|
||||
/** 场景:scenes[0].entityRefs 决定初始实例化哪些实体(缺省全量)。 */
|
||||
export interface SceneDef {
|
||||
id: string;
|
||||
entityRefs: string[];
|
||||
}
|
||||
|
||||
export interface GameDefinition {
|
||||
entities: EntityDef[];
|
||||
components?: Component[];
|
||||
behaviors?: BehaviorDef[];
|
||||
scenes?: SceneDef[];
|
||||
rules?: RuleDef[];
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────────────────────────────────
|
||||
* rt —— behavior 侧 API(注入 new Function('rt','self','dt',code) 的那个 rt)
|
||||
* 受控面铁律:时间/随机走 boot.ctx 受控种子(确定性,禁 Math.random/Date.now);引擎能力经 ctx.getEngine()(满 F 门)。
|
||||
* ────────────────────────────────────────────────────────────────────────── */
|
||||
|
||||
/** 运行时实体实例(rt.getEntity/entities/query/spawn 返回)。 */
|
||||
export interface Entity {
|
||||
id: string;
|
||||
x: number; y: number; vx: number; vy: number;
|
||||
alive: boolean;
|
||||
tags: Set<string>;
|
||||
/** 已解析的组件对象数组。 */
|
||||
components: Component[];
|
||||
get(k: string): unknown;
|
||||
set(k: string, v: unknown): unknown;
|
||||
destroy(): void;
|
||||
[k: string]: unknown; // behaviors 可直接读写自定义属性(e.hp=3、e.occupied 等)
|
||||
}
|
||||
|
||||
/** 受控输入轮询面(包 ctx.getInput() 受控事件为 behaviors 友好的轮询)。 */
|
||||
export interface RtInput {
|
||||
isDown(key: string): boolean;
|
||||
justPressed(key: string): boolean;
|
||||
justTapped(): boolean;
|
||||
/** 当前指针(副本,写它不腐蚀内部态)。 */
|
||||
readonly pointer: { x: number; y: number; down: boolean };
|
||||
}
|
||||
|
||||
/** 受控时间面(now=相对游戏时间秒,从 0;不暴露墙钟 nowMs,保确定性)。 */
|
||||
export interface RtTime {
|
||||
now(): number;
|
||||
}
|
||||
|
||||
export interface RtFx {
|
||||
/** 经 ctx.getEngine().particles 真喷粒子(满 F 门;无引擎优雅 no-op)。 */
|
||||
burst(x: number, y: number, color?: Color): void;
|
||||
/** 经 ctx.getEngine().audio.synth 真合成音效(kind ∈ score/hit/lose/win/default)。 */
|
||||
beep(kind?: string): void;
|
||||
}
|
||||
|
||||
/** behavior/rule 注入的运行时访问面(全部能力的唯一入口;其纯 API 面被 Object.freeze 防改写)。 */
|
||||
export interface Rt {
|
||||
// 实体
|
||||
getEntity(id: string): Entity | null;
|
||||
entities(): Entity[];
|
||||
/** 按 tag 或组件 id/kind 查询活实体(gameplay 主用 tag)。 */
|
||||
query(name: string): Entity[];
|
||||
spawn(spec: Partial<EntityDef> & { x?: number; y?: number; vx?: number; vy?: number; tags?: string[]; components?: Array<string | Component> }): Entity;
|
||||
destroy(e: Entity): void;
|
||||
// 输入 / 时间 / 随机(确定性)
|
||||
input: RtInput;
|
||||
time: RtTime;
|
||||
readonly dt: number;
|
||||
random(): number;
|
||||
randRange(a: number, b: number): number;
|
||||
randInt(a: number, b: number): number;
|
||||
// 分数胜负(win/lose 置不可逆 latch 终态)
|
||||
readonly score: number;
|
||||
addScore(n?: number): number;
|
||||
setScore(n: number): number;
|
||||
win(): void;
|
||||
lose(): void;
|
||||
// 工具 / 特效 / 视口
|
||||
clamp(v: number, lo: number, hi: number): number;
|
||||
dist(ax: number, ay: number, bx: number, by: number): number;
|
||||
/** AABB 重叠({x,y,w?,h?},缺省全尺寸 16;显式 0 被尊重)。 */
|
||||
overlap(a: { x: number; y: number; w?: number; h?: number }, b: { x: number; y: number; w?: number; h?: number }): boolean;
|
||||
fx: RtFx;
|
||||
view: { w: number; h: number };
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────────────────────────────────
|
||||
* 取证快照(_forensicsView().state();九门据此判进展 + 派生 driver 命名路径)
|
||||
* ────────────────────────────────────────────────────────────────────────── */
|
||||
|
||||
/** state() 快照:固定取证键 + 逐实体按 id 投影命名位(ball.x/paddle.x…)+ tag='target' → targets[]。 */
|
||||
export interface ForensicsState {
|
||||
phase: 'booting' | 'playing' | 'gameover';
|
||||
result: 'win' | 'lose' | null;
|
||||
score: number;
|
||||
elapsed: number;
|
||||
remaining: number;
|
||||
progress: number | null;
|
||||
errors: string[];
|
||||
entities: Array<{ id: string; x: number; y: number; tags: string[] }>;
|
||||
/** tap-targets driver 读:tag='target' 实体派生。 */
|
||||
targets?: Array<{ x: number; y: number; idx: number; occupied: boolean; safe: boolean }>;
|
||||
/** 逐实体 id 投影位(如 ball:{x,y,vx,vy,w?,h?,r?,angle?}),供 gatespec 命名路径解析。 */
|
||||
[entityId: string]: unknown;
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────────────────────────────────
|
||||
* createRuntime —— 建可变世界 + 产 rt(U2 装配器产出的工厂 init 调它;GameInstance 五法委托其 init/update/render/state/destroy)
|
||||
* ────────────────────────────────────────────────────────────────────────── */
|
||||
|
||||
export interface Runtime {
|
||||
rt: Rt;
|
||||
init(): void;
|
||||
update(dt: number): void;
|
||||
render(g: CanvasRenderingContext2D): void;
|
||||
state(): ForensicsState;
|
||||
destroy(): void;
|
||||
errors(): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 建运行时:实例化 entities、编译 behaviors(new Function)/rules、内置 clickable 点击派发 + 声明式渲染器,产 rt。
|
||||
* @param boot 宿主注入的受控启动上下文(含 ctx:PluginContext 受控面)。
|
||||
* @param gameDefinition 声明式领域模型。
|
||||
*/
|
||||
export declare function createRuntime(boot: GameHostBootContext | { ctx: PluginContext; seed?: number; mainContext?: CanvasRenderingContext2D | null; canvas?: HTMLCanvasElement | null }, gameDefinition: GameDefinition): Runtime;
|
||||
export default createRuntime;
|
||||
Loading…
x
Reference in New Issue
Block a user