Refactor cards into modular per-file definitions
Split the monolithic CARD_LIBRARY into one file per card under cards/definitions/, aggregated by a barrel (definitions/index.ts). card-library.ts now indexes ALL_CARDS by id with a duplicate-id guard. Public API (CARD_LIBRARY, getCard, STARTER_DECK) and all card ids are unchanged, so consumers and save data are unaffected. Also ignore the .vite build cache.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,6 +10,7 @@ lerna-debug.log*
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
|
.vite
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
|
|||||||
@@ -1,82 +1,21 @@
|
|||||||
import type { CardData } from './card.types';
|
import type { CardData } from './card.types';
|
||||||
|
import { ALL_CARDS } from './definitions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Central card library. All card definitions live here, keyed by id.
|
* Central card library. Card *definitions* live one-per-file under ./definitions
|
||||||
* Content is data — add cards by adding entries, not code paths.
|
* and are registered in ./definitions/index.ts; this module indexes them by id.
|
||||||
|
* Content is data — add cards by adding a file, not by editing code paths here.
|
||||||
*/
|
*/
|
||||||
export const CARD_LIBRARY: Record<string, CardData> = {
|
export const CARD_LIBRARY: Record<string, CardData> = buildLibrary();
|
||||||
strike: {
|
|
||||||
id: 'strike',
|
function buildLibrary(): Record<string, CardData> {
|
||||||
name: 'Strike',
|
const library: Record<string, CardData> = {};
|
||||||
type: 'attack',
|
for (const card of ALL_CARDS) {
|
||||||
rarity: 'starter',
|
if (library[card.id]) throw new Error(`Duplicate card id: ${card.id}`);
|
||||||
cost: 1,
|
library[card.id] = card;
|
||||||
target: 'enemy',
|
}
|
||||||
description: 'Deal 6 damage.',
|
return library;
|
||||||
effect: { damage: 6 },
|
}
|
||||||
},
|
|
||||||
defend: {
|
|
||||||
id: 'defend',
|
|
||||||
name: 'Defend',
|
|
||||||
type: 'skill',
|
|
||||||
rarity: 'starter',
|
|
||||||
cost: 1,
|
|
||||||
target: 'self',
|
|
||||||
description: 'Gain 5 block.',
|
|
||||||
effect: { block: 5 },
|
|
||||||
},
|
|
||||||
bash: {
|
|
||||||
id: 'bash',
|
|
||||||
name: 'Bash',
|
|
||||||
type: 'attack',
|
|
||||||
rarity: 'starter',
|
|
||||||
cost: 2,
|
|
||||||
target: 'enemy',
|
|
||||||
description: 'Deal 10 damage.',
|
|
||||||
effect: { damage: 10 },
|
|
||||||
},
|
|
||||||
quick_slash: {
|
|
||||||
id: 'quick_slash',
|
|
||||||
name: 'Quick Slash',
|
|
||||||
type: 'attack',
|
|
||||||
rarity: 'common',
|
|
||||||
cost: 1,
|
|
||||||
target: 'enemy',
|
|
||||||
description: 'Deal 4 damage. Draw 1 card.',
|
|
||||||
effect: { damage: 4, draw: 1 },
|
|
||||||
},
|
|
||||||
cleave: {
|
|
||||||
id: 'cleave',
|
|
||||||
name: 'Cleave',
|
|
||||||
type: 'attack',
|
|
||||||
rarity: 'common',
|
|
||||||
cost: 1,
|
|
||||||
target: 'all-enemies',
|
|
||||||
description: 'Deal 8 damage to ALL enemies.',
|
|
||||||
effect: { damage: 8 },
|
|
||||||
},
|
|
||||||
flurry: {
|
|
||||||
id: 'flurry',
|
|
||||||
name: 'Flurry',
|
|
||||||
type: 'attack',
|
|
||||||
rarity: 'uncommon',
|
|
||||||
cost: 1,
|
|
||||||
target: 'enemy',
|
|
||||||
description: 'Deal 3 damage 3 times.',
|
|
||||||
effect: { damage: 3, hits: 3 },
|
|
||||||
},
|
|
||||||
adrenaline: {
|
|
||||||
id: 'adrenaline',
|
|
||||||
name: 'Adrenaline',
|
|
||||||
type: 'skill',
|
|
||||||
rarity: 'uncommon',
|
|
||||||
cost: 0,
|
|
||||||
target: 'none',
|
|
||||||
description: 'Gain 1 energy. Draw 2 cards. Exhaust.',
|
|
||||||
effect: { energy: 1, draw: 2 },
|
|
||||||
exhaust: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Look up a card definition by id; throws early on typos rather than failing silently. */
|
/** Look up a card definition by id; throws early on typos rather than failing silently. */
|
||||||
export function getCard(id: string): CardData {
|
export function getCard(id: string): CardData {
|
||||||
|
|||||||
13
src/core/cards/definitions/adrenaline.ts
Normal file
13
src/core/cards/definitions/adrenaline.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const adrenaline: CardData = {
|
||||||
|
id: 'adrenaline',
|
||||||
|
name: 'Adrenaline',
|
||||||
|
type: 'skill',
|
||||||
|
rarity: 'uncommon',
|
||||||
|
cost: 0,
|
||||||
|
target: 'none',
|
||||||
|
description: 'Gain 1 energy. Draw 2 cards. Exhaust.',
|
||||||
|
effect: { energy: 1, draw: 2 },
|
||||||
|
exhaust: true,
|
||||||
|
};
|
||||||
12
src/core/cards/definitions/bash.ts
Normal file
12
src/core/cards/definitions/bash.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const bash: CardData = {
|
||||||
|
id: 'bash',
|
||||||
|
name: 'Bash',
|
||||||
|
type: 'attack',
|
||||||
|
rarity: 'starter',
|
||||||
|
cost: 2,
|
||||||
|
target: 'enemy',
|
||||||
|
description: 'Deal 10 damage.',
|
||||||
|
effect: { damage: 10 },
|
||||||
|
};
|
||||||
12
src/core/cards/definitions/cleave.ts
Normal file
12
src/core/cards/definitions/cleave.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const cleave: CardData = {
|
||||||
|
id: 'cleave',
|
||||||
|
name: 'Cleave',
|
||||||
|
type: 'attack',
|
||||||
|
rarity: 'common',
|
||||||
|
cost: 1,
|
||||||
|
target: 'all-enemies',
|
||||||
|
description: 'Deal 8 damage to ALL enemies.',
|
||||||
|
effect: { damage: 8 },
|
||||||
|
};
|
||||||
12
src/core/cards/definitions/defend.ts
Normal file
12
src/core/cards/definitions/defend.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const defend: CardData = {
|
||||||
|
id: 'defend',
|
||||||
|
name: 'Defend',
|
||||||
|
type: 'skill',
|
||||||
|
rarity: 'starter',
|
||||||
|
cost: 1,
|
||||||
|
target: 'self',
|
||||||
|
description: 'Gain 5 block.',
|
||||||
|
effect: { block: 5 },
|
||||||
|
};
|
||||||
12
src/core/cards/definitions/flurry.ts
Normal file
12
src/core/cards/definitions/flurry.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const flurry: CardData = {
|
||||||
|
id: 'flurry',
|
||||||
|
name: 'Flurry',
|
||||||
|
type: 'attack',
|
||||||
|
rarity: 'uncommon',
|
||||||
|
cost: 1,
|
||||||
|
target: 'enemy',
|
||||||
|
description: 'Deal 3 damage 3 times.',
|
||||||
|
effect: { damage: 3, hits: 3 },
|
||||||
|
};
|
||||||
24
src/core/cards/definitions/index.ts
Normal file
24
src/core/cards/definitions/index.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
import { strike } from './strike';
|
||||||
|
import { defend } from './defend';
|
||||||
|
import { bash } from './bash';
|
||||||
|
import { quickSlash } from './quick-slash';
|
||||||
|
import { cleave } from './cleave';
|
||||||
|
import { flurry } from './flurry';
|
||||||
|
import { adrenaline } from './adrenaline';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card manifest. Every card definition is registered here exactly once.
|
||||||
|
* Adding a card = create ./<card>.ts, then add one import + one array entry.
|
||||||
|
* The library (card-library.ts) keys these by id and enforces uniqueness.
|
||||||
|
*/
|
||||||
|
export const ALL_CARDS: readonly CardData[] = [
|
||||||
|
strike,
|
||||||
|
defend,
|
||||||
|
bash,
|
||||||
|
quickSlash,
|
||||||
|
cleave,
|
||||||
|
flurry,
|
||||||
|
adrenaline,
|
||||||
|
];
|
||||||
12
src/core/cards/definitions/quick-slash.ts
Normal file
12
src/core/cards/definitions/quick-slash.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const quickSlash: CardData = {
|
||||||
|
id: 'quick_slash',
|
||||||
|
name: 'Quick Slash',
|
||||||
|
type: 'attack',
|
||||||
|
rarity: 'common',
|
||||||
|
cost: 1,
|
||||||
|
target: 'enemy',
|
||||||
|
description: 'Deal 4 damage. Draw 1 card.',
|
||||||
|
effect: { damage: 4, draw: 1 },
|
||||||
|
};
|
||||||
12
src/core/cards/definitions/strike.ts
Normal file
12
src/core/cards/definitions/strike.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { CardData } from '../card.types';
|
||||||
|
|
||||||
|
export const strike: CardData = {
|
||||||
|
id: 'strike',
|
||||||
|
name: 'Strike',
|
||||||
|
type: 'attack',
|
||||||
|
rarity: 'starter',
|
||||||
|
cost: 1,
|
||||||
|
target: 'enemy',
|
||||||
|
description: 'Deal 6 damage.',
|
||||||
|
effect: { damage: 6 },
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user