Files
sow-tools/internal/topdata/FEAT_GENERATED_FAMILIES_CONTRACT.md
T
archvillainette dc93feb176 Topdata Migration (#2)
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>
2026-04-09 07:14:01 +00:00

3.6 KiB

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:

{
  "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:

{
  "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