Experimental · 0.8.1.0
This guide describes the experimental branch. For the current public package, see stable downloads. Experimental overview.
Declare cooked content for live registries¶
SchemaVersion is optional informational metadata. Examples retain 1 as an
authoring label; changing or omitting it does not disable supported declarations.
Fields, ownership, references and limits are still validated independently.
A registry declaration tells RuneSchema which cooked assets to connect to the game. Use a small JSONC file for an existing PAK, or include the declaration in your cooked content.
Step-by-step workflow¶
- Identify cooked content that lacks another reliable enrollment route; avoid duplicating ordinary loader registration.
- Choose a loose
registry/*.jsoncdeclaration or a mod-owned cooked registry asset containing exact object paths and supported lanes. - Keep identity/construction in the asset or owning loader; declarations do not create missing classes or permission.
- Mount the content provider and restart; verify every required lane and its gameplay consumer before relying on cleanup certification. Cook a declaration asset only when choosing the cooked route.
Use these JSONC examples as a starting point, with your own paths, IDs and values. Include the cooked assets they reference so the game can find everything your mod needs.
Related guides: Registry loader, PAK content, recipes and journal.
A PAK mount makes cooked packages available to Unreal. It does not by itself promise that an unreferenced item, recipe, spell, or attack is in the gameplay list that uses it. RuneSchema supports a mod-owned cooked registry asset that names specific content to resolve and reconcile with supported live registries. The game remains authoritative: an already-present matching entry is accepted rather than duplicated.
Use this declaration for a cooked catalogue or a gameplay asset that has no
other reliable native path into its live registry. A small mod may instead
reference a cooked item through assets and
connect it with recipes. RuneSchema 0.8.0.0 also
accepts recipe, journal and lore loader metadata inside the cooked declaration,
so a PAK need not duplicate those pointers in loose files. Do not create
thousands of empty pointer files for a large PAK.
Choose loose JSONC or a cooked declaration¶
If the item assets are already cooked but their PAK has no registry declaration,
you do not need to recook that PAK just to announce them. Ship a loose
RuneSchema/mods/<ModName>/registry/10-native-items.jsonc document instead.
The loose item-registration walkthrough
includes the folder layout, enable line, JSONC example, downloadable starter,
and verification steps. NativeRegistries and LoaderDefinitions are accepted
from enabled loose registry documents as well as cooked declaration assets.
For a complete unchanged-PAK layout, use the legacy sidecar conversion walkthrough. JSONC is an explicit fallback when the PAK has no declaration, not an automatic scan of all of its assets or a way to suppress rejected cooked metadata.
Use one declaration route per reference. Neither route creates missing cooked
content or substitutes for its stable native identity. Ordinary item clones
created by /assets already use their owning loader's registration route.
Alternatively, put the declaration in the owning PAK¶
Create a cooked data asset named RSREG_* or DA_RuneSchemaRegistry*. It
must contain a RegistryOwner string and a RuneSchemaRegistryJson string
(or RegistryJson). Use a stable owner matching the enabled mod folder for
the conventional path described below. This cooked route is optional when
using a loose registry document. Keep SchemaVersion: 1 and Entries: [] even when
the asset declares only native content.
With normal Asset Registry metadata, RuneSchema discovers matching cooked assets. If an IoStore package has no usable metadata, it checks this one conventional path for each enabled mod:
For the conventional path, RegistryOwner must exactly match <ModFolder>.
It may point to owned gameplay assets under another permanent content root.
The shared bridge walkthrough explains how to
author the data asset without replacing the shared base.
Minimal example: a cooked item and recipe¶
The JSON below is the value of the cooked asset's RuneSchemaRegistryJson
property. These are example paths; replace them with exact cooked object paths.
{
"SchemaVersion": 1,
"Entries": [],
"NativeRegistries": {
"Items": ["/GoldenArsenal/Items/ITEM_GoldenSpear.ITEM_GoldenSpear"],
"Recipes": ["/GoldenArsenal/Recipes/RECIPE_GoldenSpear.RECIPE_GoldenSpear"]
}
}
The item needs the correct game data class, unique internal name, and stable
persistence ID. The recipe must point to the item and be connected to the
intended station through cooked relationships or the RuneSchema recipes
loader. Registry enrollment does not make a recipe appear at a station on its
own.
Supported declaration fields¶
Cooked buildings and station placement — development extension¶
This extension ships in 0.8.0.2, after its earlier 0.8.0.1b source preview. It adds
NativeRegistries.Buildings for exact existing BuildingPieceData object paths.
Stations use this same lane; their actor behavior, recipes, costs, stability,
meshes and interactions remain cooked. A bare declaration registers identity
without granting the piece to players or inventing a build-menu location.
To cook menu placement into the registry asset, use LoaderDefinitions.Buildings:
{
"SchemaVersion": 1,
"Entries": [],
"LoaderDefinitions": {
"Buildings": {
"/Example/Buildings/BUILDING_Workbench.BUILDING_Workbench": {
"AddTo": {"Collection": "Modded Buildings", "PageIndex": 0},
"Unlock": false
}
}
}
}
The path also announces the building; do not repeat it in NativeRegistries.Buildings.
AddTo accepts one placement or an array of up to 64. PageIndex is a
nonnegative int32; omitted indices default to zero. Optional PersistenceID
and InternalName fields are assertions against the cooked asset, never
replacement identities. Unlock defaults to false. Native cooked catalogue
references remain intact; this does not automatically merge arbitrary mod-owned
catalogue assets into the game's menu.
A loose /buildings/*.jsonc definition targeting the same Asset can override
individual settings. Omitted menu/unlock settings inherit the cooked registry
metadata; supplied AddTo replaces that placement list rather than appending.
Existing loose definitions without a cooked declaration retain their old defaults.
For example, this keeps the cooked placement while overriding health:
{
"WorkbenchOverride": {
"Asset": "/Example/Buildings/BUILDING_Workbench.BUILDING_Workbench",
"Overrides": {"Health": {"MaxHealth": 2500}}
}
}
Cooked building metadata rejects Properties, Overrides, Requirements,
clones and arbitrary class references. Use the normal loose building loader for
intentional gameplay overrides. An already-published runtime clone is not an
automatic migration to a differently identified cooked asset.
Enrollment uses the existing building catalogue and world registrar on clients
and dedicated servers. Keep the buildings loader enabled and install matching
content/load order everywhere. An identity/type/assertion failure reports
RS-BLD-023 and defers world-building cleanup; unrelated character lanes are
not vetoed by this building-specific failure. Test old-save load, placement,
deconstruction, host/client interaction, world exit and re-entry before release.
Enrollment scope¶
For additional cooked rows in a vanilla DataTable, the development
LoaderDefinitions.DataTables route imports missing
rows before the usual loose JSON edits. It preserves existing target rows and
requires a matching row struct; it is separate from native asset enrollment.
Loose and cooked declarations share the same supported lanes and schemas. They name exact assets; they do not search every object in a PAK.
| Registry lanes | Enrollment boundary |
|---|---|
| Items, Recipes, Quests | Existing native identities; recipes still need station/discovery relationships. |
| Buildings (development) | Existing BuildingPieceData through the building/world registrar, with optional menu metadata. |
| Journals, Lore | Existing journal identities through the owning journal/lore service. |
| CombatSpells, UtilitySpells, EquipmentEffects | Existing native data; the mod supplies its gameplay consumers. |
| ContainerContents, FarmPlants, Trees, TreeGrowth | Cooked native-family identities; consumer behavior/lifecycle is not certified by declaration acceptance. |
| FixedTextNotifications, FTUENotifications, PlayerHooks, WorldHooks | Cooked native-family identities; enrollment does not fire a notification or activate a hook. |
| WearableMeshData | Dependency resolution/class checking, not a persistence entry. |
| Enums | Read-only verification of mod-owned cooked enum symbols. |
| Skills, SkillPerks | Explicitly blocked until native progression and consumer lifecycle are verified. |
| MeleeAttackClasses, RangedAttackClasses, CacheAssets | Optional attack metadata/artwork ownership, not universal gameplay registries; see their limits below. |
| Field | What RuneSchema does | What the mod must still provide |
|---|---|---|
Items |
Resolves cooked item data and reconciles the item identity registry. | Complete item data, unique identity, art, and gameplay references. |
Recipes |
Resolves cooked recipe data and reconciles the recipe registry. | Ingredient/output references and station or unlock relationship. |
Quests |
Resolves cooked quest data and reconciles the quest registry. | Quest objectives, triggers, and valid progress behavior. |
Journals |
Uses the journal loader to register an existing cooked journal entry of any supported native journal type. | Cooked pages, stable identity, section placement and an unlock trigger. |
Lore |
Uses the lore loader to register existing cooked Lore entries. | Cooked Lore data, stable identity, placement and an unlock trigger. |
CombatSpells |
Reconciles combat-spell data. | Cooked spell data and the weapon or gameplay path that uses it. |
UtilitySpells |
Reconciles utility-spell data. | Cooked spell data and its invocation path. |
EquipmentEffects |
Reconciles held-equipment effect data. | Valid effect references and owning equipment behavior. |
WearableMeshData |
Resolves and class-checks named mesh-data dependencies. | An equipped wearable item that references the correct male/female mesh data, meshes, materials, and hide rules. |
MeleeAttackClasses |
Supplies an ordered class plan to the optional melee fallback. | Complete cooked attack classes in intended order; enable the specific fallback setting. |
RangedAttackClasses |
Accepted by the schema but not installed as a global ranged class list. | Use an item-owned ranged collection instead. |
CacheAssets |
Declares exact original artwork ownership for source-targeted Helpy caches. Never enrolls a texture as an item or makes gameplay content available. | Full object paths of original artwork belonging to this mod; omit borrowed base-game/plugin artwork. |
Three additional fields are staged in the development source: Skills,
SkillPerks and Enums. Skills and SkillPerks accept owned cooked object
references but are not enabled native adapters: startup reports
[NATIVE-REGISTRY][UNVERIFIED] without loading or mutating those registries or
progress. Do not release a custom skill on the strength of declaration acceptance.
Enums verifies a mod-owned cooked UserDefinedEnum, preserves its cooked
symbol/value pairs and publishes their owner-scoped network fingerprint. It
does not add native enum members, allocate values, convert ESkill, or bind a
foreign enum to a native property. Use directly cooked, correctly typed mod
properties for bindings; Blueprint enum labels must be stable across releases.
Eight additional cooked-only lanes are implemented in development:
ContainerContents, FarmPlants, Trees, TreeGrowth,
FixedTextNotifications, FTUENotifications, PlayerHooks and WorldHooks.
See native data-family enrollment for exact
classes, startup guards and unverified consumer-lifecycle limits. These enroll
identities; behavior stays cooked. They do not grant pruning authority.
These are the supported NativeRegistries fields. Each field accepts at most 4,096
unique paths; a declaration accepts at most 16,384 references in total,
including LoaderDefinitions entries. The cooked JSON string is bounded to
512 KiB in 0.8.0.0 (older builds: 256 KiB). For larger catalogues, use a conventional root with explicit
RegistryShards and marked child assets as described in
bounded cooked registry shards. Those pages load
directly, without Asset Registry enumeration or a whole-project registry file.
Independent metadata-discoverable declarations remain supported. Duplicate,
invalid, unresolved, wrong-class, or conflicting entries are reported rather
than silently converted to a different content type.
Keep recipe, journal and lore metadata in the PAK¶
LoaderDefinitions accepts Recipes, Journals and Lore maps. Each key is
the full cooked object path; its value is the ordinary loader definition
body. It references an existing cooked asset, not a new runtime clone. A path
in LoaderDefinitions does not also need a NativeRegistries pointer.
{
"SchemaVersion": 1,
"Entries": [],
"NativeRegistries": {
"Items": ["/Example/Items/ITEM_Dye.ITEM_Dye"]
},
"LoaderDefinitions": {
"Recipes": {
"/Example/Recipes/RECIPE_Dye.RECIPE_Dye": {
"Unlock": false,
"AddTo": [{
"DataTable": "/Example/Stations/DT_Stations.DT_Stations",
"Row": "DyeStation",
"Category": "Dyes"
}]
}
},
"Journals": {
"/Example/Journal/JOURNAL_Trader.JOURNAL_Trader": {
"Unlock": false,
"AddTo": {"Section": "Knowledge", "Category": "People", "Group": "Craftsmen"}
}
},
"Lore": {
"/Example/Journal/JOURNAL_Note.JOURNAL_Note": {
"Unlock": false,
"UnlockOnAcquire": true,
"ItemData": "/Example/Items/ITEM_Note.ITEM_Note",
"AddTo": {"Section": "Knowledge", "Category": "Lore Scraps"}
}
}
}
}
All paths, station row/category and group above are examples. The station must
already have the matching native row/array contract. Cooked ingredient/output
references remain part of the recipe asset. See the recipe loader
and journal loader for the supported body fields,
native discovery conditions and journal routes. /lore remains Lore-only;
Journals can use People, Place, World, Recipe, Treasure or Lore entries.
Rules:
- Registration alone does not grant player progress. Cooked declarations
default to
Unlock: false, including bareNativeRegistries.Recipes,JournalsandLorepaths. ExplicitUnlock: trueopts into the existing loader's automatic delivery; it does not bypass native unlock confirmation. - Recipe bodies may carry
Discoveryfor native pickup, interaction and skill-level rules. This is the same recipe discovery contract as a loose/recipesoverride, not the journalUnlockConditionstruct. - An omitted journal
UnlockConditionleaves the asset's native condition intact. Supply a supported condition in its loader body to override it, or unlock via an NPC'sJournalEntriesfull cooked path or a cooked gameplay event. Merely placing a page does not prove discovery. - Existing loose
/recipes,/journaland/loredefinitions for the same cooked path take precedence. Identical repeated declarations are idempotent; conflicting cooked bodies reject that lane rather than choosing a winner. Declare each journal asset in eitherJournalsorLore, not both. - These declarations cannot contain
$Clone,$Patch,$Targetor vendor-offer directives. Keep those in their ordinary loose authoring loaders. Cooked journal identity assertions must match the shipped asset, not replace it. - This is an explicit announcement contract, not a wildcard scan of every asset in a PAK. Existing PAKs can be accompanied by a loose declaration; recooking is necessary only to embed the declaration inside the PAK. No game saves or mod lists are rewritten to adopt the contract.
The authoring shape is available in
cooked-registry.schema.json. Runtime
validation additionally checks class compatibility, identity conflicts,
cross-document conflicts and the combined document limit.
Orphan-only automatic cleanup¶
Automatic character cleanup consults the settled live identity registries,
not whether a loose pointer file exists. A registered cooked recipe or
journal/lore ID remains valid when its duplicate loose declaration is removed.
Already learned progress is not revoked merely because Unlock becomes false.
Unresolved IDs can be pruned after their content is disabled or removed and
the applicable registry has been verified. No orphaned IDs means no cleanup
write.
A rejected enabled cooked declaration, missing persistent registry binding, failed recipe/journal enrollment, or disabled required loader vetoes automatic character cleanup for that session. A failed load is not evidence of an orphan. Restart after correcting the declaration to rebuild its authority. World-building cleanup retains its separate live-building-registry and enabled-definition safeguards. Explicit manual owner-removal is a separate opt-in operation, not the automatic orphan-only policy.
Physical, ranged, and magic attacks¶
These are different game paths; there is no universal attack registry.
- Melee: cook the attack classes and list a complete ordered collection in
MeleeAttackClasses. This lane is an optional, guarded fallback controlled by combat fallback settings. Ordinary item registration is independent of that switch. - Ranged: declare the cooked weapon item in
Items. ItsHeldEquipmentDatamust reference a cookedRangedAttackCollectionwith a completeQuickAttackDataandFullAttackDatapair. RuneSchema can admit that pair to the live ranged component when the corresponding fallback is enabled. A list of projectile classes inRangedAttackClassesdoes not do this. - Magic: declare persistent spell data in
CombatSpellsorUtilitySpells. Keep the weapon's cookedMagicAttackCollectionand its spell links intact. Do not put spell data in a melee or ranged class field.
For step-by-step weapon authoring, use weapons and items. AI attack collection registration is not offered by this declaration.
Validate the complete path¶
- Put the PAK and its cooked registry asset inside an enabled mod folder.
- Keep the shared Registry Bridge plugin enabled if the asset derives from its authoring base.
- Confirm the log reports the package as mounted and the cooked declaration as discovered with the expected owner.
- Confirm each requested object resolves and the relevant live-registry summary reports it as present or added, not rejected.
- Confirm the item can be obtained, equipped, saved, and used; confirm a recipe is connected to its intended station and an attack actually fires.
- For multiplayer gameplay, ship matching cooked content to the server and participating clients. Registry parity diagnostics are not content download or replication of missing PAK files.
RuneSchema/mods/runeschema.txt controls whether the mod contributes its PAK
and declaration. A line set to 0 contributes neither on the next launch.
Avoid reusing another mod's content path or persistence identity. RuneSchema's
save cleanup checks the applicable settled live registry; the declaration
itself is not a cleanup authority.
Cooked object-path comparisons are case-insensitive across native paths, loader metadata and Schema provenance. Case aliases cannot enroll the same asset twice, hide conflicting policies, or split a journal asset between Lore and Journals. Conflicting publication rejects the new batch without changing the previous declarations. Original object paths and persistence identities are not rewritten.