Add examples to rules reference

This commit is contained in:
2026-06-29 13:45:32 +02:00
parent fe884ac543
commit 3aebcf8f0e
4 changed files with 209 additions and 104 deletions
+8 -4
View File
@@ -93,6 +93,7 @@ const createTables = async () => {
title VARCHAR(500),
content TEXT,
summary TEXT,
examples TEXT,
page INT,
page_end INT,
source VARCHAR(255),
@@ -109,6 +110,7 @@ const createTables = async () => {
`);
await addColumnIfMissing(connection, 'rules', 'summary TEXT');
await addColumnIfMissing(connection, 'rules', 'examples TEXT');
await addColumnIfMissing(connection, 'rules', 'page_end INT');
await addColumnIfMissing(connection, 'rules', 'tags TEXT');
await addColumnIfMissing(connection, 'rules', 'aliases TEXT');
@@ -254,14 +256,15 @@ const seedRulesIfEmpty = async () => {
for (const rule of rules) {
await connection.execute(
`INSERT IGNORE INTO rules
(rule_id, title, content, summary, page, page_end, source, source_abbr, category,
(rule_id, title, content, summary, examples, page, page_end, source, source_abbr, category,
tags, aliases, related_rules, source_method, confidence, midgame_priority)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
rule.rule_id || rule.id || null,
rule.title || '',
rule.content || '',
rule.summary || '',
rule.examples || '',
rule.page || null,
rule.pageEnd || rule.page_end || null,
rule.source || null,
@@ -471,14 +474,15 @@ const rulesHelpers = {
try {
const [result] = await pool.execute(
`INSERT INTO rules
(rule_id, title, content, summary, page, page_end, source, source_abbr, category,
(rule_id, title, content, summary, examples, page, page_end, source, source_abbr, category,
tags, aliases, related_rules, source_method, confidence, midgame_priority)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
rule.rule_id || null,
rule.title,
rule.content,
rule.summary || '',
rule.examples || '',
rule.page || null,
rule.page_end || rule.pageEnd || null,
rule.source || null,
+10 -4
View File
@@ -54,6 +54,7 @@ function normalizeRule(r) {
title: cleanTitle(r.title),
summary: cleanText(r.summary || ''),
content: cleanText(r.content),
examples: cleanText(r.examples || ''),
page: r.page,
pageEnd: r.page_end || r.pageEnd || r.page,
source: r.source,
@@ -150,6 +151,7 @@ router.get('/search', async (req, res) => {
rule.title,
rule.summary,
rule.content,
rule.examples,
rule.category,
...(rule.tags || []),
...(rule.aliases || [])
@@ -161,6 +163,7 @@ router.get('/search', async (req, res) => {
const title = (rule.title || '').toLowerCase();
const summary = (rule.summary || '').toLowerCase();
const content = (rule.content || '').toLowerCase();
const examples = (rule.examples || '').toLowerCase();
const tags = (rule.tags || []).map(v => String(v).toLowerCase());
const aliases = (rule.aliases || []).map(v => String(v).toLowerCase());
const exactTitle = title === t;
@@ -177,7 +180,8 @@ router.get('/search', async (req, res) => {
(aliases.some(a => a.includes(token)) ? 6 : 0) +
(tags.some(a => a.includes(token)) ? 4 : 0) +
(summary.includes(token) ? 3 : 0) +
(content.includes(token) ? 1 : 0);
(content.includes(token) ? 1 : 0) +
(examples.includes(token) ? 1 : 0);
}, 0);
// Higher = shown first
return (exactTitle ? 100 : 0) +
@@ -190,27 +194,29 @@ router.get('/search', async (req, res) => {
(isCanonical ? 10 : 0) +
(Number(rule.midgamePriority) || 0) +
tokenHits +
(content.includes(t) ? 1 : 0);
(content.includes(t) ? 1 : 0) +
(examples.includes(t) ? 1 : 0);
};
let filtered = allRules.filter(rule => {
const titleMatch = includesTerm(rule.title);
const summaryMatch = includesTerm(rule.summary);
const contentMatch = includesTerm(rule.content);
const examplesMatch = includesTerm(rule.examples);
const tagMatch = arrayIncludes(rule.tags);
const aliasMatch = arrayIncludes(rule.aliases);
const categoryMatch = !category || category === 'all' || rule.category === category;
const sourceMatch = !source || source === 'all' || rule.sourceAbbr === source || rule.source === source;
const midgameMatch = !midgame || midgame === 'false' || Number(rule.midgamePriority || 0) >= 70;
const explicitTagMatch = !tag || tag === 'all' || (rule.tags || []).some(t => String(t).toLowerCase() === String(tag).toLowerCase());
return (titleMatch || summaryMatch || contentMatch || tagMatch || aliasMatch || tokenMatch(rule)) && categoryMatch && sourceMatch && midgameMatch && explicitTagMatch;
return (titleMatch || summaryMatch || contentMatch || examplesMatch || tagMatch || aliasMatch || tokenMatch(rule)) && categoryMatch && sourceMatch && midgameMatch && explicitTagMatch;
});
// If category filtering yielded no results, try without category filter
if (filtered.length === 0 && category && category !== 'all') {
filtered = allRules.filter(rule => {
const sourceMatch = !source || source === 'all' || rule.sourceAbbr === source || rule.source === source;
return sourceMatch && (includesTerm(rule.title) || includesTerm(rule.summary) || includesTerm(rule.content) || arrayIncludes(rule.tags) || arrayIncludes(rule.aliases) || tokenMatch(rule));
return sourceMatch && (includesTerm(rule.title) || includesTerm(rule.summary) || includesTerm(rule.content) || includesTerm(rule.examples) || arrayIncludes(rule.tags) || arrayIncludes(rule.aliases) || tokenMatch(rule));
});
}
+178 -89
View File
@@ -37,7 +37,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A marine uses Aim as a Half Action, then Standard Attack as the other Half Action; next round he chooses Full Auto as his Full Action instead."
},
{
"id": "cr-actions-dodge",
@@ -63,7 +64,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A cultist hits Chris with three Full Auto hits; Chris rolls Dodge and gets two Degrees of Success, cancelling all three hits."
},
{
"id": "cr-actions-full-auto-burst",
@@ -91,7 +93,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "Phillip fires a bolter on Full Auto at +20 BS; with two Degrees of Success he scores the first hit plus two extra hits, up to the weapon RoF."
},
{
"id": "cr-actions-overwatch",
@@ -119,7 +122,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "Claes covers a corridor and says he fires when the lab door opens; when enemies cross the kill zone, his prepared shot triggers."
},
{
"id": "cr-actions-parry",
@@ -145,7 +149,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "Christoffer is hit by a chainblade in melee; before damage is rolled, he tests WS with his ready melee weapon to cancel the hit."
},
{
"id": "cr-actions-semi-auto-burst",
@@ -173,7 +178,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "Anders fires Semi-Auto at +10 BS; every two Degrees of Success add another hit, limited by the weapon rate of fire."
},
{
"id": "cr-actions-suppressing-fire",
@@ -201,7 +207,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A marine sprays a gantry with Full Auto to pin cultists while the Kill-team crosses the open deck."
},
{
"id": "cr-cohesion-cohesion-damage",
@@ -229,7 +236,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "The squad takes losses and the GM calls for Cohesion loss; the leader tests Command to keep the team in Squad Mode."
},
{
"id": "cr-combat-combat-circumstances",
@@ -264,7 +272,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A target in smoke and cover is harder to shoot, while a Hulking enemy in the open is easier to hit."
},
{
"id": "cr-combat-the-attack",
@@ -297,7 +306,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "Roll BS to hit, reverse the dice for hit location, roll weapon damage, then subtract armour and Toughness."
},
{
"id": "cr-conditions-pinning",
@@ -325,7 +335,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A cultist group is hit by Suppressing Fire; failed Willpower means they stay in cover and act with limited aggression."
},
{
"id": "cr-damage-critical-damage",
@@ -360,7 +371,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "An enemy has 2 Wounds left and takes 7 damage after reduction; 5 points become Critical Damage."
},
{
"id": "cr-damage-damage",
@@ -390,7 +402,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A hit deals 14 damage with Pen 4 against armour 8 and TB 4; armour counts as 4, so 6 Wounds are lost."
},
{
"id": "cr-damage-righteous-fury",
@@ -416,7 +429,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A bolter damage die rolls 10; the attacker confirms with another hit roll and adds an extra damage roll if it succeeds."
},
{
"id": "cr-equipment-weapon-special-qualities",
@@ -453,7 +467,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A weapon with Tearing rolls extra damage dice as its quality allows; a Blast weapon can catch several enemies in one attack."
},
{
"id": "cr-hordes-hordes",
@@ -485,7 +500,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A swarm of lesser enemies is tracked as Magnitude 30; area fire and explosives remove more Magnitude than single shots."
},
{
"id": "cr-renown-renown",
@@ -521,7 +537,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A player wants rare wargear from the shop, but the item requires Respected; the GM checks the bearer's Renown before approving it."
},
{
"id": "cr-requisition-requisition",
@@ -550,7 +567,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "Before deployment the GM grants 20 Requisition; players buy mission gear from the shop and return it after extraction."
},
{
"id": "cr-squad-mode-maintaining-squad-mode",
@@ -577,7 +595,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 100
"midgamePriority": 100,
"examples": "A Battle-Brother is dragged out of vox range; the GM rules he drops from Squad Mode until the team regroups."
},
{
"id": "cr-actions-actions",
@@ -608,7 +627,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 95
"midgamePriority": 95,
"examples": "A turn can be Standard Attack plus Aim, Move plus Ready, or one Full Action such as Charge or Full Auto Burst."
},
{
"id": "cr-cohesion-cohesion",
@@ -634,7 +654,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 95
"midgamePriority": 95,
"examples": "The Kill-team spends Cohesion to activate a Squad Mode ability during the engine shrine fight."
},
{
"id": "cr-conditions-conditions-and-special-damage",
@@ -667,7 +688,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 95
"midgamePriority": 95,
"examples": "A burning marine tracks fire separately from Wounds until the condition is removed or treated."
},
{
"id": "cr-psychic-perils-of-the-warp",
@@ -694,7 +716,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 95
"midgamePriority": 95,
"examples": "Chris pushes a power and triggers Perils; the GM applies warp backlash and records any Insanity or Corruption result."
},
{
"id": "cr-psychic-psychic-phenomena",
@@ -721,7 +744,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 95
"midgamePriority": 95,
"examples": "A Focus Power roll causes Psychic Phenomena; lights die, vox distorts, and everyone feels the warp press into the room."
},
{
"id": "cr-squad-mode-squad-mode",
@@ -751,7 +775,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 95
"midgamePriority": 95,
"examples": "The team enters Squad Mode before breaching a vault so a shared ability can cover the whole push."
},
{
"id": "cr-combat-combat-overview",
@@ -783,7 +808,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "At the start of a fight everyone rolls Initiative, then each combatant takes turns in round order."
},
{
"id": "cr-combat-weapon-jams",
@@ -811,7 +837,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "A Full Auto attack rolls in the jam range; the weapon stops firing until the marine spends an action to clear it."
},
{
"id": "cr-equipment-weapon-profiles",
@@ -846,7 +873,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "A weapon profile shows Range 100m, S/3/-, Damage 1d10+9, Pen 4; use those values when attacking."
},
{
"id": "err-errata-errata-reference",
@@ -877,7 +905,8 @@
"sourceAbbr": "ERR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "If a printed rule and errata disagree, the GM uses the errata and notes the ruling for later sessions."
},
{
"id": "cr-gm-tables-test-difficulty",
@@ -908,7 +937,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "A Hard Tech-Use test applies -20; a character with Int 45 rolls against target 25 before other modifiers."
},
{
"id": "cr-psychic-psychic-powers",
@@ -937,7 +967,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "Chris casts Smite; he chooses power level, makes Focus Power, then resolves damage and any warp side effects."
},
{
"id": "cr-squad-mode-squad-mode-abilities",
@@ -968,7 +999,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 90
"midgamePriority": 90,
"examples": "The leader spends Cohesion to activate a defensive squad ability while the team holds a chokepoint."
},
{
"id": "cr-equipment-astartes-power-armour",
@@ -997,7 +1029,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 85
"midgamePriority": 85,
"examples": "A vacuum leak opens in the hull; sealed power armour lets the marine keep fighting while lesser troops suffocate."
},
{
"id": "gmk-gm-tables-gm-kit-quick-tables",
@@ -1026,7 +1059,8 @@
"sourceAbbr": "GMK",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 85
"midgamePriority": 85,
"examples": "During a chase, the GM grabs the difficulty table instead of stopping play to search the full book."
},
{
"id": "cr-equipment-craftsmanship",
@@ -1057,7 +1091,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 80
"midgamePriority": 80,
"examples": "A poor-quality weapon might be unreliable; a master-crafted item may justify a bonus if its profile allows it."
},
{
"id": "cr-mission-mission-complications",
@@ -1086,7 +1121,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 80
"midgamePriority": 80,
"examples": "The sample is secured, but alarms release prisoners and start an escape timer before extraction."
},
{
"id": "cr-talents-talent-descriptions",
@@ -1113,7 +1149,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 80
"midgamePriority": 80,
"examples": "A sheet lists Air of Authority; the player opens the talent to see when the Fellowship bonus applies."
},
{
"id": "cr-traits-trait-descriptions",
@@ -1146,7 +1183,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 80
"midgamePriority": 80,
"examples": "An enemy has Fear (1) and Regeneration; the GM applies the Fear test first and healing later each round."
},
{
"id": "cr-equipment-tools-and-wargear",
@@ -1177,7 +1215,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "The GM issues an auspex for the mission; the player uses it for an Awareness or Tech-Use advantage when scanning."
},
{
"id": "cr-mission-missions",
@@ -1210,7 +1249,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "Primary objective: secure the sample. Secondary objective: save prisoners. Rewards depend on what survives."
},
{
"id": "cr-skills-awareness",
@@ -1237,7 +1277,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "The GM asks for Awareness to notice the Gland Hound scent before it bursts from the vents."
},
{
"id": "cr-skills-command",
@@ -1264,7 +1305,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "Claes orders rescued prisoners to run for the Thunderhawk; a good roll keeps them moving under fire."
},
{
"id": "cr-skills-dodge",
@@ -1291,7 +1333,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "A Chaos bolt hits Chris; he uses his Reaction to Dodge before damage is rolled."
},
{
"id": "cr-skills-intimidate",
@@ -1318,7 +1361,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "Phillip threatens a terrified cultist for the vault code instead of negotiating."
},
{
"id": "cr-skills-medicae",
@@ -1345,7 +1389,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 75
"midgamePriority": 75,
"examples": "An Apothecary tests Medicae to identify Nurgle plague-biotech in a prisoner before release."
},
{
"id": "cr-gm-tables-fate-points",
@@ -1376,7 +1421,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 70
"midgamePriority": 70,
"examples": "A player fails a vital Dodge and spends a Fate Point to reroll; burning one would be permanent and reserved for survival."
},
{
"id": "cr-gm-tables-movement",
@@ -1411,7 +1457,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 70
"midgamePriority": 70,
"examples": "A marine charges across 12 metres of gantry; if the floor collapses, the GM calls for Agility or Athletics."
},
{
"id": "cr-squad-mode-solo-mode-abilities",
@@ -1438,7 +1485,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 70
"midgamePriority": 70,
"examples": "A lone marine separated from the team uses his Chapter Solo Mode ability while fighting back to the squad."
},
{
"id": "cr-skills-acrobatics",
@@ -1465,7 +1513,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine vaults a broken bridge in the clone chamber without losing momentum."
},
{
"id": "cr-skills-carouse",
@@ -1492,7 +1541,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A character resists a combat drug side effect or intoxicating gas with Carouse."
},
{
"id": "cr-skills-charm",
@@ -1519,7 +1569,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine calms a panicked survivor long enough to get useful directions."
},
{
"id": "cr-skills-chem-use",
@@ -1546,7 +1597,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The team identifies which sterilant canister will weaken the plague membrane."
},
{
"id": "cr-skills-ciphers",
@@ -1573,7 +1625,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A Dark Angels rune marks a hidden warning; Ciphers reveals it means quarantine."
},
{
"id": "cr-skills-climb",
@@ -1600,7 +1653,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine climbs a torn cable bundle to reach a higher gantry."
},
{
"id": "cr-skills-concealment",
@@ -1627,7 +1681,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The Kill-team hides demolition charges where a patrol will not spot them."
},
{
"id": "cr-skills-contortionist",
@@ -1654,7 +1709,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine trapped by bio-cables wriggles free before the vault field pulses again."
},
{
"id": "cr-skills-deceive",
@@ -1681,7 +1737,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A disguised vox order tricks a patrol into checking the wrong corridor."
},
{
"id": "cr-skills-demolition",
@@ -1708,7 +1765,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The team plants charges on the engine shrine and tests Demolition to avoid a bad detonation."
},
{
"id": "cr-skills-drive",
@@ -1735,7 +1793,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A player drives a damaged ground vehicle through shell craters on the next planet."
},
{
"id": "cr-skills-evaluate",
@@ -1762,7 +1821,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine judges whether a relic blade is usable or just ceremonial salvage."
},
{
"id": "cr-skills-gamble",
@@ -1789,7 +1849,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A player reads odds during a downtime wager or catches someone cheating."
},
{
"id": "cr-skills-inquiry",
@@ -1816,7 +1877,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The team questions rescued prisoners to learn which corridor leads to Specimen Holding."
},
{
"id": "cr-skills-interrogation",
@@ -1843,7 +1905,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A captured cultist resists questions about Morbus Threx until Interrogation succeeds."
},
{
"id": "cr-skills-invocation",
@@ -1870,7 +1933,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "Chris spends a Full Action centering his will before using a risky psychic power."
},
{
"id": "cr-skills-lip-reading",
@@ -1897,7 +1961,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "Through glass, a marine reads a lab acolyte silently ordering the release of specimens."
},
{
"id": "cr-skills-literacy",
@@ -1924,7 +1989,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A damaged dataslate is readable only after testing Literacy on corrupted High Gothic notes."
},
{
"id": "cr-skills-logic",
@@ -1951,7 +2017,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A reactor puzzle needs the correct sequence: coolant, sterilant, then plasma."
},
{
"id": "cr-skills-lore-common",
@@ -1978,7 +2045,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine recalls standard Deathwatch quarantine protocol for contaminated survivors."
},
{
"id": "cr-skills-lore-forbidden",
@@ -2005,7 +2073,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "Chris identifies signs of warp-tainted plague rites in the gene-vats."
},
{
"id": "cr-skills-lore-scholastic",
@@ -2032,7 +2101,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A character recalls formal xenobiology theory to classify a strange bio-sample."
},
{
"id": "cr-skills-navigation",
@@ -2059,7 +2129,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The Kill-team plots the escape craft vector toward THETA-92 before the signal degrades."
},
{
"id": "cr-skills-performer",
@@ -2086,7 +2157,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine uses solemn oratory to steady frightened Imperial prisoners."
},
{
"id": "cr-skills-pilot",
@@ -2113,7 +2185,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A jump pack landing through broken hull plating requires Pilot (Personal)."
},
{
"id": "cr-skills-psyniscience",
@@ -2140,7 +2213,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "Chris senses the trapped psyker causing void-vox anomalies near the vault."
},
{
"id": "cr-skills-scrutiny",
@@ -2167,7 +2241,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A survivor seems calm; Scrutiny reveals he is hiding mutation symptoms."
},
{
"id": "cr-skills-search",
@@ -2194,7 +2269,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The team searches a lab bench for gene-data before the deck collapses."
},
{
"id": "cr-skills-security",
@@ -2221,7 +2297,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A sealed stasis locker needs Security to bypass without triggering an alarm."
},
{
"id": "cr-skills-shadowing",
@@ -2248,7 +2325,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A marine follows a fleeing acolyte without revealing the Kill-team position."
},
{
"id": "cr-skills-silent-move",
@@ -2275,7 +2353,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The squad crosses a sensor corridor quietly to avoid adding patrols."
},
{
"id": "cr-skills-sleight-of-hand",
@@ -2302,7 +2381,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A prisoner tries to palm a scalpel; Sleight of Hand decides if anyone notices."
},
{
"id": "cr-skills-speak-language",
@@ -2329,7 +2409,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "Techna-Lingua lets a Techmarine understand machine-cant warnings."
},
{
"id": "cr-skills-survival",
@@ -2356,7 +2437,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "On THETA-92, Survival helps find safe ground in hostile weather and alien spoor."
},
{
"id": "cr-skills-swim",
@@ -2383,7 +2465,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A flooded sump corridor forces a Swim test in armour-assisted movement."
},
{
"id": "cr-skills-tactics",
@@ -2410,7 +2493,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The team identifies the best chokepoint before Tyrant Horrors reach the shrine."
},
{
"id": "cr-skills-tech-use",
@@ -2437,7 +2521,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A Techmarine isolates the vault transmitter and recovers coordinates."
},
{
"id": "cr-skills-tracking",
@@ -2464,7 +2549,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "The team follows slime, blood, and claw marks toward an escaped specimen."
},
{
"id": "cr-skills-trade",
@@ -2491,7 +2577,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "Trade (Armourer) helps judge whether a damaged weapon can be repaired mid-mission."
},
{
"id": "cr-skills-wrangling",
@@ -2518,7 +2605,8 @@
"sourceAbbr": "CR",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 55
"midgamePriority": 55,
"examples": "A handler tries to calm or redirect a trained xenos-beast instead of killing it."
},
{
"id": "mox-supplements-mark-of-the-xenos-session-reference",
@@ -2551,7 +2639,8 @@
"sourceAbbr": "MoX",
"sourceMethod": "curated",
"confidence": 0.98,
"midgamePriority": 45
"midgamePriority": 45,
"examples": "If the next planet reveals xenos bioforms, the GM can use this as a quick reminder before opening supplement stats."
}
],
"searchIndex": {
+13 -7
View File
@@ -61,6 +61,17 @@ function RuleContent({ content, query, compact = false }) {
);
}
function RuleExample({ example, query, compact = false }) {
if (!example) return null;
const text = compact && example.length > 180 ? `${example.slice(0, 180).replace(/\s+\S*$/, '')}...` : example;
return (
<div className={compact ? 'mt-2 rounded border border-amber-500/25 bg-amber-950/20 p-2' : 'mt-4 rounded border border-amber-500/30 bg-amber-950/20 p-3'}>
<div className="mb-1 text-xs font-semibold uppercase tracking-wide text-amber-200">Example</div>
<div className="text-slate-100">{splitHighlightedText(text, query)}</div>
</div>
);
}
function RulesTab({ authedPlayer, sessionId }) {
const [searchQuery, setSearchQuery] = useState('');
const [searchResults, setSearchResults] = useState([]);
@@ -419,6 +430,7 @@ function RulesTab({ authedPlayer, sessionId }) {
<div className="text-sm">
<RuleContent content={rule.content} query={searchQuery} compact />
<RuleExample example={rule.examples} query={searchQuery} compact />
</div>
</div>
))}
@@ -476,13 +488,7 @@ function RulesTab({ authedPlayer, sessionId }) {
)}
<RuleContent content={selectedRule.content} query={searchQuery} />
{selectedRule.examples && (
<div className="mt-4 p-4 bg-slate-800 rounded-lg border border-slate-600">
<h4 className="font-semibold mb-2 text-green-300">Examples:</h4>
<div className="text-slate-300">{selectedRule.examples}</div>
</div>
)}
<RuleExample example={selectedRule.examples} query={searchQuery} />
{selectedRule.relatedRules && selectedRule.relatedRules.length > 0 && (
<div className="mt-4">