npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cael.ai/game-kit

v0.1.31

Published

Cael game host SDK: protocol, pack zip, scene session, and authored-layer ports.

Readme

@cael.ai/game-kit

在 Babylon.js Editor 中接入玩法、Play 验证,并导出 zip。

安装发布到 npm 的包。玩家订阅 zip 内容包。不要用 file: 指向本地仓库。

1. 安装

npm install @cael.ai/game-kit

使用场景或 React 壳时:

npm install react react-dom @babylonjs/core

使用表单入口时安装 @rjsf/utils。

2. 编辑器插件

project.bjseditor:

{
  "plugins": [{ "nameOrPath": "@cael.ai/game-kit/babylon-plugin" }]
}

用 Babylon.js Editor 打开工程。布局中出现 Cael · Sidebar 和 Cael · Inspector。

3. 玩法宿主场景

  1. 新建或打开玩法宿主场景。不使用 Editor 自带的 example / 演示场景。
  2. 删除模板自带的 ground / box / sky / 示例灯 / 示例相机。编辑导航使用 Editor preview 相机。
  3. 保存场景。

npm install 在工程根目录存在 project.bjseditor,且 src/scripts/cael-game-runtime.ts 不存在时,写入该文件。已存在则不覆盖。文件被删除后,插件再次执行同一安装脚本。不要手写该文件。

在 Editor 中:

  1. 图层面板选中 Scene 根。
  2. Inspector → Scripts → Add。
  3. 选择 scripts/cael-game-runtime.ts,保持 enabled。
  4. 移除 Editor 示例脚本(例如 scripts/box.ts)。
  5. 保存场景。

该脚本不静态 import kit 或项目玩法。一个项目只在一个玩法宿主场景上挂该脚本。

4. 场景与侧栏

| Scene 文件 | Cael · Sidebar 局面 / 表 | |---|---| | 地形、建筑、装饰、静态灯、环境 | 牌、可玩实例、玩法相机、玩法灯 |

静态节点在 Play 时留在同一 Scene。可玩的牌和玩法相机放在侧栏局面里。

5. 局面与资源

空局面使用 createEmptyGameShapeDocument(seed)(@cael.ai/game-kit/runtime),在侧栏填表、摆实例。

自带开局把局面 JSON 放在 fixtures/author-default-template.json。不使用 webpack import 加载该 JSON。没有该文件时 Play 使用空局面。

资源放在 public/game-assets/<目录名>/。Play 静态 Host 按目录扫描清单。

6. Play

点 Play 后:

  1. Scene 脚本 onStart 同步创建相机 cael-play-boot-camera。
  2. 插件生成 public/editor-play/runtime.js,并启动静态 Host http://127.0.0.1:39471。runtime.js 缺失、kit 版本变化,或 cael.gameplayBoot / cael.editorPlayScene 比该产物新时,插件重新构建。
  3. IIFE 在当前已打开的 Scene 上调用 bootGameHostSession。Stop 回到 edit,侧栏会话保留。

7. 玩法 boot

package.json:

{
  "cael": {
    "gameplayBoot": "src/lib/game/boot-gameplay.ts"
  }
}

该文件导出名称包含 boot 的函数。网页、Editor Play 和 zip 的 install() 调用同一函数。

7.1 配置表

功能表始终在侧栏。专属表写入 installGamePack 的 configAssetIds 后出现在侧栏。

import {
  installGamePack,
  listKitBaseConfigAssetIds,
} from "@cael.ai/game-kit/lib/game/game-type-profile"
import { GAME_CONFIG_ASSET_IDS } from "@cael.ai/game-kit/lib/game/game-asset-ids"

installGamePack("my-game", {
  configAssetIds: [
    ...listKitBaseConfigAssetIds(),
    GAME_CONFIG_ASSET_IDS.cardPacks,
  ],
})

已安装的包要改专属表时,调用 registerGameTypeExclusiveConfigAssetIds。功能表和项目设置保留,专属表被替换。

已有协议表只把 id 写入档案。新的列结构在 boot 里 registerGameConfigTable:assetId、definitionKey、行的 zod schema。登记后,侧栏和 game_config_read / game_config_write 使用这张表。默认 agentReadable / agentWritable 为真;关闭时传入 capabilities。

import { z } from "zod"
import { registerGameConfigTable } from "@cael.ai/game-kit/lib/game/game-table-registry"

registerGameConfigTable({
  assetId: "weather_table",
  definitionKey: "weatherRules",
  rowSchema: z.object({ id: z.string(), label: z.string() }),
})

installGamePack 与 registerGameConfigTable 的调用顺序不限。未调用 installGamePack 时,该表不进入空项目侧栏。

7.2 读表

系统读取当帧传入的 definitions。协议内的表使用 definitions.cardPacks.rows。registerGameConfigTable 登记的表使用 readConfigTableRows(definitions, definitionKey)。表数据留在 definitions。运行时 LLM 读写同一份 definitions。

7.3 命令

在同一份档案里写 commandKinds(kind + 文案)。侧栏列出这些指令。

setGameProjectRuntimePort 提供 reduceGameCommand 与 listGameCommandSuggestions。执行使用 Intent system:在 boot 里调用 registerGameIntentSystems(@cael.ai/game-kit/lib/game/game-type-pipelines)。后注册的替换先注册的。档案未打开 Intent 管线时,这组 system 不挂上。

commandKinds 的 kind 与运行时命令的 type 都是字符串。新指令写入档案、运行端口和 Intent system。

7.4 声音与后处理

调用一次 registerGameHostPresentation(@cael.ai/game-kit/gameplay)。runRenderFrame 在场景上下文齐全时调用该口。宿主内不调用 bind、sync、unlock、dispose、syncFrame。

