Skip to main content

Crate wh40kdc

Crate wh40kdc 

Source
Expand description

Rust types for the 40kdc-data Warhammer 40K schema layer.

Every type in this crate is generated from the canonical JSON Schemas by cargo run -p xtask -- codegen. The schema content these types describe is published under CC0 — see the crate README.

use wh40kdc::Unit;

let data = std::fs::read_to_string("path/to/units.json").unwrap_or("[]".to_string());
let units: Vec<Unit> = serde_json::from_str(&data).unwrap();

With the default bundled-data feature the whole dataset ships embedded behind a linked, typed API (Dataset) — find an entity and follow it to its weapons, abilities, phases, and faction:

use wh40kdc::{Dataset, Phase};

let ds = Dataset::embedded();
let kharn = ds.find_unit("Kharn").unwrap(); // resolves "Khârn the Betrayer"
let shooting: Vec<&str> = ds
    .abilities_of(kharn)
    .into_iter()
    .filter(|a| ds.phases_of(a).contains(&Phase::Shooting))
    .map(|a| a.ability_id.as_str())
    .collect();
assert_eq!(shooting, ["berzerker-frenzy"]);

Re-exports§

pub use data::normalize_name;
pub use data::Collection;
pub use data::Dataset;
pub use data::RawData;
pub use data::clamp_weapon_count;
pub use data::maximal_loadout;
pub use data::option_cap;
pub use data::validate_loadout;
pub use data::Loadout;
pub use data::Violation;
pub use data::ViolationCode;
pub use data::WeaponBound;
pub use translate::describe_ability;
pub use translate::describe_award;
pub use translate::describe_condition;
pub use translate::describe_effect;
pub use translate::describe_effect_inline;
pub use translate::describe_effect_with_scope;
pub use translate::describe_scope;
pub use translate::describe_scoring_card;
pub use translate::describe_trigger;
pub use terrain::keystone_measurements;
pub use terrain::resolve_layout;
pub use terrain::Keystone;
pub use terrain::KeystoneError;
pub use terrain::KeystoneMeasurement;
pub use terrain::ResolvedPiece;
pub use terrain::TerrainKeystoneError;
pub use terrain::TerrainResolveError;
pub use terrain::BOARD_INCHES;
pub use scoring::empty_player_game;
pub use scoring::player_primary;
pub use scoring::player_secondary;
pub use scoring::player_total;
pub use scoring::score_award;
pub use scoring::score_cap;
pub use scoring::score_primary_event;
pub use scoring::score_secondary;
pub use scoring::score_secondary_event;
pub use scoring::score_turn;
pub use scoring::set_primary;
pub use scoring::wtc_result;
pub use scoring::AssertedAward;
pub use scoring::PlayerGame;
pub use scoring::RoundCell;
pub use scoring::ScoreEntry;
pub use scoring::ScoringMode;
pub use scoring::WtcResult;

Modules§

cruncher
Expected-value damage-projection engine: pure-function math over schema profiles and a flat Buff stack (default cruncher). Mirrors tools/src/cruncher/ in the TS package; the conformance/cruncher/ corpus pins both implementations to within 5e-4 per pipeline stage. The damage-projection engine: pure-function math over schema profiles and a flat Buff stack.
data
Linked, typed access over the embedded dataset (default bundled-data). Linked, typed access over the embedded 40kdc dataset.
defaults
Generation of default values for serde.
error
Error types.
export
Roster exporter: resolved Roster → NewRecruit JSON / wtc-compact / wtc-full / simple / canonical Roster JSON (default export). Dataset-free — outputs depend only on the Roster shape, which keeps Rust and TS byte-identical for export goldens. Roster exporters — the symmetric counterpart to the importer.
import
Army-list importer: ListForge share payload + NewRecruit (JSON / wtc / simple) → resolved 40kdc roster (default import). The same module hosts the Roster domain types, which are also reused by the exporter — so it stays available whenever either import or export is enabled. Army-list importer: turn an external list-builder export into a resolved 40kdc [Roster].
scoring
Card-driven secondary-mission scoring engine: pure-function VP computation from asserted awards, plus per-round, per-player scoring state. Mirrors tools/src/scoring/ in the TS package (the reference implementation); the conformance/scoring corpus pins both ports. Depends only on the generated types, so it stays available even in a types-only build. Card-driven secondary-mission scoring engine — pure-function VP computation.
terrain
Terrain layout geometry: resolve template-anchored layouts to absolute board-space vertices. Pure (no data deps), so available in every build. Cross-impl pinned by the terrain-resolver conformance corpus. Terrain layout resolver — the Rust mirror of tools/src/terrain/resolve.ts.
translate
Plain-English translation of secondary-card scoring awards (mission “how to play” readouts) plus the shared Ability-DSL condition humanizer. Mirrors tools/src/translate/ in the TS package; the conformance/scoring-translation/ corpus pins both implementations to byte-identical output. Depends only on the generated types, so it stays available even in a types-only (default-features = false) build. Plain-English translation of secondary-card scoring awards — the Rust mirror of tools/src/translate/ in the TS package. Output is ASCII-only and must be byte-for-byte identical to the TS oracle; the conformance/scoring-translation corpus pins both ports (the differ compares structurally, with no tolerance). Any phrasing change here is a semantic corpus change (bump conformance/SPEC_VERSION).

