Skip to content

XRef Tables — Review Matrix

STATUS: PROPOSED — NOT IMPLEMENTED. Verified 2026-08-27.

The three cross-reference tables specified here — enemy_biomes, card_eligible_classes, card_eligible_factions — appear in zero source or SQL files. This is an April 2026 schema proposal that was never built.

Branch: feat/xref-tables
Context: Three join tables being added to replace single-FK eligibility with many-to-many: - enemy_biomes — which biomes an enemy can appear in - card_eligible_classes — which classes can receive a card as a reward/shop offer - card_eligible_factions — which factions can include a card in their run pool

Semantics (empty join table = eligible for all)
An enemy with no enemy_biomes entries appears in every biome (fallback behaviour preserved).
A card with no card_eligible_classes entries is available to every class.
A card with no card_eligible_factions entries is available in every faction's run.


1. Enemy → Biome Matrix

Biome keys: submerged-archive · sunblasted-ruin · machine-sanctuary

Initial seeding mirrors the existing name-keyword logic. Multi-biome entries are possible and encouraged for future cross-over enemies.

Enemy Type AssetId GUID suffix Sub-Archive Sun-Ruin Mach-Sanct Notes
Needlefin Archivist Minion 2002 ...11
Choir Eel Minion 2003 ...12
Brine Pike Minion 2050 ...15
Archive Custodian Elite 2005 ...13
Archive Breach Core Boss 2006 ...14
Ash Scavenger Minion 2007 ...21
Sand Shark Minion 2008 ...22
Glassback Jackal Minion 2009 ...25
Ward Captain Elite 2010 ...23
Ruin Sovereign Boss 2011 ...24
Lattice Sentry Minion 2012 ...31
Calibration Hound Minion 2013 ...32
Servo Manta Minion 2014 ...35
Calibration Overseer Elite 2015 ...33
Control Chamber Core Boss 2016 ...34

Tutorial enemies (Valerii campaign): no biome assignments yet. These are campaign-only and don't appear in QuickPlay biome pools. Assign when QuickPlay cross-faction content is added.

Design questions to resolve: - [ ] Should any enemies span multiple biomes? (e.g. a generic enemy type that fit both ruin AND archive) - [ ] Void-Stalker variants (Tutorial) — assign to a future void-realm biome when QuickPlay adds it?


2. Card → Eligible Classes Matrix

Cards with no entries = eligible for all classes (blank = universal).
Cards with entries = restricted to listed classes only.
Initial seeding is derived from the existing single ClassId FK.

Card AssetId Anchor Drifter Conduit Machinist Catalyst Faction Gated Notes
Neutral / Shared pool
Shield Challenge 1000 Valerii No class restriction
Stand Between 1001 Valerii No class restriction
Ablative Drone 1002 Neutral
Ghostwalk Feint 1003 Currently Drifter → class-tied
Emergency Shunt 1004 Neutral
Rescue Compound 1005 Neutral
Anchor starter cards
Foundry Bulwark 1100
Dense Impact 1101
Holdfast Array 1102
Gravemass Advance 1103
Sinkline Guard 1104
Drifter starter cards
Phase Strike 1200
Flicker Jab 1201
Dimensional Slip 1202
Echo Mark 1203
Tempo Burst 1204
Conduit starter cards
Arc Discharge 1300
Volt Siphon 1301
Insulation Field 1302
Plasma Lash 1303
Flux Tap 1304
Machinist starter cards
Repair Drone Bay 1400
Rivet Burst 1401
Field Plating 1402
Caliber Shot 1403
Machine Spindle 1404
Catalyst starter cards
Mutagenic Strike 1500
Hothouse Surge 1501
Adaptive Plating 1502
Unstable Slash 1503
Chaotic Draw 1505

Design questions: - [ ] Should any class-specific cards be cross-class? (e.g. "Rivet Burst" also usable by Conduit?) - [ ] Neutral pool: some are currently unlocked — should they stay that way or get class restrictions added?


3. Card → Eligible Factions Matrix

Cards with no entries = available in any faction's run.
Cards with entries = only offered when playing that faction's quest.
Initial seeding derived from existing single FactionId FK.

Card AssetId Valerii Axiom Syndicate Censors Salvari Notes
Valerii faction cards
Shield Challenge 1000 Also has Valerii FactionId
Stand Between 1001
Valerii Shieldwall 1600 Starter
Edict Shield 1160~?
Silent Tribunal
Cold Marshal
Axiom faction cards
Syntacta Analysis 1602 Starter
Syndicate faction cards
Aethari Ignition 1602~ Starter
Echo Flare
Crystal Veil 1606 Starter
Censors faction cards
Annalis Recall 1604~ Starter
Echo Strike
Historical Record 1614 Shop
Salvari faction cards
Salvari Salvage Starter
Borrowed Plate
Neutral cards (no faction gate)
Ablative Drone 1002 All factions
Emergency Shunt 1004 All factions
Rescue Compound 1005 All factions
All class starters 1100-1504 All factions

Design questions: - [ ] Should faction cards also be eligible for alliances with other factions? (e.g. Valerii card available in Axiom run) - [ ] Salvari faction: currently no Salvari starter — is that correct?


4. Implementation Plan

Tables being added

-- enemy_biomes
CREATE TABLE enemy_biomes (
    enemy_id UUID NOT NULL REFERENCES enemies(id) ON DELETE CASCADE,
    biome_key VARCHAR(50) NOT NULL,
    PRIMARY KEY (enemy_id, biome_key)
);

-- card_eligible_classes
CREATE TABLE card_eligible_classes (
    card_id UUID NOT NULL REFERENCES cards(id) ON DELETE CASCADE,
    class_id UUID NOT NULL,
    PRIMARY KEY (card_id, class_id)
);

-- card_eligible_factions
CREATE TABLE card_eligible_factions (
    card_id UUID NOT NULL REFERENCES cards(id) ON DELETE CASCADE,
    faction_id UUID NOT NULL,
    PRIMARY KEY (card_id, faction_id)
);

Admin UI changes

  • EnemyEdit: multi-select with fixed options (3 biomes)
  • CardEdit: replace classId / factionId single-selects with eligibleClassIds[] / eligibleFactionIds[] multi-selects

Game logic (follow-up: after admin data is populated)

  • QuickPlayRunService.FilterEnemiesByBiome() → query from enemy_biomes table instead of keyword matching
  • Card reward/shop pool → filter by card_eligible_classes and card_eligible_factions