Docs Tools

AI schemes

A scheme is a complete AI. Switch with one click in Farsight — even the game in progress can be taken over right away. Export a zip to share with others, import other people's schemes to test them, and every scheme's results are tracked automatically.

A scheme = a complete AI: a folder + a manifest scheme.json + code. Each game instance picks one scheme; you switch with one click in Farsight, and the new scheme can even take over the game in progress right away.

Schemes shared by others are imported into a separate area, kept apart from your own schemes; to change one, use “Copy to mine”.

schemes/
  mine/<id>/          mine: ones you wrote, or copied from another scheme to modify (change freely; takes effect next game)
  installed/<id>/     installed: zips shared by others are unpacked here (trust must be confirmed before the first run)
brains/xwar3/         built-in: the reference brain (a full AI)
brains/examples/      built-in: the four teaching examples hello / rush / macro / micro, the companion example buddy, and two gameplay mods (Hero Roguelike, Endless Defense)

A scheme doesn’t have to be an AI that plays for you: a kind: mod scheme is a set of gameplay rules — you play, and it sets the challenges. See Gameplay mods.

Using it in Farsight

The “AI schemes” page (sidebar “System → AI schemes”):

ActionWhat it does
Import scheme (zip)Installs it into installed/; if the same id is already installed, it asks whether to replace it (after replacing, trust must be confirmed again)
Use on instance…Pick an instance + “Apply now” (stops the current AI; the new scheme takes over this game) or “Apply at next Start test”
Copy to mineCopies it into mine/, sets the author to “me” and the version to 0.1.0, and records which version of which scheme it was copied from
Export zipPacks it as <id>-<version>.zip; sending that to someone is how you share it
Open folderOpens the scheme folder in File Explorer so you can edit the code directly
TrustRequired before someone else’s scheme runs for the first time (see “Trust and safety” below)
Recent resultsWin/loss, duration and end reason for every game this scheme played
DeleteOnly “mine” and “installed” schemes can be deleted; a scheme an instance is using can’t be

Instance cards also have a new “AI scheme” row: pick a scheme from the dropdown → “Switch (applies now)”. When the instance isn’t running, the button says “Select”, and the next “Start test” launches the AI with that scheme.

The manifest: scheme.json

{
  "format": 1,
  "id": "fast-rush",
  "name": "Three-minute rush",
  "version": "1.2.0",
  "author": "Someone",
  "description": "One sentence on what strategy this AI plays",
  "entry": "rush_bot.py",
  "class": "RushBot",
  "fair": true,
  "hz": 5,
  "races": ["human", "orc"],
  "license": "MIT"
}
FieldRequiredDescription
id✔Lowercase letters, digits, -, _; 2–41 characters
entry✔A .py file in the scheme folder (no absolute paths, no ..)
kindDefault bot (a subclass of openwar3.Bot that plays for you); mod = a gameplay mod (a subclass of openwar3.Mod; never uses fair mode and isn’t judged by melee rules)
className of the Bot (or Mod) subclass in the entry file; if omitted, the last openwar3.Bot subclass in the entry file is used
fairDefault true: sees only what’s within vision, the same rule as the Arena. false = full-map visibility, and only then can it use the JASS channel (companions need it)
judgeDefault true: wins and losses are judged by melee rules. Set it to false for RPG / companion schemes
hzHow many times per second on_tick is called; default 5
formatManifest format version, currently 1; a manifest newer than your local OpenWar3 is rejected with a prompt to update
Othersname, version, author, description, races, license, homepage and forked_from are for display only

The scheme folder is added to Python’s module search path, so the entry file can import other files in the same folder. Third-party packages (numpy, torch…) aren’t installed automatically — state clearly in description what’s needed.

The smallest scheme needs just two files:

# my_bot.py
from openwar3 import Bot

class MyBot(Bot):
    def on_tick(self, g):
        for w in g.idle_workers():
            mine = g.nearest(g.gold_mines(), w)
            if mine:
                g.gather(w, mine)
{"id": "my-first", "name": "My first AI", "entry": "my_bot.py"}

Put them in schemes/mine/my-first/ and refresh Farsight to see it. An even easier starting point: pick an example under “Built-in” and click “Copy to mine”.

How schemes run, and results

Schemes are run by the scheme runner (it’s what Farsight’s “Start test / Switch” launches):

python tools/run_scheme.py --inst 20 --scheme builtin/micro --hours 6
  • Each instance has one long-running supervisor process, which starts a child process for every game to run the scheme: if the scheme’s code crashes, the supervisor is unaffected; if you change the code of one of your own schemes, the next game automatically uses the new code.
  • At the end of each game one results row is recorded: scheme, version, author, win/loss, reason, game duration, error count. The win rates in Farsight are computed from these.

How wins and losses are decided:

SituationRecorded as
All enemy buildings are goneWin
All our buildings are gone (even if units are still alive — that’s how melee games decide a loss)Loss
All our units are goneLoss
Ended / stopped manually in FarsightUndecided
At the time of switching, the game had already run for more than 60 game seconds (taken over midway)Counted separately, not included in the win rate
The game clock hasn’t moved for a long timeUndecided

Once a game is decided, the runner closes the score screen, starts the next game according to the “Next game” settings, and the scheme takes over again — you can leave it running all night to build up results. Pausing doesn’t end a game: while paused, the Bot keeps running as usual; only the game clock stops.

Trust and safety

A scheme is code, and when it runs it has the same permissions as you do (it can read and write files and access the network). So:

  • Schemes in installed/ are not trusted by default; both Farsight and the runner refuse to run them until you click “Trust”;
  • Replacing an installed scheme with one that has the same id resets trust (a new version means new code);
  • Imports are checked: the zip must be at most 50 MB with at most 2000 files; no absolute paths or .. (so nothing can be written outside the scheme folder); an invalid manifest or a missing entry file is rejected outright.

Before you trust a scheme, click “Open folder” and read through the code. Only take schemes from people you trust.

API (for scripts)

EndpointDescription
GET /api/schemesScheme list + results + the scheme each instance has selected and is running
GET /api/schemes/results?ref=A scheme’s last 30 games
POST /api/schemes/importImport a zip
GET /api/schemes/export?ref=Download the zip
POST /api/schemes/forkCopy to mine
POST /api/schemes/trustTrust
DELETE /api/schemes?ref=Delete (refused while an instance is using it)
POST /api/instances/{n}/schemeChange an instance’s scheme: take over the current game right away, or apply at the next Start test

In Python, use the library directly: from openwar3 import schemes (list_schemes, install_zip, export_zip, fork, trust, stats…).

Later: a scheme website

An exported zip is the unit of sharing, so the website only needs to add a layer on top: upload from Farsight with one click; downloads from the website go through exactly the same checks as “Import scheme” and still require confirming trust; results can optionally be reported, and the website aggregates win rates by version. Farsight already has a spot reserved for the “Share to scheme website” button. See the roadmap for progress.