Structs§

Ability
Community-authored structured representation of what a game ability does. NOT GW text.
AbilityInteractionsItem
AbilityInteractionsItem
ArmyCompositionPredicate
A draw-time predicate over an army list (not runtime board state, so deliberately NOT the Ability DSL condition). Used to gate when_drawn operations such as redraws. Example: a card that is void unless the opponent fields a large unit (10e ‘Cull the Horde’ redrew when the opponent had no unit of 14+ models) is { subject: ‘opponent’, quantifier: ‘none’, unit_filter: { model_count_min: 14 } } with operation ‘redraw’.
ArmyCompositionPredicateUnitFilter
Criteria a unit in the army must satisfy to match. All present criteria must hold (logical AND).
BaseSize
A model’s base. ‘round’ carries ‘diameter’; ‘oval’ carries ‘width’+‘length’. ‘flying-base’ (with ‘size’: small/large), ‘hull’, and ‘unique’ are categories the GW base-size guide gives without standard millimetre dimensions; entries carrying such a category, or any millimetre value not taken from an authoritative source, set ‘draft’: true to mark them for later hand-authoring.
ChoiceEffect
ChoiceEffect
ComposedFeature
A feature placed on an area template, positioned in the area’s centroid-local frame (y-down inches). When the area is placed, rotated, or mirrored, its composed features are carried along.
CompoundCondition
CompoundCondition
Condition
Condition
ConditionalEffect
ConditionalEffect
ContributorRef
GitHub handle or ‘40kdc-community’
DataslateVersion
Dataslate version: a quarterly tag (e.g. ‘2025-q3’) or a named kebab-case slug for non-quarterly slates (e.g. ‘pre-launch-provisional’)
DeploymentPattern
A deployment map: per-side deployment zones, objective positions, and (11e) per-side territory polygons. Pattern geometry carries forward unchanged from 10th edition; downstream tooling (e.g. bevy-deploy-helper) consumes this as the canonical encoding.
DeploymentPatternName
DeploymentPatternName
DeploymentPatternSource
Mission pack or source the pattern originates from (e.g. ‘leviathan’).
DeploymentPatternTerritoriesItem
DeploymentPatternTerritoriesItem
DeploymentPatternZonesItem
DeploymentPatternZonesItem
DeploymentPatternZonesItemColor
Hex render color for the zone overlay.
DeploymentPatternZonesItemName
DeploymentPatternZonesItemName
Detachment
A detachment option within a faction, providing a detachment rule, enhancements, and stratagems.
DetachmentName
DetachmentName
DetachmentRestrictions
DetachmentRestrictions
DiceGatedEffect
DiceGatedEffect
DicePoolAllocationEffect
DicePoolAllocationEffect
DicePoolAllocationEffectOptionsItem
DicePoolAllocationEffectOptionsItem
DicePoolAllocationEffectOptionsItemRequirement
DicePoolAllocationEffectOptionsItemRequirement
DicePoolAllocationEffectPool
DicePoolAllocationEffectPool
Edition
Game edition, e.g. ‘10th’ or ‘11’
Effect
Effect
Enhancement
A purchasable upgrade for a character unit, provided by a detachment.
EnhancementName
EnhancementName
EntityId
Kebab-case identifier
Faction
A playable faction or sub-faction.
FactionName
FactionName
ForceDisposition
A 11e strategic-intent tag granted by detachments. Players compare dispositions at game start to determine the shared mission; asymmetric primary objectives result.
ForceDispositionName
ForceDispositionName
ForceDispositionText
Community-authored description of the disposition’s effect (original prose only — no reproduced rules text).
GameVersion
GameVersion
GameVersionRef
GameVersionRef
InteractionFlag
InteractionFlag
Keyword
Keyword
KeywordList
KeywordList
LeaderAttachment
Defines which character units can attach to which bodyguard units.
Mission
An 11e primary mission (the objective a player scores). Which mission a player plays is selected by the Force Disposition matchup matrix (see mission-matchup), keyed on the player’s own disposition and their opponent’s. Victory points are capped per game and per battle round.
MissionMatchup
One cell of the 11e Force Disposition matrix: given the player’s own Force Disposition and their opponent’s, the mission that player plays. Mirrors a single row on a physical Force Disposition card. The (disposition, opponent_disposition) pair is the conceptual key; compound uniqueness across entries is a data convention, not enforced by this schema.
MissionName
MissionName
MissionSource
Mission pack or source the mission originates from.
PhaseList
PhaseList
PhaseMapping
PhaseMapping
Piece
One terrain piece placed on the board. Geometry comes from a catalog template or an inline footprint (if both are present, footprint is authoritative and template is provenance).
PieceKeystonesItem
PieceKeystonesItem
PieceLinkGroup
Pieces sharing a link_group value are linked terrain — treated as a single terrain feature (and, where an objective sits among them, a single objective).
PieceName
PieceName
PieceObjective
Objective-marker metadata. Only meaningful when is_objective is true.
ResourcePool
A faction’s resource system (Miracle Dice, Pain tokens, Blessings dice pool, etc.).
ResourcePoolGenerationItem
ResourcePoolGenerationItem
ResourcePoolName
ResourcePoolName
Scope
Scope
ScoringTrigger
When a VP award is evaluated. A bare phase is the legacy shorthand for ‘during this phase’; richer triggers add timing (the moment within a phase/turn/game), player_turn, and a battle_round window. A card’s section headers map onto these: ‘ANY BATTLE ROUND’ omits battle_round; ‘SECOND BATTLE ROUND ONWARDS’ is { min: 2 }; ‘END OF THE BATTLE’ is timing: end-of-battle.
ScoringTriggerBattleRound
Battle-round window in which the trigger is active. Absent means any battle round (1-5). ‘Second battle round onwards’ is { min: 2 }.
SecondaryCard
An 11e mission card. The deck-level rule (draw 2 per turn, keep unscored cards) is separate and not modelled here. This is the per-card shape: an optional on-draw deck operation, an optional player action, and zero or more VP-award blocks. Primary mission cards reuse this shape via card_type. Mechanic blocks reference the Ability DSL; prose is community-authored (no reproduced rules text).
SecondaryCardActionsItem
SecondaryCardActionsItem
SecondaryCardActionsItemActionId
Optional kebab-case identifier used to reference this action from action-completed conditions in awards[].when.
SecondaryCardActionsItemBattleRound
Battle-round window in which the action can be started. Absent means any battle round. ‘From the second battle round onwards’ (Triangulate, Extract Intelligence) is { min: 2 }.
SecondaryCardAwardsItemVariant0ExclusiveGroup
Awards sharing this kebab-case group key resolve as ‘score only the highest, not the sum’ (the card’s literal OR between tier rows). Awards with different exclusive_group values, or no value, accrue independently.
SecondaryCardAwardsItemVariant1ExclusiveGroup
Awards sharing this kebab-case group key resolve as ‘score only the highest, not the sum’ (the card’s literal OR between tier rows). Awards with different exclusive_group values, or no value, accrue independently.
SecondaryCardAwardsItemVariant1Per
What vp_per counts, as a kebab-case descriptor (e.g. ‘operation-marker-within-range-of-controlled-central-objective’). Required when vp_per is present.
SecondaryCardName
SecondaryCardName
SecondaryCardSubtype
Finer classification within the deck (e.g. a category or tactical/fixed split). Free-form — not enum-locked until 11e categories are confirmed.
SecondaryCardWhenDrawn
Optional deck operation performed when this card is drawn (e.g. redraw, swap). Distinct from combat effects — deck operations have no combat target, so they are not modelled via the Ability DSL effect language. If condition is present, the operation fires only when the predicate holds.
SecondaryCardWhenDrawnBattleRound
Battle-round window in which the draw operation is eligible (e.g. { max: 1 } means ‘only when drawn in the first battle round’). Absent means the operation fires regardless of round.
SequenceEffect
SequenceEffect
SimpleCondition
SimpleCondition
SingleEffect
SingleEffect
StatValueString
StatValueString
Stratagem
A CP-costed ability usable during specific game phases.
StratagemName
StratagemName
StratagemTargetRestrictions
StratagemTargetRestrictions
TerrainLayout
A recommended arrangement of terrain pieces on the board, independent of the deployment map (a deployment-pattern references the layouts it recommends via recommended_terrain_layout_ids). Each piece draws its geometry from a catalog template (a terrain-template entity) or an inline footprint; geometry is the source of truth. Placement is template-centroid-anchored: position is the piece’s centroid, which is invariant under rotation and mirror, so orientation and location are decoupled. Resolved board-space vertices are derived by the shared terrain resolver (pinned by the conformance corpus), never stored here. No layout data is authored yet beyond migrated examples.
TerrainLayoutName
TerrainLayoutName
TerrainLayoutSource
Mission pack or source the layout originates from.
TerrainTemplate
A reusable terrain piece in the standard catalog: a gameplay area (the 11e terrain-area templates) or a scenery feature (walls, containers, pipes, floor segments). Footprints are authored in natural local inches; the terrain resolver derives each footprint’s polygon area centroid and re-centers on it, so a layout piece that instances a template places its centroid via the layout’s position. An area template may carry an embedded features list — scenery placed in the area’s centroid-local frame — making the template a reusable composition (e.g. a ruin with its walls). Placing such a template places all of its features, transformed by the area’s own placement.
TerrainTemplateName
TerrainTemplateName
TerrainTemplateSource
Catalog or mission pack the template originates from.
TerrainTemplateUpperFloor
An elevated platform carried by this feature (e.g. a ruin’s second storey). Its footprint is authored in the SAME local frame as footprint and re-centered on the GROUND footprint’s polygon area centroid, so the two floors stay registered when the piece is placed, rotated, or mirrored. Non-resolved metadata: the terrain resolver does not emit it; authoring/visualization tools render it as an overlay. Meaningful for kind: "feature".
TimingFlag
TimingFlag
Unit
A unit datasheet entry with stat profiles and point costs.
UnitComposition
Describes the internal model-type breakdown of a unit.
UnitCompositionModelsItem
UnitCompositionModelsItem
UnitCompositionModelsItemName
UnitCompositionModelsItemName
UnitCompositionModelsItemProfileName
UnitCompositionModelsItemProfileName
UnitModelCount
UnitModelCount
UnitName
UnitName
UnitPointsItem
UnitPointsItem
UnitProfilesItem
UnitProfilesItem
UnitTransportCapacity
UnitTransportCapacity
Vec2
A 2D point in board inches. Origin at a board corner; JSON uses y-down (downstream renderers may flip to y-up).
Wargear
A non-weapon item a model may carry — an icon, attachment, or other piece of equipment with no weapon profile. Weapons live in weapon.schema.json; this entity exists so wargear-option swaps and add-ons can reference equipment that is not a weapon.
WargearCategory
Free-form grouping such as ‘icon’, ‘upgrade’, or ‘equipment’.
WargearName
WargearName
WargearOption
A wargear option available to models within a unit: a weapon/wargear swap, a pure add-on, or a choice between alternatives. Models start with the unit’s base loadout; an option modifies that loadout for the number of models its model_constraint permits.
WargearOptionModelConstraint
Limits how many models may take this option. The eligible-model count is: any_number ? model_count : per_n_models ? floor(model_count / per_n_models) : (max_count ?? 1); then clamped by max_count when both are set. model_name scopes the option to a specific model profile (e.g. the unit’s champion); omit for single-profile units.
WargearOptionModelConstraintModelName
WargearOptionModelConstraintModelName
Weapon
A weapon entry with one or more stat profiles (e.g., standard and overcharge modes).
WeaponKeyword
Catalog entry for a weapon keyword (Lethal Hits, Sustained Hits N, Anti-X N+, etc.). Each weapon profile references entries here via {keyword_id, parameters?} instead of carrying free-text strings. The optional effect describes the keyword’s game mechanic in the Ability DSL; null when the behaviour is faction-specific flavour not yet modelled.
WeaponKeywordName
WeaponKeywordName
WeaponName
WeaponName
WeaponProfilesItem
WeaponProfilesItem
WeaponProfilesItemKeywordsItem
WeaponProfilesItemKeywordsItem
WeaponProfilesItemKeywordsItemParameters
Reference-site parameters conforming to the catalog entry’s required_parameters. Only the three documented keys are accepted; any other key is invalid.
WeaponProfilesItemKeywordsItemParametersTargetKeyword
WeaponProfilesItemKeywordsItemParametersTargetKeyword
WeaponProfilesItemName
WeaponProfilesItemName
WeaponProfilesItemStats
WeaponProfilesItemStats
X40kdcBundledSchemas
Auto-generated by tools/src/bundle-schemas.ts. Single self-contained schema for Rust codegen — do not edit by hand.

