Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
c5dce0c
docs(types): extract Types/Ids/SerializeReferences full references
VPDPersonal Jul 19, 2026
24e44db
docs(readme): rework READMEs around extracted references
VPDPersonal Jul 19, 2026
baf5db7
chore(devtests): add docs-media demo types
VPDPersonal Jul 19, 2026
e1cb7e0
docs(skills): update sync-readmes file count and sample list
VPDPersonal Jul 19, 2026
3797af9
docs(types): note Serializable requirement for generic argument candi…
VPDPersonal Jul 19, 2026
dcd1438
Merge remote-tracking branch 'origin/main' into docs/types-reference-…
VPDPersonal Jul 19, 2026
92bcd7a
Merge remote-tracking branch 'origin/main' into docs/types-reference-…
VPDPersonal Jul 20, 2026
3d3b394
docs(types): clarify TypeSelector example comment for managed references
VPDPersonal Jul 21, 2026
afa1318
docs(serializereferences): illustrate the reference with editor media
VPDPersonal Jul 21, 2026
69868c9
test(devtests): add SerializeReferences screenshot harness
VPDPersonal Jul 21, 2026
7e2ff8c
Merge remote-tracking branch 'origin/main' into docs/types-reference-…
VPDPersonal Jul 21, 2026
cc54782
docs(claude-md): trim derivable content from nested memory files
VPDPersonal Jul 21, 2026
d3190f9
Merge remote-tracking branch 'origin/main' into docs/types-reference-…
VPDPersonal Jul 21, 2026
fd35d14
docs(serialize-references): split project-wide tooling into Serialize…
VPDPersonal Jul 22, 2026
df34af5
Merge remote-tracking branch 'origin/main' into docs/types-reference-…
VPDPersonal Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .claude/skills/sync-readmes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Verify and update Aspid.FastTools README files against the actual c
user-invocable: false
---

The package ships **fourteen** README files (4 main + 10 sample) that drift from the code easily. Use after any change touching namespaces of public types, public API surface, `[CreateAssetMenu]` paths, source generator output, or sample structure.
The package ships **sixteen** README files (4 main + 12 sample) that drift from the code easily. Use after any change touching namespaces of public types, public API surface, `[CreateAssetMenu]` paths, source generator output, or sample structure.

## Files in scope

Expand All @@ -17,16 +17,18 @@ The package ships **fourteen** README files (4 main + 10 sample) that drift from
| `Aspid.FastTools/Packages/tech.aspid.fasttools/Documentation/EN/README.md` | EN | `../Images/` |
| `Aspid.FastTools/Packages/tech.aspid.fasttools/Documentation/RU/README.md` | RU | `../Images/` |

Per-feature references (`SerializedPropertyExtensions.md`, `VisualElementExtensions.md`) live alongside the Documentation copies inside `Documentation/EN/` and `Documentation/RU/`.
Per-feature references (`Types.md`, `SerializeReferences.md`, `SerializeReferenceTooling.md`, `Ids.md`, `SerializedPropertyExtensions.md`, `VisualElementExtensions.md`) live alongside the Documentation copies inside `Documentation/EN/` and `Documentation/RU/`.

Expected structural differences between root and Documentation copies (not drift):

- **Badge block** (Unity / Release / License shields) — only in the root copies.
- **`## Source Code` / `## Исходный код` block** linking to the GitHub repo — only in the Documentation copies.
- **Badge block** (Unity / Stable / Preview / License shields) — only in the root copies.
- **Language switcher** under the banner — root links `README.md` / `README_RU.md`; Documentation copies link the sibling locale as `../RU/README.md` / `../EN/README.md`.
- **Source-code link row** (`[Source Code](…) · [Unity Asset Store](…) · [Releases](…)`, RU: `Исходный код`) under the one-liner — only in the Documentation copies.
- **LICENSE / CHANGELOG links** (in `## License` / `## Лицензия`) — root uses repo-relative paths; Documentation copies use absolute `github.com/.../blob/main/...` URLs.
- **Image paths** — see table above.
- **Feature-reference links** — root uses the full `Documentation/EN/...` path; Documentation copies link to the bare filename (same folder).

