Build RimWorld mods with repeatable scaffolding, current dependency resolution, guarded deployment, package auditing, live-test planning, and release checklists—without copying a pile of personal paths and accounts into every mod.
This repository is a control layer for a collection of mod repositories. Each mod still owns its source, metadata, assets, tests, and player-facing description. The shared layer handles the parts that are easy to get subtly wrong or let drift:
- create a modern C# mod, independent tests, artwork metadata, and an optional RimBridgeServer companion as one coherent scaffold;
- query current stable compatible NuGet packages instead of trusting stale versions in documentation;
- validate metadata, dependency, packaging, and paired-deployment invariants;
- refuse unsafe deploy roots and deployment over a running RimWorld process;
- plan a minimal GABS live-test profile without disturbing unrelated mods;
- stage public ZIPs without companion tools, SDK DLLs, private Harmony copies, symbols, or platform junk;
- capture an immutable GitHub/Steam/optional-Discord release plan before any publication begins.
The core scripts and generated mod task runner support macOS, Linux, and Windows. Platform-specific integrations remain optional: for example, BrrainzTools supplies macOS UI evidence, while Steam, Discord, GABS, Unity, and RimBridgeServer are discovered only when the selected workflow needs them.
Requirements are Git and Python 3.10 or newer. Clone this repository using its current GitHub Code URL, enter the clone, then preview setup:
macOS or Linux:
python3 scripts/bootstrap.py --configure-profileWindows PowerShell:
py scripts\bootstrap.py --configure-profileThe preview shows the exact profile and template destinations. Apply it after review:
python3 scripts/bootstrap.py --configure-profile --applypy scripts\bootstrap.py --configure-profile --applySetup uses the Git author and authenticated GitHub CLI login when available. It creates a private user profile and copies editable starter templates outside the clone. Optional Workshop, support/funding, community, signature, and Steam-user values default to empty; missing values remove their complete template sections rather than producing dead links.
The default user configuration locations are:
| Platform | Directory |
|---|---|
| macOS | ~/Library/Application Support/steam-mods |
| Linux | ${XDG_CONFIG_HOME:-~/.config}/steam-mods |
| Windows | %APPDATA%\steam-mods |
Set STEAM_MODS_CONFIG_DIR to choose another directory. Re-run setup with
explicit values when desired, for example:
python3 scripts/bootstrap.py --configure-profile \
--author-name "Example Author" \
--organization "Example Studio" \
--github-owner example-user \
--package-id-prefix example.user \
--tool-github-owner upstream-tool-owner \
--control-repository example-user/steam-mods \
--rimbridge-package-id example.tools.rimbridgeserver_steam \
--rimbridge-package-id example.tools.rimbridgeserver \
--gabs-preferred-game your-rimworld-game-id \
--gabs-fallback-game your-fallback-game-id \
--gabs-preferred-profile your-live-proof-profile \
--workshop-url "https://example.test/workshop" \
--community-url "https://example.test/community" \
--support-url "https://example.test/support" \
--replace-profile \
--applyAll visible boilerplate is user-owned after setup. Edit
profile.json for values and templates/ for wording. The scripts prefer those
local templates over the neutral tracked starters.
Setup discovers RimBridgeServer package IDs from RIMWORLD_MOD_DIR or a sibling
RimBridgeServer checkout when possible. The repeatable
--rimbridge-package-id option handles installations with another namespace.
GABS game IDs and profile names are installation-specific and must be supplied
with the --gabs-* options before creating a mod or planning a live deploy.
macOS or Linux:
python3 scripts/modctl.py doctor
python3 scripts/check_repository.pyWindows PowerShell:
py scripts\modctl.py doctor
py scripts\check_repository.pydoctor separates required commands, optional agents, source checkouts, the
local profile, Unity, and the explicit RimWorld deployment directory. Missing
optional integrations do not make source-only work unusable.
Bootstrap can also preview or install the shared toolchain. Every mutation still
requires --apply:
python3 scripts/bootstrap.py \
--clone-tools \
--install-dotnet \
--install-unity \
--install-skillsOn Windows the .NET path uses Microsoft's PowerShell installer; macOS and Linux use the official shell installer. The exact configured Unity editor is discovered in each platform's conventional Unity Hub location.
A central inventory is optional. Point the control script directly at any clone:
python3 scripts/modctl.py inspect /path/to/ExampleMod
python3 scripts/modctl.py validate /path/to/ExampleMod
python3 scripts/modctl.py plan-deploy /path/to/ExampleMod
python3 scripts/modctl.py plan-release /path/to/ExampleModUse --projects-root or STEAM_MODS_PROJECTS_ROOT when mod repositories are
not siblings of this clone. A private mods.json becomes useful only for
cross-mod reports, description maintenance, persistent announcement metadata,
or remote-workspace lookup.
The generator is dry-run-first and derives the package ID from the configured
profile unless --package-id is explicitly supplied:
python3 scripts/new_mod.py \
--name "Example Mod" \
--repo ExampleMod \
--description "One concise player-facing sentence." \
--preview /absolute/path/to/preview.png \
--preview-prompt "Exact landscape artwork prompt" \
--icon /absolute/path/to/icon.png \
--icon-prompt "Exact square icon prompt"Review the dependency, artwork, target, and file plan, then repeat with
--apply. The generated repository contains native entry points for both
families of shell:
./scripts/check
./scripts/build-quiet.sh
RIMWORLD_MOD_DIR="/absolute/path/to/RimWorld/Mods" ./scripts/deploy.sh.\scripts\check.ps1
.\scripts\build-quiet.ps1
$env:RIMWORLD_MOD_DIR = "C:\absolute\path\to\RimWorld\Mods"
.\scripts\deploy.ps1Both wrappers call the same standard-library Python task runner and deployment guard, so Windows and POSIX behavior do not drift independently.
Every mod owns a root ModDescription.md containing concise mod-specific copy.
The user profile and user-owned templates supply optional links, support text,
signatures, and announcement wording:
python3 scripts/mod_descriptions.py render ExampleMod --target steam
python3 scripts/mod_descriptions.py check --no-steam-live
python3 scripts/mod_descriptions.py update-steam ExampleMod --confirm
python3 scripts/mod_descriptions.py update-github-readmes --confirmDiscord destinations are optional and private. A release plan renders only the
forum or community destinations present in local destinations.json; mention
and crosspost behavior comes from that destination rather than a hard-coded
community assumption.
config/standards.json: game line, framework, artwork, and dependency policy;config/profile.example.json: documented shape of private identity/link/tool configuration;config/*.example.json: generic examples for optional local inventories and destinations;templates/descriptions/andtemplates/discord/: neutral starter text copied to user storage during setup;templates/new-mod/: cross-platform modern code-mod scaffold;templates/unity-assets/: shader/AssetBundle source and three-platform runtime scaffold;scripts/bootstrap.py: setup, discovery, cloning, and explicit installation;scripts/modctl.py: inspection, validation, deploy plans, release plans, and ZIP audits;scripts/resolve_dependencies.py: current stable dependency facts;skills/: creation, development, and release workflows for coding agents;docs/: the detailed standards, evidence model, portability contract, and adoption guidance.
For an AI coding agent, start with AGENTS.md. For deeper human
documentation, use the docs knowledge map, especially
NEW_MODS.md, DEVELOPMENT.md,
TESTING.md, RELEASES.md, and
PORTABILITY.md.