开工包

做作品之前把这一份交给 AI,之后你不用再跟它交代平台的事。 这是一个网址,不是某台电脑上的文件 —— 谁的电脑、哪个 AI 都能用。

怎么用

把这句发给 AI:

读 https://gudao.games/kit.txt ,然后我想做<一句话说你要什么>

要自检和上传的工具,还是在电脑上的 gamehub/kit/ 里 (check.py / upload.py)。 不装工具也能交作品:直接用投稿页,单个 html 和整包 zip 都收。

鼓捣星球 · 开工包

第零步:先让手上真的有一个 index.html

这是给你本人看的。现在不用懂代码,不用装 Python,也不用打开黑色窗口;每一步看到“成了”再往下。

  1. 找到 AI。 点任务栏上的 Edge 或 Chrome;找不到就点任务栏上的 Windows 四格“开始”按钮,在搜索框输入 Edge,再点“Microsoft Edge”。看到浏览器后,点顶部标签旁的“+”新开一页,再点最上方的长条地址框,输入 kimi.comdoubao.comchat.deepseek.comchatgpt.com,按回车,任选能打开的一个。若出现“登录/注册”,请家长帮你。看到能输入消息的大框,成了。
  2. 把开工包给它。 点消息框旁的“+”、回形针或“上传文件”;在弹窗左边点“下载”或“桌面”,点 开工包.md,再点“打开”。看到消息框旁出现文件名后,点消息框输入 请先读完这份开工包,读完告诉我。,点发送箭头。找不到文件就点浏览器顶部原来的文档标签(或任务栏上的文档图标),点正文,按住 Ctrl 依次按 AC;点浏览器顶部的 AI 标签,点消息框,按住 CtrlV,再点发送。看到发出的文件卡片或以“鼓捣星球 · 开工包”开头的长文,并收到 AI 回话,成了。
  3. 告诉它做什么。 点消息框,照抄:我想做一个小猫接星星的小游戏,用方向键移动,接到星星加分。请按照开工包做,给我完整、不省略的 index.html;第一行是 <!DOCTYPE html>,最后一行是 </html>,全部放在一个 HTML 代码框里。 点发送箭头。看到代码框的开头和结尾都对,成了。
  4. 变成电脑文件。 点代码框右上角“复制”或两个重叠方块;看到“已复制”或小勾,成了。点任务栏上的 Windows 四格“开始”按钮,在搜索框输入“记事本”,再点“记事本”;点白色空白处,按住 CtrlV,看到代码出现。点左上角“文件”→“另存为”,左边点“桌面”;在“文件名”框输入 index.html,把“保存类型”选成“所有文件(.)”,编码选 UTF-8,点“保存”。

最后判据: 按住键盘上的 Windows 徽标键,再按 D;看到桌面后双击 index.html。如果弹出“选择打开方式”,点 Edge 或 Chrome,再点“确定”。浏览器显示游戏画面,而不是记事本或一页代码,这一步才真的成了;若打开记事本,按第 4 步重新另存。


把这一整份粘给 AI,或者让它读这个文件。之后你不用再交代平台的事。

这份东西是给你省事的,不是来管你的。 八成篇幅在讲"这个站给你什么",只有最后三条是真不许 —— 那三条要么有血的教训,要么是法律。

给 AI 读者的三句话,读完再往下:

  1. 这份文档里的东西分三层力度:【红线】是铁律,就是第二部分那三条;【事实】是平台环境的物理现实,改不了,只能绕;【建议】是"通常这么干好",不是要求。
  2. 任何一条【建议】和"作品本来该有的样子"冲突时,以作品为准,拿不准就问用户。不要为了满足文档里的某一条,把作品改造成另一个东西。
  3. 你(AI)见不到站长。所有需要站长办的事 —— 加公共库、聊联机、特殊要求 —— 统一写进上传时的 --notes,并且告诉用户"这句话请转给站长"。

一句话

鼓捣星球是个作品站,逛的人里很多是小学生。你做的东西会被放进作品页的一个 iframe 里跑,点开就能玩。

想做多大做多大。多文件随便用。用什么引擎都行。反过来也一样 —— 一个 60 行的换算器和两万行的游戏,在这个站上是平等的作品。

站上现在 88 件作品,一半以上是「用的」不是「玩的」 —— 汉字、口算、错题本、元素周期表这些。工具和游戏一样正经,别以为这儿只收游戏。

两件你该知道的事:

  1. 站上有个「同题竞技」区 —— 同一道题让不同的 AI 各做一遍并排放着。霓虹突击那道题现在有 11 个 AI 的答卷你的作品有可能被拿去这么比。
  2. 现在最缺什么(实话): 学习工具官方已经供得很全,不缺;真缺的是"一两个下午能做完、但有始有终"的中小型游戏,以及两个人一起玩的东西。你想投什么都收,但知道缺口在哪对你有用。 > 说清楚「两个人一起玩」今天能做到哪一步: > 只能是同一台电脑、两人分键盘(一人 WASD 一人方向键那种)。 > 联机还没有 —— /net.txt 是草案,平台这边还在做,作品这边一行都不用写。 > 手机上也做不了双人 —— 虚拟手柄只有一套,两个人没法各拿一个。 > 往联机或者手机双人的方向做,今天一定白做。

第一部分 · 你有什么

1. 体量不限,小体量也不心虚

站上现在正跑着的东西长这样:

作品形态
真理单个 html,21021 行
NO HUMAN THERE一个目录,src/ 底下 22 个 js
PVZ · Cocos 重制版Cocos 引擎的构建产物,32 MB
方块兄弟一个目录,5.5 MB 素材
汉字学习助手单个 html + 3755 个笔画数据文件,纯 DOM,一行 canvas 都没有
骰子概率单个 html,几百行,一个下午就能做完

没有"必须单文件"这回事。 一个目录扔进去、内部用相对路径,就能跑。

但入口文件必须叫 index.html,而且要放在作品文件夹的最外面一层。这里的“包”就是你准备上传(或压成 zip)的作品文件夹;“根目录”就是双击打开它后,现在看到的这一层。上传时,机器只在这一层找 index.html,找不到就会拒收。如果作品只有一个文件,就直接交名叫 index.html 的那个文件,不用再套文件夹。

对照下面两张图。文件名不必和图里一模一样,位置要一样。图里的 / 只表示“这是文件夹”,├──└── 只是画出来的连接线,不是文件名的一部分。

✅ 对:打开“我的游戏”后,这一层就有 index.html

我的游戏/                 ← 这个文件夹就是要上传的“包”
├── index.html             ← 入口在最外面一层
├── game.js
└── images/
    └── cat.png
❌ 错:打开“我的游戏”后,这一层只有另一个文件夹

我的游戏/                 ← 这一层不能当作上传的“包”
└── 我的游戏-v1/           ← 最常见的错:外面又多套了一层
    ├── index.html         ← 机器在外面那层找不到它
    ├── game.js
    └── images/
        └── cat.png

按下面检查,不用打开命令行。每一步都要先看到最右边写的“成了”,再做下一步。 AI 只给了 index.html 这一个游戏文件,才叫“单文件作品”;只要还有图片、声音、 .js 文件或任何文件夹,就是“多文件作品”。在“下载”或“桌面”里看到照片、作业等别的文件时,不要按 Ctrl+A,更不要把整层都压进 zip。

