npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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-engine

Usage

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 bans

Save/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 Pick

API Reference

init(config: BPEngineConfig): BPEngine

Factory function to create a new draft engine.

Config Options:

  • isRadiantFirst (required): true if Radiant is first pick
  • sequence (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