Data Catalogs

Data Catalogs are the bridge between simple serialized data and real runtime/editor values.

Instead of storing direct object references everywhere, you store stable ids:

  • catalog id (Catalog)
  • entry key (Key)

Then the system resolves those ids to actual values through registered catalogs.

Create assets (Unity menu)

In the Project window: Create → CupkekGames → Data → Catalog, entries are grouped by kind:

SubmenuPurposeConcrete types (samples library)
ValueKey → typed value (string, int, float, bool). Inspector uses IValueCatalog.GetDisplayValue next to the key (e.g. tier key 0Common).StringCatalog, IntCatalog, FloatCatalog, BoolCatalog
AssetKey → Unity Object (Sprite, ScriptableObject, …). Inspector shows object preview + ObjectField readout.SpriteCatalog, ScriptableObjectCatalog (both AssetCatalog<T>)
KeysKey list only; no per-key stored value.KeyCatalog

Each catalog asset has a Catalog Id field (serialized as _catalogId) that must match the CatalogKey.Catalog string and the ServiceLocator registration key.

Runtime UI (samples): ItemTierFeature resolves tooltip tier text with IValueCatalog.GetDisplayValue under InventoryConstants.ItemTierCatalogId. Slot Background USS uses a slug from that display when present (e.g. common), otherwise a slug from the raw key; ClearSlotVisual strips both those slugs and legacy raw-key classes for every known tier key.

Why This Architecture Is Powerful

  • Serialization everywhere: Data remains plain and serializable across ScriptableObjects, JSON, save files, and tooling.
  • Stable schema: Your runtime model does not need to change when underlying asset providers change.
  • Inspector-friendly: You can still select assets visually (dropdown + preview) while storing only string keys.
  • Portable data: Key-based data can be authored in-editor, generated by tools, or loaded from external sources later.
  • Future-ready pipelines: The same key model works for local catalogs now and remote/web-fed catalogs later.

Real-World Benefit

You can keep a field like IconKey as two strings, but in inspector it still behaves like asset selection.

That means:

  • designers get clear previews and dropdowns
  • serialized data stays lightweight and diff-friendly
  • runtime can resolve values from whichever catalog source is currently registered

Core Interfaces

  • ICatalogCatalogId + GetKeys() (every catalog registers this).
  • IAssetCatalog / IAssetCatalog<T> — resolve a key to a Unity Object (T : Object). Used by asset-backed authoring and CatalogKey previews for sprites and other assets.
  • AssetCatalog<T> — typical ScriptableObject implementation for asset catalogs (SpriteCatalog, ScriptableObjectCatalog, custom AssetCatalog<YourSO>).
  • IValueCatalog / IValueCatalog<T> — resolve a key to a non-Object value plus a GetDisplayValue(string key) string for the inspector. The CatalogKey drawer calls this when no IAssetCatalog is registered for that catalog id.
  • Concrete value catalogs in samples: StringCatalog, IntCatalog, FloatCatalog, BoolCatalog (each implements IValueCatalog<T> and registers ICatalog, IValueCatalog, and IValueCatalog<T>).

Adding another primitive-backed catalog (for example double) follows the same pattern: implement IValueCatalog<double>, register the three interfaces, and add a Create menu under Catalog → Value.

Registration Model

Asset catalog (AssetCatalog<T>) — register with catalog id (often append: true so several assets share one logical id):

csharp
ServiceLocator.Register(this, typeof(ICatalog), catalogId, append: true); ServiceLocator.Register(this, typeof(IAssetCatalog), catalogId, append: true); ServiceLocator.Register(this, typeof(IAssetCatalog<T>), catalogId, append: true);

Value catalog (e.g. StringCatalog) — same id pattern, value interfaces:

csharp
ServiceLocator.Register(this, typeof(ICatalog), catalogId, append: true); ServiceLocator.Register(this, typeof(IValueCatalog), catalogId, append: true); ServiceLocator.Register(this, typeof(IValueCatalog<string>), catalogId, append: true);

Keys-only (KeyCatalog) — ICatalog only.

Consumers resolve by catalog id string, for example:

csharp
var iconCatalogs = ServiceLocator.GetAll<IAssetCatalog>("ItemIcon"); var tierStrings = ServiceLocator.GetAll<IValueCatalog>("ItemTier");

Web / Remote JSON Direction

This model also supports future external content flows:

  • import data from local JSON files
  • fetch remote JSON payloads
  • map incoming ids to catalog keys
  • resolve runtime values from registered providers

The key point is that your gameplay schema stays unchanged because it already stores ids, not hard references.

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL