218 lines
5.9 KiB
Markdown
218 lines
5.9 KiB
Markdown
# Asset Declaration and Virtual Asset Contract Specification
|
|
|
|
Status: Draft
|
|
Scope: Common `asset.json` contract
|
|
Purpose: Define the shared declaration model for raw and virtual assets.
|
|
|
|
## Authority and Precedence
|
|
|
|
This specification consolidates the initial packer agenda and decision wave into normative form.
|
|
|
|
## Core Rules
|
|
|
|
The common `asset.json` contract requires these top-level fields:
|
|
|
|
- `schema_version`
|
|
- `asset_uuid`
|
|
- `name`
|
|
- `type`
|
|
- `inputs`
|
|
- `output`
|
|
- `preload`
|
|
|
|
The common contract may also include:
|
|
|
|
- `build`
|
|
|
|
## Meaning of `asset_uuid`
|
|
|
|
`asset_uuid` is the stable asset-local identity anchor.
|
|
|
|
Rules:
|
|
|
|
- it is required;
|
|
- it must be stable across relocate and rename flows;
|
|
- it is not the project-local runtime artifact identity;
|
|
- it is not a substitute for registry-owned `asset_id`;
|
|
- it exists so the asset root can preserve identity even when path-based assumptions drift;
|
|
- it must remain compatible with packer reconcile behavior and migration flows.
|
|
|
|
## Meaning of `name`
|
|
|
|
`name` is the logical asset reference label.
|
|
|
|
Rules:
|
|
|
|
- it is required;
|
|
- it is not the stable artifact identity;
|
|
- it may still be used by runtime-facing APIs and source-level workflows.
|
|
|
|
## Meaning of `type`
|
|
|
|
`type` identifies the authoring-side asset family.
|
|
|
|
Rules:
|
|
|
|
- it is not the runtime bank identity;
|
|
- the runtime-facing technical target belongs in `output.format`.
|
|
|
|
Examples:
|
|
|
|
- `tile_bank`
|
|
- `sound_bank`
|
|
|
|
## Inputs
|
|
|
|
`inputs` is a structured object keyed by semantic role.
|
|
|
|
Rules:
|
|
|
|
- each key names an input role such as `sprites`, `palettes`, or `sources`;
|
|
- each value is a list of paths;
|
|
- paths are relative to the asset root;
|
|
- even a single input is represented as a list.
|
|
|
|
This model supports grouped virtual assets such as atlases and bank-style assets.
|
|
|
|
## Output
|
|
|
|
`output` is the runtime-relevant output declaration.
|
|
|
|
Required baseline fields:
|
|
|
|
- `output.format`
|
|
- `output.codec`
|
|
|
|
Optional baseline field:
|
|
|
|
- `output.metadata`
|
|
- `output.pipeline`
|
|
|
|
Rules:
|
|
|
|
- `output.format` defines the semantic/runtime format contract;
|
|
- `output.codec` defines storage/extraction behavior;
|
|
- `output.metadata` carries runtime-relevant format-specific detail;
|
|
- `output.pipeline` carries pipeline-injected metadata kept separate at authoring time;
|
|
- codec must remain explicit and must not be hidden inside format naming.
|
|
|
|
### Explicit Index Collections
|
|
|
|
When `output.pipeline` carries ordered collections whose members need stable semantic identity, that identity must not depend on raw list position alone.
|
|
|
|
Rules:
|
|
|
|
- collections such as `output.pipeline.palettes` may remain JSON arrays for authoring ergonomics;
|
|
- when a collection member has runtime- or packing-relevant identity, each entry must carry an explicit `index`;
|
|
- `output.pipeline.palettes` entries must use the shape `{ "index": <int>, "palette": { ... } }`;
|
|
- the packer must sort such entries by numeric `index`, not by physical array position;
|
|
- duplicate or malformed indices are structural errors;
|
|
- missing or malformed `palette` payloads are structural errors;
|
|
- editorial reordering of the JSON array alone must not change semantic meaning.
|
|
|
|
Example:
|
|
|
|
```json
|
|
{
|
|
"output": {
|
|
"pipeline": {
|
|
"palettes": [
|
|
{
|
|
"index": 0,
|
|
"palette": {
|
|
"originalArgb8888": [4294901760, 4278255360],
|
|
"convertedRgb565": [63488, 2016]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Metadata Source Segmentation and Runtime Sink
|
|
|
|
`asset.json` may keep metadata segmented by concern during authoring.
|
|
|
|
Rules:
|
|
|
|
- declaration-time metadata may come from multiple sources under the asset contract (for example, format metadata, codec-related metadata, and build/pipeline-derived declarations);
|
|
- `output.pipeline` may carry nested pipeline-derived metadata objects;
|
|
- this segmentation exists for authoring clarity and does not define multiple runtime sinks;
|
|
- runtime consumers must read effective metadata from the runtime asset entry metadata sink (`AssetEntry.metadata`);
|
|
- convergence/normalization behavior is normative in the build artifact specification.
|
|
|
|
## Build
|
|
|
|
`build` is optional and process-oriented.
|
|
|
|
Rules:
|
|
|
|
- it may describe how authoring inputs are transformed or organized;
|
|
- if a parameter affects the runtime-facing output contract, it belongs in `output.metadata`;
|
|
- `build` must not hide runtime-relevant semantics.
|
|
|
|
## Operational State Exclusion
|
|
|
|
`asset.json` is a declaration artifact, not a catalog cache.
|
|
|
|
Rules:
|
|
|
|
- transient UI state must not be stored in `asset.json`;
|
|
- registry-managed fields such as `asset_id` and `included_in_build` must not be duplicated into `asset.json`;
|
|
- packer cache or snapshot bookkeeping must not be materialized into `asset.json` as normal operational state;
|
|
- `asset.json` should remain focused on identity anchoring plus declared authoring/packing behavior.
|
|
|
|
## Preload
|
|
|
|
Each registered asset must declare preload intent explicitly.
|
|
|
|
Baseline shape:
|
|
|
|
```json
|
|
{
|
|
"preload": {
|
|
"enabled": true
|
|
}
|
|
}
|
|
```
|
|
|
|
Rules:
|
|
|
|
- `preload.enabled` is required and boolean;
|
|
- preload participation is declared, not inferred;
|
|
- richer preload policy fields are deferred.
|
|
|
|
## Defaults and Materialization
|
|
|
|
Defaults that affect runtime-visible behavior must not remain hidden.
|
|
|
|
Rules:
|
|
|
|
- runtime-relevant defaults should be materialized in `asset.json` whenever practical;
|
|
- if materialized later, the resulting artifact must expose effective values explicitly.
|
|
|
|
## Versioning
|
|
|
|
The `asset.json` schema is versioned independently from:
|
|
|
|
- registry schema
|
|
- runtime-facing artifact schema
|
|
- format contract versions
|
|
|
|
Format-specific contracts evolve through values such as `TILES/indexed_v1`.
|
|
|
|
## Non-Goals
|
|
|
|
- field-level format schemas for every output family
|
|
- rich preload policies
|
|
- source-language lowering behavior for asset references
|
|
|
|
## Exit Criteria
|
|
|
|
This specification is complete enough when:
|
|
|
|
- the common `asset.json` shape is stable;
|
|
- raw and virtual assets share a coherent baseline contract;
|
|
- format-specific specs can build on it cleanly.
|