这一步点哪里在哪打字看到什么算这一步成了
1. 找到游戏文件点任务栏上的黄色文件夹。找不到就点 Windows 四格“开始”按钮,然后直接在键盘打字;窗口打开后,左边先点“下载”,没看到游戏再点“桌面”。左边没有这两项,就点“此电脑”,再双击“下载”或“桌面”找不到黄色文件夹时,点“开始”后直接输入 文件资源管理器;即使没看到输入框也可以打字。看到搜索结果后点“文件资源管理器”窗口里能看到刚拿到的游戏文件、游戏文件夹或 .zip;一个都没看到就还没成,不要猜
2. 显示真正的完整文件名点窗口顶部“查看”→“显示”→“文件扩展名”;如果“查看”下面直接有“文件扩展名”,就点它并打勾这一步不用打字文件名末尾显示出 .html.txt.js.zip 等真正的结尾。这时才看得出一个看似叫 index.html 的文件,会不会其实叫 index.html.txt
3. 如果拿到的是 zip,先解压文件名末尾不是 .zip 就直接做第 4 步;是 .zip 就用鼠标右键点它,再点“全部提取…”或“全部解压缩”,在弹窗里点“提取”这一步不用打字,保存位置保持弹窗原样原来的 .zip 旁边多出一个末尾没有 .zip 的黄色文件夹;双击这个黄色文件夹后能看到游戏文件
4. 如果游戏文件散在别的文件中,先单独装好已经打开一个只装游戏文件的黄色文件夹,就直接做第 5 步。如果游戏文件和照片、作业等混在“下载”或“桌面”,不要选全部:点刚才拿文件用的 AI 网页或应用,再点消息框。AI 回答后回到文件资源管理器,在空白处点鼠标右键→“新建”→“文件夹”;按住 Ctrl,只逐个点中 AI 列出的文件,按住 Ctrl 再按 X;双击新文件夹,在空白处按住 Ctrl 再按 V在 AI 消息框输入 请把你刚才给我的这个游戏的全部文件名逐行列出来,不要漏掉图片、声音和文件夹。 并发送;新文件夹的名字输入 我的游戏,按回车打开的“我的游戏”里只看到 AI 列出的游戏文件,没有照片、作业等别的文件。AI 如果说不确定,就还没成,不要移动或上传,找家长或老师帮忙
5. 找到真正的最外面一层看当前窗口:如果这一层只有另一个文件夹,就双击里面那个文件夹;如果进去后还是只有一个文件夹,就再双击,直到这一层能看到 .html 文件。不要搬文件,也不要删除外面的文件夹这一步不用打字当前这一层能直接看到至少一个 .html 文件,而不是必须再双击文件夹才能看到;从现在起,这一层就是你的作品文件夹最外层
6. 认准入口网页如果这一层已经有完整文件名正好是 index.html 的文件,就点一下它。如果没有,哪怕只有一个别的 .html 也不要猜:点刚才使用的 AI 对话,再点消息框;AI 回答后,点任务栏黄色文件夹回到作品文件夹,再点它说的那个文件需要问时,在 AI 消息框输入 请只告诉我这个游戏用来打开游戏的入口网页的完整文件名。,再点发送箭头只有一个入口文件被选中;它要么本来就完整显示为 index.html,要么完整文件名和 AI 回答一字不差。对不上就还没成,不要改名
7. 改成真正的 index.html如果选中的文件已经完整显示为 index.html,不要改,直接做第 8 步。否则用鼠标右键点它;看到文字“重命名”就点,只有小图标时把鼠标停在图标上,看到“重命名”再点;仍找不到就点“显示更多选项”→“重命名”。名字变成输入框后,按住 Ctrl 再按 A,把包括 .txt 在内的整个旧名字全选中在变成输入框的文件名里输入 index.html,按回车;如果 Windows 问“更改扩展名可能导致文件不可用”,点“是”在已经显示扩展名的情况下,完整文件名正好是 index.html,末尾没有第二个 .txt
8. 自己验入口如果文件资源管理器不在最前面,点任务栏上的黄色文件夹;在作品文件夹最外层快速双击 index.html。出现“选择打开方式”时,点 Edge 或 Chrome,再点“仅一次”或“确定”;如果打开的是记事本,就关掉记事本,右键点 index.html→“打开方式”→Edge 或 Chrome这一步不用打字浏览器打开并显示你的游戏,不是记事本、空白页或一页代码。看到游戏,入口的名字和位置才真的对了;没看到就先别上传
9. 多文件作品压成 zip单文件作品不做这一步。多文件作品点任务栏黄色文件夹回到刚才认准的作品文件夹;确认窗口里没有照片、作业等别的文件后,点任意一个游戏文件,按住 Ctrl 再按 A;右键点任意一个被选中的文件,有“压缩为 ZIP 文件”就点它。没有时点“显示更多选项”→“发送到”→“压缩(zipped)文件夹”;菜单里直接有“发送到”就直接点新 zip 的名字变成输入框时输入 我的游戏.zip,按回车同一窗口里出现完整文件名为 我的游戏.zip 的新文件;没有出现就还没成
10. 再验最终的 zip单文件作品不做这一步;多文件作品快速双击第 9 步出现的 我的游戏.zip,打开后不要先双击任何文件夹这一步不用打字在 zip 当前这一层的文件列表里能直接找到 index.html,就是对的;如果必须先双击某个文件夹才能找到,就是错的,回到第 5 步重新认最外层

站上确实有叫 大厅.htmltruth_survival.html 的作品 —— 那是站长手工登记进清单的老作品,走的不是投稿这条路。你走投稿,就按 index.html 来。

大小(服务端真实数字,不是建议值):

怎么交上限
单个 html8 MB
打成 zip24 MB;解开后 96 MB;最多 800 个文件;目录最多套 12 层;单个文件 24 MB

2. 第三方库:公共库在 /g/_lib/

不用自己打包一份,也不用去连 CDN(CDN 一定连不上,见第 6 节)。直接从平台的公共库引,路径写 /g/_lib/... 就行。

现在里面有这些,全都逐个验过线上真取得到:

版本格式体积路径(/g/_lib/ 下)
three.js(3D,最常用)r185.1ESM635 KBthree/three-0.185.1.module.js
three.js addons(examples/jsm 全量 425 个文件)r185.1ESM8.8 MBthree/addons-0.185.1/
Babylon.js(另一套 3D)6.49.0ESM4.2 MBbabylonjs/core-6.49.0.mjs
Phaser(2D 游戏框架,站上最对口)3.90.0ESM / UMD1.2 MBphaser/phaser-3.90.0.esm.min.js · phaser/phaser-3.90.0.min.js
PixiJS(2D 渲染器)8.20.0ESM / UMD800 KBpixijs/pixi-8.20.0.min.mjs · pixijs/pixi-8.20.0.min.js
p5.js(创意编程、画画、小玩具)1.11.13UMD1.0 MBp5/p5-1.11.13.min.js
matter.js(2D 物理)0.20.0UMD366 KBmatter-js/matter-0.20.0.js
cannon-es(3D 物理,常配 three)0.20.0ESM338 KBcannon-es/cannon-es-0.20.0.mjs
Tone.js(音乐合成,不用带音频文件)15.1.22UMD337 KBtone/Tone-15.1.22.js
howler.js(音频播放)2.2.4UMD105 KBhowler/howler-2.2.4.js
GSAP(补间动画)3.15.0UMD71 KBgsap/gsap-3.15.0.min.js
lil-gui(调参面板)0.21.0ESM / UMD57 KBlil-gui/lil-gui-0.21.0.esm.js · lil-gui/lil-gui-0.21.0.umd.js
canvas-confetti(撒彩带庆祝)1.9.4ESM / UMD24 KBcanvas-confetti/confetti-1.9.4.module.mjs · canvas-confetti/confetti-1.9.4.browser.js

ESM 用 importmap 引;UMD 直接 <script src>,拿全局变量。每个库的全局变量名、逐个用法、加入日期,都写在 /g/_lib/README.txt 里。

版本是钉死在文件名上的,以后加新版本是并排放、不覆盖 —— 你今天引的路径,明年还是这个东西。

three.js 的完整例子(addons 要两条映射,少一条就 import 不出来)

<script type="importmap">
{
  "imports": {
    "three": "/g/_lib/three/three-0.185.1.module.js",
    "three/addons/": "/g/_lib/three/addons-0.185.1/"
  }
}
</script>
<script type="module">
  import * as THREE from 'three';
  import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
  import { GLTFLoader }    from 'three/addons/loaders/GLTFLoader.js';
  // …你的场景
</script>

三件事:

顺带:three r152 之后颜色 API 换了,用 outputColorSpace / SRGBColorSpace,老的 outputEncoding / sRGBEncoding 已经删了,写了会静默不生效。

一个大坑:这些库"从文件加载资源"的接口,在本站用不了

作品的 CSP 是 connect-src 'none'fetch / XHR 一律发不出去,连同源的也不行(第 6 节里的那条事实)。GLTFLoader.load()p5.loadJSON()、Phaser 的 loader、 PIXI.Assets.load() 底层全是 fetch,在这儿会失败 —— 投稿检查器也会把 fetch/XHR 直接判成 stop。

逐库的具体写法在 /g/_lib/README.txt 的「这些库怎么加载资源」一节。

缺库还可以往里加。 这个目录只有站长能写,流程是:在 --notes 里写一句"我要 XX 库",站长放进去,之后所有作品都能用。

自己把库的代码打包进作品目录也完全可以,两条路都行。

⚠️ 用了公共库,就双击打不开了【事实】

这两条是打架的,选一条:

  • 双击 index.html 能开 → 别用 type="module",别引 /g/_lib/。库自己打包进目录,用普通 <script src="./xxx.js">
  • 用公共库或 ES 模块 → 双击必白屏,只能在站上开, 或者本地起个服务器(python -m http.server)看

为什么:双击是 file:// 协议。/g/_lib/… 会被解析成 file:///g/_lib/…, 找不到;而且 Chrome 不允许 file:// 页面加载 type="module" 的脚本。站上的「NO HUMAN THERE」就是这样,它双击打不开。

人审第 2 条写的是「双击能打开」—— 你要是走了公共库这条路, 上传时在 --notes 里说一句「用了公共库,请在站上验」,别让人当成坏作品退回。

3. 手柄和键位,站上有现成的四套

作品页会给手机用户自动生成一个虚拟手柄,也会把 Xbox 手柄翻译成键盘事件 —— 你的代码一个字都不用改,只要键位对得上其中一套:

