Skip to content

Commit 63dc265

Browse files
Kryptos-FRxen2
authored andcommitted
docs: unwrap asset system markdown
1 parent 12dae00 commit 63dc265

6 files changed

Lines changed: 59 additions & 167 deletions

File tree

docs/asset-system/README.md

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
# Asset System — Contributor Overview
1+
# Asset System — Overview
22

3-
This document explains the Stride asset system for engine contributors. It covers the complete
4-
pipeline from design-time authoring through build compilation to runtime loading, and shows
5-
how all parts are wired together.
3+
This document explains the Stride asset system. It covers the complete pipeline from design-time authoring through build compilation to runtime loading, and shows how all parts are wired together.
64

7-
> **For game-project custom assets** (not engine contributions), the same pipeline applies
8-
> with minor differences noted in each spoke file. See also the external guide:
9-
> [Creating custom assets](https://doc.stride3d.net/latest/en/manual/scripts/custom-assets.html).
5+
> **For game-project custom assets** (not engine contributions), the same pipeline applies with minor differences noted in each spoke file. See also the external guide: [Creating custom assets](https://doc.stride3d.net/latest/en/manual/scripts/custom-assets.html).
106
117
## The Three-Phase Pipeline
128

@@ -24,15 +20,11 @@ flowchart LR
2420
D -->|"loaded into"| E
2521
```
2622

27-
**Design time:** The author edits asset properties in GameStudio. Properties are persisted to a
28-
`.sdXXX` YAML file. The file is deserialized into an instance of the asset class.
23+
**Design time:** The author edits asset properties in GameStudio. Properties are persisted to a `.sdXXX` YAML file. The file is deserialized into an instance of the asset class.
2924

30-
**Build time:** The build pipeline invokes the compiler registered for the asset type. The
31-
compiler reads the asset class instance and produces compiled binary content, which is written
32-
to the content database.
25+
**Build time:** The build pipeline invokes the compiler registered for the asset type. The compiler reads the asset class instance and produces compiled binary content, which is written to the content database.
3326

34-
**Runtime:** The game calls `ContentManager.Load<RuntimeType>(url)`. The engine reads the
35-
compiled binary and returns a typed instance.
27+
**Runtime:** The game calls `ContentManager.Load<RuntimeType>(url)`. The engine reads the compiled binary and returns a typed instance.
3628

3729
## Assembly Map
3830

@@ -75,37 +67,26 @@ See [editor.md](editor.md) for implementation details for each tier.
7567

7668
## Implementation Checklist
7769

78-
Use this checklist when adding a new asset type. Steps marked **optional** are only needed
79-
in specific circumstances.
70+
Use this checklist when adding a new asset type. Steps marked **optional** are only needed in specific circumstances.
8071

8172
### Always required
8273

83-
- [ ] **Runtime type**`[DataContract]`, `[ContentSerializer]`, `[ReferenceSerializer]`,
84-
`[DataSerializerGlobal]` → see [runtime-type.md](runtime-type.md)
85-
- [ ] **Asset class**`[DataContract]`, `[AssetDescription]`; add `[AssetContentType]` and
86-
`[AssetFormatVersion]` when the asset has a compiled runtime output → see [asset-class.md](asset-class.md)
87-
- [ ] **Compiler**`[AssetCompiler(typeof(%%Asset%%), typeof(AssetCompilationContext))]` on
88-
the compiler class; implement the protected `Prepare` override → see [compiler.md](compiler.md)
89-
- [ ] **Module initializer**`AssemblyRegistry.Register(...)` in the assembly's `Module.cs`
90-
→ see [registration.md](registration.md)
74+
- [ ] **Runtime type**`[DataContract]`, `[ContentSerializer]`, `[ReferenceSerializer]`, `[DataSerializerGlobal]` → see [runtime-type.md](runtime-type.md)
75+
- [ ] **Asset class**`[DataContract]`, `[AssetDescription]`; add `[AssetContentType]` and `[AssetFormatVersion]` when the asset has a compiled runtime output → see [asset-class.md](asset-class.md)
76+
- [ ] **Compiler**`[AssetCompiler(typeof(%%Asset%%), typeof(AssetCompilationContext))]` on the compiler class; implement the protected `Prepare` override → see [compiler.md](compiler.md)
77+
- [ ] **Module initializer**`AssemblyRegistry.Register(...)` in the assembly's `Module.cs` → see [registration.md](registration.md)
9178

9279
### Recommended
9380

94-
- [ ] **`.sdtpl` template** — adds the asset to the **Add Asset** menu in GameStudio →
95-
see [registration.md](registration.md#sdtpl-template-files-new-asset-menu)
81+
- [ ] **`.sdtpl` template** — adds the asset to the **Add Asset** menu in GameStudio → see [registration.md](registration.md#sdtpl-template-files-new-asset-menu)
9682

9783
### Conditional
9884

99-
- [ ] **`AssetViewModel<T>` (Tier 2)** — only if custom editor commands or display logic is
100-
needed → see [editor.md](editor.md#tier-2-custom-assetviewmodelt)
101-
- [ ] **`AssetEditorViewModel` + XAML View (Tier 3)** — only if a dedicated editor panel is
102-
needed → see [editor.md](editor.md#tier-3-full-custom-editor)
103-
- [ ] **`GetInputFiles` override** — only if the compiler reads external files →
104-
see [compiler.md](compiler.md#declare-external-file-dependencies-getinputfiles)
105-
- [ ] **`GetInputTypes` override** — only if compilation depends on another asset being
106-
compiled first → see [compiler.md](compiler.md#declare-asset-dependencies-getinputtypes)
107-
- [ ] **Version upgrader** — only when bumping `[AssetFormatVersion]` on an existing asset →
108-
see [asset-class.md](asset-class.md#versioning-and-upgraders)
85+
- [ ] **`AssetViewModel<T>` (Tier 2)** — only if custom editor commands or display logic is needed → see [editor.md](editor.md#tier-2-custom-assetviewmodelt)
86+
- [ ] **`AssetEditorViewModel` + XAML View (Tier 3)** — only if a dedicated editor panel is needed → see [editor.md](editor.md#tier-3-full-custom-editor)
87+
- [ ] **`GetInputFiles` override** — only if the compiler reads external files → see [compiler.md](compiler.md#declare-external-file-dependencies-getinputfiles)
88+
- [ ] **`GetInputTypes` override** — only if compilation depends on another asset being compiled first → see [compiler.md](compiler.md#declare-asset-dependencies-getinputtypes)
89+
- [ ] **Version upgrader** — only when bumping `[AssetFormatVersion]` on an existing asset → see [asset-class.md](asset-class.md#versioning-and-upgraders)
10990

11091
## Key Terms
11192

docs/asset-system/asset-class.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ The asset class is the design-time representation of an asset. An instance is se
1313
| `AssetComposite` | The asset is composed of named sub-parts that can be individually referenced and overridden in derived assets. | `SceneAsset`, `PrefabAsset` |
1414
| `AssetCompositeHierarchy<TAssetPartDesign, TAssetPart>` | Like `AssetComposite` but with a parent/child hierarchy among parts. Used for scenes and prefabs. Prefer `AssetComposite` unless you need a tree structure. | `SceneAsset`, `PrefabAsset` |
1515

16-
> **Decision:** Start with `Asset`. Upgrade to `AssetWithSource` if the asset's primary content
17-
> comes from a file on disk that Stride did not produce. Use `AssetComposite` only if your asset
18-
> must support per-part archetype inheritance.
16+
> **Decision:** Start with `Asset`. Upgrade to `AssetWithSource` if the asset's primary content comes from a file on disk that Stride did not produce. Use `AssetComposite` only if your asset must support per-part archetype inheritance.
1917
2018
## Required Attributes
2119

@@ -105,5 +103,4 @@ public sealed class %%AssetName%%Asset : Asset // or AssetWithSource
105103
```
106104

107105
> [!NOTE] Game projects
108-
> Replace `StrideConfig.PackageName` with a string literal matching your game's package name
109-
> (e.g. `"MyGame"`). The rest of the pattern is identical.
106+
> Replace `StrideConfig.PackageName` with a string literal matching your game's package name (e.g. `"MyGame"`). The rest of the pattern is identical.

docs/asset-system/compiler.md

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
## Role
44

5-
The compiler transforms a design-time `Asset` instance into compiled runtime content stored in
6-
the content database. It is invoked during the game build and by the editor for live preview. A
7-
compiler is registered by decorating the compiler class with `[AssetCompiler]`. The compiler runs
8-
on a background thread and must not access any editor UI state.
5+
The compiler transforms a design-time `Asset` instance into compiled runtime content stored in the content database. It is invoked during the game build and by the editor for live preview. A compiler is registered by decorating the compiler class with `[AssetCompiler]`. The compiler runs on a background thread and must not access any editor UI state.
96

107
## Register the Compiler
118

@@ -14,15 +11,11 @@ on a background thread and must not access any editor UI state.
1411
public class %%AssetName%%Compiler : AssetCompilerBase { ... }
1512
```
1613

17-
`AssetCompilationContext` is the standard context for game-asset compilation. Other contexts exist
18-
for thumbnail generation and template expansion, but `AssetCompilationContext` is always the right
19-
choice for new engine assets.
14+
`AssetCompilationContext` is the standard context for game-asset compilation. Other contexts exist for thumbnail generation and template expansion, but `AssetCompilationContext` is always the right choice for new engine assets.
2015

2116
## Implement `Prepare`
2217

23-
`Prepare` is called once per asset. It must populate `result.BuildSteps` with one or more
24-
`AssetCommand<T>` instances that do the actual work. The commands are executed later, possibly in
25-
parallel with commands from other assets.
18+
`Prepare` is called once per asset. It must populate `result.BuildSteps` with one or more `AssetCommand<T>` instances that do the actual work. The commands are executed later, possibly in parallel with commands from other assets.
2619

2720
```csharp
2821
protected override void Prepare(
@@ -37,13 +30,11 @@ protected override void Prepare(
3730
}
3831
```
3932

40-
`targetUrlInStorage` is the URL under which the compiled output must be saved in the content
41-
database. Pass it to `ContentManager.Save` inside `DoCommandOverride`.
33+
`targetUrlInStorage` is the URL under which the compiled output must be saved in the content database. Pass it to `ContentManager.Save` inside `DoCommandOverride`.
4234

4335
## Implement the Build Command
4436

45-
The command does the actual compilation work. It extends `AssetCommand<TParameters>` where
46-
`TParameters` is the asset type (or a dedicated parameters struct for complex conversions).
37+
The command does the actual compilation work. It extends `AssetCommand<TParameters>` where `TParameters` is the asset type (or a dedicated parameters struct for complex conversions).
4738

4839
```csharp
4940
public class %%AssetName%%Command(string url, %%AssetName%%Asset parameters, IAssetFinder assetFinder)
@@ -65,19 +56,13 @@ public class %%AssetName%%Command(string url, %%AssetName%%Asset parameters, IAs
6556
}
6657
```
6758

68-
`Parameters` is the typed asset instance passed from `Prepare`. `Url` is the
69-
`targetUrlInStorage` value passed to the constructor.
70-
`MicrothreadLocalDatabases.ProviderService` provides the content database to the
71-
`ContentManager` on the compiler thread.
59+
`Parameters` is the typed asset instance passed from `Prepare`. `Url` is the `targetUrlInStorage` value passed to the constructor. `MicrothreadLocalDatabases.ProviderService` provides the content database to the `ContentManager` on the compiler thread.
7260

7361
## Declare External File Dependencies (`GetInputFiles`)
7462

75-
Override `GetInputFiles` when the compiler reads external files (e.g. a `.png` or `.fbx`). This
76-
allows the build system to detect changes and invalidate the cache correctly.
63+
Override `GetInputFiles` when the compiler reads external files (e.g. a `.png` or `.fbx`). This allows the build system to detect changes and invalidate the cache correctly.
7764

78-
The pattern requires **two parts**: overriding `GetInputFiles` on the compiler class, and wiring
79-
it to the build command via `InputFilesGetter` in `Prepare`. Without the wiring, the build cache
80-
will never invalidate when source files change.
65+
The pattern requires **two parts**: overriding `GetInputFiles` on the compiler class, and wiring it to the build command via `InputFilesGetter` in `Prepare`. Without the wiring, the build cache will never invalidate when source files change.
8166

8267
**Step 1 — Override `GetInputFiles` on the compiler:**
8368

@@ -90,9 +75,7 @@ public override IEnumerable<ObjectUrl> GetInputFiles(AssetItem assetItem)
9075
}
9176
```
9277

93-
Check that `asset.Source` is not null or empty before calling `GetAbsolutePath``GetAbsolutePath`
94-
throws an `ArgumentException` if passed a null or empty path. `GetAbsolutePath` is a helper on
95-
`AssetCompilerBase` that resolves a `UFile` source path relative to the asset's location on disk.
78+
Check that `asset.Source` is not null or empty before calling `GetAbsolutePath``GetAbsolutePath` throws an `ArgumentException` if passed a null or empty path. `GetAbsolutePath` is a helper on `AssetCompilerBase` that resolves a `UFile` source path relative to the asset's location on disk.
9679

9780
**Step 2 — Wire it to the command in `Prepare`:**
9881

@@ -102,19 +85,14 @@ result.BuildSteps.Add(
10285
{ InputFilesGetter = () => GetInputFiles(assetItem) });
10386
```
10487

105-
`InputFilesGetter` is a `Func<IEnumerable<ObjectUrl>>` delegate on `Command`. The build engine
106-
calls it when computing the command hash; without it, file changes are invisible to the cache.
88+
`InputFilesGetter` is a `Func<IEnumerable<ObjectUrl>>` delegate on `Command`. The build engine calls it when computing the command hash; without it, file changes are invisible to the cache.
10789

10890
> [!NOTE]
109-
> Alternatively, override `GetInputFiles()` (no parameters) directly on the command class itself.
110-
> `Command.GetInputFiles()` calls `InputFilesGetter` by default, but you can override it instead
111-
> to keep the logic self-contained on the command — this avoids the delegate wiring entirely.
112-
> `TextureConvertCommand` uses this approach.
91+
> Alternatively, override `GetInputFiles()` (no parameters) directly on the command class itself. `Command.GetInputFiles()` calls `InputFilesGetter` by default, but you can override it instead to keep the logic self-contained on the command — this avoids the delegate wiring entirely. `TextureConvertCommand` uses this approach.
11392
11493
## Declare Asset Dependencies (`GetInputTypes`)
11594

116-
Override `GetInputTypes` when the compiler needs another asset to be compiled first, or needs to
117-
read another asset's compiled output during compilation.
95+
Override `GetInputTypes` when the compiler needs another asset to be compiled first, or needs to read another asset's compiled output during compilation.
11896

11997
```csharp
12098
public override IEnumerable<BuildDependencyInfo> GetInputTypes(AssetItem assetItem)
@@ -135,30 +113,18 @@ public override IEnumerable<BuildDependencyInfo> GetInputTypes(AssetItem assetIt
135113
| `CompileAsset` | The uncompiled `Asset` object of the dependency is read during compilation. |
136114
| `CompileContent` | The compiled output of the dependency is read during compilation. |
137115

138-
Use `CompileAsset` when you only need to read the asset class properties — this is cheap and
139-
imposes no hard build-order constraint beyond "loaded". Use `CompileContent` when you need the
140-
compiled binary output, which requires the dependency to be fully compiled first. Use `Runtime`
141-
for runtime references that are embedded in the compiled output, not accessed at compile time.
116+
Use `CompileAsset` when you only need to read the asset class properties — this is cheap and imposes no hard build-order constraint beyond "loaded". Use `CompileContent` when you need the compiled binary output, which requires the dependency to be fully compiled first. Use `Runtime` for runtime references that are embedded in the compiled output, not accessed at compile time.
142117

143118
> [!WARNING]
144-
> Do not create circular dependencies via `GetInputFiles` or `GetInputTypes`. Asset A depending
145-
> on B while B depends on A will deadlock the build.
119+
> Do not create circular dependencies via `GetInputFiles` or `GetInputTypes`. Asset A depending on B while B depends on A will deadlock the build.
146120
147121
## Assembly Placement
148122

149-
Compiler classes live in the same assembly as the asset class. For engine assets in
150-
`Stride.Assets`, the compiler also lives in `Stride.Assets`. The `[AssetCompiler]` attribute is
151-
discovered at startup when the assembly is registered with `AssemblyCommonCategories.Assets`.
152-
Compilers must not reference editor assemblies.
123+
Compiler classes live in the same assembly as the asset class. For engine assets in `Stride.Assets`, the compiler also lives in `Stride.Assets`. The `[AssetCompiler]` attribute is discovered at startup when the assembly is registered with `AssemblyCommonCategories.Assets`. Compilers must not reference editor assemblies.
153124

154125
## Template
155126

156-
The `Prepare` method and build command shown above form the complete starting template for a new
157-
compiler. Copy both blocks, replace `%%AssetName%%` with your asset's PascalCase name, and fill
158-
in the property mapping inside `DoCommandOverride`.
127+
The `Prepare` method and build command shown above form the complete starting template for a new compiler. Copy both blocks, replace `%%AssetName%%` with your asset's PascalCase name, and fill in the property mapping inside `DoCommandOverride`.
159128

160129
> [!NOTE] Game projects
161-
> For game-project custom assets, the compiler class lives in the game project itself.
162-
> Add `<PackageReference Include="Stride.Core.Assets.CompilerApp" IncludeAssets="build;buildTransitive" />`
163-
> to the game project's `.csproj` — this brings in the infrastructure that discovers and invokes
164-
> the compiler; it does not change where the compiler class lives.
130+
> For game-project custom assets, the compiler class lives in the game project itself. Add `<PackageReference Include="Stride.Core.Assets.CompilerApp" IncludeAssets="build;buildTransitive" />` to the game project's `.csproj` — this brings in the infrastructure that discovers and invokes the compiler; it does not change where the compiler class lives.

0 commit comments

Comments
 (0)