Native topdata migration summary - Replaced the legacy 2dabuilder runtime path with the native topdata builder. - Native build, validate, compare, and convert flows now cover the canonical topdata pipeline. - compare-topdata is now a native self-check; legacy reference-builder runtime usage was removed. - Parts generation follows the native asset-scan contract and uses sow-assets via project asset resolution. - Generated feat families, class-feat injects, masterfeat/successor expansion, and dataset-derived feat generation were brought to parity and regression-covered. - Remaining mirrored datasets were migrated into native-owned canonical data while preserving lock IDs. - normalize-topdata bridge behavior and migration-era ownership markers were removed. - Documentation was rewritten around the native workflow and active contracts were cleaned up. - Final hardening pass removed stale validator assumptions and cleaned ignored/generated artifacts for PR readiness. Reviewed-on: https://gitea.westgate.pw/ShadowsOverWestgate/sow-tools/pulls/2 Co-authored-by: vickydotbat <vickydotbat@tutamail.com> Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
111 lines
3.6 KiB
Markdown
111 lines
3.6 KiB
Markdown
# `feat` Generated Families Contract
|
|
|
|
Canonical authored paths:
|
|
|
|
- `topdata/data/feat/base.json`
|
|
- `topdata/data/feat/lock.json`
|
|
- `topdata/data/feat/generated/skill_focus.json`
|
|
- `topdata/data/feat/generated/greater_skill_focus.json`
|
|
- `topdata/data/feat/generated/weapon_focus.json`
|
|
- `topdata/data/feat/generated/weapon_specialization.json`
|
|
- `topdata/data/feat/generated/greater_weapon_focus.json`
|
|
- `topdata/data/feat/generated/greater_weapon_specialization.json`
|
|
- `topdata/data/feat/generated/improved_critical.json`
|
|
- `topdata/data/feat/generated/overwhelming_critical.json`
|
|
- `topdata/data/feat/generated/proficiencies.json`
|
|
- `topdata/data/feat/modules/activecombat/core.json`
|
|
- `topdata/data/feat/modules/activecombat/specialattacks.json`
|
|
- `topdata/data/feat/modules/class/core.json`
|
|
- `topdata/data/feat/modules/combat/core.json`
|
|
- `topdata/data/feat/modules/defensive/core.json`
|
|
- `topdata/data/feat/modules/magical/core.json`
|
|
- `topdata/data/feat/modules/other/core.json`
|
|
- `topdata/data/feat/modules/proficiency/core.json`
|
|
- `topdata/data/feat/modules/racial/core.json`
|
|
- `topdata/data/feat/modules/removedandhidden/core.json`
|
|
- `topdata/data/feat/modules/skillfeat/affinity.json`
|
|
- `topdata/data/feat/modules/skillfeat/focus.json`
|
|
- `topdata/data/feat/modules/skillfeat/greaterfocus.json`
|
|
- `topdata/data/feat/modules/skillfeat/other.json`
|
|
|
|
`skill_affinity` is no longer authored as a generated feat file. It is synthesized from
|
|
canonical `racialtypes` race grants.
|
|
|
|
Compact family-expansion shape:
|
|
|
|
```json
|
|
{
|
|
"family": "skill_focus",
|
|
"family_key": "skillfocus",
|
|
"template": "masterfeats:skillfocus",
|
|
"child_source": {
|
|
"dataset": "skills",
|
|
"predicate": "accessible"
|
|
},
|
|
"overrides": {
|
|
"skills:craft_alchemy": {
|
|
"ICON": "ife_foc_alchm"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Weapon family shape:
|
|
|
|
```json
|
|
{
|
|
"family": "weapon_focus",
|
|
"family_key": "weaponfocus",
|
|
"template": "masterfeats:weaponfocus",
|
|
"child_source": {
|
|
"dataset": "baseitems",
|
|
"column": "WeaponFocusFeat"
|
|
},
|
|
"overrides": {
|
|
"baseitems:heavymace": {
|
|
"ICON": "ife_wepfoc_Lma"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Rules:
|
|
|
|
- compact generated families are:
|
|
- `skill_focus`
|
|
- `greater_skill_focus`
|
|
- `weapon_focus`
|
|
- `weapon_specialization`
|
|
- `greater_weapon_focus`
|
|
- `greater_weapon_specialization`
|
|
- `improved_critical`
|
|
- `overwhelming_critical`
|
|
- `proficiencies`
|
|
- compact families must declare `template`
|
|
- compact families must also declare:
|
|
- `family_key`
|
|
- `child_source.dataset`
|
|
- weapon families must also declare `child_source.column`
|
|
- skill families use `child_source.predicate: "accessible"` to mean
|
|
`HideFromLevelUp != 1`
|
|
- compact `overrides` are keyed by source dataset key:
|
|
- `skills:*` for skill families
|
|
- `baseitems:*` for weapon families
|
|
- generated rows carry `meta.family` so the underscore family rule is preserved even
|
|
before wiki generation exists
|
|
- emitted feat keys must prefer existing canonical lock/TLK identities over newly
|
|
derived child spellings
|
|
- `proficiencies.json` is limited to the real masterfeat-backed `weaponproficiencycommoner_*`
|
|
family
|
|
- manual and irregular feat content continues to live under `feat/modules/`
|
|
- generated families and module-authored feats are merged into the same final `feat.2da`
|
|
pipeline and share inheritance, override, TLK, and family-metadata behavior
|
|
|
|
Current rollout policy:
|
|
|
|
- `feat.2da` still builds natively
|
|
- `feat.2da` is still excluded from `compare-topdata` output-catalog self-check coverage
|
|
via `compare_reference: false`
|
|
- manual and irregular feat families remain authored directly in modules rather than
|
|
compact generated-family files
|