方案名移动按键
contraWASD ↑↓←→(两套一起发)J 攻击 · K 跳 · Enter 开始 · R 重开
wasdWASD ↑↓←→(两套一起发)Space 动作 · Enter 开始 · R 重开
baoziWASD ↑↓←→(两套一起发)Z 跳 · X 冲刺 · H 大厅 · R 重开
darkWASD ↑↓←→(两套一起发)E 互动 · F 手电 · Shift 跑 · V 视角

移动键一次发两份:WASD 一份、方向键一份。【事实】(2026-08-23 起) 推一下摇杆往左,你的作品会先收到 KeyA(keyakeyCode 65), 紧接着收到一个 ArrowLeft(keyArrowLeftkeyCode 37)。所以只认 WASD 的作品和只认 ↑↓←→ 的作品,在手机上都能动

有两件事要留神:

  1. 同一个方向会来两个 keydown。 移动这种"按住就一直生效"的写法不受影响; 但你要是在 keydown 里做一次性动作(比如按一下上就跳一格、按一下左就换一格菜单),记得自己去重 —— 判断 if (已经按住了) return;,别一次算两下。
  2. 别拿方向键当别的用。 方向键和 WASD 在平台这一层是同一个动作, 你要是让 W 移动、↑ 翻菜单,手机上推摇杆会两件事一起发生。菜单和选关请用 Enter / 数字键,那几个键平台不会替你补发。

三样属性都带全【事实】——codekey、老式 keyCode 平台每次都发。你读哪一样都行(e.code === 'ArrowLeft' / e.key === 'a' / e.keyCode === 37), 不用为了兼容触屏专门写第二套判断。

照着用能省事。 键位实在对不上也没关系 —— 登记的时候可以给一份自己的按钮表(站上「包子塔」就是这么干的,它额外要 1~5 选关键)。

4. 作品页已经帮你包了一层

这些都不用你做

你只管把作品本身做好玩。

4.5 站上那层「小伙伴」:你不用做,但可以接【建议】

站上 46 个学生工具里有一层共用的东西:一只吉祥物、星星、连击、彩纸、合成音效、连续来玩天数、家长抽屉。孩子答对一题它就冒个星星,连对了会喊一声。

你不用做这些。 要是自己再造一套,两套会打架。

但它得知道你什么时候答对了

它不读你的代码,只盯 window.__ZG 上的三个数字:

你维护它意思
window.__ZG.answered一共答了几题
window.__ZG.correct答对了几题
window.__ZG.records存了几条记录(错题本、收藏这类)
window.__ZG = window.__ZG || {};
// 判完对错之后
window.__ZG.answered = (window.__ZG.answered || 0) + 1;
if (对了) window.__ZG.correct = (window.__ZG.correct || 0) + 1;

这三个数一变,它就有反应;不维护的话,那层还在,只是永远不动。

两句实话

  1. 这层不是平台自动给的。 它是后期用一个脚本注进那 46 个工具的源码里的。你新交上来的作品不会自动有 —— 但只要你维护了上面那三个数, 以后给你加上去就能直接用,不用改你的代码。
  2. 只有「用的」那类工具有这层,「玩的」没有 —— 游戏自己有分数和反馈, 再来一只吉祥物在旁边喊就吵了。

5. 存档用 localStorage(键名一定要加前缀)【事实】

iframe 开了 allow-same-originlocalStorage / sessionStorage 正常可用。存进度、存最高分、存设置,都行。(只存在玩家自己机器上,这也正是平台要的。)

⚠️ 全站 89 件作品共用同一个 localStorage

所有作品都从 w.weisitech.cn 这一个域出流,而 localStorage 按域隔离 —— 所以你和另外 88 件作品共用一个仓库,大约 5 MB,大家一起花。

三个后果:

  1. 你存 highscore,别人也存 highscore,互相覆盖
  2. 别的作品读得到你存的一切 —— 站上真出过这事:有个作品把密码原文存进去,同域的任何作品都能读走
  3. 容量是大家分的,别一个人塞满

做法:键名统一加自己作品的前缀,比如 sudoku_bestsudoku_mute别存任何不想让别的作品看见的东西 —— 那里没有隔离,只有约定。

6. 六个环境事实【事实】(不是规矩,是坑,知道了能少调半天)