Enums§

AbilityAbilityType
AbilityAbilityType
AbilityBehavior
How this ability interacts with the game flow — not a runtime predicate
AbilityInteractionsItemType
AbilityInteractionsItemType
ArmyCompositionPredicateQuantifier
Whether the army must contain (‘any’) or lack (‘none’) a unit matching unit_filter for the predicate to hold.
ArmyCompositionPredicateSubject
Whose army list the predicate inspects.
BaseSizeShape
BaseSizeShape
BaseSizeSize
Flying-base size class, when ‘shape’ is ‘flying-base’.
BattleSize
11e battle size, which sets the army’s points limit and detachment-point budget: ‘incursion’ = 1000 pts / 2 detachment points; ‘strike-force’ = 2000 pts / 3 detachment points.
ComposedFeatureMirror
ComposedFeatureMirror
CompoundConditionOperator
CompoundConditionOperator
ConditionNode
ConditionNode
DiceGatedEffectComparison
DiceGatedEffectComparison
DiceGatedEffectThreshold
Fixed threshold or model characteristic to compare against
DiceGatedEffectThresholdString
DiceGatedEffectThresholdString
DicePoolAllocationEffectOptionsItemRequirementType
DicePoolAllocationEffectOptionsItemRequirementType
EffectNode
EffectNode
Footprint
A terrain piece’s 2D footprint in local inches (y-down): an axis-aligned rectangle with its min corner at the local origin, a right triangle with the right angle at the local origin and legs along +x/+y, or an explicit polygon (>= 3 points). The placement resolver re-centers the footprint on its polygon area centroid, so the local-origin convention does not affect where the piece lands — only its shape matters.
ForceDispositionId
One of the five confirmed 11e launch Force Dispositions. Shared by force-disposition entities and the mission-matchup matrix.
InteractionFlagInteractionType
InteractionFlagInteractionType
Phase
The five official game phases. Unchanged between 10th and 11th edition — 11e reorders Pile In timing within the Fight phase but adds no top-level phase.
PieceKeystonesItemEdge
The board edge the measurement runs from, in the y-down board frame (left/right pin x against board width; top/bottom pin y against board height).
PieceKeystonesItemRef
Which feature of the placed piece the measurement reaches: a footprint vertex (by resolver vertex order) or an axis-aligned bounding face of the placed footprint.
PieceKeystonesItemRefSide
PieceKeystonesItemRefSide
PieceMirror
Reflection applied in the centroid-local frame before rotation: horizontal negates local x (left-right flip), vertical negates local y.
PieceObjectiveRole
Designates this terrain area — or, when link_group’d, the union of linked areas (one objective for the set) — as carrying an objective of the given 11e role: home (inside a deployment zone), center (board middle), or expansion (no-man’s-land). Implies is_objective.
PiecePieceType
An area is a gameplay terrain zone (the 11e ‘terrain area’); a feature is physical scenery (walls, containers, pipes) placed on an area.
PlayerTurn
Which player’s turn this applies during
ResourcePoolPoolType
ResourcePoolPoolType
ScopeDuration
ScopeDuration
ScopeRange
ScopeRange
ScoringTriggerTiming
The moment the award is checked. ‘End of your turn’ = end-of-turn; ‘End of your Command phase’ = end-of-phase with phase: command; ‘End of the battle’ = end-of-battle.
SecondaryCardActionsItemTiming
Non-phase moment the action happens, for card rules that are not started in a phase (Locate and Deny’s start-of-battle marker placement, Punishment’s start-of-turn condemnation, Consecrate’s end-of-turn objective selection). Mutually informative with starts — a card action uses one or the other.
SecondaryCardActionsItemUseLimitScope
Whether use_limit is enforced per turn or once per game (e.g. Recover the Relics / Find and Deny ‘Overwhelming Force’ is once per game).
SecondaryCardAwardsItem
SecondaryCardAwardsItem
SecondaryCardAwardsItemVariant0Mode
Which scoring track this award belongs to on cards that print both. Fixed missions are chosen for the whole game and score the (usually lower) fixed values; Tactical missions are drawn each turn and score the tactical values. Omitted on cards that score the same regardless of approach. A card may carry parallel fixed and tactical awards for the same condition; a consumer scores only the awards matching the player’s chosen approach.
SecondaryCardAwardsItemVariant1Mode
Which scoring track this award belongs to on cards that print both. Fixed missions are chosen for the whole game and score the (usually lower) fixed values; Tactical missions are drawn each turn and score the tactical values. Omitted on cards that score the same regardless of approach. A card may carry parallel fixed and tactical awards for the same condition; a consumer scores only the awards matching the player’s chosen approach.
SecondaryCardCardType
Whether this is a secondary card or a primary mission card (which reuses this shape).
SecondaryCardWhenDrawnOperation
The deck manipulation this card triggers on draw.
Side
Which player a zone or territory belongs to.
SimpleConditionType
SimpleConditionType
SingleEffectTarget
SingleEffectTarget
SingleEffectType
SingleEffectType
SourceType
Type of game element that is the source of an enrichment entry
StatValue
A stat that can be a fixed number or a dice expression
StratagemCategory
Whether this is a universal core stratagem or tied to a specific detachment
StratagemTiming
StratagemTiming
StratagemType
GW-printed stratagem category from the card
TerrainAreaKeyword
An 11e terrain-area keyword. Confirmed launch set; extend as further keywords publish on dataslate.
TerrainTemplateKind
area = a gameplay terrain zone; feature = physical scenery placed on an area.
TimingFlagTiming
TimingFlagTiming
UnitAttachmentRole
UnitAttachmentRole
UnitRole
Battlefield role from the datasheet header. Unit types (Infantry, Vehicle, etc.) belong in keywords.
WeaponKeywordRequiredParametersItem
WeaponKeywordRequiredParametersItem
WeaponProfilesItemRange
WeaponProfilesItemRange
WeaponType
WeaponType
ZoneShape
A zone footprint, expressed as an axis-aligned rectangle or an explicit polygon. Vertices/extent are relative to the owning element’s position.

Constants§

BUNDLED_SCHEMA
The bundled, self-contained JSON Schema (draft 2020-12) these types were generated from. Consumers can feed this to a JSON Schema validator to check data before deserializing; the canonical validation CLI lives in the @alpaca-software/40kdc-data npm package.

Functions§

encode_base_size
Canonical string encoding of a base size, shared by the conformance runner and its tests so both sides of the cross-impl contract agree byte-for-byte. Mirrors the TS encodeBase. Examples: round 32 → "round:32"; oval 75×42 → "oval:75x42"; small flyer → "flying-base:small:draft"; hull → "hull:draft".