RimWorks.Quickstarts.Ref 4.0.2

dotnet add package RimWorks.Quickstarts.Ref --version 4.0.2
                    
NuGet\Install-Package RimWorks.Quickstarts.Ref -Version 4.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RimWorks.Quickstarts.Ref" Version="4.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RimWorks.Quickstarts.Ref" Version="4.0.2" />
                    
Directory.Packages.props
<PackageReference Include="RimWorks.Quickstarts.Ref" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RimWorks.Quickstarts.Ref --version 4.0.2
                    
#r "nuget: RimWorks.Quickstarts.Ref, 4.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RimWorks.Quickstarts.Ref@4.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RimWorks.Quickstarts.Ref&version=4.0.2
                    
Install as a Cake Addin
#tool nuget:?package=RimWorks.Quickstarts.Ref&version=4.0.2
                    
Install as a Cake Tool

Quickstarts: RimWorld dev quicktest scenarios

Steam Workshop Discord Maintainability Rating Reliability Rating Coverage

<img src="https://raw.githubusercontent.com/RimWorks/Rimworld-Quickstarts/main/About/ModIcon.png" alt="Quickstarts icon" width="96" align="right">

A developer tool for RimWorld. Skip the menus and boot straight into a colony that is already set up the way you need it. Quickstarts replaces the vanilla dev quicktest button with your own scenarios, written in C# and launched from the dev menu or a command line flag.

Vanilla's quicktest drops you on a random map with random colonists. A quickstart is the same colony every time, so the same scenario doubles as a smoke test. Run it with a flag and the game asserts against the live simulation. It writes a JSON report and JUnit XML, then exits with a pass or fail code.

Requires Harmony or Concord. Quickstarts prefers Concord when both are active.

Quickstarts preview card

Install

Subscribe on the Workshop, or drop a release zip into your Mods folder. Quickstarts only does anything when RimWorld's dev mode is on.

Define a quickstart

Add a reference to RimWorks.Quickstarts.Ref, then subclass AbstractQuickstart. Every non-abstract subclass with a parameterless constructor is found automatically.

using RimWorks.Quickstarts;
using RimWorks.Quickstarts.Verification;
using RimWorld;
using Verse;

public class TinyColony : AbstractQuickstart {
  public override TaggedString description => "One small map, three colonists, paused.";

  public override int mapSize => 50;

  public override void PrepareColonists(List<Pawn> pawns) {
    foreach (Pawn pawn in pawns) {
      pawn.playerSettings.hostilityResponse = HostilityResponseMode.Attack;
    }
  }

  public override QuickstartVerification Verify() {
    QuickstartVerification verification = new QuickstartVerification();
    verification.Assert("colonists spawned", () => Find.CurrentMap.mapPawns.FreeColonistsSpawnedCount > 0);
    return verification;
  }
}

The hooks run in this order:

Hook When it runs
PostStart Before generation, while the menu is still up. Good for dev toggles.
PostApplyConfiguration World exists, pawns not generated yet. Good for pawn counts.
PostConfigured After the scenario finishes its own setup. Nothing can undo you here.
PrepareColonists Map is live, colonists are spawned.
PostLoaded Last, just before the pause.

Launch one

Three ways, in the order they win:

  1. -quickstart=TinyColony on the command line.
  2. The RIMWORLD_QUICKSTART environment variable.
  3. The default set in the mod's settings.

With none of those, the game starts normally and the main menu's dev quicktest button opens a picker instead.

Fix the world seed

By default every launch generates a new planet, so a CI failure cannot be replayed. Override seed on the quickstart, or pass -quickstartseed=abc123 to beat whatever the quickstart says. The seed that ran goes into the log and into the JSON report.

public override string? seed => "abc123";

Two runs on the same seed give you the same planet, the same landing tile, the same map, and the same colonists. Seeds are only stable within one build of the mod.

CI mode

Add -quickstartverify to run Verify() and exit 0 or 1. Add -quickstartreport=<path> to also write a JSON report, which turns on verify by itself.

scripts/run-quickstart.sh TinyColony /tmp/report.json

By default Verify() runs against a map nothing has happened on yet. Override ticksBeforeVerify to drive the simulation first, which is where most tick-path bugs surface.

public override int ticksBeforeVerify => 2500;   // about 40 in-game seconds

A run also fails when the game logs a red error, even if every assertion holds. That is the check that catches a broken mod interaction. The report counts errors from before the launch, during mod and def loading, in their own field, and they never fail the run.