这些是平台环境决定的,踩了不会有人骂你,但东西会不好使:

  1. alert() / confirm() / prompt() 用不了。作品跑在 iframe 里,沙箱没开 allow-modals,这三个会被静默吞掉 —— 不报错,就是什么也不发生。要提示就自己画一个 div。
  2. 键盘事件监听挂在 documentwindow 上。手机虚拟手柄和 Xbox 手柄的按键是 dispatch 到 document 上的(会冒泡到 window)。挂在 <canvas> 元素上收不到 —— 电脑上好好的,手机上按了没反应,就是这个原因。
  3. fetch / XMLHttpRequest / WebSocket 收不到东西。作品的 CSP 是 connect-src 'none',所有网络请求都会被浏览器拦掉。要用的数据直接写进代码里(JSON 内联、base64 内联),不要想着运行时去取。 > 3D 模型文件也算。 .glb / .gltf / 外部贴图靠 XHR 加载 —— > Babylon 的 SceneLoader、three 的 GLTFLoader 全都会被这条拦掉, > 哪怕模型文件就放在你自己的作品目录里。 > 两条路:模型用代码建(几何体拼),或者把模型内联成 data: URL。 > 这一条最容易踩,因为报错在库的内部,看着完全不像 CSP 的事。
  4. 想让作品能被录像,主画面用 <canvas>录像功能抓的是页面上最大的那个 canvas(宽高都要大于 50)。纯 DOM 做的作品照样能上架,只是录不了像。 > 但别为了这条把架构掰弯。 站上一半以上的东西是「用的」—— > 换算器、表格、汉字练习、单位转换这类。那些用 DOM 才对: > 表单能填、文字能选、读屏软件能念、手机键盘能弹出来。 > 硬塞进 canvas 全都丢了,换来一个没人会去录的录像功能。 > > 判断很简单:这东西是拿来玩的,还是拿来用的? > 玩的 → canvas 一般是对的。用的 → 老老实实用 DOM。
  5. window.open() 和表单提交用不了。沙箱没开 allow-popups,CSP 是 form-action 'none'。要跳转就在页面内自己做。
  6. 平台会往你的页面里注入一小段脚本(那个手柄/录像桥,带 data-zgames-bridge="1" 标记)。它插在 </body> 前,不影响你的代码,你也不用管它 —— 只是别自己写一个同名标记的东西。

7. 手机:是提示,不是要求【建议】

站上一多半作品标的是「⌨️ 电脑体验更佳」,包括 NO HUMAN THERE、禁区、 PVZ Cocos 版这些好东西。做不做手机适配你自己定,不做完全 OK。

只有一件事别做:明明手机上玩不了却勾了「手机可玩」。骗人才是问题,不适配不是。

如果想让它手机上好用,两条最省力的路:用上面那四套键位之一(虚拟手柄自动就有了),或者画面用 100% / vw / vh 而不是写死像素(竖屏就不会留黑边)。


第二部分 · 只有三条真不许【红线】

这一部分是铁律。踩了直接下架,不走验收流程。就三条。每条都写了为什么,因为不讲道理的禁令没人会守。


不许一 · 不连外部网站

运行的时候不许去别的网站取任何东西。

为什么

这条有真实教训:站上的 NO HUMAN THERE 一直是坏的,就因为它从 esm.sh 引 Babylon。 CDN 哪天变了、慢了、被墙了,作品就白屏 —— 而你本地测的时候一切正常,根本发现不了。它现在好了,改动只有一行:importmap 从 esm.sh 改成 /g/_lib/

一行的事,但没人提前说,就白坏了那么久。 这个包存在的全部理由就是这个。

另外两个理由:外部资源会把访客的 IP 和访问记录漏给第三方(这个站上是小孩),公网上还会拖慢加载。

而且它根本跑不起来。 作品的 CSP 是:

default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:;
style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:;
media-src 'self' data: blob:; font-src 'self' data:; connect-src 'none';
frame-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'

浏览器会直接拦掉外部请求。这不是我们的规定,是物理事实。

落到代码上就两句话

  1. 任何 http:// / https:// / // 开头的地址,都不该出现在会去取东西的位置 —— src / href / srcset / poster / @import / url() / importmap / <meta http-equiv="refresh">,一个都不行。
  2. fetch / XMLHttpRequest / WebSocket / EventSource / sendBeacon 一律别用 —— 连同源的 fetch('/什么路径') 也发不出去,connect-src'none'

不算数的两种:xmlns="http://www.w3.org/2000/svg" 这类 XML 命名空间(不是请求), data: / blob: 开头的(本来就是内联的)。

<a href="https://…"> 稍微特殊:它不会被 CSP 拦,但会把玩家从作品里带到站外去。那是「广告与导流」那条红线,同样不许。要给出处就用纯文字写。

替代方案(这才是重点)

