scaffold-gateables
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance Notes
性能说明
- Take your time to understand the game before proposing features
- Quality is more important than speed — wrong gateables hurt the game permanently
- Do not skip the locked-path verification in Step 4
- 先花时间了解游戏,再提出功能建议
- 质量比速度更重要——错误的可授权解锁功能会对游戏造成永久性伤害
- 不要跳过步骤4中的锁定路径验证
Scaffold Gateables
搭建可授权解锁功能
Add gateable features to an existing game. This skill produces hooks — skin pickers, continue-after-death flows, bonus modes, save slots, daily challenges — each wired through EventBus with a single capability-check seam (). It does NOT add any specific monetization SDK (Play.fun, sub.games, Stripe, etc.); it produces the scaffolding that any paywall, subscription, or entitlement layer can later switch on.
isEntitled(key)The default state is everything locked — returns for all keys. The game must feel completely normal in that state. When a downstream monetization layer flips an entitlement on, the gateable feature lights up.
isEntitled(key)false为现有游戏添加可授权解锁的功能。该技能会生成“钩子”——皮肤选择器、死后续玩流程、奖励模式、存档槽、每日挑战——每个功能都通过EventBus连接,并带有一个单一的权限检查接口()。它不会添加任何特定的变现SDK(如Play.fun、sub.games、Stripe等);它生成的脚手架可让后续任何付费墙、订阅或授权层启用这些功能。
isEntitled(key)默认状态下所有功能均锁定——对所有key返回。在此状态下,游戏必须运行完全正常。当下游变现层开启某项权限时,对应的可授权解锁功能才会激活。
isEntitled(key)falseCore Principles
核心原则
Use these to reason about what to propose and what to reject. They are rules, not guidelines.
- Never gate the core loop. If the game is about jumping, everyone jumps. Gate skins, not gravity.
- Prefer additive over subtractive. Add a bonus mode; don't shrink the free mode. Free players never feel punished.
- Match the game's rhythm. Short sessions → session-scoped perks (continue, daily skin, daily challenge seed). Long-form → persistence (save slots, unlock tree, bonus chapters).
- Propose 2–3 gateables at silver and gold only. Bronze is the default — every player gets the bronze experience by default, so no feature is scaffolded there. Aim for one or two silver conveniences and one gold spectacle. Numbers are targets — suggest what actually fits the game.
- Every gateable must degrade cleanly. With returning
isEntitled, the game must feel normal — not broken, not missing.false
遵循这些原则来判断应提出或拒绝哪些功能。这些是规则,而非指南。
- 绝不锁定核心玩法循环。如果游戏的核心是跳跃,那么所有玩家都能跳跃。锁定皮肤,而非重力。
- 优先选择新增功能而非削减原有功能。添加奖励模式;不要缩小免费模式的内容。免费玩家永远不应感到被惩罚。
- 匹配游戏节奏。短会话游戏→会话级福利(续玩、每日皮肤、每日挑战种子)。长流程游戏→持久化功能(存档槽、解锁树、奖励章节)。
- 仅在白银和黄金层级提出2-3项可授权解锁功能。青铜是默认层级——所有玩家默认都能获得青铜体验,因此不会在该层级搭建任何功能。目标是1-2项白银层级的便利功能和1项黄金层级的特色功能。数字仅为参考——建议提出真正适合游戏的功能。
- 每项可授权解锁功能都必须能平滑降级。当返回
isEntitled时,游戏必须运行正常——不能出现故障或缺失内容。false
Tier Vocabulary
层级术语
Use game-standard progression labels: bronze / silver / gold. This keeps the skill monetization-agnostic and reads naturally to players.
Bronze is the default tier — every player is bronze by default. The bronze experience IS the core game loop that everyone always gets. No feature is scaffolded at bronze; scaffold-gateables only produces features at silver and gold.
The downstream integration layer maps silver/gold to its own paid tier system:
| scaffold-gateables | sub.games | Play.fun (points-based) |
|---|---|---|
| silver | supporter ($3–8/mo) | mid-threshold points |
| gold | founder ($150/yr) | high-threshold points |
State this mapping in the Step 2 output so the handoff to or is explicit.
/subgames/monetize-game使用游戏标准的进阶标签:bronze / silver / gold。这能让该技能保持与变现无关,且对玩家来说通俗易懂。
Bronze是默认层级——所有玩家默认都是青铜层级。青铜体验就是所有玩家都能获得的核心游戏玩法循环。不会在青铜层级搭建任何功能;搭建可授权解锁功能仅会在silver和gold层级生成功能。
下游集成层会将白银/黄金层级映射到自身的付费层级系统:
| scaffold-gateables | sub.games | Play.fun(基于积分) |
|---|---|---|
| silver | 支持者(3-8美元/月) | 中等阈值积分 |
| gold | 创始人(150美元/年) | 高阈值积分 |
在步骤2的输出中说明此映射,以便明确对接或。
/subgames/monetize-gameInstructions
操作步骤
The user wants to add gateables to the game at (or the current directory if no path given). Optional hint tokens after the path (e.g., ) bias the proposal.
$ARGUMENTSskins continue用户希望在指定的游戏(若未给出路径则为当前目录)中添加可授权解锁功能。路径后的可选提示标记(如)会影响提案方向。
$ARGUMENTSskins continueStep 1: Understand the game
步骤1:了解游戏
- Read — detect engine (
package.json→ Phaser,phaser→ Three.js).three - Read ,
src/core/Constants.js,src/core/EventBus.js.src/core/GameState.js - Read to find
src/main.jsand the orchestrator entry point.window.render_game_to_text() - Read at the project root if it exists (written by the
progress.mdpipeline)./make-game - Read the primary scene/system files to understand the core loop.
Then tell the creator one sentence:
The core loop is— I will not gate it. Gateables will be additive features that layer on top.<verb>
- 读取——检测引擎(
package.json→Phaser,phaser→Three.js)。three - 读取、
src/core/Constants.js、src/core/EventBus.js。src/core/GameState.js - 读取以找到
src/main.js和编排器入口点。window.render_game_to_text() - 若项目根目录存在(由
progress.md流水线生成),则读取该文件。/make-game - 读取主要场景/系统文件以理解核心玩法循环。
然后告知创作者一句话:
核心玩法循环是****——我不会锁定它。可授权解锁功能将是叠加在核心玩法之上的新增功能。<动作>
Step 2: Propose features
步骤2:提出功能建议
Generate 2–3 candidate gateables at silver and gold tiers anchored in the five principles. Present as a Markdown table:
| Feature | Tier | Entitlement key | What it adds | Locked path | EventBus events | GameState additions |
|---|---|---|---|---|---|---|
| Skin picker | silver | | 5 cosmetic variants via a picker on GameOverScene | Default skin only; button greyed out | | |
| Continue after death | silver | | One continue per session offered on death | No continue prompt; immediate restart | | |
| Daily challenge mode | gold | | Unique seeded run each day with its own leaderboard | No daily challenge menu visible | | |
Anchor picks in the principles. Reject any suggestion that gates the core loop. Never propose bronze-tier features — bronze is the default everyone gets. Prefer cosmetic > convenience > bonus > persistence for short-session games; flip the order for long-form.
In interactive mode (user-invoked skill): wait for creator confirmation before implementing. Let them drop, swap, or tweak suggestions.
In pipeline mode (called from Step 1.25): auto-pick the top 2–3 and continue without prompting.
/make-game基于五项原则,生成2-3项候选的白银和黄金层级可授权解锁功能。以Markdown表格形式呈现:
| 功能 | 层级 | 权限Key | 新增内容 | 锁定路径 | EventBus事件 | GameState新增字段 |
|---|---|---|---|---|---|---|
| 皮肤选择器 | silver | | 在GameOverScene中添加包含5种外观变体的选择器 | 仅显示默认皮肤;按钮置灰 | | |
| 死后续玩 | silver | | 每次死亡后提供1次续玩机会 | 无续玩提示;立即重启 | | |
| 每日挑战模式 | gold | | 每日提供独特的随机种子关卡及专属排行榜 | 不显示每日挑战菜单 | | |
基于原则选择功能。拒绝任何锁定核心玩法循环的建议。绝不提出青铜层级的功能——青铜是所有用户默认获得的层级。对于短会话游戏,优先选择外观类>便利类>奖励类>持久化类功能;长流程游戏则顺序相反。
交互模式(用户调用技能): 在实现前等待创作者确认。允许他们删除、替换或调整建议。
流水线模式(由步骤1.25调用): 自动选择排名前2-3的功能并继续执行,无需提示。
/make-gameStep 3: Implement
步骤3:实现
Follow this order strictly:
3a. Create — the single capability-check seam:
src/systems/Entitlements.jsjs
// src/systems/Entitlements.js
// Single capability check for all gateable features.
// Returns false by default — every gateable must degrade cleanly when locked.
// Wire this to your monetization layer (sub.games, Play.fun, custom paywall)
// by replacing the body with real checks. See `/monetize-game` or `/subgames`.
export function isEntitled(key) {
// TODO: wire to monetization layer.
return false;
}3b. Add events to (append-only, form).
src/core/EventBus.jsdomain:action3c. Add state fields to . Update to preserve persistent fields (e.g., , ) and clear transient ones (e.g., , ).
src/core/GameState.jsreset()unlockedSkinsbonusModeUnlockedusedContinuecontinueOffered3d. Add constants to under a new section (skin list, continue cooldown, bonus mode config, etc.).
src/core/Constants.jsGATEABLES3e. Create gateable modules in the existing subdirectories matching the game's layout:
src/- (Phaser scene or Three.js panel)
src/ui/SkinPicker.js src/systems/ContinueFlow.jssrc/systems/BonusMode.js- etc.
Each gateable's entry point calls and branches:
isEntitled(key)js
import { isEntitled } from '../systems/Entitlements.js';
function openSkinPicker() {
if (!isEntitled('premium_skins')) {
// Locked path: greyed-out button with lock icon, no picker opens.
// Default skin remains selected. Game continues normally.
return;
}
// Entitled path: open the picker scene.
scene.scene.launch('SkinPickerScene');
}Never create a pre-gameplay title screen or skin-picker-first flow. The template boots directly into gameplay. Gateable UI opens from pause menu, settings, or GameOverScene only.
3f. Update in additively — add new observable fields (, , ) without removing existing ones. This is load-bearing for AI test harnesses.
window.render_game_to_text()src/main.jsselectedSkincontinueAvailablebonusModeActive严格按照以下顺序执行:
3a. 创建——单一权限检查接口:
src/systems/Entitlements.jsjs
// src/systems/Entitlements.js
// 所有可授权解锁功能的单一权限检查接口。
// 默认返回false——所有可授权解锁功能在锁定时必须能平滑降级。
// 通过替换函数体为真实检查逻辑,将其对接至你的变现层(sub.games、Play.fun、自定义付费墙)。
// 请查看`/monetize-game`或`/subgames`。
export function isEntitled(key) {
// TODO: 对接至变现层。
return false;
}3b. 向添加事件(仅追加,采用格式)。
src/core/EventBus.jsdomain:action3c. 向添加状态字段。更新方法以保留持久化字段(如、)并清除临时字段(如、)。
src/core/GameState.jsreset()unlockedSkinsbonusModeUnlockedusedContinuecontinueOffered3d. 向添加常量,新增章节(皮肤列表、续玩冷却时间、奖励模式配置等)。
src/core/Constants.jsGATEABLES3e. 在现有子目录中创建可授权解锁功能模块,匹配游戏的目录结构:
src/- (Phaser场景或Three.js面板)
src/ui/SkinPicker.js src/systems/ContinueFlow.jssrc/systems/BonusMode.js- 等等
每个可授权解锁功能的入口点都会调用并分支处理:
isEntitled(key)js
import { isEntitled } from '../systems/Entitlements.js';
function openSkinPicker() {
if (!isEntitled('premium_skins')) {
// 锁定路径:按钮置灰并显示锁定图标,不打开选择器。
// 仍选择默认皮肤。游戏正常运行。
return;
}
// 有权限路径:打开选择器场景。
scene.scene.launch('SkinPickerScene');
}绝不要创建游戏开始前的标题界面或先显示皮肤选择器的流程。模板直接进入游戏玩法。可授权解锁功能的UI仅能从暂停菜单、设置界面或GameOverScene打开。
3f. 增量更新中的——添加新的可观察字段(、、),不要删除现有字段。这对AI测试工具至关重要。
src/main.jswindow.render_game_to_text()selectedSkincontinueAvailablebonusModeActiveStep 4: Verify
步骤4:验证
- clean.
npm run build - and play with
npm run devreturningisEntitled(default). Core loop must feel identical to pre-skill state. If anything feels broken or missing, you gated the core loop — revert and revise.false - Temporarily edit to
Entitlements.jsfor all keys. Confirm each feature activates correctly. Revert.return true; - If exists and snapshots
tests/via exact equality (render_game_to_text()), update baselines — field additions are intentional. If tests usetoEqual, no update needed.toMatchObject - Append a section to
## Gateablesat the project root with:progress.md- Features added (name + tier + entitlement key)
- EventBus events added
- GameState fields added (marked as persistent or transient)
- Constants keys added
- Locked-path description (one line per feature)
- 编译正常。
npm run build - 运行并在
npm run dev返回isEntitled(默认状态)下游玩。核心玩法循环必须与使用该技能前的状态完全一致。如果任何内容出现故障或缺失,说明你锁定了核心玩法循环——回滚并修改。false - 临时编辑使其对所有key返回
Entitlements.js。确认每个功能都能正确激活。然后恢复原代码。true; - 若存在目录且通过精确相等(
tests/)快照toEqual的输出,则更新基准线——添加字段是有意为之。若测试使用render_game_to_text(),则无需更新。toMatchObject - 在项目根目录的中追加
progress.md章节,包含:## 可授权解锁功能- 添加的功能(名称+层级+权限Key)
- 添加的EventBus事件
- 添加的GameState字段(标记为持久化或临时)
- 添加的常量Key
- 锁定路径描述(每项功能一行)
Troubleshooting
故障排除
Feature works when entitled but the game breaks when locked
有权限时功能正常,但锁定时游戏出现故障
Cause: You gated part of the core loop, or the locked path is incomplete.
Fix: Revert. The locked path must produce normal-feeling gameplay. Test by running with returning — if anything is missing or broken, revise.
isEntitledfalse原因: 你锁定了部分核心玩法循环,或锁定路径不完整。
修复: 回滚。锁定路径必须让游戏运行正常。通过在返回的状态下运行游戏进行测试——如果任何内容缺失或故障,修改方案。
isEntitledfalseSnapshot tests fail after render_game_to_text
update
render_game_to_text更新render_game_to_text()
后快照测试失败
render_game_to_text()Cause: Tests use exact on output; you added new fields.
Fix: Regenerate baselines — the additions are intentional and backward-compatible for any consumer that tolerates extra keys.
toEqual原因: 测试使用精确的比对输出;你添加了新字段。
修复: 重新生成基准线——添加字段是有意为之,且对任何能容忍额外Key的消费者来说是向后兼容的。
toEqualSkin picker blocks first play
皮肤选择器阻碍首次游戏体验
Cause: Picker launches pre-gameplay.
Fix: Move entry point to a pause menu, settings screen, or GameOverScene. The template boots directly into gameplay and must continue to do so.
原因: 选择器在游戏开始前启动。
修复: 将入口点移至暂停菜单、设置界面或GameOverScene。模板直接进入游戏玩法,必须保持此逻辑。
Entitlements.js
already exists
Entitlements.jsEntitlements.js
已存在
Entitlements.jsCause: The skill has been run before, or a monetization layer is already wired.
Fix: Read the file. If it's a stub (), add new keys and continue. If it's wired to a real monetization layer, leave it alone and only add the new entitlement keys as new function branches.
return false原因: 该技能已运行过,或已对接变现层。
修复: 读取该文件。如果是占位符(),则添加新的key并继续。如果已对接真实的变现层,则保留原文件,仅添加新的权限Key作为新的函数分支。
return falseProposal over-gates or feels punishing
提案过度锁定或让玩家感到被惩罚
Cause: You picked features that restrict the free experience.
Fix: Principle 2 (additive over subtractive). Free players should never feel punished by the absence of a gateable. If removing a gateable makes the game feel worse for a free player, it's gating the wrong thing.
原因: 你选择了限制免费体验的功能。
修复: 遵循原则2(优先新增而非削减)。免费玩家不应因缺少可授权解锁功能而感到被惩罚。如果移除某项可授权解锁功能会让免费玩家的游戏体验变差,说明你锁定了错误的内容。
Output
输出内容
Tell the user:
- What was added — list each gateable (name, tier, entitlement key)
- The single wiring seam — point at and explain: "Flip
src/systems/Entitlements.jsto returnisEntitled(key)for a key to activate that feature. Wire it totrue(Play.fun) or/monetize-game(subscription) next."/subgames - How to test — "Run and play. Everything should feel normal (all gateables locked by default). Edit
npm run devtoEntitlements.jstemporarily to see features light up."return true; - Next step — suggest or
/monetize-gameas appropriate./subgames
告知用户:
- 已添加内容——列出每项可授权解锁功能(名称、层级、权限Key)
- 单一对接接口——指向并说明:“将
src/systems/Entitlements.js修改为对指定key返回isEntitled(key)即可激活该功能。下一步可将其对接至true(Play.fun)或/monetize-game(订阅)。”/subgames - 测试方法——“运行并游玩。所有内容应运行正常(默认状态下所有可授权解锁功能均锁定)。临时编辑
npm run dev使其返回Entitlements.js以查看功能激活效果。”true; - 下一步建议——根据情况建议使用或
/monetize-game。/subgames
Example Usage
示例用法
Default proposal in the current game directory
当前游戏目录下的默认提案
/scaffold-gateablesResult: reads the game, proposes 2–3 gateables, implements them after confirmation. Creates , new UI modules, new events and state. Game feels unchanged until the entitlement seam is flipped.
Entitlements.js/scaffold-gateables结果:读取游戏内容,提出2-3项可授权解锁功能,确认后实现。创建、新的UI模块、新事件和状态。在权限接口未修改前,游戏体验无变化。
Entitlements.jsBiased proposal with hints
带提示的定向提案
/scaffold-gateables skins continueResult: proposal biased toward a skin picker and a continue-after-death flow. Other suggestions still possible if they fit the game better.
/scaffold-gateables skins continue结果:提案偏向皮肤选择器和死后续玩流程。如果其他建议更适合游戏,仍可提出。
Explicit project path
指定项目路径
/scaffold-gateables ./examples/flappy-birdResult: operates on the given directory rather than the cwd.
/scaffold-gateables ./examples/flappy-bird结果:在指定目录而非当前工作目录中操作。
Tips
提示
Run this once per game. If you later want to add more gateables, usefor specific additions or run this skill again — it detects existing/add-featureand only appends new keys.Entitlements.jsIntegration comes next:wires Play.fun points to gateables via/monetize-game;Entitlements.js(from the/subgamesrepo, separate install) wires subscription tiers. Either way,subdotgames/skillsis the only file that needs to change to turn gateables on.Entitlements.js
每个游戏运行一次该技能。如果之后想添加更多可授权解锁功能,使用添加特定功能,或再次运行该技能——它会检测已存在的/add-feature并仅追加新的key。Entitlements.js下一步是集成:通过/monetize-game将Play.fun积分对接至可授权解锁功能;Entitlements.js(来自/subgames仓库,需单独安装)将订阅层级对接至可授权解锁功能。无论哪种方式,只需修改subdotgames/skills即可启用可授权解锁功能。Entitlements.js