2 authoring reference registry
forgejo-actions edited this page 2026-07-11 10:33:50 +00:00

Authoring Reference Registry

Purpose

The authoring reference registry is the editor's typed index of IDs that authors can choose, validate, inspect, rename, or delete. It turns scene snapshots and catalog snapshots into AuthoringReferenceCard rows, then gives UI panels a shared lookup API for validation, autocomplete, impact previews, and catalog-item migration plans.

The registry is a projection, not a source of truth. Source content remains in scene documents and catalog files. Panels should build the registry from shared snapshots and signatures, then route edits back through the owning authoring workflow.

Steps

  1. Build or retrieve the shared content workspace for the current editor frame.
  2. Build the registry from the workspace snapshots and source signatures.
  3. Use validate(kind, id) for live field health and autocomplete-backed pickers.
  4. Use impact_for(kind, id) before rename or delete operations.
  5. For typed catalog-backed IDs, create a rename or delete migration plan and route the edits through the owning authoring workflow.
  6. Rebuild the workspace and registry after saving so stale signatures do not drive follow-up edits.

Construction

AuthoringReferenceRegistry::from_sources collects cards through registered contributors and then builds three indexes:

  • (AuthoringReferenceKind, normalized id) to card index;
  • reference kind to card indexes;
  • reference kind to autocomplete card indexes.

IDs are normalized with trim plus ASCII lowercase for lookups. Cards remain sorted by kind, label, and id for stable UI output.

Frame-level UI code should use AuthoringReferenceRegistryFrameCache::registry_for_sources. Its cache key is built from explicit AuthoringReferenceSourceSignatures when supplied, or from debug/content hashes of the source snapshots as a fallback. The shared content workspace supplies the preferred source signatures.

Contributor Registration

contributors.rs owns the contributor manifest and collector table. Every contributor has an AuthoringReferenceContributorDescriptor with:

  • domain_id;
  • label;
  • source dependencies;
  • capabilities;
  • optional world-domain catalog registry id;
  • autocomplete provider descriptors.

Current contributor domains are game data, scene, mob, NPC, dialogue, quest, and NPC service. Source dependencies tell readers which snapshots the contributor needs. Capabilities declare whether the contributor provides references, record editors, effects, validation hints, or autocomplete metadata.

Adding a domain requires two matching registrations:

  1. Add a descriptor to CONTRIBUTOR_MANIFEST.
  2. Add an AuthoringReferenceContributor with a collector callback to CONTRIBUTORS.

The collector should use the builder helpers (define, define_usage, push, push_usage, and scene-transient variants) so definitions, references, usages, and catalog metadata remain consistent.

Reference Kinds

AuthoringReferenceKind is descriptor-backed. Each kind declares a label, stable registry provider id, whether it requires a definition, and optional catalog binding.

Current kinds are:

  • quest and quest flag;
  • inventory item, currency, vendor stock, and crafting recipe;
  • party tag, faction, scene variable, trigger, runtime event, and condition preset;
  • dialogue sequence;
  • mob, NPC, and NPC service;
  • unlock.

Kinds with requires_definition = true become missing when references exist without a definition source. Kinds such as quest flags, party tags, factions, scene variables, runtime events, and unlocks can be reference-only because they may be intentionally open-ended or runtime-defined.

Catalog-backed kinds carry CatalogRegistryId and CatalogItemIdKind. Migration and diagnostics should use that typed binding instead of string-matching labels.

Definition And Impact Resolution

The builder distinguishes definitions from references:

  • define and define_usage record a definition source.
  • push and push_usage record a reference source.
  • scene-transient helpers also attach the SceneTransient source layer diagnostic.

Each card keeps all sources, definition sources, reference sources, and typed usages. A usage can include owner asset path, field path, route, source label, and repair adapter.

validate(kind, id) returns an AuthoringReferenceResolution for live fields. Empty IDs return Empty, known IDs return the card health, and unknown IDs return Missing with a repair hint.

impact_for(kind, id) returns an AuthoringReferenceImpact for rename/delete previews. It includes the same health and catalog binding, plus definition and reference source lists and usages. Use impact resolution when a UI needs to explain what will change; use validation when a UI only needs field health.