你想要就这么做
用 Three.js / Babylon / 别的库/g/_lib/…;里面没有就跟站长说加一个
用某个库但等不及把库的 .js 下下来放进作品目录,相对路径引
网络字体下下来内联成 @font-face + base64,或者干脆用系统字体
图片 / 音频放进作品目录,或者内联成 data: URI
一份数据(关卡、词库、配方表)直接写成 js 常量或内联 JSON,别用 fetch 取
排行榜、联机现在做不了(connect-src 'none')。想做找站长聊

不许二 · 内容红线

这条是法律,不是审美。 踩了直接下架,不走验收流程。投稿、留言、愿望、昵称,全都算在内。

不行的说明
血腥暴力写实的血浆、断肢、虐杀、自残。打斗本身没问题 —— 魂斗罗打了三十年也没人说什么。问题是往写实和残忍上走
色情低俗裸露、性暗示、擦边。包括角色设计和文字
辱骂歧视骂人、地域黑、性别歧视、拿残障和长相开玩笑
赌博与诱导消费押注、下注、充值、能兑现的筹码、抽卡氪金引导、任何形式的收款入口。这个站不收一分钱,也不许有人在里面收。骰子、纸牌、转盘、概率抽奖这些玩法本身没问题 —— 出问题的是"押上东西赌输赢"和"引导花钱"
广告与导流作品里塞二维码、微信号、QQ 号、外部链接、"加我领资料"
抄袭侵权直接搬别人的作品、素材、音乐。借鉴玩法没问题,整段搬运不行
收集个人信息见下面「不许三」
违法与政治敏感不用多解释。另外不许自己画中国地图 —— 公开使用的中国地图要审图号,自绘属违规

恐怖类:不禁,但必须标

站里本来就有恐怖作品(黑暗生态NO HUMAN THERE禁区),做得还挺好。恐怖不是问题,不打招呼地吓人才是。

做法结果
投稿时那道题选「会」(命令行 --scary yes)正常上架,玩之前会看到提醒
看着轻松无害,玩到一半突然 jump scare下架。这是骗人,不是设计
血腥程度超过"氛围恐怖",往写实残忍走按上面的红线处理

判断标准很土但管用:你敢不敢让一个二年级的小孩,在没有大人陪着的时候点开它。


不许三 · 不许问真实姓名、学校、班级、手机号

这条也是法律 —— 站上是未成年人,未成年人个人信息受《个人信息保护法》和未成年人保护法网络专章单独保护。

不许在作品里问、收集、显示:

要区分玩家?用昵称,而且只存在本机(localStorage)。需要"输入你的名字"这种,写清楚"随便取一个就行"。

作品里也不要出现任何联系方式(手机号、QQ、微信号)—— 那既是这条,也是「广告与导流」那条。


第三部分 · 做完了怎么办

先自检一遍

在站长这台机器上(仓库就在本地):

python D:\ppgame\gamehub\kit\check.py 你的文件.html
python D:\ppgame\gamehub\kit\check.py 你的作品目录\

在别的电脑上(手里只有一个浏览器和一个 python):

# 把自检脚本抓下来,存成 check.py,然后照上面那样跑
curl -o check.py https://gudao.games/check.txt
python check.py 你的文件.html

它就是同一个文件,换了个后缀挂出来的 —— 站上不放行 .py, 所以线上那份叫 check.txt。内容一个字都没改。

连 python 都没有的话,照第二部分那三条自己核一遍也行 —— 自检脚本检的就是那三条,没有第四条。

它只检上面那三条。检出来会告诉你是哪一条、在第几行、怎么改

