Skip to content

fix(unity): build the Player when no subtarget given - #302

Merged
webbertakken merged 1 commit into
mainfrom
fix/standalone-subtarget-player
Oct 24, 2026
Merged

webbertakken merged 1 commit into
mainfrom
fix/standalone-subtarget-player

Conversation

@webbertakken

@webbertakken webbertakken commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

The default build script lets users pick a standalone subtarget with -standaloneBuildSubtarget Player|Server. When the flag was missing, it passed StandaloneBuildSubtarget.Default (0) to Unity. Unity's BuildPipeline.BuildPlayer (2023.2 reference source) replaces Default with EditorUserBuildSettings.standaloneBuildSubtarget, which is stored in the project's Library, and writes the result back there. A Library that once built a Server, for example one restored from a CI cache, therefore keeps building Servers. On a runner without the Dedicated Server module that fails with Dedicated Server support for MacStandalone is not installed (a failing unity-builder job).

This makes a standalone build without a subtarget build the Player, whatever the Library remembers.

Behaviour changes for users (Unity 2021.2+, default build script only)

  • No -standaloneBuildSubtarget on a standalone target: builds the Player. Before, it built whatever subtarget the project's Library last used. If you relied on the editor's saved "Dedicated Server" setting, pass -standaloneBuildSubtarget Server explicitly. -standaloneBuildSubtarget Default keeps the old behaviour.
  • Unknown value (e.g. Headless, 7): the build now fails with Unknown standaloneBuildSubtarget "…"; expected Player or Server. Before, it fell back to the persisted subtarget without saying so.
  • Value case: matching is now case-insensitive (server works).
  • Non-standalone targets (Android, iOS, WebGL, …): the flag is ignored with a warning, and the subtarget sent to Unity stays 0, as it already was without the flag. Before, -standaloneBuildSubtarget Server on Android passed 1 to Unity as that target's subtarget, where the value has a target-specific meaning rather than "Server".
  • Unchanged: builds with a build profile (Unity 6), and every target when the flag is given correctly.

What changed

  • Input/BuildSubtarget.cs (new, with .meta): BuildSubtarget.Resolve(target, options) holds the rule above. Builder.cs calls it from the BuildPlayerOptions initialiser. The change is applied to dist/default-build-script and to the two plugins/unity copies, so they stay in step.
  • src/generated/embedded-assets.ts is regenerated.
  • scripts/test-build-subtarget.sh (new, run in the Tests workflow) compiles BuildSubtarget.cs with the .NET SDK, at C# 9 as in Unity 2021.2, against minimal Unity stubs. The stubs' enum values come from Unity's reference source. It asserts ten cases, including both behaviour changes above.

Verified locally

  • The new test fails on the old default (2 of 10 failing: "standalone without a subtarget builds the Player", "an empty subtarget builds the Player") and passes with this change.
  • bun run test (357 pass, 0 fail), generate-embedded-assets.mjs --check, validate-platform-scripts.sh, shellcheck and actionlint all pass.
  • Not verified: compiling against the real UnityEditor assemblies. That happens in unity-builder's build matrix once a CLI release includes this.

Summary by CodeRabbit

  • Tests
    • Added automated checks for build target selection, including default and explicitly configured subtargets, invalid values, and non-standalone targets.
    • The test suite now runs these checks as part of the standard workflow and reports failures when validation does not pass.

Standalone builds without -standaloneBuildSubtarget handed Unity StandaloneBuildSubtarget.Default, so Unity reused the subtarget persisted in the project's Library. A Library cached from a Server build made later Player builds fail with "Dedicated Server support for <platform> is not installed".
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d4456cf4-6d49-459a-8a6f-002e4bf06367
Commits

Reviewing files that changed from the base of the PR and between 7da0cea and 497afc4.

Files ignored due to path filters: 10
  • dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs is excluded by !**/dist/**
  • dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/BuildSubtarget.cs is excluded by !**/dist/**
  • dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/BuildSubtarget.cs.meta is excluded by !**/dist/**
  • plugins/unity/dist/unity-builder/dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs is excluded by !**/dist/**
  • plugins/unity/dist/unity-builder/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/BuildSubtarget.cs is excluded by !**/dist/**
  • plugins/unity/dist/unity-builder/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/BuildSubtarget.cs.meta is excluded by !**/dist/**
  • plugins/unity/src/unity-builder/dist/default-build-script/Assets/Editor/UnityBuilderAction/Builder.cs is excluded by !**/dist/**
  • plugins/unity/src/unity-builder/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/BuildSubtarget.cs is excluded by !**/dist/**
  • plugins/unity/src/unity-builder/dist/default-build-script/Assets/Editor/UnityBuilderAction/Input/BuildSubtarget.cs.meta is excluded by !**/dist/**
  • src/generated/embedded-assets.ts is excluded by !**/generated/**
Files selected for processing: 2
  • .github/workflows/tests.yml
  • scripts/test-build-subtarget.sh

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

Adds a standalone script that compiles and tests BuildSubtarget.Resolve against Unity stubs. The tests workflow runs the script.

Changes: Build subtarget tests

Layer / File(s) Summary
Set up the test harness
scripts/test-build-subtarget.sh
The script checks for dotnet, creates a temporary project, and defines Unity stubs for compilation.
Run assertions in the workflow
scripts/test-build-subtarget.sh, .github/workflows/tests.yml
The harness checks subtarget results, exceptions, and warnings. It builds and runs the tests. The workflow invokes the script.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: frostebite

Merge Risk: Minimal · up to 497af

The new tests cover subtarget resolution. No concrete issue requiring a fix before merge was established.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title "fix(unity): build the Player when no subtarget given" matches the main change. The PR makes a standalone build without -standaloneBuildSubtarget build the Player instead of the subtarget pe…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description is detailed and covers the change, user-visible behavior, implementation scope, testing, and verification results. It does not use the template headings or include the required checkli…
Full details: Title check

Explanation

The title "fix(unity): build the Player when no subtarget given" matches the main change. The PR makes a standalone build without -standaloneBuildSubtarget build the Player instead of the subtarget persisted in the project's Library. The title is short, specific, and follows a conventional-commit style. It does not cover the input validation, case-insensitivity, or non-standalone warning changes, which is acceptable.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1 files. (1 skipped: 1 unsupported.)

Full details: Description check

Explanation

The description is detailed and covers the change, user-visible behavior, implementation scope, testing, and verification results. It does not use the template headings or include the required checklist, but the missing items are non-critical because the required change information is present.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@webbertakken
webbertakken merged commit 9e2a4a2 into main Oct 24, 2026
20 checks passed
@webbertakken
webbertakken deleted the fix/standalone-subtarget-player branch October 24, 2026 15:23
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