Skip to content

fix(mod-manager): time the quit teardown on a clock that never stops - #254

Merged
Furroxide merged 1 commit into
devfrom
fix/mod-manager-quit-clock
Oct 19, 2026
Merged

Furroxide merged 1 commit into
devfrom
fix/mod-manager-quit-clock

Conversation

@Furroxide

Copy link
Copy Markdown
Owner

Outcome

#234 holds a quit while TopiaForge's teardown runs, for at most 10 s, so that a stuck teardown cannot keep the game
open. In the game that limit never passed. PluginQuitCoordinator read its clock from the plugin's startup
stopwatch, and WriteLastRunReport stops that stopwatch once startup is reported. A deadline read from a stopped
clock never arrives, so a teardown that never finished held the quit for good. The game then never exited and had to
be closed by force. That opens the next start in safe mode with every mod off, which is what #234 set out to prevent.

The coordinator now reads a quit clock: a Stopwatch the plugin starts once and never stops. Startup timings still
read the startup stopwatch, unchanged.

  • A normal quit was not affected. A teardown that finishes resumes the held quit at once. Only the deadline for a
    stuck one was frozen.
  • Why the tests missed it. PluginQuitCoordinatorTests drives the coordinator with a clock of its own, so the
    deadline logic was right. The plugin handed it the wrong clock, in a MonoBehaviour the test harness cannot run.
    The new check therefore reads the plugin's source. It checks three things: the quit clock starts with the plugin,
    nothing stops or resets it, and the PluginQuitCoordinator the plugin makes reads it and never the startup
    stopwatch. Any other quit timer the plugin adds can reuse the check (ReadsTheQuitClock).
  • How it was found. fix(launcher): ask an owned game to quit before restarting it #253's launcher-quit watcher was built on the same clock. In a real restart it looked for the
    launcher's request only once, on the first frame.

Deviations from the plan

Compatibility and security

Verification

On a Windows 11 x64 machine, on dev at 22d68d1 (the mutations ran on 680d7a9; the one commit between, #251, changes only Dart):

  • dotnet build TopiaForge.slnx -c Release -warnaserror: 0 warnings, 0 errors.
  • dotnet run --project tests\TopiaForge.ModManager.Tests\TopiaForge.ModManager.Tests.csproj -c Release: all pass.
    The new check is the eleventh in "Plugin quit coordination: 11 behavioral checks passed."
  • dotnet format TopiaForge.slnx --verify-no-changes, limited to the two edited files: no change.
  • Mutations, 3 of 3 caught, each restored, with the plugin still compiling:
    • the coordinator reads the startup stopwatch again, as on dev;
    • the quit clock is restarted when startup is reported;
    • the quit clock is created stopped.
  • In the game: not run on its own, because a stuck teardown cannot be made on demand. fix(launcher): ask an owned game to quit before restarting it #253's restarts on
    Robotopia 0.0.2545 ran with this fix. There the launcher-quit watcher, which reads the same clock, looked twice a
    second as designed, and the game quit within 1 s of the launcher's request.
  • python -I .github/scripts/check_topiaforge_residue.py and check_readme_counts.py: pass.

Checklist

  • I read AGENTS.md and preserved CLEAN/Bloc/Unity/TopiaForge UI boundaries.
  • I added focused regression coverage for meaningful defects.
  • I ran the relevant build, analyze, test, format, package, and line-count gates.
  • I added provenance, license text, and modification notes for new third-party material. (None added.)
  • I did not include secrets, proprietary game assemblies, generated build directories, or unrelated changes.

The quit coordinator's teardown limit read the plugin's startup
stopwatch, which WriteLastRunReport stops once startup is reported. A
deadline read from a stopped clock never passes, so a teardown that
never finished would have kept the game open for good instead of letting
it quit after 10 s. The coordinator now reads a quit clock that starts
with the plugin and is never stopped, and a test fails if a quit timer
the plugin makes reads the startup stopwatch again.

Signed-off-by: Furroxide <221987073+Furroxide@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Unity PR artifacts are ready.

Artifact Link
VPM package listing Download artifact

Workflow run: Unity Source Validation #657
Commit: 20e6575

Artifacts are temporary and expire according to the workflow retention policy.

@Furroxide
Furroxide merged commit ca2e52b into dev Oct 19, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant