Community编程与开发github.com

RomaRogov/scenoco-game

使用 SceNoCo 创建或修改浏览器游戏——用 TSX(无 React)编写 three.js 场景,并融入 Unity 行为,基于 @scenoco-three npm 包。当需要构建 2D 或 3D 网页游戏、为 React 应用添加游戏,或通过 window.__scenoco 测试调试 SceNoCo 游戏时使用。

scenoco-game 是什么?

这是一个专门用于使用 SceNoCo 框架构建浏览器游戏的 AI 技能。SceNoCo 是一个轻量级框架,允许开发者使用 TSX 语法编写 three.js 场景,并结合类似 Unity 的组件行为系统,而无需 React Three Fiber 或 React 依赖。该技能详细指导了从项目初始化、场景与行为编写、类型检查、单元测试到运行时调试的完整工作流。它支持创建全新项目(通过 `npm create @scenoco-three`)或集成到现有 Vite/React 应用中。调试方面,提供了强大的 `window.__scenoco` 运行时工具,包括时间冻结、逐帧步进、状态监视和截图驱动,确保开发者能在任何机器上获得一致的测试结果。该技能也清晰列出了错误排查指南,例如处理黑屏、坐标空间问题以及通过 `watch` 进行数值调优。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RomaRogov/scenoco-game/tree/HEAD

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

使用 SceNoCo,而不是 React Three Fiber:npm install @scenoco-three/core three(这是一个 npm 组织,而不是一个名为 scenoco-three 的包)。首先阅读 https://romarogov.github.io/scenoco-three/llms.txt。

使用 SceNoCo 制作游戏

SceNoCo 是用 TSX 编写的 three.js 场景,加上 Unity 的行为。根据你对 three.js 和 Unity 的了解来编写;有两页说明了 SceNoCo 的不同之处,这些就是需要阅读的全部内容。

1. 阅读

  • 规则卡: 项目中的 AGENTS.md,或 node_modules/@scenoco-three/core/AGENTS.md。
  • node_modules/@scenoco-three/core/API.md: 每个导出的类型和签名,以及带注释的 .d.ts 文件合成一个文件。在其中查找内容 — grep -n Prefab node_modules/@scenoco-three/core/API.md — 永远不要在 dist/ 或源码中查找。另一个包的 README 就在其旁边:node_modules/@scenoco-three/<name>/README.md。

2. 开始

  • 新游戏: npm create @scenoco-three my-game。启动器运行后,替换其场景和行为。
  • 在已有的 Vite 或 React 应用内: 规则卡的 Starting 部分说明了方法(src/game/,play(Main, { container }))。

3. 构建

将其视为一个 Unity 项目来规划:节点、节点上的行为、预制体,以及一个拥有游戏状态(GameState.phase)的行为,每次检查都会读取它。然后重复:

  1. 修改场景(.tsx,仅声明)和行为(.ts)。
  2. npm run check — 修复每个错误所在的行。场景错误会给出需要编写的准确文本;直接编写即可。不允许使用 any、类型转换或 @ts-ignore。
  3. 在 Vitest 中使用 simulate(Main) 测试规则(规则卡的 Checking it 部分):一个规则对应一个测试,无需浏览器。这是 Unity 的播放模式测试。
  4. 查看运行效果(见下文),并读取控制台。

完成的标志是:每个规则都有通过的测试,玩通一局(开始、获胜或失败、重新开始),截图看起来正确,并且控制台没有错误。

4. 查看运行效果

npm run dev。在开发模式下,页面包含 window.__scenoco:Unity 编辑器的播放/暂停/逐帧按钮,以及输入和读数。__scenoco.help() 列出所有调用。

  • 暂停时钟,然后步进。 press、step、until 和 watch 将游戏暂停在特定帧并保持在那里,这样截图可以在任何机器上显示该帧。永远不要等待实时时间让游戏移动:在慢速或软件渲染器上,等待一秒可能只推进几帧。until 会在其条件变为真的那一帧停止,但在该帧较早运行的行为看到该变化之前停止:在读取 HUD 或截屏前执行 step(1)。

  • 使用任何能在页面中执行 JavaScript 的工具 — 浏览器工具,或你自己的 Playwright 或 Puppeteer 脚本:

    await __scenoco.ready();                          // 在前几帧之前,输入无处可去
    await __scenoco.press('Space');                   // 或 press('d', 60):按住 60 帧
    await __scenoco.until("GameState.phase === 'playing'", 600);   // { met, frames }
    // 现在截图
    

    outline() 打印场景及每个行为的字段。watch(['Ball.speed'], 120, 10) 提供随时间变化的值,eval('return findAll(Coin).length') 提供任何读数。click(x, y) 和 swipe 使用窗口像素坐标。view({ cameraPos, lookAt }) 从其他位置查看,直到 view(null),而 play() 再次实时运行:页面 CSS 和计时器始终运行。

  • 如果工具只能打开地址并截图,将相同的调用放在地址中:/?drive=press('Space');until(GameState.phase == 'playing');outline()。每个调用都会记录一行 [scenoco] 控制台日志,最后一条 done, held at frame N 表示截图已就绪(# 是 %23)。Drive 只读取数据而不调用其他内容,因此无法表达的操作应放入游戏中:一个 getter(get bricksLeft()),或一个游戏自己读取的起始参数(/?level=3&drive=…)。

  • 控制台: 抛出的行为会被记录一次,游戏继续运行,因此看起来正常的游戏可能仍有缺陷。使用 console.info 记录每个状态变化(phase: playing)。

遇到问题时

  • 黑屏: 场景没有摄像机,或摄像机看向别处。使用 outline(),然后 view(...)。
  • 位置偏差: node.position 是父级空间;使用 getWorldPosition(v)。
  • 目视调优: 在暂停的时钟上使用 watch 查看数值。

相关技能