**Sample READMEs** — one EN + one RU per sample folder under `Aspid.FastTools/Packages/tech.aspid.fasttools/Samples~/` (`Types/`, `Ids/`, `EnumValues/`, `ProfilerMarkers/`, `VisualElements/`).
**Sample READMEs** — one EN + one RU per sample folder under `Aspid.FastTools/Packages/tech.aspid.fasttools/Samples~/` (`Types/`, `Ids/`, `EnumValues/`, `ProfilerMarkers/`, `VisualElements/`, `SerializeReferences/`).

## Workflow

Expand All @@ -45,7 +47,6 @@ For every fact the README states, prove it from the code:
Where READMEs historically lie (re-verify these even if the text looks plausible):

- **Namespaces** — they are split per feature (runtime and editor alike); never assume a type sits in the root `Aspid.FastTools`. Check the `using` lines in samples.
- **The two ID registries** — `StringIdRegistry` and `IdRegistry` have different APIs, menu paths, and runtime behavior; don't conflate them — read both sources.
- **Sample asset menu paths** — samples use their own menu segment order; always re-grep `[CreateAssetMenu]` instead of trusting the existing README.

### 2. Apply edits to all matching files
Expand Down
37 changes: 1 addition & 36 deletions Aspid.FastTools.Generators/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ Deploy pipeline: `Aspid.FastTools.Generators/ILRepack.targets` merges `Aspid.Gen

A repo-level PostToolUse hook (`.claude/hooks/rebuild-generators-on-change.sh`) also runs `dotnet build` automatically after any `Edit`/`Write` to `*.cs` under `Aspid.FastTools.Generators/Aspid.FastTools.Generators/`. The hook intentionally **does not** trigger for tests, the Sample project, or Unity-side edits — keep that scope if you modify it.

## Solution Structure

```
Aspid.FastTools.Generators/ ← generator implementation (+ ILRepack.targets deploy merge)
Aspid.FastTools.Generators.Tests/ ← unit tests + GeneratorTestHost helper
Aspid.FastTools.Generators.Sample/ ← manual smoke-test project
Aspid.FastTools.Generators.sln
Directory.Build.targets ← copies the merged DLL into the Unity package
```

## Target Framework

`netstandard2.0` — required by Roslyn. No Unity assemblies, no runtime packages.
Expand Down Expand Up @@ -95,32 +85,7 @@ Pipeline data passed between stages **must be value-equatable**. Roslyn caches r
- `Equals` and `GetHashCode` over every field
- For nested arrays use `ImmutableArray<T>` with element-wise comparison (or `EquatableArray<T>` if introduced)

Reference shapes:

```csharp
internal readonly struct TypeData : IEquatable<TypeData>
{
public readonly string TypeKey; // "Foo.Outer.Inner"
public readonly string TypeName;
public readonly string? Namespace;
public readonly string ContainingTypeChain; // "Outer.Middle." or ""
public readonly string FullyQualifiedDisplay;
public readonly string TypeParamList; // "<T,U>" or ""
public readonly string ConstraintsClause;
public readonly int Arity;
// ... ctor + IEquatable<TypeData> Equals/GetHashCode over all fields
}