但过了这三条不等于能上架。 上架前站长还会按站上的《投稿规则》 (https://gudao.games/rules.html)人工看五条能不能跑:

  1. 不连外部网站(和上面第一条同一件事)
  2. 双击 index.html 就能打开
  3. 3 秒内能开始玩 —— 别一上来先看一页说明
  4. 控制台不许有红字(小 bug 没关系,报错刷屏不行)
  5. 是你自己做的(AI 帮忙没问题,说清哪个 AI 就行)

这五条不是禁令,是人审清单。 第 3、4 条 check.py 检不出来,但站长真的会看 —— Grok 4.6 指出"验收口径有两份",这一段就是为了补上它。

然后上传

完整说明:https://gudao.games/upload.txt

第一次投稿:直接用网页,不用 Python

这一步点哪里在哪打字看到什么算成功
1. 打开投稿页点浏览器最上面显示网址的长框输入 https://gudao.games/submit.html,按回车页面出现「投稿说明」和绿色的「🚀 提交,等待审核」
2. 登录或加入右上角已经是你的昵称就不用点;否则点「登录 / 加入」第一次用就在弹窗里填一个不是真名的昵称和密码,勾选守则后点「加入社区」;有账号就点「已有账号?登录」并填昵称和密码页面右上角显示你的昵称
3. 填作品信息依次点「作品名字」「用了哪个 AI」「制作心得」下面的框,再点「会」或「不会」在对应方框里填写;没用 AI 就写「纯手写」作品名字已经显示在框里,「会 / 不会」只有一个被选中
4. 选作品文件点「点这里选文件,或把 .html / .zip 拖进来」;在弹出的窗口里点你的文件,再点「打开」这一步不用打字:只有一个网页就选 .html;有图片、声音或多个文件就选整个作品的 .zip选文件的位置显示文件名和大小
5. 交上去点绿色的「🚀 提交,等待审核」这一步不用打字页面显示「✅ 交上去了!编号……,等待审核」;只有看到这句才算交成功

如果漏选「会不会突然吓人」,页面会显示「还有一题没选:这个作品会不会突然吓人?」; 这时作品没有交上去。 点选「会」或「不会」,再点一次「🚀 提交,等待审核」。

站长让你用 upload.py

这里的下载地址要站长确认。 我们查了本站公开文件清单、上传说明和已经构建好的网站文件,只找到 check.txtkit.txtupload.txt,没找到 upload.py 的公开下载地址。站长电脑里的 D:\ppgame\gamehub\kit\upload.py 在你家电脑上不存在; 没拿到脚本时不要猜网址,用上面的投稿页。

这条路只适合站长已经把投稿工具和投稿身份一起配好、而且电脑装了 Python 的人。 upload.pycheck.py 必须放在同一个文件夹里。多文件作品的整个目录放在这两个脚本旁边,不要把脚本放进作品目录里

这一步点哪里在哪打字看到什么算成功
1. 拿到工具点你平时和站长说话的聊天窗口里的输入框输入「请把 upload.pycheck.py 两个文件发给我」并发送站长发来名为 upload.pycheck.py 的两个文件
2. 放好工具分别点两个文件旁边的「下载」;保存到这样一个文件夹:单文件作品的 .html 在里面,多文件作品的整个目录在里面这一步不用打字打开这个文件夹时,能同时看到两个脚本和你的 .html 或作品目录
3. 打开命令窗口在文件资源管理器里打开这个文件夹,点窗口最上方显示文件夹位置的长框输入 cmd,按回车出现黑色窗口,最后一行以 > 结尾;下面的命令都在这里输入
4. 检查 Python点黑色窗口最后一行的 > 后面输入 python --version,按回车显示 Python 3.8 或更高版本;如果提示找不到 Python 或跳到应用商店,关掉黑窗,改用上面的投稿页
5. 上传仍点黑色窗口最后一行的 > 后面把下面对应的一整行输入进去,把文件名、目录名和作品名字换成你自己的,再按回车最后显示「✔ 交上去了,编号……」;这才表示已经进入待审队列

一句话版(作品会突然吓人就用 yes,不会就用 no):

如果黑色窗口出现 uid(输入时不显示):,说明投稿身份还没配好。不要填昵称、密码, 不要猜,也不要把 uid 发给 AI 或贴进聊天。 点黑色窗口右上角的 × 关掉它, 改用上面的投稿页;这一次还没有上传。

如果漏写 --scary,工具会显示「还有一题没回答」并立刻停下: 这一次没有上传,也没有进入待审队列。--scary yes--scary no 补回原来的整条命令,再把整条命令输入一次,不是只输入 --scary no

这题没有默认答案:别的孩子会看到你的作品,而会不会突然吓人只有作者本人知道, 平台不会替你猜。填 yes 不会让作品过不了审,只是会先提醒玩家。

--mobile 只在手机真能玩时加;--notes "给站长的话" 可以写缺库申请、联机想法、键位表或任何需要人工看一眼的事。封面和手机徽章都是可选步骤,不做也能投稿。

传上去只进待审队列,站上看不见。 站长在后台点「通过」后才会上架; 这条对所有人一样。


附:什么时候需要站长

怎么办
公共库缺库--notes 里说,同时先自带库上传(见第 2 节)
联机平台正在做,见 https://gudao.games/net.txt ;想接入就在 --notes 里说
排行榜平台不做全局排行榜,这是定过的。作品自己在 localStorage 里记最高分没问题
恐怖向不用找谁,投稿时那道题选「会」就行(命令行 --scary yes
其他一切"我不确定行不行"--notes 里问,比猜了被退回强

本文的三条红线出自站上的《投稿规则》(web/src/pages/rules.astro)与 server.py 的实际实现。规矩只有一份,改了那边这里要跟着改。