Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .llm/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ See [create-csharp-file](./skills/create-csharp-file.md) for detailed C# rules.

1. `using` directives INSIDE namespace; `#if` blocks INSIDE namespace; `#define` at file top
2. NO underscores in method names (including tests)
3. Explicit types over `var`
3. Explicit types over `var`. Prefer compiler-proven definite assignment or direct initialization over placeholder `default` assignments; retain `default` when it expresses a real return or failure contract.
4. **NEVER use `#region` or `#endregion`** (see [no-regions](./skills/no-regions.md))
5. NEVER use nullable reference types (`string?`)
6. One file per MonoBehaviour/ScriptableObject (production AND tests). One member ordering across the codebase (#672): const, events, delegates, static properties, static fields, properties, fields, constructors, static methods, methods -- each tier ordered public → protected → internal → private, including const. A nested type goes at the END of its containing type or in its own file, never between members. `npm run lint:nested-type-placement` enforces both and `:fix` reorders what it can; a member whose move would cross a `#if` boundary or a directive is reported, never moved ([#575](https://github.com/Ambiguous-Interactive/unity-helpers/issues/575), [#672](https://github.com/Ambiguous-Interactive/unity-helpers/issues/672); see [create-csharp-file](./skills/create-csharp-file.md))
7. NEVER use `?.`, `??`, `??=` on UnityEngine.Object types
8. **Aim for zero comments.** Reach for a better name before a better sentence, and spell names out rather than abbreviating. A comment that survives that explains **why**, never **what**; a non-doc comment INSIDE a type or member spanning more than one line uses the `/* ... */` block form, the two-line license header excepted (see [create-csharp-file](./skills/create-csharp-file.md)). `npm run lint:comment-block-form` enforces the block form and `:fix` converts what it can; `Runtime/`, `Editor/`, `Tests/` and `Generator~/` are enforced without baseline exemptions ([#635](https://github.com/Ambiguous-Interactive/unity-helpers/issues/635)). Delete before converting -- a run that only restates the code says **what**
9. Generate `.meta` files with `./scripts/generate-meta.sh <path>` after creating ANY file/folder -- never commit Unity's auto-written stub, which omits the importer block. And **an `AddComponent`-able MonoBehaviour belongs in a runtime-capable test assembly**: Unity refuses one it can identify as an editor script, and a type with no `MonoScript` merely escapes that policy until someone gives it a correctly-named file (12 red tests, session 244). `npm run lint:editor-assembly-monobehaviours` now holds it statically from `includePlatforms` plus asmdef ownership, over the 14 that legitimately live in an Editor-only assembly -- each carrying a reason and a FROZEN `AddComponent` site count, so a new call site reds the excuse instead of hiding behind it ([#678](https://github.com/Ambiguous-Interactive/unity-helpers/issues/678)). Exception: no `.meta` for dot folders (`.llm/`, `.github/`, `.git/`, `.vscode/`). See [create-unity-meta](./skills/create-unity-meta.md)
10. Enums: explicit values, `None`/`Unknown` = 0 with `[Obsolete]` (see [create-enum](./skills/create-enum.md))
11. Never reflect on our own code; use `internal` + `[InternalsVisibleTo]` (see [avoid-reflection](./skills/avoid-reflection.md))
11. Never reflect on our own code; expose actual implementation members through `internal` + `[InternalsVisibleTo]`. Production code must contain no test-only methods, wrappers, state, callbacks, branches or instrumentation. Do not add or rename `ForTest`, `ForTesting`, `ForTests`, `TestHooks` or `TestOnly` members. Keep test setup and simulated failures in test assemblies; use real implementation phases and filesystem/lifecycle controls. Legitimate production discovery of test assemblies remains supported (see [avoid-reflection](./skills/avoid-reflection.md)).
12. Never use magic strings; use `nameof()` (see [avoid-magic-strings](./skills/avoid-magic-strings.md))
13. All code must follow [high-performance-csharp](./skills/high-performance-csharp.md) and [defensive-programming](./skills/defensive-programming.md) (never throw from public APIs; use `TryXxx` patterns; handle all inputs gracefully)
14. For forbidden patterns and alternatives, see [forbidden-patterns reference](./references/forbidden-patterns.md)
Expand Down
4 changes: 4 additions & 0 deletions .llm/references/avoid-reflection-part-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Do not use these reflection APIs to access WallstopStudios code members:

Change `private` members to `internal` and rely on the `InternalsVisibleTo` infrastructure already in place.

Expose the actual implementation, not a test-only wrapper. Shipped production code must contain no test-only APIs, state, callbacks, branches or instrumentation, including code hidden behind `UNITY_INCLUDE_TESTS`. Never introduce `ForTest`, `ForTesting`, `ForTests`, `TestHooks` or `TestOnly` members, and do not merely rename such hooks. Test setup and simulated failures belong in test assemblies. Prefer the real lifecycle method, algorithm phase, state field or filesystem primitive; preserve failure and cleanup controls while changing their setup. Legitimate production discovery of test assemblies and authoring types remains supported.

`npm run lint:production-test-hooks` scans shipped C# under Runtime, Editor, production Generator projects, Samples and Styles, including generator source literals. It rejects forbidden naming tokens in ordinary source and emitted literal code, plus explicit test-only hook/code marker forms; its contract tests retain rejecting and accepting controls. Test projects and the enumerated host check tools are excluded. Every expected production root must exist as a directory, and the scan must find production C#; missing roots and empty scans fail rather than accepting a subset. This naming/marker gate is not a complete C# parser. Interpolation expressions inside strings are masked; references or local functions found only inside those expressions are not covered. It does not prove semantic absence of test-only code: review production call sites and behavior, including suffix-free injected delegates and conditional instrumentation. Do not claim end-to-end scheduling coverage when a test exercises only separately exposed implementation phases.

```csharp
// ❌ FORBIDDEN - Reflection on our code
var field = typeof(OurClass).GetField("_someField", BindingFlags.NonPublic | BindingFlags.Instance);
Expand Down
2 changes: 1 addition & 1 deletion .llm/references/context-ci-and-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ redacted, uploaded, and required by the aggregate gate (#813).
for. Session 251 shipped a `CS0103` in both and cost the whole eight-leg matrix.
`typecheck:editor-tests` is the FOURTH tree, `Tests/Editor/**`, and the only gate that compiles it
([#616](https://github.com/Ambiguous-Interactive/unity-helpers/issues/616)); two ways, default and
`:odin`. It inherits the editor pin and so EditorCheck's exclusions -- 42 of 820 files, one line
`:odin`. It inherits the editor pin and so EditorCheck's exclusions -- 45 of 856 files, one line
with its reason each in the csproj.
`typecheck:integrations` is the FIFTH tree: `Runtime/Integrations/**`, the 19 Reflex/VContainer/Zenject files EVERY other project named in an `Exclude`, so no `WUH###` rule ever ran there and four `??`-on-a-`ScriptableObject` sites shipped; no DI package is on nuget.org, so it takes the Odin route -- three shims declaring only what those 19 name -- and builds default, `:legacy-reflex` and `:player` ([#687](https://github.com/Ambiguous-Interactive/unity-helpers/issues/687)).
- `dotnet test -c Release -p:ProtobufNetOracle=v3` and then
Expand Down
18 changes: 18 additions & 0 deletions .llm/references/unity-mcp-fixture-runner-part-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,21 @@ namespace 'Unity.CompilationPipeline'` -- the name bound to a NAMESPACE, not to
([#569](https://github.com/Ambiguous-Interactive/unity-helpers/issues/569)). Before filing such a
failure as an artifact OR as a regression, grep the code under test for `Application.isPlaying`.
It is a third category: a real defect that only this harness can see.

### Native asynchronous runner limits (session 348)

The pipeline backend rejects `mode: "all"` with `async_tests: true` before clearing its
previous result. A response can therefore contain an old completed run. Run `editor` and
`playmode` separately and verify a fresh job identity and status, its filter and discovered case count.
A request timeout does not end the native job; poll that job until terminal before editing
C# sources, refreshing assets or submitting another run.

Capture growing validation logs and generated host-only C# samples outside the Unity
package, for example under `/tmp`. Unity imports even gitignored package files. A changing
log caused file-size assertions during `AssetDatabase.Refresh`; generated documentation
samples also entered authored-script validation. Preserve those artifacts outside the
package before a native run, and copy completed logs into ignored progress afterward.

Compare summary totals with individual results. This backend can report more summary cases
than its callback result list contains. Preserve both counts and investigate missing failed
identities; an incomplete leaf list cannot justify accepting a failed summary.
6 changes: 3 additions & 3 deletions .llm/skill-splits.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
{
"name": "avoid-reflection",
"sha256": "8b083202f8331761e9159f7f317f087a9a6ce8aef1860d43b4282230dcf2358d",
"sha256": "3a8ce96749ecfefdf8864388b691fe1b39a496e32d14af5df21b226ce28bf4ce",
"parts": ["avoid-reflection-part-1.md", "avoid-reflection-part-2.md"],
"routerSha256": "d9d0748a7f8782677f897b396994d260daea9240daff339b3c6588c46e59da3e"
},
Expand Down Expand Up @@ -428,13 +428,13 @@
},
{
"name": "unity-mcp-fixture-runner",
"sha256": "c870473c8d0b849846ad569b11e1bca1824782bab93b62ad6184a38136789392",
"sha256": "a4e69aad560a6e06836d3640c8f0b20f712badfdfe0b69a271e961cbd449c10e",
"parts": [
"unity-mcp-fixture-runner-part-1.md",
"unity-mcp-fixture-runner-part-2.md",
"unity-mcp-fixture-runner-part-3.md"
],
"routerSha256": "eb5d855ae47ea6901443ccbdb70a53c16825d013834996ae6291718855a2b12f"
"routerSha256": "0aabdfc757a7a062cb60843685662b97e513d94104bdfd8d53beedaa8668b1ca"
},
{
"name": "unity-performance-patterns",
Expand Down
2 changes: 2 additions & 0 deletions .llm/skills/unity-mcp-fixture-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@
### [Three things the probe itself gets wrong (session 224)](../references/unity-mcp-fixture-runner-part-3.md#three-things-the-probe-itself-gets-wrong-session-224)

### [Three the bridge itself gets wrong (session 225)](../references/unity-mcp-fixture-runner-part-3.md#three-the-bridge-itself-gets-wrong-session-225)

### [Native asynchronous runner limits (session 348)](../references/unity-mcp-fixture-runner-part-3.md#native-asynchronous-runner-limits-session-348)
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `WProtoMember.IsPacked = false` to write unpacked numeric and enum collections matching protobuf-net defaults, while preserving existing packed writes and both read forms ([#937](https://github.com/Ambiguous-Interactive/unity-helpers/issues/937)).
- Add `SystemArrayPool<T>.TryWithBuffer` for synchronous borrowed spans with explicit state, optional results, and reported callback or cleanup errors ([#924](https://github.com/Ambiguous-Interactive/unity-helpers/issues/924)).
- Add `WUH022` to report boxing disposable structs and suggest concrete or constrained generic disposal ([#924](https://github.com/Ambiguous-Interactive/unity-helpers/issues/924)).
- Add opt-in `WUH021` to flag repeated size observations, including interface `Count`, known `Length`/`LongLength` properties, and non-predicate LINQ `Count()`/`LongCount()`, when one snapshot is intended.
Expand All @@ -27,6 +28,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fix singleton asset recreation after stale GUID cleanup by requesting synchronous cleanup and pausing batching during creation and import ([#942](https://github.com/Ambiguous-Interactive/unity-helpers/issues/942)).
- Fix unexpected singleton asset creation failures blocking later attempts until a domain reload ([#936](https://github.com/Ambiguous-Interactive/unity-helpers/issues/936)).
- Stop WallstopProto `WPROTO044` inheritance diagnostics at an intermediate `[WProtoNotSerialized]` boundary, including referenced assemblies, while retaining contradictory declaration errors ([#937](https://github.com/Ambiguous-Interactive/unity-helpers/issues/937)).
- Fix WallstopProto map keys to match protobuf-net 3.2.56: write zero enum keys and omit zero floating-point keys while preserving reads of older payloads ([#937](https://github.com/Ambiguous-Interactive/unity-helpers/issues/937)).
- Fix periodic effects repeating ticks before their cadence at large clocks; initial delays, tick limits, refresh phase, and catch-up limits are preserved ([#934](https://github.com/Ambiguous-Interactive/unity-helpers/issues/934)).
- Fix cache and effect lifetimes at large clocks, including small timing offsets and jitter; preserve remaining effect time and disabled cache expiry ([#932](https://github.com/Ambiguous-Interactive/unity-helpers/issues/932)).
- Fix discarded worker jobs retaining captured references after shutdown, including submissions racing disposal ([#844](https://github.com/Ambiguous-Interactive/unity-helpers/issues/844)).
- Fix pool acquisition and warm-up failures leaking items or leaving phantom active rentals; acquisition callbacks can query pool state across threads ([#827](https://github.com/Ambiguous-Interactive/unity-helpers/issues/827)).
- Fix timed cache refresh failures changing cached values or consuming initial jitter, and preserve expiry when finite lifetime plus jitter exceeds float range ([#817](https://github.com/Ambiguous-Interactive/unity-helpers/issues/817)).
- Fix singleton loading to use the Resources root when configured subfolders contain only slashes and whitespace; spaces inside valid folders are preserved ([#867](https://github.com/Ambiguous-Interactive/unity-helpers/issues/867)).
- Fix invisible whitespace-only toggle captions by showing `(Unnamed)`; literal string values and padded captions stay unchanged ([#867](https://github.com/Ambiguous-Interactive/unity-helpers/issues/867)).
- Fix sprite sheet automatic config lookup throwing for invalid paths; invalid paths and missing sidecars preserve loaded settings ([#929](https://github.com/Ambiguous-Interactive/unity-helpers/issues/929)).
- Fix sprite sheet configuration save/load accepting blank texture paths; valid filenames containing spaces and serialized hashes keep their exact values ([#867](https://github.com/Ambiguous-Interactive/unity-helpers/issues/867)).
- Fix blank custom validation messages hiding the default warning in standard and Odin inspectors; nonblank messages and serialized string values retain their exact text ([#867](https://github.com/Ambiguous-Interactive/unity-helpers/issues/867)).
Expand Down Expand Up @@ -68,6 +80,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improve `JesseSort` for mixed regions, sparse disorder, and natural runs using the upstream live-phase design ([#747](https://github.com/Ambiguous-Interactive/unity-helpers/issues/747)).
- Improve parent and child collection transfers with bulk copying for `Component` fields while retaining typed enumeration for derived components ([#781](https://github.com/Ambiguous-Interactive/unity-helpers/issues/781)).

### Removed

- Remove production test-only APIs and injected callbacks; package tests now access real implementation internals ([#935](https://github.com/Ambiguous-Interactive/unity-helpers/issues/935)).

## [3.6.2] - 2026-09-28

### Added
Expand Down
Loading
Loading