Skip to content

Families Roles and Classification Policy

off-cmd edited this page Sep 16, 2026 · 1 revision

Families, Roles and Classification Policy

Relevant source files

The following files were used as context for generating this wiki page:

Purpose and Scope

This page defines how FFXIV virtual file paths are mapped into logical texture families, sub-parts, and processing roles within XIVUpscaler (clarity). It details the policy rules governing upscaling tiers, source and output edge caps, role-specific function dispatch, and the test suites enforcing these invariants.

Sources: clarity/processing/roles.py:1-40, tests/test_roles_policy.py:1-158, tests/test_manifest_classify.py:1-122 clarity/processing/roles.py:1-40


Path Mapping and the Classifier (classify)

The manifest scanning and database population phases rely on the path classification engine to inspect asset paths and store their categorized metadata (family, part, role).

Path parsing uses prefix matching and suffix inspection. For instance:

  • Character equipment (chara/equipment/), accessories (chara/accessory/), and weapons (chara/weapon/) map to their respective families with roles driven by filename suffixes (_n for normal, _m for mask, _d for color/diffuse) tests/test_manifest_classify.py:46-56.
  • Human character paths (chara/human/) extract sub-parts (such as body, face, hair, tail, zear) which refine the family name (e.g., human-body, human-face) tests/test_manifest_classify.py:67-85.
  • World assets (bg/ and bgcommon/) inspect zone segments to branch housing and indoor/outdoor subsets into distinct policy families like bg-hou, bg-ind, and bgcommon-hou tests/test_manifest_classify.py:88-100.
  • UI assets (ui/icon/ and ui/uld/) map to ui-icon and ui-uld families tests/test_manifest_classify.py:102-105.
graph TD
    A["RawPath: string"] --> B["clarity.manifest.classify()"]
    B --> C{"Prefix Match"}
    C -->|"chara/equipment/"| D["Family: equipment"]
    C -->|"chara/human/obj/body/"| E["Family: human-body, Part: body"]
    C -->|"bg/.../hou/..."| F["Family: bg-hou"]
    C -->|"ui/icon/"| G["Family: ui-icon"]
    D --> H["Suffix Inspection (_n, _m, _d)"]
    H --> I["Role: normal | mask | color"]
    
    classDef default fill:#fff,stroke:#000,stroke-width:1px;
    class A,B,C,D,E,F,G,H,I default;
Loading

Figure 1: Path classification flow mapping raw strings to family and role structures.

Sources: tests/test_manifest_classify.py:46-122 tests/test_manifest_classify.py:46-122


Families, Processing Roles, and the Policy Map

The dictionary roles.POLICY establishes the canonical mapping from resource family names to a tuple of (top_tier, max_source_edge) clarity/processing/roles.py:16-37.

Each family defines its maximum allowable upscaling tier ("4x", "2x", or None) and a source dimension cap (max_source_edge) clarity/processing/roles.py:16-37. If a family has a top tier of None (such as human-hair or vfx), it is explicitly excluded from processing pipelines clarity/processing/roles.py:53-59.

Family Top Tier Max Source Edge (cap) Role Behavior / Notes
equipment, accessory, weapon "4x" 1024 High-detail character gear
monster, demihuman, human-body "2x" 2048 Character models
bg, bgcommon "2x" 1024 Standard world environment maps
bg-hou, bg-ind, bg-zear "2x" 2048 Specialized housing/interior geometry
ui-icon "4x" 512 Inventory and HUD icons
ui-uld, ui-other "2x" 2048 Layout configuration textures
human-hair, vfx None 0 Excluded (handled by external pipelines) clarity/processing/roles.py:26-36

Sources: clarity/processing/roles.py:16-37, tests/test_roles_policy.py:24-42 clarity/processing/roles.py:16-37


Tier Selection Logic (top_tier and tiers_below)

The function top_tier(family, w, h, override) determines the target maximum upscale tier clarity/processing/roles.py:41-65. It enforces two primary halving invariants:

  1. Source Edge Cap: If the source dimension (max(w, h)) exceeds the family's cap (cap), the texture downgrades down to "native" outright clarity/processing/roles.py:63-64.
  2. Output Edge Cap: If the resulting scaled dimension exceeds MAX_EDGE_OUT (4096), the scale halves iteratively until it fits within bounds clarity/processing/roles.py:38, 63-64.
graph TD
    A["top_tier(family, w, h, override)"] --> B{"Family in POLICY?"}
    B -->|No / Tier is None| C["Return None (Skipped)"]
    B -->|Yes| D["Determine Scale via TIER_SCALE or override"]
    D --> E{"max(w, h) > family_cap?"}
    E -->|Yes| F["Halve scale down to 1 (native)"]
    E -->|No| G{"max(w, h) * scale > MAX_EDGE_OUT (4096)?"}
    G -->|Yes| H["Halve scale iteratively"]
    G -->|No| I["Return Target Tier String"]
    F --> I
    H --> I

    classDef default fill:#fff,stroke:#000,stroke-width:1px;
    class A,B,C,D,E,F,G,H,I default;
Loading

Figure 2: Evaluation sequence inside top_tier() enforcing source and output constraints.

Sources: clarity/processing/roles.py:41-78, tests/test_roles_policy.py:50-128 clarity/processing/roles.py:41-78


Role Dispatch Table (ROLE_FN)

Processing execution dispatches to specific subsystem functions based on the texture's assigned role via ROLE_FN clarity/processing/roles.py:81-87.

Sources: clarity/processing/roles.py:81-87, tests/test_roles_policy.py:43-47 clarity/processing/roles.py:81-87


Policy Invariants and Test Verification

To prevent regressions in classification or scale logic, the test suites (tests/test_roles_policy.py and tests/test_manifest_classify.py) enforce strict invariants:

  • Exclusivity of Caps: Source caps are evaluated strictly (max(w, h) > cap), meaning an edge matching the cap exactly is accepted, while one pixel over triggers a downgrade tests/test_roles_policy.py:105-114.
  • Override Restrictions: Command-line overrides (e.g., --top 2x) can select lower tiers or apply limits, but cannot resurrect an excluded family whose policy tier is None tests/test_roles_policy.py:115-123.
  • Chain Consistency: Every valid policy top tier yields a descending chain of mips ending in "native" via tiers_below() tests/test_roles_policy.py:150-157.

Sources: tests/test_roles_policy.py:1-158, tests/test_manifest_classify.py:1-178 tests/test_roles_policy.py:1-157

Clone this wiki locally