Table of Contents

Component Family Classification

Groups components into semantic families for stable, readable Workbench visualizations.

Status: โœ… Implemented ยท Visibility: Internal ยท Category: Schema

๐ŸŽฏ What it solves

The Workbench Data Flow Timeline and Access Matrix show every component a system touches, but a flat list of dozens of component names doesn't read as a picture โ€” there's no visual grouping to tell "movement data" apart from "combat data" apart from "network sync data" at a glance. Component Family Classification assigns each component to one of a small set of well-known families so the Workbench can group and order rows consistently, without requiring the schema author to maintain a separate taxonomy file.

โš™๏ธ How it works (in brief)

Each component resolves to a family name through two steps, in order: an explicit [ComponentFamily("Name")] attribute on the struct wins if present; otherwise a server-side heuristic substring-matches the component's name against fixed token lists (e.g. Position/Velocity/Transform โ†’ Spatial, Health/Damage/Shield โ†’ Combat). Unmatched names fall back to Misc. The heuristic is the safety net for components you didn't explicitly tag, and the only path available when classifying components from a recorded trace (no live Type to read attributes from). The Workbench renders families in a fixed canonical order so the layout is stable across sessions, independent of declaration order or alphabetical sort.

๐Ÿ’ป Usage

using System.Runtime.InteropServices;
using Typhon.Schema.Definition;

// Explicit โ€” wins over the name heuristic regardless of the component's name.
[Component("Game.Squad", revision: 1)]
[ComponentFamily("AI")]
[StructLayout(LayoutKind.Sequential)]
public struct SquadCommandComponent
{
    public int TargetEntityId;
}

// No attribute โ€” classified by the name heuristic from "Position" -> Spatial.
[Component("Game.Position", revision: 1)]
[StructLayout(LayoutKind.Sequential)]
public struct PositionComponent
{
    public float X;
    public float Y;
    public float Z;
}

There is no API call to make as the application developer โ€” registering the component (RegisterComponentFromAccessor<T>()) is enough. Classification happens server-side when a Workbench session attaches.

Family Heuristic tokens (substring match)
Spatial Position, Velocity, Bounds, Rotation, Transform, Scale, Pose
Combat Health, Damage, Armor, Shield, Hp, Hit
AI Behaviour, Behavior, Target, Pathfind, NavMesh, Decision
Inventory Inventory, Equipment, Equipped, Ammo, Item
Rendering Sprite, Animation, Mesh, Material, Tint, Render
Networking Network, Replication, Sync, Snapshot
Input Input, Command, Action
Misc (default fallback โ€” no match)

โš ๏ธ Guarantees & limits

  • [ComponentFamily] always overrides the heuristic, regardless of how the component is named.
  • The heuristic always returns a family โ€” there's no "unclassified" state; unmatched names land in Misc.
  • Row order in the Workbench is fixed: Spatial โ†’ Combat โ†’ AI โ†’ Inventory โ†’ Rendering โ†’ Networking โ†’ Input โ†’ Misc, identical across sessions.
  • Token matching is ordinal substring matching against fixed, non-configurable lists โ€” there is no way to add custom families or tokens without an attribute on the component itself.
  • Trace (recorded) sessions can only use the name heuristic โ€” [ComponentFamily] requires reflecting the live CLR Type, which a trace replay doesn't have.
  • This is a presentation/grouping aid only โ€” family has no effect on storage, indexing, validation, or schema evolution.
  • This is a Workbench-only concern.

๐Ÿงช Tests

  • ComponentFamilyResolverTests โ€” attribute-wins-over-heuristic, per-token heuristic classification (TestCase per family), Misc fallback, canonical family order
  • Sibling: Workbench Per-Session Schema Loading & ALC Reload โ€” classification runs server-side each time a Workbench session attaches or reloads
  • Source: src/Typhon.Engine/Schema/internals/ComponentFamilyResolver.cs, src/Typhon.Schema.Definition/Attributes.cs