A complete example: Garden Snake

You already know Snake, so you can see where the format puts each rule. Here is a complete OpenGDD package for it, in five small files. It is a different game from the platformer in Get started. To work from the real files, download Garden Snake as a zip or open the package page.

the whole package on disk

garden-snake/
  manifest.json     what this is
  tuning.json       the numbers
  01-overview.md    the player fantasy and the pitch
  02-mechanics.md   the rules
  05-build-plan.md  build stages and acceptance tests

manifest.json, complete

{
  "opengdd": "0.9",
  "id": "garden-snake",
  "version": "1.0.0",
  "title": "Garden Snake",
  "designer": {
    "name": "OpenGDD Examples"
  },
  "target": {
    "platform": "web-2d",
    "genre": "arcade",
    "session_minutes": 5,
    "audience": "anyone; one player and one garden"
  }
}

The first thing in 01-overview.md is the fantasy block: in a few lines, who the player is in the game and how playing should feel. Everything else in the package should support it.

the fantasy block, opening 01-overview.md

You are a garden snake with an appetite bigger than the garden, growing longer with every fallen apple until there is no room left for you.
Feel: hungry, tidy, inevitable.
NOT: violent, rushed, cluttered.

The rules are prose. A rule does not repeat a number that tuning.json holds. The rule names the number, and the number is written in tuning.json.

a rule, from 02-mechanics.md

Time advances in steps of `snake.tick_seconds`. Each tick, the
head moves one cell in the current direction, the body follows,
and the tail cell empties.

After every `snake.speedup_every_apples` apples eaten in the current
run, later ticks become `snake.speedup_step_seconds` shorter, down to
`snake.minimum_tick_seconds`.

tuning.json, complete

{
  "values": {
    "snake.tick_seconds": 0.4,
    "snake.speedup_every_apples": 5,
    "snake.speedup_step_seconds": 0.025,
    "snake.minimum_tick_seconds": 0.15,
    "garden.size": 13,
    "snake.start_length": 3
  },
  "ranges": {
    "snake.tick_seconds": [0.3, 0.8],
    "snake.speedup_every_apples": [2, 12],
    "snake.speedup_step_seconds": [0.01, 0.05],
    "snake.minimum_tick_seconds": [0.1, 0.2]
  }
}

ranges says how far each number may change. You may change it when you balance the design, and the builder may choose any value inside the range while balancing the build. garden.size has no range, so it stays as written.

An acceptance test is a check the finished game must pass. Garden Snake has four. The Acceptance tests chapter explains the block.

one of the four acceptance tests, from 05-build-plan.md

{
  "type": "scenario",
  "given": "a run in progress with the head one cell from the apple",
  "when": ["the head moves onto the apple", "play continues until the head moves into the wall", "a fresh run continues until the head moves into the snake's own body"],
  "then": ["eating grows the snake by one cell, scores one apple, and a new apple appears in an empty cell", "the wall ends its run on the spot", "the body ends its run on the spot", "each finished run reports its apple count"],
  "diagnostics": ["tick-log", "garden-before-after"]
}

What to notice:

  • You describe Snake the way you would describe it to a friend.
  • Change a number once in tuning.json and every rule that names it stays correct.
  • The tests say what a build must show, not how to program it.
  • The fantasy block sets the feeling. The overview delegates presentation choices to the builder in a > DELEGATED: blockquote. The gameplay rules are Fixed: the builder follows them exactly.

This package validates with no errors and no warnings. Chapters marked Optional describe things you add only when your game needs them.

All chapters · What a package contains →