internal readonly struct IdStructData : IEquatable<IdStructData>
{
public readonly string StructName;
public readonly string TypeParameters; // "<T>" or ""
public readonly int Arity;
public readonly string? Namespace;
public readonly ImmutableArray<ContainingTypeInfo> ContainingTypes;
// ... IEquatable<IdStructData> walks ContainingTypes element-wise
}
```
Reference shapes: `TypeData` and `IdStructData` in the generator sources.

Cache stability is regression-tested in `IncrementalCacheTests` — that test runs each generator twice over compilations differing only in an unrelated source file, and asserts every output step is `Cached`/`Unchanged`. Adding a non-equatable field to any pipeline struct will fail it.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2681730314047826224
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3946854324957946979}
- component: {fileID: 9052271508596160596}
m_Layer: 0
m_Name: BrokenWeaponPreset
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3946854324957946979
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2681730314047826224}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9052271508596160596
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2681730314047826224}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 812007f2bd1be48ee8eca8c040018591, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Game.Gear.Loadout
_primary:
rid: 2339642446330462275
_sidearms:
- rid: 2339642446330462276
references:
version: 2
RefIds:
- rid: 2339642446330462275
type: {class: Pistoll, ns: Game.Gear, asm: Assembly-CSharp}
data:
_damage: 10
- rid: 2339642446330462276
type: {class: Shotgun, ns: Game.Gear, asm: Assembly-CSharp}
data:
_pellets: 8
_spread: 12

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2681730314047826224
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3946854324957946979}
- component: {fileID: 9052271508596160596}
m_Layer: 0
m_Name: SharedWeaponPreset
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3946854324957946979
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2681730314047826224}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9052271508596160596
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2681730314047826224}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 812007f2bd1be48ee8eca8c040018591, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Game.Gear.Loadout
_primary:
rid: 2339642446330462275
_sidearms:
- rid: 2339642446330462275
references:
version: 2
RefIds:
- rid: 2339642446330462275
type: {class: Pistol, ns: Game.Gear, asm: Assembly-CSharp}
data:
_damage: 10

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2681730314047826224
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3946854324957946979}
- component: {fileID: 9052271508596160596}
m_Layer: 0
m_Name: WeaponPreset
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3946854324957946979
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2681730314047826224}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9052271508596160596
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2681730314047826224}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 812007f2bd1be48ee8eca8c040018591, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Game.Gear.Loadout
_primary:
rid: 2339642446330462275
_sidearms:
- rid: 2339642446330462276
references:
version: 2
RefIds:
- rid: 2339642446330462275
type: {class: Pistol, ns: Game.Gear, asm: Assembly-CSharp}
data:
_damage: 10
- rid: 2339642446330462276
type: {class: Shotgun, ns: Game.Gear, asm: Assembly-CSharp}
data:
_pellets: 8
_spread: 12

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using UnityEngine;
using System.Collections.Generic;
using Aspid.FastTools.Types;

// Docs-media harness: mirrors the SerializeReference Selector example in
// Documentation/EN|RU/SerializeReferences.md — IWeapon implementations picked into
// [SerializeReference] fields. Lives in DevTests, but uses a neutral game-like
// namespace because the picker breadcrumbs are visible in the recorded media.

// ReSharper disable once CheckNamespace
namespace Game.Gear
{
public interface IWeapon
{
void Fire();
}

[Serializable]
public sealed class Pistol : IWeapon
{
[SerializeField] [Min(0)] private int _damage = 10;

public void Fire() => Debug.Log($"Pistol: {_damage} dmg");
}

[Serializable]
public sealed class Shotgun : IWeapon
{
[SerializeField] [Min(1)] private int _pellets = 8;
[SerializeField] [Range(0f, 45f)] private float _spread = 12f;

public void Fire() => Debug.Log($"Shotgun: {_pellets} pellets, {_spread}° spread");
}

[Serializable]
public sealed class PlasmaRifle : IWeapon
{
[SerializeField] [Min(0f)] private float _power = 40f;
[SerializeField] [Min(0f)] private float _range = 60f;

public void Fire() => Debug.Log($"Plasma rifle: {_power} power, {_range} m");
}

public sealed class Loadout : MonoBehaviour
{
[TypeSelector]
[SerializeReference] private IWeapon _primary;

[TypeSelector]
[SerializeReference] private List<IWeapon> _sidearms;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Aspid.FastTools/Assets/DevTests/Types/Scripts/DocsMedia.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading