Why a details file
Without it you type the details into the publish form every time. With it, the form is already filled in when your upload finishes. You only check it and publish. The details also travel with the code: a new version, a remix or an agent reading the game with get_game_files finds them in the same place.
habiv.json
Put a file named habiv.json at the root of the zip or folder, next to index.html. Every field is optional.
{
"$schema": "https://habiv.com/habiv.schema.json",
"title": "Paper Plane",
"tagline": "Fold, fly and dodge the birds with one button.",
"description": "Guide a paper plane through a sky full of grumpy birds. Hold to climb, let go to dive, and grab the stars for bonus points.\n\nThe wind picks up every 20 seconds. Stay low when it gusts.",
"categories": [
"arcade",
"reaction"
],
"tags": [
"one button",
"endless",
"high score"
],
"orientation": "landscape",
"duration_sec": 60,
"controls": {
"keys": [
{
"key": "Space",
"action": "Climb (hold)"
},
{
"key": "P",
"action": "Pause"
}
],
"touch": "Hold anywhere to climb"
},
"model": "Claude Sonnet 4.5",
"agent": "Claude Code",
"prompt": "Make a one-button game where a paper plane dodges birds. Rounds last about a minute."
}The $schema line is optional too. It points editors such as VS Code at the schema, so they autocomplete the fields and flag mistakes.
Single HTML files
A game that is one HTML file can't carry a second file, so put the same JSON in a script tag instead. The browser ignores it, and Habiv reads it on upload:
<!-- In the <head> of a single-file game -->
<script type="application/habiv+json">
{
"title": "Paper Plane",
"tagline": "Fold, fly and dodge the birds with one button.",
"description": "Guide a paper plane through a sky full of grumpy birds.",
"categories": ["arcade"],
"controls": {
"keys": [{ "key": "Space", "action": "Climb (hold)" }],
"touch": "Hold anywhere to climb"
}
}
</script>With neither, Habiv still uses the page's <title> for the title and <meta name="description"> for the one-line description. Placeholder titles like “Document” or “Unity WebGL Player” are skipped.
Fields
| Field | Type | What it's for |
|---|---|---|
title | text, 80 | The game's name. |
tagline | text, 140 | One line shown on cards and in link previews. |
description | text, 4,000 | About the game on its page: the goal, how a round goes, tips and credits. Line breaks are kept. |
categories | list, up to 3 | Main one first: arcade, puzzle, reaction, ambient, rhythm, racing, cozy, horror, experimental or other. "category" with one value also works. |
tags | list, up to 5 | Lower case words like "one button" or "pixel art", 24 characters each. |
orientation | text | portrait, landscape or any. |
duration_sec | number | How long a typical round lasts, in seconds. 3600 means endless. 45 or less puts the game in Quick play. |
controls | object | How to play: "keys" is up to 6 rows of { "key", "action" } (16 and 60 characters), "touch" a hint for phones (80). |
model | text, 80 | The AI model that made it, e.g. Claude Sonnet 4.5. |
agent | text, 80 | The tool or agent, e.g. Claude Code, Codex, Cursor. |
prompt | text, 8,000 | The prompt or brief behind the game, shown on its page. |
changelog | text, 500 | What changed, for a new version of a game already on Habiv. |
Anything too long is cut to fit, and anything Habiv can't read is skipped. A mistake in the file never stops your game from uploading: the checks step shows a warning and you fill that field in by hand.
What Habiv does with it
- Uploading on the website. Once the checks finish, the Details step is filled in from the file and says which fields came from it. Anything you already typed stays as it is.
- A new version of a game. Your game's current details stay. If the new file says something different, the Details step offers a Use the build's details button, so nothing changes unless you ask.
- Publishing from an AI agent. Details the agent passes to
publish_gamewin. The file fills in whatever is still empty, andget_publish_statustells the agent what it found and what the page is still missing, so it can fill the rest withupdate_game.
You can change every detail later in My games → Edit, whatever the file says.
Ask your AI
Every prompt on the AI prompts page already asks for the file. For a game you made another way, paste this into the AI that has the game open:
Write the Habiv details for this game.
- Describe the game for its Habiv page in a habiv.json file at the root of the bundle. For a single HTML file, put the same JSON inside <script type="application/habiv+json"> in the <head>. Habiv fills in the upload form from it. Fields: title; tagline (one line, up to 140 characters); description (plain text for players: the goal, how a round goes, tips; up to 4,000 characters); categories (1 to 3 of arcade, puzzle, reaction, ambient, rhythm, racing, cozy, horror, experimental, other, main one first); tags (up to 5, lower case); orientation (portrait, landscape or any); duration_sec (a typical round in seconds, 3600 for endless); controls ({ "keys": [{ "key": "Space", "action": "Jump" }], "touch": "Tap to jump" }, up to 6 keys); model and agent (the AI model and tool that made it); prompt (what I asked for); changelog (for a new version). Format: https://habiv.com/docs/details
Read the game's code to get the controls right. Write the description for players, not developers: no build steps.