Docs / Start here
fradiation.json
The optional file at the top of a build that sets the entry point, viewport and threads, and declares mutations and scoreboards. Every field, limit and icon name.
One JSON file tells the site what your game can unlock and score. The site is very literal about it.
The file is optional. Without it a build has no mutations and no scoreboards, the entry point is index.html, and the uploader asks you for a stage size.
Where it goes
- Name it
fradiation.json, lowercase, and put it at the top of the build, next toindex.html(or whatever yourentryis). - In a zip where everything sits inside one top-level folder, that folder is dropped first. The file goes inside that folder, beside
index.html. - It is plain JSON. No comments, no trailing commas.
- The uploader reads it in your browser and does not store it as a build file. It isn't served from your game's origin.
- The Unity kit copies
fradiation.jsonfrom your project root into the build.
What a web upload reads
Five fields: entry, viewport, threads, mutations, boards. Anything else in the file is ignored, including $schema.
Title, slug, description, engine, origin and AI disclosure come from the game's details form, on its Manage page. Setting "title" or "engine" in this file does nothing.
Example
{
"$schema": "https://www.fradiation.games/fradiation.schema.json",
"entry": "index.html",
"viewport": { "width": 1280, "height": 720 },
"threads": false,
"mutations": [
{
"key": "first-blood",
"name": "First Blood",
"description": "Destroy your first drone.",
"tier": "alpha",
"icon": "crosshair"
},
{
"key": "untouched",
"name": "Untouched",
"description": "Clear a level without taking damage.",
"tier": "beta",
"icon": "shield"
},
{
"key": "waterfall-room",
"name": "Damp Discovery",
"description": "Find the room behind the waterfall.",
"tier": "beta",
"icon": "waves",
"secret": true
},
{
"key": "boss-hard",
"name": "No Mercy",
"description": "Beat the final boss on Hard.",
"tier": "gamma",
"icon": "crown"
},
{
"key": "speedrun",
"name": "Under Ten",
"description": "Finish the game in under 10 minutes.",
"tier": "gamma",
"icon": "timer"
},
{
"key": "everything",
"name": "Completionist",
"description": "Collect every item in the game.",
"tier": "cherenkov",
"icon": "trophy"
}
],
"boards": [
{
"key": "high-score",
"name": "High score",
"order": "desc",
"format": "number",
"max": 5000000
},
{
"key": "fastest-clear",
"name": "Fastest clear",
"order": "asc",
"format": "time",
"max": 3600000
}
]
}The game refers to these by key: fradiation.unlockMutation("first-blood"), fradiation.submitScore("fastest-clear", ms). See The SDK.
Fields
Top level
| Field | Type | Default | Notes |
|---|---|---|---|
entry | string | "index.html" | The HTML file to load. Must match a file in the build exactly: a relative path, no leading ./ or /. |
viewport | object | none | Native size of the game. See below. Without it the uploader asks for a stage size (default 1280 x 720). |
threads | boolean | false | Serve the build cross-origin isolated. See below. |
mutations | array | [] | At most 30 per file, of which at most 3 gamma and 1 cherenkov. |
boards | array | [] | At most 10 per file. |
viewport
| Field | Type | Limits |
|---|---|---|
width | integer | 160 to 4096 |
height | integer | 120 to 4096 |
The site letterboxes the game to this aspect ratio. Make the game fill its window (100% width and height) and handle resize. Don't hard-code a canvas size.
threads
true serves the build cross-origin isolated (COOP same-origin, COEP require-corp), for engines that need SharedArrayBuffer: multithreaded Unity, threaded Godot. Anything loaded from another origin must then send CORP or CORS headers, so bundle everything. Leave it false unless your engine needs threads.
Mutations
Mutations are a game's achievements. Each one is declared here and unlocked from game code with unlockMutation(key).
| Field | Type | Default | Limits |
|---|---|---|---|
key | string | required | Matches ^[a-z0-9-]{2,40}$: lowercase letters, digits and dashes, 2 to 40 characters. This is the id your game passes to the SDK. |
name | string | required | 1 to 40 characters |
description | string | required | 1 to 120 characters |
tier | string | required | alpha, beta, gamma or cherenkov |
icon | string | required | One of the names in Icons |
secret | boolean | false | See Secret mutations |
Tiers
Tiers run alpha, beta, gamma, cherenkov, from common to rare. Pick the tier by how hard the mutation is to earn. The site does not measure that for you.
| Tier | Rads to the player | Cap per file |
|---|---|---|
alpha | 25 | none beyond the 30 total |
beta | 50 | none beyond the 30 total |
gamma | 100 | 3 |
cherenkov | 250 | 1 |
Rads are paid the first time a signed-in player unlocks the mutation. Developers can unlock their own mutations but get no rads from their own games.
The caps apply to the file in each upload, and the file as a whole is limited to 30 mutations. Secret mutations count toward the same caps. An upload over a cap is refused with a message such as fradiation.json: at most 3 gamma mutations.
Secret mutations
"secret": true hides a mutation until the player unlocks it. Before that it shows as a locked "?" with the name, icon and description withheld. Use it for things you don't want to give away.
Icons
icon must be one of these 100 names, exactly as written. They are Lucide icon names.
skull flame zap bomb crosshair shield shield-alert trophy crown star rocket
ghost heart swords sword target timer gem key eye radiation biohazard atom
bug sparkles medal award flag map compass footprints gauge infinity moon sun
snowflake droplet anchor bot radar satellite plane car hand-fist dumbbell
brain clover dice-5 puzzle gamepad-2 joystick coins package hammer wrench
lock unlock hourglass siren tent tree-pine mountain waves wind
cloud-lightning egg fish bird cat dog rabbit turtle axe shovel pickaxe
wand-sparkles scroll cake pizza beer coffee music headphones camera film tv
cpu battery-charging plug magnet flask-conical syringe pill bone ear hand
thumbs-up party-popper fire-extinguisher shellAny other name is refused. The full list is also in the JSON Schema.
Boards
A board is a scoreboard. The game submits a number with submitScore(key, value) and the site keeps each player's best.
| Field | Type | Default | Notes |
|---|---|---|---|
key | string | required | Matches ^[a-z0-9-]{2,40}$. |
name | string | required | 1 to 40 characters. |
order | string | "desc" | "desc": higher is better. "asc": lower is better, for times. |
format | string | "number" | "number": shown as a whole number with separators. "time": the value is in milliseconds, shown as m:ss.mmm. |
max | number | none | Greater than 0. Scores above it are rejected as implausible. |
- Negative scores are always rejected. There is no minimum.
maxis a ceiling for both orders. On an"asc"time board it rejects slow times, not fast ones. Set it above the slowest run you would accept.- A
"number"board displays whole numbers. To keep two decimals, submit the value times 100. - The first score a player posts on a board pays 5 rads, once per board. Developers get none.
How changes apply
- Mutations and boards are upserted by
keywhen a build is sealed, which is when its upload finishes. It does not wait for the build to go live. Changing a name, description, tier or icon changes it for the whole game at once. - Renaming a
keymakes a new mutation or board. The old one stays, along with anything players unlocked or scored on it. - Removing an entry from the file does not remove it from the game.
- Caps are checked against the file in the upload, not against everything the game has ever registered.
- A draft runs its newest build, so a draft picks up changes on the next upload.
JSON Schema
The schema for this file is at https://www.fradiation.games/fradiation.schema.json. Put it first in the file and editors that support $schema, VS Code included, give you autocomplete and inline errors:
{
"$schema": "https://www.fradiation.games/fradiation.schema.json"
}Give the same URL to a coding agent when it writes the file. See Working with agents for the other machine-readable files.
Common mistakes
- Comments or trailing commas. The uploader stops with
fradiation.json isn't valid JSON. - Wrong place. The file must sit at the top of the build, not in a subfolder of it.
- Expecting the file to set the title.
title,slug,description,engine,originandaiare ignored. Use the game's Manage page. - An icon that isn't in the list. The upload is refused with a message that names the field, for example
fradiation.json: mutations.2.icon: .... Lucide has many more icons than this list. Only these 100 are allowed. - Keys with capitals or underscores.
First_Bloodfails.first-bloodworks. - Too many gamma or cherenkov mutations. The limits are 3 and 1. The message reads
fradiation.json: at most 3 gamma mutations.orat most 1 cherenkov mutation. - A key in game code that isn't in the file. The SDK does not throw. The call resolves with the same defaults as outside the site (
signedIn: false), and nothing is kept. See Testing. - Times in seconds. A
"time"board reads milliseconds. Submitting92shows0:00.092. "order": "desc"on a time board. The slowest player would rank first. Use"asc".maxset too low. Real scores are rejected and the game gets the default result back.entrywritten as./index.htmlor/index.html. It must equal a file path in the build:index.html.- Renaming a key after launch. Players who unlocked the old one keep it, and the new one starts at zero unlocks.