The game convention

A Gamentic game is an ordinary self-contained HTML5 game plus a handful of marker comments. Follow them and the game gains a live Inspector, server-injected art and audio, export and remixing. Ignore them and it is still a game — the convention is purely additive.

Your AI reads the canonical version of this from the server with get_convention, which is required before writing any game. This page is the human summary — useful for reviewing what the AI produced, or for writing a game by hand.

The marker comments

Five globals carry everything the platform can see or change. Each is declared once in game.html, and each assignment ends with an exact marker comment. The server finds those markers by text to inject generated art, audio and models; the Inspector finds GAME_CONFIG to build the tuning panel.

GlobalMarkerHolds
window.GAME_CONFIG// __GI_CONFIG__Every tunable number, colour, toggle and level layout
window.GAME_ASSETS// __GI_ASSETS__Generated images, by name
window.GAME_AUDIO// __GI_AUDIO__Generated music, speech and sound effects
window.GAME_MODELS// __GI_MODELS__Generated 3D models and rigs
window.GAME_DATA// __GI_DATA__Content the AI edits without touching code — dialogue, levels, item tables

1. One config object

Everything tunable goes in a single global, and the right-hand side must be valid JSON: double-quoted keys, no trailing comma, no functions, comments or expressions.

window.GAME_CONFIG = {
  "gravity": 0.6,
  "playerSpeed": 4.5,
  "enemyColor": "#ff4757",
  "hardMode": false,
  "level": [[1,1,0],[0,1,0],[0,1,1]]
}; // __GI_CONFIG__

Never write a defensive fallback on a marker line. This is the single most common mistake:

window.GAME_ASSETS = {};                          // __GI_ASSETS__   correct
window.GAME_ASSETS = window.GAME_ASSETS || {};    // __GI_ASSETS__   breaks injection

With ||, ??, a ternary or Object.assign(...) the right-hand side stops being JSON, so the server can no longer rewrite the block — and generated art simply never lands. Nothing errors. The guard is not needed anyway: these globals are defined right here, exactly once.

Each marker may appear only once in the whole file, and the game loop must read window.GAME_CONFIG directly every frame. Copy a value into a local at start-up and a panel edit will not take effect until the next reload.

2. The harness

Five lines let the Inspector push edits into a running game. Copy them verbatim.

window.__GI_SET = function (patch) {
  Object.assign(window.GAME_CONFIG, patch);
  if (typeof window.__giOnChange === 'function') window.__giOnChange(patch);
};
console.log('__GI__' + JSON.stringify({ type: 'ready', config: window.GAME_CONFIG }));

Two optional hooks:

3. The schema

The schema describes the panel. It is passed to create_game and is never inlined into the game HTML, which is why editing a game in the Inspector cannot corrupt it.

{
  "groups": [
    { "label": "Feel", "fields": [
      { "key": "gravity", "type": "float", "min": 0.1, "max": 2, "step": 0.05, "label": "Gravity" }
    ]},
    { "label": "Controls", "fields": [
      { "key": "restart", "type": "action", "label": "Restart" }
    ]}
  ]
}
TypeControlNeeds
int / floatSlidermin, max, step
boolToggle
enumDropdownoptions
colorColour pickervalue is #rrggbb
stringText field
grid2dGrid editorrows, cols, palette; value is a 2D number array
actionButtonfires __giOnAction(key)

Every field except action needs a matching default in GAME_CONFIG. Groups should mean something — Feel, Difficulty, Appearance, Controls — rather than one undifferentiated lump. A game whose difficulty numbers are not exposed cannot be tuned by the person playing it, which is most of the point.

4. A self-contained package

Nothing may load from another domain: no CDN script, no remote font, no external image, no fetch() to the internet. Graphics are drawn on canvas, sound is synthesized with WebAudio or injected as generated audio. This is not a house style — the sandboxes these games run in block external resources outright.

Self-contained describes the package, not a single file. A game is a folder:

game.html          the shell: markers, boot, <script src="src/..."> in load order
src/**.js          your code, split by responsibility
media/**           images and audio (the server puts them here)

Marker blocks and the harness stay in game.html. Move one into src/ and nothing errors — generated art and audio just quietly stop arriving, because the server looks for those markers in game.html alone.

game.html must end with </html>; a truncated upload is rejected rather than stored half-written. Export, remix and publishing to itch.io or Newgrounds all carry src/ and media/ along with the shell.

Next