# Beyond All Reason: the Lua game code behind a Recoil engine RTS

> A read of the Beyond-All-Reason repository: how you set up a dev copy inside a launcher install, what the Lua test setup looks like, and where the game code stops and the engine begins.

**beyond-all-reason/Beyond-All-Reason** — Main game repository for Beyond All Reason.

- Repository: https://github.com/beyond-all-reason/Beyond-All-Reason
- Website: https://www.beyondallreason.info/
- Stars: 4,225 · Forks: 673
- Language: Lua
- License: NOASSERTION
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/beyond-all-reason-beyond-all-reason

## Three repositories, and this is only the middle one

Beyond All Reason consists of two primary components according to the README: the lobby, called Chobby and living in a separate BYAR-Chobby repository, and the game code, which is this repository. Underneath both sits the Recoil RTS engine in its own repository. Three codebases, three clone operations if you touch all of them.

That division explains the setup instructions, which are otherwise unusual. You cannot build this repository on its own, and the README is explicit about it: to develop the game you first need a working install of the lobby and launcher. There are two routes to that. Download the full BAR application from the website and run it, which is what anyone who has played the game already has done, or download a Chobby release and launch it, which automatically downloads and installs the engine and its dependencies.

The game itself is Lua, and the top-level layout is the Spring engine's directory convention rather than anything project-specific. `luarules/` holds rule logic, `common/` shared code, `luaui/` interface code, `gamedata/` definitions, `modules/`, `scripts/`, `effects/`, `features/`, `shaders/`, `sounds/`, `music/`, `anims/`, `bitmaps/`, `fonts/` and `icons/` cover content. `singleplayer/` sits alongside them, and the entry points a new contributor will look at first are `init.lua`, `modinfo.lua`, `modoptions.lua` and `EngineOptions.lua`. The README links to the Spring wiki page describing that structure, which is the right place to learn what each directory means.

## Cloning into the launcher install directory

The dev setup drops a clone into the game's own data folder. Open the launcher, not the full game, and click the Open install directory button, which sits alongside Toggle log and Upload log. On Windows that path is typically the user's `AppData/Local/Programs/Beyond-All-Reason/data` directory; on Linux it is `.local/state/Beyond All Reason/`.

Then two things happen in that directory. Create an empty file called `devmode.txt`, and clone the repository into the `games` sub-directory, creating it if needed, under a directory name ending in `.sdd`:

```
git clone --recurse-submodules https://github.com/beyond-all-reason/Beyond-All-Reason.git BAR.sdd
```

The `--recurse-submodules` flag is not optional. A `.gitmodules` file at the repository root and a `recoil-lua-library` directory in the tree show that part of the codebase lives in a submodule, so a shallow clone without it produces a tree that fails in a confusing way rather than an obvious one.

The README gives a concrete way to confirm the path is right: look for `Beyond-All-Reason/data/games/BAR.sdd/modinfo.lua` on Windows or `.local/state/Beyond All Reason/games/BAR.sdd/modinfo.lua` on Linux. The `.sdd` suffix is the engine's signal that the directory is a mod rather than base game data, which is also why the name is constrained rather than free-form.

## Running a match against your own code

Once the clone is in place the loop is short. Launch the full game from the launcher as normal, then go to Settings > Developer > Singleplayer and select Beyond All Reason Dev. Launching a match through the game interface from there uses the dev copy of the Lua sitting in the install directory's data/games folder rather than the shipped one.

That is the whole feedback cycle, and it is short because there is no build step for game code. The engine loads Lua from disk, so a change to a rule or interface file takes effect on the next match without compiling anything. The cost is on the other side: there is no type system catching a renamed function, which is why the tooling section below matters.

If you are also working on the lobby, its code goes into the same `games` directory, following the guide in the Chobby README. The README also points at automated integration tests with documentation in `tools/headless_testing/README.md`, described as an optional advanced step.

Single player is therefore not a separate mode you have to enable for development. It is the default path for testing your changes, and the developer menu entry is the only extra step.

## Testing Lua with busted and the Lux package manager

The test setup requires Lua 5.1 specifically, and the README gives the install command per platform:

```zsh
sudo apt install -y lua5.1
```

On Windows the route is MSYS2 UCRT64 with `pacman -S --needed mingw-w64-ucrt-x86_64-lua51`, and on macOS it is `brew install lua@5.1`. Lua 5.1 rather than a current release is a consequence of inheriting the Spring engine's Lua version, and getting it wrong shows up as tests failing to load.

Package management runs through Lux, either by following its getting started guide or by building from source with Cargo. From the repository root, where `lux.toml` lives:

```zsh
lux --max-jobs=2 update
```

