aptx-bp-engine
v1.0.1
Published
Dota2 Captain's Mode Draft Engine
Readme
bp-engine
Dota2 Captain's Mode Draft Engine - A TypeScript library for implementing the complete Ban/Pick flow.
Features
- Complete 24-step Captain's Mode draft sequence
- Decoupled first/second pick from Radiant/Dire teams
- TypeScript support with full type definitions
- Snapshot support for saving/resuming drafts
- Hero selection validation (prevent duplicates)
Installation
npm install bp-engine
# or
pnpm add bp-engine
# or
yarn add bp-engineUsage
Basic Example
import { init, DRAFT_SEQUENCE } from 'bp-engine';
// Initialize a draft (Radiant as first pick)
const engine = init({
isRadiantFirst: true,
});
// Start the draft
let turn = engine.start();
console.log(turn);
// { type: 'b', isRadiant: true, isEnd: false, stepIndex: 0, totalSteps: 24 }
// Process each turn
while (!turn.isEnd) {
const heroId = await getUserSelection(turn); // Your UI logic
turn = engine.select(heroId);
}
// Get final result
const result = engine.format();
// {
// radiant: { bans: [...], picks: [...] },
// dire: { bans: [...], picks: [...] },
// currentStep: 24,
// isComplete: true
// }Team Configuration
The isRadiantFirst parameter determines which team goes first:
// Radiant goes first (先手方)
const engine = init({ isRadiantFirst: true });
// Step 0: Radiant bans
// Step 2: Dire bans
// Dire goes first (先手方)
const engine = init({ isRadiantFirst: false });
// Step 0: Dire bans
// Step 2: Radiant bansSave/Resume Draft
// Save current state
const snapshot = engine.getSnapshot();
// Save to localStorage, database, etc.
// Resume later
const engine = init({
isRadiantFirst: true,
initialStates: snapshot,
});Check Available Heroes
// Check if a hero can be selected
if (engine.canSelect(heroId)) {
engine.select(heroId);
}
// Get all selected hero IDs
const selectedIds = engine.getSelectedHeroIds();Draft Sequence
The default 24-step Captain's Mode sequence:
Round 1 BAN (7):
First Pick: 2 bans
Second Pick: 2 bans
First Pick: 1 ban
Second Pick: 2 bans
Round 1 PICK (6):
First Pick: 1 pick
Second Pick: 2 picks
First Pick: 2 picks
Second Pick: 1 pick
Round 2 BAN (4):
Second Pick: 2 bans
First Pick: 2 bans
Round 2 PICK (6):
Second Pick: 2 picks
First Pick: 1 pick
Second Pick: 1 pick
First Pick: 1 pick
Round 3 BAN (2):
First Pick: 1 ban
Second Pick: 1 ban
Final PICK (4):
First Pick, Second Pick, First Pick, Second PickAPI Reference
init(config: BPEngineConfig): BPEngine
Factory function to create a new draft engine.
Config Options:
isRadiantFirst(required):trueif Radiant is first picksequence(optional): Custom draft sequence (defaults to DRAFT_SEQUENCE)initialStates(optional): Snapshot to restore from
BPEngine Methods
| Method | Description |
|--------|-------------|
| start() | Start the draft, returns first TurnInfo |
| select(heroId) | Select a hero for current turn, returns next TurnInfo |
| undo() | Undo last selection |
| getCurrentTurn() | Get current turn info without changing state |
| canSelect(heroId) | Check if hero is available |
| getSelectedHeroIds() | Get array of selected hero IDs |
| getSnapshot() | Get current state array for saving |
| format() | Get structured DraftState output |
Types
interface TurnInfo {
type: 'b' | 'p'; // Current action (ban or pick)
isRadiant: boolean; // Is it Radiant's turn?
isEnd: boolean; // Draft complete?
stepIndex: number; // Current step (0-24)
totalSteps: number; // Always 24
}
interface DraftState {
radiant: {
bans: (number | null)[]; // 7 slots
picks: (number | null)[]; // 5 slots
};
dire: {
bans: (number | null)[];
picks: (number | null)[];
};
currentStep: number;
isComplete: boolean;
}License
MIT