public override bool failOnLogError => false;                  // turn the check off
public override int allowedLogErrors => 2;                     // tolerate a known-noisy dependency
public override IEnumerable<string> ignoredLogErrors => ["null hediff"];   // substrings, no case

An ignored error still shows up in the report. It just does not count against the budget.

The report looks like this:

{
  "quickstart": "TinyColony",
  "seed": "abc123",
  "ticksRun": 2500,
  "passed": true,
  "logErrors": 0,
  "logWarnings": 3,
  "logTruncated": false,
  "preLaunchErrors": 0,
  "total": 1,
  "failed": 0,
  "results": [
    { "label": "colonists spawned", "passed": true, "detail": null }
  ],
  "errors": []
}

RimWorld keeps the last 1000 log lines and collapses a message repeated in a row into a repeats count. So logErrors is a floor, not an exact total, and logTruncated tells you when the queue dropped older lines.

Timeouts

scripts/run-quickstart.sh wraps the game in timeout, so a wedged run cannot hang CI. Set QUICKSTART_TIMEOUT to change the limit from the default 600 seconds.

The script also arms an in-game watchdog 30 seconds inside that limit, with -quickstarttimeout=<seconds>. It fires first and writes a report naming the stage the run died in, which timeout alone cannot tell you.

Code Meaning
0 every assertion passed and the log was clean
1 an assertion failed, or the error budget blew
2 the in-game watchdog fired. a report exists, with stage
124 timeout fired. probably no report
137 timeout needed SIGKILL

Stages, in order: configuring, generating-world, generating-map, ticking, verifying.

JUnit output

-quickstartjunit=<path> writes the same run as JUnit XML, which GitHub Actions and most other CI tools read natively. It turns a failed assertion into an annotation on the PR instead of a line in a log nobody opens. Independent of the JSON, so a run can write both, either or neither.

<testsuites tests="4" failures="0" errors="0">
  <testsuite name="ScenarioTestQuickstart" tests="4" failures="0" errors="0">
    <testcase classname="ScenarioTestQuickstart" name="a game exists" />
    <testcase classname="ScenarioTestQuickstart" name="no log errors" />
  </testsuite>
</testsuites>

One assertion is one <testcase>. The error budget is a synthetic no log errors case, captured errors go in <system-err>, and a watchdog timeout is an <error>. Publish it with:

- uses: mikepenz/action-junit-report@v5
  if: always()
  with:
    report_paths: /tmp/quickstart-junit.xml

This does not feed SonarCloud. The .NET scanner wants VSTest TRX or Sonar's generic format, not JUnit.

Build

gamecrate steam build rimworld --beta public         # 1.6 assemblies to compile against
gamecrate steam build rimworld --beta version-1.5    # and 1.5
dotnet build Quickstarts.slnx -c Release -p:GameVersion=1.6
scripts/build-versions.sh                            # or every version loadFolders.xml declares

A build needs no npm install. node_modules holds the release tooling, and the msbuild properties live in Source/Directory.Build.props.

Output lands in 1.6/Assemblies/, 1.6/Harmony/Assemblies/ and 1.6/Concord/Assemblies/, one folder per game version. loadFolders.xml loads only the backend folder whose library is active, so the other one never has to resolve.

More modding tools from RimWorks

Tool What it does
Pickle Run Gherkin tests against a live RimWorld session, in the game
RimLogging Structured logging, an in-game log viewer, and one-click bug report sharing

License

MIT.

Product Compatible and additional computed target framework versions.
.NET Framework net472 is compatible.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.7.2

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.0.2 44 10/1/2026
4.0.1 79 9/30/2026
4.0.0 87 9/27/2026
3.2.3 92 9/25/2026
3.2.2 90 9/25/2026
3.2.1 108 9/19/2026
3.2.0 104 9/15/2026
3.1.1 103 9/14/2026
3.1.0 102 9/14/2026
3.0.26 99 9/13/2026
3.0.25 95 9/13/2026
3.0.24 105 9/12/2026
3.0.23 100 9/12/2026
3.0.22 111 9/8/2026
3.0.21 99 9/8/2026
3.0.20 107 9/8/2026
3.0.19 96 9/8/2026
3.0.18 101 9/8/2026
3.0.17 106 9/8/2026
3.0.16 114 9/8/2026
Loading failed