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

@shieldbattery/broodrep

v0.3.0

Published

WebAssembly bindings for the broodrep StarCraft replay parser

Readme

@shieldbattery/broodrep

WebAssembly bindings for the broodrep StarCraft replay parser library.

Installation

pnpm install @shieldbattery/broodrep

Usage

Browser

import init, { parseReplay, version } from '@shieldbattery/broodrep'

// Initialize the WASM module
await init()

// Load a replay file
const fileInput = document.getElementById('replay-file')
fileInput.addEventListener('change', async event => {
  const file = event.target.files[0]
  const arrayBuffer = await file.arrayBuffer()
  const uint8Array = new Uint8Array(arrayBuffer)

  try {
    const replay = parseReplay(uint8Array)
    const header = replay.header
    console.log('Replay parsed:', replay)
    console.log('Game title:', header.title)
    console.log('Map name:', header.mapName)
    console.log(
      'Players:',
      replay.players().filter(p => !p.isEmpty && !p.isObserver),
    )
  } catch (error) {
    console.error('Failed to parse replay:', error)
  }
})

Node.js

import * as fs from 'node:fs'
import { parseReplay, version } from '@shieldbattery/broodrep'

// Read replay file
const replayData = fs.readFileSync('example.rep')
const uint8Array = new Uint8Array(replayData)

try {
  const replay = parseReplay(uint8Array)
  const header = replay.header
  console.log('Game:', header.title)
  console.log('Map:', header.mapName)
  console.log('Format:', replay.format)
  console.log('Engine:', header.engine)
  console.log('Players:', replay.players().filter(p => !p.isEmpty && !p.isObserver).length)
} catch (error) {
  console.error('Failed to parse replay:', error)
}

API Reference

parseReplay(data: Uint8Array, options?: DecompressionConfig): Replay

Parses a StarCraft replay file and returns a Replay object for retrieving game information.

Parameters:

  • data: A Uint8Array containing the replay file bytes
  • options: Optional decompression configuration to customize security limits

Returns: A Replay object with the following interface:

class Replay {
  readonly format: ReplayFormat // "legacy", "modern", or "modern121"
  readonly header: ReplayHeader // Game header information

  // Methods for retrieving player information
  players(): Player[] // All player slots (including empty)
  observers(): Player[] // Only observers
  slots(): Player[] // All slots
  hostPlayer(): Player | undefined // The host player if identifiable

  // Methods for retrieving raw section data
  getRawSection(section: ReplaySection): Uint8Array | undefined
  getRawCustomSection(section_id: number): Uint8Array | undefined

  // Method for retrieving parsed ShieldBattery data
  getShieldBatterySection(): ShieldBatteryData | undefined
}

interface ReplayHeader {
  engine: Engine // "starCraft", "broodWar", or "unknown"
  frames: number // Number of game frames
  startTime: number // Unix timestamp of game start
  title: string // Game title
  mapWidth: number // Map width in tiles
  mapHeight: number // Map height in tiles
  availableSlots: number // Number of available player slots
  speed: GameSpeed // Game speed setting
  gameType: GameType // Game type (e.g., "melee", "freeForAll")
  gameSubType: number // Game sub-type value
  hostName: string // Name of the game host
  mapName: string // Map name
}

interface Player {
  slotId: number // Map slot ID (post-randomization)
  networkId: number // Network ID (255 for computer, 128-131 for observers)
  playerType: PlayerType // "inactive", "computer", "human", etc.
  race: Race // "zerg", "terran", "protoss", "random"
  team: number // Team number
  name: string // Player name
  isEmpty: boolean // Whether this is an empty slot
  isObserver: boolean // Whether this is an observer
}

interface ShieldBatteryData {
  starcraftExeBuild: number // StarCraft executable build number
  shieldbatteryVersion: string // ShieldBattery client version
  teamGameMainPlayers: [number, number, number, number] // Main players in team games
  startingRaces: [
    number,
    number,
    number,
    number,
    number,
    number,
    number,
    number,
    number,
    number,
    number,
    number,
  ] // Starting race for each player
  gameId: string // Game UUID on ShieldBattery
  userIds: [number, number, number, number, number, number, number, number] // ShieldBattery user IDs
  gameLogicVersion: number | undefined // Game logic version (if available)
}

DecompressionConfig

Configuration object for customizing security limits during replay parsing.

// Create decompression config object
const options = {
  maxDecompressedSize: 200 * 1024 * 1024, // 200MB
  maxCompressionRatio: 1000.0, // Allow 1000:1 compression ratio
}

const replay = parseReplay(replayData, options)

Properties:

  • maxDecompressedSize?: number - Maximum bytes to decompress (default: 100MB). Prevents excessive memory usage.
  • maxCompressionRatio?: number - Maximum compression ratio allowed (default: 500:1). Higher ratios may indicate zip bomb attacks.

Note: Timing limits from the library are automatically disabled in WASM environments and cannot be configured due to limitations of Rust's time implementation.

version(): string

Returns the version of the broodrep library.

ShieldBattery Support

The library includes support for parsing ShieldBattery-specific data from replays created through the ShieldBattery platform. This data provides additional context about games played on ShieldBattery.

Basic Usage

import { parseReplay } from '@shieldbattery/broodrep'

// Parse a replay
const replay = parseReplay(replayData)

// Check for ShieldBattery data
const shieldBatteryData = replay.getShieldBatterySection()

if (shieldBatteryData) {
  console.log('Game ID:', shieldBatteryData.gameId)
  console.log('StarCraft Build:', shieldBatteryData.starcraftExeBuild)
  console.log('ShieldBattery Version:', shieldBatteryData.shieldbatteryVersion)

  // Game logic version (if available in newer format)
  if (shieldBatteryData.gameLogicVersion !== undefined) {
    console.log('Game Logic Version:', shieldBatteryData.gameLogicVersion)
  }

  // User IDs of active players
  const activeUserIds = shieldBatteryData.userIds.filter(id => id !== 0)
  console.log('User IDs:', activeUserIds)

  // Starting races as numbers (0=Zerg, 1=Terran, 2=Protoss, 6=Random)
  const activePlayers = replay.players().filter(p => !p.isEmpty && !p.isObserver)
  const startingRaces = shieldBatteryData.startingRaces.slice(0, activePlayers.length)
  console.log('Starting Races:', startingRaces)
} else {
  console.log('No ShieldBattery data (normal for non-ShieldBattery replays)')
}

ShieldBatteryData Fields

  • gameId: Unique UUID for the game on ShieldBattery platform
  • starcraftExeBuild: Build number of the StarCraft executable used
  • shieldbatteryVersion: Version string of the ShieldBattery client
  • gameLogicVersion: Version of game logic modifications (if available)
  • userIds: Array of ShieldBattery user IDs corresponding to players
  • teamGameMainPlayers: Identifies main players in team games
  • startingRaces: Original race selection for each player slot (before randomization)

Building

# Install wasm-pack if not already installed
cargo install wasm-pack

# Build
pnpm run build

## Testing

```bash
# Run WASM tests in nodejs
pnpm test

Examples

See the examples directory for complete usage examples:

  • index.html - Interactive web demo with file upload
  • usage.mjs - Comprehensive JavaScript examples

For the web version, run:

pnpm run dev

Error Handling

The parseReplay function will throw if an error occurs. Always wrap calls in try-catch blocks for proper error handling.