Skip to content

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.

.md

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 to index.html (or whatever your entry is).
  • 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.json from 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

json
{
  "$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

FieldTypeDefaultNotes
entrystring"index.html"The HTML file to load. Must match a file in the build exactly: a relative path, no leading ./ or /.
viewportobjectnoneNative size of the game. See below. Without it the uploader asks for a stage size (default 1280 x 720).
threadsbooleanfalseServe the build cross-origin isolated. See below.
mutationsarray[]At most 30 per file, of which at most 3 gamma and 1 cherenkov.
boardsarray[]At most 10 per file.

viewport

FieldTypeLimits
widthinteger160 to 4096
heightinteger120 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).

FieldTypeDefaultLimits
keystringrequiredMatches ^[a-z0-9-]{2,40}$: lowercase letters, digits and dashes, 2 to 40 characters. This is the id your game passes to the SDK.
namestringrequired1 to 40 characters
descriptionstringrequired1 to 120 characters
tierstringrequiredalpha, beta, gamma or cherenkov
iconstringrequiredOne of the names in Icons
secretbooleanfalseSee 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.

TierRads to the playerCap per file
alpha25none beyond the 30 total
beta50none beyond the 30 total
gamma1003
cherenkov2501

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.

text
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 shell

Any 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.

FieldTypeDefaultNotes
keystringrequiredMatches ^[a-z0-9-]{2,40}$.
namestringrequired1 to 40 characters.
orderstring"desc""desc": higher is better. "asc": lower is better, for times.
formatstring"number""number": shown as a whole number with separators. "time": the value is in milliseconds, shown as m:ss.mmm.
maxnumbernoneGreater than 0. Scores above it are rejected as implausible.
  • Negative scores are always rejected. There is no minimum.
  • max is 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 key when 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 key makes 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:

json
{
  "$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, origin and ai are 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_Blood fails. first-blood works.
  • Too many gamma or cherenkov mutations. The limits are 3 and 1. The message reads fradiation.json: at most 3 gamma mutations. or at 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. Submitting 92 shows 0:00.092.
  • "order": "desc" on a time board. The slowest player would rank first. Use "asc".
  • max set too low. Real scores are rejected and the game gets the default result back.
  • entry written as ./index.html or /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.