The job limit is not cosmetic. The README notes that `--max-jobs` was tied to one contributor's machine and that higher values sometimes caused deadlocks, which is worth knowing before anyone raises it.

Then the suite itself runs through Busted, with a tag filter for a subset and a shell mode for interactive work:

```zsh
busted -t focus
```

The Lux wrapper adds `lx test`, `lx check` for an emmylua type check, and `lx shell --test` to drop into a shell where busted can be run by hand, which is how the example output in the README was produced. Two configuration files in the tree confirm the tooling: `.busted` for the runner and `.emmyrc.json` for the type checker. Formatting and linting have their own configs too, `.stylua.toml` and `.luacheckrc`.

## Asset licensing is split into separate files

The repository handles asset rights unusually explicitly. Alongside `LICENSE.md` there are several narrow licence files: `license_bitmaps.txt`, `license_general.txt`, `license_icons.txt`, `license_music.txt`, `license_sounds.txt`, `license_unitpics.txt`, plus `cmdcolors_icexuick.txt`. Splitting licences by asset class is the right approach for a game, because bitmaps and music almost never share the same terms, and a single LICENSE.md would have hidden that.

GitHub's metadata reports the licence as NOASSERTION, which is consistent with multiple licence files and means the repository metadata does not resolve to one. Read LICENSE.md and the class-specific files before redistributing any asset.

Two other files deserve a mention. `changelog.md` sits at the repository root, which is where a contributor looks first for game changes, and `AI_POLICY.md` exists alongside `CONTRIBUTING.md`, alongside a `.claude/` directory and `luaai.lua` in the tree. That combination says the project has thought about how AI-generated contributions are handled rather than leaving it implicit.

## What a first contribution looks like in practice

Nothing in this repository is versioned by GitHub releases. There are no release tags to point at, so the shipped game and any given commit of this repository have no direct version relationship. The version a player runs comes from the launcher, which pulls the engine and dependencies through Chobby.

That is the main structural difference from a typical open source project. Contribution here means editing Lua against a live game with a clone inside the install directory, not submitting a patch that a maintainer reviews against a test harness. The testing tools exist and are documented, but the integration tests are described as an optional advanced step rather than the default verification path.

The issue tracker carries 774 open items, which is a lot of surface for a project whose primary verification path is a running game. With an active Discord linked from the README and a wiki-based documentation model, the realistic route for a contributor with a question is that Discord rather than an issue thread.

The last push was on 2026-09-23, so the repository is being worked on. The homepage at beyondallreason.info carries the download links, the play guides and, by implication, the current state of a project that has been in public release for a while.

## Conclusion

This repository is where you work if you are changing Beyond All Reason's game behaviour, and it is not a standalone build. The workflow requires an existing launcher install, a `devmode.txt` marker and a clone whose directory name ends in `.sdd`, so a contributor who has never launched the game cannot clone their way to a working build. Single player is fully reachable from there, through Settings > Developer > Singleplayer and the Beyond All Reason Dev entry. For tests, install Lua 5.1 and the Lux package manager, run `lux --max-jobs=2 update` from the repo root, then `busted`.

## FAQ

### Can you play Beyond All Reason single-player?

Yes, and the developer menu is where the two paths meet. Once a development copy is cloned into the launcher install directory, you go to Settings > Developer > Singleplayer and select Beyond All Reason Dev, then launch a match normally through the game interface, and that match runs your local Lua code. A `singleplayer/` directory also exists at the repository root for the game's own single player logic.

### How do I set up a development copy of the Beyond All Reason game code?

Install the launcher first, then open it and use the Open install directory button. In that directory create an empty `devmode.txt` file, then clone the repository into the `games` sub-directory as a folder whose name ends in `.sdd`, using `git clone --recurse-submodules`. Verify the path by looking for `modinfo.lua` inside the clone.

### How do you run the Lua tests for Beyond All Reason?

Install Lua 5.1 and the Lux package manager, then run `lux --max-jobs=2 update` from the repository root where `lux.toml` lives. The suite runs through Busted with `busted`, or filtered with `busted -t focus`. Lux also wraps it as `lx test`, offers `lx check` for the emmylua type check, and `lx shell --test` for a shell where busted can be run manually.

## Sources

- [beyond-all-reason/Beyond-All-Reason on GitHub](https://github.com/beyond-all-reason/Beyond-All-Reason)
- [Issues](https://github.com/beyond-all-reason/Beyond-All-Reason/issues)
- [Project website](https://www.beyondallreason.info/)
- [README](https://github.com/beyond-all-reason/Beyond-All-Reason/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/beyond-all-reason-beyond-all-reason
