边缘游戏:成长、离线结算与可靠存档
以 examples/edge-garden 为起点:game.js 负责模型,simulation.js 负责计算,main.js 协调视图和宿主,audio.js 管理音频。不要把动画、持久状态和桥接写到同一个无限循环。
先确定进度模型
把模型定义为有版本的 JSON:资源、背包、成长阶段和上次结算时间。先校验存档正文再应用;不认识的业务 schema 明确提示,不猜测字段或静默覆盖。配色/折叠方式是每屏配置,进度是安装共享 saves。
保存时使用当前 revision 作为 expectedRevision,新槽用 null。提交成功才更新本地修订。SAVE_CONFLICT 时重读,再合并可交换操作或提示用户;多实例扣费/奖励不能采用简单最后写入覆盖。布局或包回退不会回退存档,作者负责正文兼容范围。
有界离线结算
js
const {elapsedMs, clockMovedBack, capped} = widgetHost.elapsedSince(savedAt, {
maxMs: 8 * 60 * 60 * 1000
});savedAt 来自已验证的成功快照。八小时是示例业务上限,不是平台额度。使用聚合计算或有上限的步进,限制资源上限;时钟倒退明确提示并按零时长/业务保守规则处理,不将本地时间当防作弊依据。
动画与保存节奏
requestAnimationFrame 只画可见状态;隐藏暂停绘制,减少动画改静态帧,省电降频。模拟步数有上限,恢复后补算有界时间,不追赶全部历史帧。每个保存槽最多一个在途提交和一份合并后的待保存状态,记录检查点而非每帧落盘。
widgetHost.onClosing 是正常退出前的一次有界保存机会,不能否决退出,也不应承担唯一存档责任。周期和关键业务操作本来就要保存。未完成写入不可宣称成功,取消不撤回已经提交的快照。
验证
覆盖首次空槽、读取损坏、业务格式不支持、重复点击、提交失败、响应丢失后重读、多屏冲突、时间倒退、超长离线和关闭中保存。真实设备运行另外记录。规则见存档与边缘花园。