Contracts

Optional

A contract is a short list of questions about one game mechanic, such as what a backpack does with a pile of items that will not fit. Answer the questions and the mechanic is defined well enough to build and test. A contract with the answers filled in is an adoption. To use one, start from the Contracts pages. The files below are what they produce.

The adoption file#

contracts/backpack.json, part of a filled-in Container adoption

{
  "contract": "container",
  "version": 1,
  …
  "answers": {
    "capacity-limit": "slot-count",
    "partial-acceptance": "fill-what-fits",
    "leftover-destination": "left-where-it-is",
    …
  },
  "values": {
    "slot-count": 12,
    …
  },
  …
}

This backpack has twelve slots. It takes the part of a delivery that fits and leaves the rest where it came from. The adoption file also carries a copy of the contract's definition, left out above: the questions, their options and the rules. In this excerpt, marks fields left out. Each option has a meaning: the promise you choose, in plain words. An option can also carry semantics: exact wording for the builder and the tests. The definition's mechanism text says what every game that uses this contract must do.

Put it in your game#

The adoption lives in contracts/ with the copied definition, the answers, the values, any content rows, and any inputs the tests need. Some questions and settings apply only after a particular answer. Two adoptions can use the same contract with different answers.

The example writes its slot count directly. A contract can also let a setting cite a value from your ordinary tuning, so existing names stay connected. The contract says which forms it allows. Content rows can list things such as the item types a container accepts.

The filename gives the adoption its address: contracts.backpack. contracts.backpack.slot-count names its slot count. The authoring tool can update references when you rename an adoption, and validation reports references that no longer resolve.

Adding a contract does not supply the rest of a game's rules. The chapters still say how the mechanic is used in play.

Check the promise#

Package validation checks the adoption's form, required answers, declared values and rows, citations and numeric rules. It does not run your finished game.

The contract's acceptance tests travel in a separate file, the verification pack. With the matching pack beside it, an adoption is checked: the tests ship with your design. Without it, the adoption is promised: you have stated the behaviour and the builder still owes it. Checked never means a game has passed the tests.

Keep the exact matching pack beside the adoption. The copied definition names the pack's SHA-256 fingerprint, and validation compares it with the file. A pack from another version does not work. Rendering the pack shows the named tests for your answers. It does not run them or add them to your build plan.

Change or remove it#

Changing an answer changes what the builder must implement. Review the resulting tests and your ordinary game rules together. Updating to a newer version of a contract can keep your answers while changing what they mean. It does not migrate your game rules or saved games.

Removing an adoption leaves its tuning and prose to review. Update references that used its address, and remove its pack only when no other adoption needs it. You can also use a contract as a checklist without adopting it, by recording your decisions in ordinary prose.

A contract records design promises. The builder chooses how to implement them. Only evidence from running the game shows that the promises are kept.

Full rules: OpenGDD specification, §10.

← Personalization questions · All chapters · What validation proves →