Publishing
Third-party games are submitted as a zip build on the "Submit a game" page (/platform/submit/) and published to instfun.games after review. This page covers eligibility, packaging requirements, metadata format, the upload flow and review rules.
Eligibility
- You need a platform account with a bound email. The submit page uses your on-device SDK guest identity; if no email is bound, the page guides you through binding first (see the Integration guide).
- Uploading requires connectivity; without a bound email the server returns
EMAIL_REQUIRED. - Each account may upload at most 2 times per UTC day; exceeding it returns
RATE_LIMITED(the page shows the remaining quota; quota is consumed after all validations pass and is not refunded on failure). - The same
gameIdcannot be submitted again while a pending or approved submission exists (GAME_ID_CONFLICT).
Package requirements
Zip layout (files at the root; do not nest them one level deeper):
my-game.zip
├── index.html # game entry
├── game-info.json # metadata (required)
├── thumbnail.png # cover image, short side at least 512px
└── assets/... # other static assets| Requirement | Description |
|---|---|
| Entry file | index.html must be at the zip root and open directly under the hosted path |
| Metadata | game-info.json must be at the zip root, UTF-8 encoded, valid JSON, no larger than 2MB |
| Cover image | thumbnail.png, at least 512px on the short side |
| File types | Static files only; no server-side code, executables or runtime installation |
| Size | The zip must not exceed 30MB |
| Asset references | Use relative paths; do not rely on external CDNs or absolute root paths (games are hosted at instfun.games/play/{gameId}/) |
| Runtime | Runs in the browser; there is no access to Node.js or other local runtimes |
game-info.json fields
Start from the official template and fill in at least the default locale:
{
"gameId": "my-game",
"defaultLocale": "en",
"locales": {
"en": {
"name": "My Game",
"description": "One sentence about your game.",
"intro": "A short paragraph describing the core loop.",
"howToPlay": ["Step one", "Step two", "Step three"],
"controls": "Touch: tap. Keyboard: arrows and space.",
"genres": ["Puzzle"]
},
"zh": {
"name": "我的游戏",
"description": "一句话介绍你的游戏。",
"intro": "一段话描述核心玩法。",
"howToPlay": ["第一步", "第二步", "第三步"],
"controls": "触屏:点按。键盘:方向键与空格。",
"genres": ["益智"]
}
}
}| Field | Required | Description |
|---|---|---|
gameId | Yes | Unique game identifier matching ^[a-z0-9][a-z0-9-]{1,63}$ (lowercase letters, digits, hyphens, 2–64 chars). Instfun.init({ gameId }) must use the same value |
defaultLocale | Yes | Default locale code; must exist in locales |
locales | Yes | Map of locale codes to copy objects, at least one locale. Covering the site's 8 locales is recommended: en, es, de, fr, ru, ja, ko, zh |
locales.{locale}.name | Yes (for the default locale) | Game name |
locales.{locale}.description | Recommended | One-sentence summary used in listings |
locales.{locale}.intro | Recommended | Gameplay description paragraph |
locales.{locale}.howToPlay | Recommended | Array of getting-started steps |
locales.{locale}.controls | Recommended | Control instructions |
locales.{locale}.genres | Recommended | Genre tags (for example Puzzle); the server merges and dedupes them across locales |
The server only parses and validates game-info.json; it does not unpack or execute other files in the package.
Upload steps
- Open the Submit page and make sure your account has a bound email; check the remaining daily quota.
- Drag the zip into the upload area or choose a file; the page pre-checks the extension and size (it warns above 29MB).
- Click "Submit for review" and watch the progress indicator.
- The server validates the email, size, zip format,
game-info.jsonfields andgameIduniqueness in order, then returns the submission record and the updated quota. - Track status (pending / approved / rejected) and submission time in the "My submissions" list.
Review and publishing
- A submission starts as "pending review"; the team manually checks content and playability.
- Approved games are published to instfun.games by the platform; developers do not deploy anything themselves. Placement and display information are generated from the metadata.
- This flow does not yet support resubmission after rejection, multiple versions, or automatic publishing. Rejected submissions are kept; you may fix and upload again, subject to the 2-per-day quota.
- Keep the build and source revision that can reproduce the submission; they may be needed during review or troubleshooting.
Common rejection reasons
| Reason | Error / symptom | What to do |
|---|---|---|
| No bound email | EMAIL_REQUIRED(403) | Bind an email before uploading |
| File over 30MB | PAYLOAD_TOO_LARGE(413) | Compress assets, remove unused files, upload again |
| Not a zip or a corrupt zip | INVALID_PACKAGE(422), reason magic / unzip | Repackage and verify the extension and file integrity |
Missing root game-info.json | INVALID_PACKAGE(422), reason missing_manifest | Put game-info.json at the zip root |
Invalid or incomplete game-info.json | INVALID_PACKAGE(422), reason bad_manifest | Fix gameId, defaultLocale, locales against the template; ensure valid JSON |
gameId conflicts with an existing submission | GAME_ID_CONFLICT(409) | Choose another gameId or wait for the existing submission to be processed |
| More than 2 uploads in a day | RATE_LIMITED(429) | Try again the next day; do not retry automatically |
Missing index.html or a non-opening entry | Manual review rejection | Verify the root entry file and relative asset paths |
| Missing cover or too small | Manual review rejection | Provide a thumbnail.png at least 512px on the short side |
| Runtime errors or a blank screen | Manual review rejection | Open the unzipped index.html in a browser to check |
| Requires a server or external APIs | Manual review rejection | Submit purely static front-end games; the platform provides no custom backend |
| Infringing or disallowed content | Manual review rejection | Make sure assets and content are compliant |
第三方游戏通过官网「上架游戏」页(/platform/submit/)提交 zip 构建产物,经平台审核后统一发布到 instfun.games。本页说明资格、打包要求、元数据格式、上传步骤与审核规则。
上架资格
- 需要一个已绑定邮箱的平台账号。上传页会自动使用本机 SDK 游客身份;若尚未绑定邮箱,页面会先引导完成邮箱绑定(绑定入口见「接入指南」)。
- 上传需要在线;未绑定邮箱时服务端返回
EMAIL_REQUIRED。 - 每个账号每天(UTC)最多上传 2 次,超限返回
RATE_LIMITED(页面显示「今日额度」,额度在完成全部校验后消耗,失败不返还)。 - 同一
gameId在已有待审核或已通过的提交存在时不能重复提交(GAME_ID_CONFLICT)。
打包要求
zip 内部结构(根目录直接放文件,不要多套一层目录):
my-game.zip
├── index.html # 游戏入口
├── game-info.json # 元数据(必需)
├── thumbnail.png # 封面图,短边不小于 512px
└── assets/... # 其它静态资源| 要求 | 说明 |
|---|---|
| 入口文件 | zip 根目录必须有 index.html,在平台托管路径下可直接打开 |
| 元数据 | zip 根目录必须有 game-info.json,UTF-8 编码、合法 JSON、不超过 2MB |
| 封面图 | thumbnail.png,短边不小于 512px |
| 文件类型 | 仅静态文件;不要包含服务端代码、可执行文件或依赖运行时安装的内容 |
| 大小 | zip 总大小不超过 30MB |
| 资源引用 | 使用相对路径,不要依赖外部域名 CDN 或绝对根路径(游戏将被托管在 instfun.games/play/{gameId}/ 下) |
| 运行环境 | 浏览器内运行,不需要也无法访问 Node.js 等本地运行时 |
game-info.json 字段
以官网提供的模板为基准,至少填写默认语言:
{
"gameId": "my-game",
"defaultLocale": "en",
"locales": {
"en": {
"name": "My Game",
"description": "One sentence about your game.",
"intro": "A short paragraph describing the core loop.",
"howToPlay": ["Step one", "Step two", "Step three"],
"controls": "Touch: tap. Keyboard: arrows and space.",
"genres": ["Puzzle"]
},
"zh": {
"name": "我的游戏",
"description": "一句话介绍你的游戏。",
"intro": "一段话描述核心玩法。",
"howToPlay": ["第一步", "第二步", "第三步"],
"controls": "触屏:点按。键盘:方向键与空格。",
"genres": ["益智"]
}
}
}| 字段 | 必填 | 说明 |
|---|---|---|
gameId | 是 | 游戏唯一标识,匹配 ^[a-z0-9][a-z0-9-]{1,63}$(小写字母、数字、连字符,2~64 位)。接入 SDK 时 Instfun.init({ gameId }) 必须与它一致 |
defaultLocale | 是 | 默认语言代码,必须出现在 locales 中 |
locales | 是 | 语言代码到文案对象的映射,至少 1 种语言;建议覆盖官网支持的 8 种语言:en、es、de、fr、ru、ja、ko、zh |
locales.{locale}.name | 是(默认语言必须有) | 游戏名称 |
locales.{locale}.description | 建议 | 一句话简介,用于列表 |
locales.{locale}.intro | 建议 | 玩法介绍段落 |
locales.{locale}.howToPlay | 建议 | 上手步骤字符串数组 |
locales.{locale}.controls | 建议 | 操作说明 |
locales.{locale}.genres | 建议 | 类型标签字符串数组(如 Puzzle);服务端会汇总所有语言去重 |
服务端只解析并校验 game-info.json,不会解压或执行包内其它文件。
上传步骤
- 打开上架游戏页,确认账号已绑定邮箱并查看今日剩余额度。
- 把 zip 拖入上传区或点击选择文件;页面在前端做扩展名与大小预检(超过 29MB 会提示)。
- 点击「提交审核」上传,页面显示进度。
- 服务端依次校验邮箱、大小、zip 格式、
game-info.json字段与gameId查重,通过后返回提交记录与最新额度。 - 在「我的提交」列表查看状态(待审核 / 已通过 / 已拒绝)与提交时间。
审核与发布
- 提交后状态为「待审核」,平台人工确认内容与可玩性。
- 审核通过后由平台统一发布到 instfun.games,无需开发者自行部署;上架位置与展示信息由平台根据元数据生成。
- 本次流程暂不提供驳回后重传、版本并存与自动上线;被拒绝的提交不会自动删除,可修正后重新上传(受每日 2 次额度限制)。
- 请保留可以复现问题的构建产物与源码版本,审核或排障时可能需要。
常见拒绝原因
| 原因 | 对应错误 / 表现 | 处理方式 |
|---|---|---|
| 未绑定邮箱 | EMAIL_REQUIRED(403) | 先完成邮箱绑定再上传 |
| 文件超过 30MB | PAYLOAD_TOO_LARGE(413) | 压缩资源、移除无用文件后重传 |
| 不是 zip 或 zip 损坏 | INVALID_PACKAGE(422),reason magic / unzip | 重新打包,确认扩展名与文件完整 |
缺少根目录 game-info.json | INVALID_PACKAGE(422),reason missing_manifest | 把 game-info.json 放到 zip 根目录 |
game-info.json 非法或字段缺失 | INVALID_PACKAGE(422),reason bad_manifest | 对照模板修正 gameId、defaultLocale、locales;确认是合法 JSON |
gameId 与已有提交冲突 | GAME_ID_CONFLICT(409) | 更换 gameId,或等待已有提交处理完 |
| 当日上传超过 2 次 | RATE_LIMITED(429) | 次日再试,不要自动重试 |
缺少 index.html 或入口无法打开 | 人工审核拒绝 | 确认根目录入口文件与相对资源路径正确 |
| 封面缺失或尺寸不足 | 人工审核拒绝 | 提供短边 ≥ 512px 的 thumbnail.png |
| 运行时报错或白屏 | 人工审核拒绝 | 在浏览器直接打开 zip 解压后的 index.html 自查 |
| 需要服务端 / 依赖外部接口 | 人工审核拒绝 | 仅提交纯前端静态游戏;平台不提供自定义服务端 |
| 内容违规或侵权 | 人工审核拒绝 | 确保素材版权与内容合规 |