| name | frb-build-verification |
| description | Verify FlatRedBall (FRB1) still compiles after editing Gum source it shares. Triggers: changes under GumCommon/ or MonoGameGum/Forms/, projitems sync, the FRB compile constant, CS0246/CS0103 from FRB. Only when a FlatRedBall checkout sits beside the Gum repo. |
FRB Build Verification
FRB1 (FlatRedBall) compiles Gum source (not the DLLs) under a net6.0 target with the FRB constant defined, via shared .projitems. A change that builds fine in the Gum solutions can still break FRB1 — so when you touch shared source, build an FRB canary.
The projitems-sync rules (which files FRB1 pulls, and what to update when you add/rename/delete) live in .claude/agents/coder.md — read that, don't duplicate it here. This skill is only about running the build.
Precondition — skip entirely if absent
This is only doable when a FlatRedBall checkout exists as a sibling of the Gum repo (i.e. <gum-repo>/../FlatRedBall/). The cross-repo csproj imports are sibling-relative (..\..\..\..\FlatRedBall\…), so without that layout the build can't resolve. If the sibling is absent, skip FRB verification and say so — it is not a failure; the maintainer/CI covers it. Do not hardcode an absolute path; check for the sibling.
Check the sibling's checked-out branch before trusting the canary — git status/git branch --show-current there. A stale or already-merged local branch doesn't error, it just silently compiles against old FRB-side source, so a clean canary result proves nothing. The sibling's default branch is origin/NetStandard, not main/master.
Worktree must be a sibling of Gum, not nested under .claude/worktrees/
The sibling-relative imports (..\..\..\..\FlatRedBall\…) are computed from the csproj's location. A git worktree is a full checkout, so its internal directory structure mirrors the primary checkout at the same depth — the import resolves correctly as long as the worktree root itself sits at the same level as Gum\ and FlatRedBall\ (i.e. directly under the parent GitHub\ folder). A worktree nested under .claude/worktrees/<branch>/ is one level too deep, so the import resolves to nowhere (MSB4019).
Create issue worktrees as a sibling of the Gum repo (e.g. <gum-repo>/../gum-wt-<branch>/), not under .claude/worktrees/.
Canaries
Pick by what you changed. The "Lives in" column is the repo containing the .csproj file itself — don't go hunting for it in the other repo. Both rows still need the FlatRedBall sibling present (row 1's target also pulls in some FlatRedBall-side Embedded\*.cs files), but only row 2's .csproj is physically located there.
| Changed source | Lives in | Build target (relative to that repo's root) | Covers |
|---|
GumCommon/ (anything in GumCoreShared.projitems) | Gum repo (this repo) | GumCore/GumCoreXnaPc/GumCore.DesktopGlNet6/GumCore.DesktopGlNet6.csproj | GumCommon shared into FRB |
MonoGameGum/Forms/ (in FlatRedBall.Forms.Shared.projitems) | FlatRedBall sibling repo | Engines/Forms/FlatRedBall.Forms/FlatRedBall.Forms.DesktopGlNet6/FlatRedBall.Forms.DesktopGlNet6.csproj | Forms shared into FRB |
Types referenced by Gum/SvgPlugin/SkiaInGumShared/ (e.g. renames/moves in Runtimes/GumShapes/, Runtimes/SkiaGum/) | Gum repo (this repo) | Gum/SvgPlugin/SkiaInGumShared/SkiaInGum.csproj | Legacy FRB Skia-adapter layer — references GumCore.DesktopGlNet6.csproj directly, so it also needs the FlatRedBall sibling even though its own .csproj lives here |
GueDeriving/*Runtime, MonoGameGum/Renderables/, MonoGameGum/ExtensionMethods/, MonoGameGum/Input/ (Cursor, Keyboard, gamepad drivers), and the Forms/DefaultVisuals/ runtimes are not compiled by FRB1 (it generates its own) — changing only those needs no FRB build.
Don't infer this from the directory path. FormsUtilities.cs lives under MonoGameGum/Forms/ but is not Included in FlatRedBall.Forms.Shared.projitems, so it needs no canary despite the directory match — even though it has its own live #if FRB branches (those serve other consumers of the file, not FRB). The inverse also happens: Input/CursorExtensions.cs lives under the normally-not-compiled MonoGameGum/Input/, but is Included in FlatRedBall.Forms.Shared.projitems (it carries the GetEventFailureReason diagnostic, which Forms uses), so editing it does need the Forms canary. grep the exact filename against the projitems file in the table above before requiring a canary; if it's not Included there, FRB doesn't compile it.
Interpreting results — baseline first
main is sometimes already red under FRB (e.g. a shared file gained a member that lives behind #if !FRB, or the FRB-side projitems is out of sync). So build the base branch first to capture the baseline errors, then build your branch and attribute only the new errors. A pre-existing error that survives on both is not yours to fix here (flag it separately).
Common genuinely-new breaks: a shared method/property guarded by #if !FRB referenced from un-guarded code (CS0103/CS0246), a .cs file added/renamed/deleted without updating the FRB-side projitems, or a net7.0+ BCL API used in shared source without an #if NET7_0_OR_GREATER gate (FRB multi-targets down to net6.0).