A TypeScript library providing core game components including cards, decks, and dice for tabletop and digital games.
- π² Dice System - Customizable dice with faces, values, and symbols
- π Card Management - Flexible card system with stats, costs, and traits
- π― Deck Operations - Complete deck management with shuffle, draw, and discard
- π¦ TypeScript First - Full type safety and IntelliSense support
- π Modern ESM/CJS - Dual package exports for maximum compatibility
- β Well Tested - Comprehensive unit test coverage
- π Fully Documented - Complete API documentation
npm install @jojech/game-coreyarn add @jojech/game-corepnpm add @jojech/game-coreimport { Die, DicePool } from '@jojech/game-core';
// Create a standard 6-sided die
const d6 = new Die({ sides: 6 });
const result = d6.roll();
console.log(result); // { value: 4 }
// Create a custom die with symbols
const customDie = new Die({
  sides: 4,
  faces: [
    { symbols: ['βοΈ'], value: 1 },
    { symbols: ['π‘οΈ'], value: 1 },
    { symbols: ['βοΈ', 'βοΈ'], value: 2 },
    { symbols: ['π₯'], value: 3 }
  ]
});
// Use multiple dice
const pool = new DicePool([d6, customDie]);
const poolResult = pool.rollAll();
console.log(poolResult); // Combined results from both diceimport { Card } from '@jojech/game-core';
const fireballCard = new Card({
  title: 'Fireball',
  subtitle: 'Spell',
  cost: [{ resource: 'mana', amount: 3 }],
  primary: [
    { label: 'Damage', value: 6 }
  ],
  flavorText: 'A burst of flame erupts from your fingertips.',
  tags: ['spell', 'fire', 'damage'],
  traits: ['instant']
});
console.log(fireballCard.title); // 'Fireball'
console.log(fireballCard.getCost()); // [{ resource: 'mana', amount: 3 }]import { Deck, Card } from '@jojech/game-core';
// Create some cards
const cards = [
  new Card({ title: 'Lightning Bolt' }),
  new Card({ title: 'Heal' }),
  new Card({ title: 'Shield' })
];
// Create a deck
const deck = new Deck('My Spell Deck', cards, {
  shuffle: true,
  minSize: 1,
  maxSize: 60
});
// Draw cards
const hand = deck.drawCards(5);
console.log(hand.length); // 3 (all available cards)
// Play a card
if (hand.length > 0) {
  deck.playCard(hand[0].stateId);
}
// Check deck state
console.log(deck.getActiveDeckSize()); // 0
console.log(deck.getInPlaySize()); // 1Create and roll dice with customizable faces and values.
interface DieOptions {
  sides: number;
  faces?: DieFace[];
  defaultColor?: string;
  label?: string;
}
interface DieFace {
  descriptor?: string;
  symbols?: string[];
  value?: number;
  color?: string;
}Methods:
- roll(): DieResult- Roll the die and return the result
- getFaces(): DieFace[]- Get all faces of the die
- getSides(): number- Get the number of sides
Flexible card system supporting various game mechanics.
interface CardOptions {
  title: string;
  subtitle?: string;
  primary?: CardStatOptions[];
  secondary?: CardStatOptions[];
  flavorText?: string;
  imageUrl?: string;
  suits?: string[];
  cost?: CardCost[];
  tags?: string[];
  setIdentifier?: string;
  traits?: string[];
  onReveal?: string;
  onPlay?: string;
  onDiscard?: string;
  onExhaust?: string;
}Methods:
- getCost(): CardCost[]- Get the card's resource cost
- getTags(): string[]- Get the card's tags
- getTraits(): string[]- Get the card's traits
Complete deck management with state tracking.
interface DeckOptions {
  shuffle?: boolean;
  minSize?: number;
  maxSize?: number;
}Methods:
- drawCards(count: number): CardState[]- Draw cards from the deck
- playCard(stateId: string): CardState | null- Move a card to play
- discardCard(stateId: string): CardState | null- Discard a card
- shuffleDeck(): void- Shuffle the active deck
- getActiveDeckSize(): number- Get active deck size
- getDiscardPileSize(): number- Get discard pile size
- getInPlaySize(): number- Get in-play cards count
Manage and roll multiple dice together.
Methods:
- rollAll(): DieResult- Roll all dice in the pool
- addDie(die: Die): void- Add a die to the pool
- removeDie(index: number): Die | null- Remove a die from the pool
- getDiceCount(): number- Get the number of dice in the pool
- Node.js 18 or higher
- npm, yarn, or pnpm
- Clone the repository:
git clone https://github.com/jojech/game-package.git
cd game-package- Install dependencies:
npm install- Build the project:
npm run build- Run tests:
npm test- npm run build- Build the library for production
- npm run build:watch- Build in watch mode for development
- npm test- Run tests in watch mode
- npm run test:ci- Run tests once (for CI)
- npm run test:coverage- Run tests with coverage report
- npm run typecheck- Type check without emitting files
- npm run lint- Lint the source code
- npm run lint:fix- Lint and fix issues automatically
- npm run format- Format code with Prettier
- npm run format:check- Check code formatting
- npm run changeset- Create a new changeset for release
- npm run version- Update version using changesets
- npm run release- Build and publish to npm
The project uses Vitest for unit testing. Tests are located alongside source files with the .test.ts extension.
# Run tests in watch mode
npm test
# Run tests once
npm run test:ci
# Run with coverage
npm run test:coverage- Fork the repository
- Create your feature branch (git checkout -b feature/amazing-feature)
- Make your changes
- Add tests for new functionality
- Ensure all tests pass (npm test)
- Run linting (npm run lint:fix)
- Create a changeset (npm run changeset)
- Commit your changes (git commit -m 'Add some amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Open a Pull Request
This project uses Changesets for version management. To release a new version:
- Create a changeset: npm run changeset
- Commit the changeset file
- The release workflow will automatically create a PR with version updates
- Merge the PR to publish to npm
ISC Β© Jeremy Johnson
See CHANGELOG.md for a detailed history of changes.