fix(tier2): recHook 透传到资源系统——F 门/三联动门记 resource.* call-ID
F 门/三联动门读 window.__engineCalls 找 resource.addCoins/consumeIngredient 前缀,
但旧版只有 engine-caps(粒子/音频)经 recHook 记 __engineCalls,资源系统只记内部
_callCounts、不进 __engineCalls → calls=0、F 门 + 三联动门真接线判据永假。
修(additive,不破契约必填项):host 经 boot 上下文透传 recHook → main.js 喂
createGameCore → resource-system 完单真调 addCoins/合成真调 consumeIngredient 时
recHook('resource.addCoins'/'resource.consumeIngredient') 记进 __engineCalls。
headless/静态校验下 recHook 缺省 no-op、不抛错。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
44d1b45583
commit
8ea6133e63
@ -203,6 +203,9 @@ export async function bootPhaserHost(opts) {
|
||||
// 受控能力面经 boot 上下文额外透传(游戏经 ctx.getEngine() 拿;headless 下 no-op 能力)。
|
||||
// 注:契约 PhaserHostBootContext 不含 caps 字段,caps 经 game 内部约定取;此处 additive 透传不破契约必填项。
|
||||
caps,
|
||||
// recHook additive 透传:游戏逻辑(如资源系统完单/合成)经它把 call-ID 记进 window.__engineCalls,
|
||||
// 供 F 门 / 富游戏三联动门证「真调资源(addCoins/consumeIngredient)、非自绘伪装」(同 caps 不破契约必填项)。
|
||||
recHook,
|
||||
}));
|
||||
// 就绪钩子(harness 可挂取证全局;headless 下用于逻辑校验)。
|
||||
onReady(host, { game, phaserGame: null, canvas: null, caps, uncaught, latchInfo, pollLatch });
|
||||
@ -248,6 +251,7 @@ export async function bootPhaserHost(opts) {
|
||||
seed,
|
||||
assets,
|
||||
caps, // additive 透传受控面(游戏经 ctx.getEngine() 拿;不破契约必填项)
|
||||
recHook, // additive 透传:游戏逻辑经它记 call-ID 进 __engineCalls(F 门 / 三联动门真接线证据)
|
||||
}));
|
||||
// 挂逐帧 latch 轮询:Phaser scene events 'postupdate' 每帧后调(A4 铁律核心)。
|
||||
self.events.on('postupdate', pollLatch);
|
||||
|
||||
@ -44,9 +44,11 @@ export function createGameCore(deps) {
|
||||
if (!rng || typeof rng.next !== 'function') {
|
||||
throw new Error('[game-core] 必须注入受控随机源 random(next/range)'); // 错误路径留痕
|
||||
}
|
||||
// call-ID 取证钩子(host 经 main.js 透传;缺省 no-op)。资源系统据它把 'resource.*' 记进 __engineCalls(F 门/三联动门)。
|
||||
const recHook = deps.recHook || (() => {});
|
||||
|
||||
// 三系统装配(资源是中心,合成 / 订单都注入它 → 耦合点 3/4/5 真接线)。
|
||||
const resource = createResourceSystem({ random: rng, startIngredients: START_INGREDIENTS, startCoins: START_COINS });
|
||||
const resource = createResourceSystem({ random: rng, startIngredients: START_INGREDIENTS, startCoins: START_COINS, recHook });
|
||||
const merge = createMergeSystem({ resource, chains: MERGE_CHAINS, random: rng });
|
||||
const order = createOrderSystem({
|
||||
resource, templates: ORDER_TEMPLATES, activeCount: ACTIVE_ORDER_COUNT, loseStreak: LOSE_STREAK, random: rng,
|
||||
|
||||
@ -54,8 +54,10 @@ export default function createGame(opts) {
|
||||
async boot(ctx) {
|
||||
// 据 boot.seed 派生受控随机源(确定性;禁裸 Math.random)。
|
||||
const random = createSeededRandom(ctx.seed >>> 0);
|
||||
// 建游戏核心(三系统逻辑,平台预建写死)。
|
||||
core = createGameCore({ random });
|
||||
// 建游戏核心(三系统逻辑,平台预建写死)。recHook 由 host 经 boot 上下文 additive 透传:
|
||||
// 资源系统完单/合成时经它把 'resource.addCoins'/'resource.consumeIngredient' 记进 window.__engineCalls,
|
||||
// 供 F 门 / 富游戏三联动门证真接线(headless 下 ctx.recHook 缺省 → no-op)。
|
||||
core = createGameCore({ random, recHook: ctx.recHook });
|
||||
core.start(); // title → play(spike 直接进局;产线可加标题页)
|
||||
|
||||
// 受控能力面(host 经 boot 上下文 additive 透传 caps;headless 下为 no-op 能力面)。
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
* @param {{ next:()=>number, range:(a:number,b:number)=>number }} [deps.random] 受控随机源(资源系统本身少用随机,预留)
|
||||
* @param {Record<string, number>} deps.startIngredients 开局库存
|
||||
* @param {number} deps.startCoins 开局金币
|
||||
* @param {(id:string)=>void} [deps.recHook] call-ID 取证钩子(host 经 boot 透传 → window.__engineCalls);
|
||||
* 每次真调命令记 'resource.<cmd>' call-ID,供 F 门 / 富游戏三联动门(callsAddCoins/callsConsumeIngredient)证真接线。
|
||||
* @returns {ResourceSystem}
|
||||
*/
|
||||
export function createResourceSystem(deps) {
|
||||
@ -38,6 +40,9 @@ export function createResourceSystem(deps) {
|
||||
ingredients: { ...(deps.startIngredients || {}) },
|
||||
};
|
||||
|
||||
// call-ID 取证钩子(缺省 no-op;headless / 静态校验下无 host → no-op,不抛错)。
|
||||
const recHook = (deps && deps.recHook) || (() => {});
|
||||
|
||||
// F 门真接线取证:四个命令的真实调用计数(机器证据,agent 自述不作数)。
|
||||
const _callCounts = { addCoins: 0, spendCoins: 0, consumeIngredient: 0, addIngredient: 0 };
|
||||
|
||||
@ -52,6 +57,7 @@ export function createResourceSystem(deps) {
|
||||
addCoins(n) {
|
||||
// 受控日志锚:金币变动是经济门核心,留可追溯计数。
|
||||
_callCounts.addCoins++;
|
||||
recHook('resource.addCoins'); // 真接线 call-ID(F 门 / 三联动门 callsAddCoins 读 __engineCalls)
|
||||
state.coins += Math.max(0, n | 0);
|
||||
},
|
||||
|
||||
@ -80,6 +86,7 @@ export function createResourceSystem(deps) {
|
||||
const have = state.ingredients[itemId] || 0;
|
||||
if (have < need) return { ok: false, reason: 'no_stock' }; // 库存不足 → 失败
|
||||
state.ingredients[itemId] = have - need;
|
||||
recHook('resource.consumeIngredient'); // 真接线 call-ID(三联动门 callsConsumeIngredient 读 __engineCalls;仅真扣成功记)
|
||||
return { ok: true };
|
||||
},
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user