Autocomplete Provider IDs

Registry-backed autocomplete provider IDs come from kind descriptors and contributor descriptors. Stable provider IDs include:

  • registry.quest
  • registry.quest_flag
  • registry.inventory_item
  • registry.currency
  • registry.vendor_stock
  • registry.crafting_recipe
  • registry.trigger
  • registry.scene_variable
  • registry.dialogue_sequence
  • registry.mob
  • registry.npc
  • registry.npc_service

Game-data record editor providers also expose value-snippet routes:

  • game_data.records.catalog
  • game_data.records.item_taxonomy
  • game_data.records.item_aliases
  • game_data.records.items
  • game_data.records.vendor_stocks
  • game_data.records.crafting_recipes
  • game_data.records.loot_tables
  • game_data.records.loadout_rules
  • game_data.records.gathering_nodes

Use AuthoringReferenceRegistry::contributor_autocomplete_provider_descriptors() when a panel needs the current contributor-owned provider list. Do not hard-code a separate provider table in UI code.

Expected Outputs

A successful registry build produces sorted reference cards, typed autocomplete provider descriptors, validation resolutions for field editors, impact reports for preview panels, and migration plans with touched definitions, references, usage routes, rollback safety, and transaction metadata.

Rename And Delete Migration

plan_catalog_item_rename and plan_catalog_item_delete produce AuthoringCatalogItemMigrationPlan values. These plans are preview objects for typed catalog-backed IDs.

A rename plan:

  • resolves current impact and target impact;
  • blocks empty, unchanged, untyped, undefined, or already-defined target IDs;
  • warns when the target ID is referenced but not defined;
  • creates definition and reference edits from the current impact;
  • adds transaction metadata with touched catalog item, definition source, reference source, and usage references.

A delete plan:

  • resolves impact for the source ID;
  • blocks untyped, empty, or undefined IDs;
  • blocks deletion while references still exist;
  • warns when deleting existing definitions without references;
  • creates edits that remove definition/reference rows by setting to_id to None.

Migration metadata uses AuthoringRollbackSafety::MultiAssetPartialRollbackRisk because edits may span multiple owner assets or catalog shards.

Blocked Migration Cases

The planner intentionally blocks these cases:

  • no source ID was provided;
  • the reference kind is not backed by a typed catalog registry and item id kind;
  • the source ID has no definition source;
  • rename target ID is empty;
  • rename target equals the source ID case-insensitively;
  • rename target already has a definition source;
  • delete target still has reference sources.

The planner does not block a rename target that is referenced but undefined. It emits a warning because the rename will bind those references to the renamed catalog item.

Contributor Rules

Collectors should attach typed usages whenever possible. Prefer AuthoringReferenceUsageRoute variants such as game-data item, vendor stock, crafting recipe, quest, scene trigger, NPC service, asset, or unresolved only when no route is available.

For catalog-backed references, preserve catalog metadata from AuthoringReferenceKind::catalog_binding and catalog_registry_descriptor. This keeps source layer, fallback, and override diagnostics available to authoring panels.

Scene-derived catalog references should use the scene-transient helpers until baked scene catalog ownership exists. The transient layer diagnostic tells authors that the reference is editor-derived, not a stable catalog source.

Panels should read cards, validation, impact, and autocomplete descriptors from the registry. They should not rescan catalogs for their own ID pickers; that creates drift from rename/delete previews and repair routing.

Common Mistakes

  • Hard-coding autocomplete provider tables in a panel.
  • String-matching labels instead of using AuthoringReferenceKind descriptors and catalog bindings.
  • Treating scene-transient references as durable catalog definitions.
  • Renaming to an ID that already has a definition source.
  • Deleting a catalog item while reference sources still exist.

Recovery Paths

When a migration plan is blocked, inspect the blocked reason, resolve missing definitions or remaining references, rerun impact_for, and rebuild the plan. If a panel sees stale data after a save, refresh the shared content workspace before trying another migration. If a new domain is invisible to autocomplete, check both the contributor descriptor and collector registration.