NUGANUGA Web SDK
你的游戏运行在 https://play.nuganuga.com 上的沙箱 iframe 里。SDK 是通往平台的唯一通道 — 认证、排名、分享、广告和统计都不需要你自己实现。
1. 引入 SDK
始终使用这个绝对路径。分发和版本管理由平台负责。
<script src="/sdk/nuga-sdk.js"></script>
<script src="./game.js"></script>2. 四个调用
const ctx = await Nuga.ready(); // 等待平台就绪
await Nuga.game.start(); // 玩家真正开始一局时
await Nuga.score.submit({ score }); // 每局只提交一个数值分数
await Nuga.game.finish(); // 平台绘制结果页面不要自己画结果页、重玩按钮、分享按钮或排行榜 — finish() 之后平台会为每款游戏渲染完全一致的界面。
3. 其他能力
Nuga.game.getContext();
Nuga.player.get();
Nuga.challenge.get();
Nuga.storage.get(key);
Nuga.storage.set(key, value);
Nuga.audio.setMuted(true);
Nuga.locale.get(); // 'en' | 'ko' | ...
Nuga.event.track('level_up', { level: 3 });
Nuga.on('pause', () => pauseLoop());4. 清单文件
放在包根目录的 nuga.json:
{
"schemaVersion": 1,
"name": "Reaction Hunter",
"slug": "reaction-hunter",
"description": "Click 10 targets as fast as possible.",
"rule": "Tap every target as fast as you can.",
"category": "REACTION",
"orientation": "PORTRAIT",
"duration": { "min": 5, "max": 30 },
"input": ["POINTER", "TOUCH"],
"ranking": { "type": "LOW_TIME", "unit": "ms" },
"entry": "index.html",
"locales": {
"ko": { "name": "리액션 헌터", "description": "10개의 타겟을 빠르게 클릭하세요." }
}
}排名类型:HIGH_SCORE, LOW_SCORE, LOW_TIME, HIGH_TIME, CUSTOM。分类:REACTION、TIMING、ACCURACY、MEMORY、PUZZLE、LUCK、ARCADE。
5. 沙箱规则
违反其中任何一条的包,都会在到达玩家之前被静态校验拒绝:
- 禁止外部 URL — 不能用 CDN、网络字体或远程图片。所有资源都要打包进来。
- 禁止
eval、new Function、document.write和document.cookie。 - 禁止自建网络通信:指向绝对 URL 的
fetch、XMLHttpRequest、WebSocket和 Service Worker 会同时被 CSP 和静态校验拦截。 - 禁止顶层跳转和弹窗。
- 包体小于 5 MB;微型游戏建议控制在 1 MB 以内。
- 至少调用一次
Nuga.score.submit()— 产生不了分数的游戏无法进入排名。 - 平台外壳是固定的:index.html、外壳样式表和 game.js 中的框架必须保持不变。只有 run() 主体和 #field 样式可以修改。
6. 分数会被服务端验证
每一局都会分配一个服务端会话。你的游戏看不到会话令牌 — 由平台外壳持有并代为提交 — 服务端会先比对实际耗时和清单中声明的范围,然后才让成绩进入排行榜。
你还可以做得更好。用服务端下发的种子生成随机数,并记录实际发生的过程,服务端就会依据这些事件重新计算分数,而不是相信你上报的数字。记录无法支撑的成绩会被直接拒绝。
const rng = Nuga.random(); // 由服务端播种 — 与 Math.random() 不同,可复现
const target = rng.int(0, 8);
Nuga.replay.record('hit', 172); // 一条与分数相关的事件,每局最多 400 条在 nuga.json 中声明玩法机制即可启用。不声明也能进入排名,只是仅有时长和范围校验。
"verification": { "kind": "REPLAY_V1", "mechanic": "REACTION",
"params": { "rounds": 5 } }7. 发布
压缩包的根目录(不是外层文件夹),然后在创作者后台上传。静态校验、构建、运行时、响应式、玩法和安全测试都会自动执行,全部通过后即可发布。