帧顺序:

  1. bindSceneAudio:第一次,或资源缓存更换时。在此配置解析上下文,并按 definitions 预加载音效。
  2. syncAudioSettings:将 definitions.projectSettings.audio 应用到播放器。
  3. syncFrame({ advance: true }):推进依赖时间的后处理。
  4. stepSpatial:绘制前的项目空间步进。没有则省略。
  5. syncFrame({ advance: false }):用步进之后的局面投影后处理,不推进时间。
  6. 第一次指针按下时,kit 调用 unlockAmbient。卸下 Scene host 时调用 disposeAudio。

牌面、战斗等一次性音效在项目 system 里调用 gameAudioPlayer(@cael.ai/game-kit/components/game/game-audio-player)。

7.5 场景 system 与其它口

帧预算探针默认出现在监视里。项目阶段写在档案 customPerfMetricDefs,或用 registerGamePackCustomPerf 覆盖文案。采样打开时,用 measureCustomPerf(sessionKey, id, fn) 写入。id 为字符串。

在同一份 boot 里按需要注册:

| 口 | 作用 | |---|---| | setGameplayPipelineRegistrar | 向场景 pipeline 注册本项目的 Babylon system | | registerGamePackSettingsSections | 项目设置表的分区。未登记时只有字体、主题、画质 | | registerGameProjectFontDefaults | 项目字体。未登记时字体槽为 null | | registerDefaultNineSlice | 默认九宫格。未登记时没有内置贴图 | | setGameBoardSceneRootIds | 板场景根 id | | setGameWorldMutationHooks | 生成、销毁等写入副作用 | | setGameEcsWorldGameplayHooks | World 上的玩法读口 |

保存后点 Play。

8. Editor Play 场景投影

在 package.json 的 cael 中设置:

"editorPlayScene": "src/components/game/babylon/register-editor-play-scene.ts"

该文件导出 registerProjectEditorPlayScene,调用一次 registerEditorPlaySceneHost(@cael.ai/game-kit/gameplay)。IIFE 先调用 gameplayBoot,再调用该函数。

向宿主提供 registry、场景 system、局内 HUD。帧循环、指针、相机关闭和监视由 kit 执行。

局内键盘与 HUD 的文件路径由项目决定,由 registerProjectEditorPlayScene 交给宿主。示例工程使用同目录的 editor-play-shell.ts。

gameplayBoot 与 pack 入口不 import 该登记文件和 HUD。无场景投影时不设置 editorPlayScene。

9. 导出

原创导出生成一个游戏 zip,以及每个资源挂载各自的资源 zip。游戏 zip 包含:

| 路径 | 内容 | |---|---| | manifest.json | 包身份、原创 / 二创;资源包记录 id / download / sha256 / bytes | | game/template.json | 局面与配置表 | | game/gameplay.js | 玩法制品,调用 gameplayBoot |

资源字节在 <挂载 id>.zip。同一批资源文件两次导出,资源 zip 的 SHA-256 不变。玩法经包内 install() 注入。zip 内不包含 .ts。

game/gameplay.js 由 scripts/build-gameplay-pack.mjs 编译。入口默认 src/gameplay/pack-entry.ts,该文件只调用 boot。其它入口路径设置 cael.gameplayPackEntry。cael.gameplayPackExport 要求制品中出现 function <导出名>(。

package.json:

{
  "scripts": {
    "build:gameplay-pack": "node ./node_modules/@cael.ai/game-kit/scripts/build-gameplay-pack.mjs"
  }
}

编辑器导出调用同一脚本。工程内不放置 scripts/build-gameplay-pack.mjs。

Author 工程提供:

| 路由 | 响应 | |---|---| | GET /api/author/gameplay-module | 已编译的 game/gameplay.js | | GET /api/author/game-asset-roots | { roots: [{ bundleId, publicPath, displayName? }] } |

import { GamePackExportPanel } from "@cael.ai/game-kit/author"

<GamePackExportPanel sessionKey={sessionKey} />

面板中的目录写入资源 zip。导出时选择保存目录,游戏 zip 与资源 zip 写入该目录。网页没有目录选择时逐个下载。只要字节时调用 assembleOriginalGamePackZip,其中 resourcePacks 为独立资源 zip。无面板时调用 downloadAuthorFullPackZip。

资源分包在面板中勾选。槽 id 写入后保持不变。局面引用 { mount, path, kind }。二创不重打父包的 game/gameplay.js 和父包资源。

10. 网页播放

网页 Author 与广场播放调用同一个 gameplayBoot,再调用 bootGameHostSession(@cael.ai/game-kit/runtime)。

网页场景组件在 boot 里用 setHostedGameScene 注册。

没有 Editor Scene 时,用 AuthoredScenePort(@cael.ai/game-kit/authoring)把导出的 .babylon 挂到播放器已有 Scene。Editor Play 使用已打开的 Scene。

常见问题

| 现象 | 处理 | |---|---| | 没有 Cael · Sidebar / Inspector | project.bjseditor 挂上 @cael.ai/game-kit/babylon-plugin 后重启 Editor | | Play 黄条 plugin is not loaded | 同上 | | Play 为空场景 | 脚本挂在 Scene 根 且 enabled。控制台查看 [cael-game-runtime] | | No camera defined | Scene 根挂 cael-game-runtime | | Could not resolve "@cael.ai/game-kit/..." | Scene 脚本改为 kit 写入的 cael-game-runtime.ts | | Editor Play runtime is missing after build | 确认已安装 kit | | 改了玩法但 Play 仍是旧制品 | 删除 public/editor-play/runtime.js 后再 Play |

License

MIT