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

homeworlds

v0.9.0

Published

TypeScript rules engine for the Binary Homeworlds board game.

Readme

homeworlds

TypeScript rules engine for the Binary Homeworlds board game.

npm version CI TypeScript

Install

npm install homeworlds

Features

  • Complete Binary Homeworlds rules enforcement
  • Immutable state — every action returns a new state object
  • Built-in validation — validate.action separates checking from execution
  • O(1) undo/rewind — each action produces an UndoRecord for instant reversal
  • Isomorphic — runs in Node.js and the browser
  • Zero config — no setup beyond install

Quick Example

import { create, performAction } from "homeworlds";

// Create initial state for two players
const state = create.state(["alice", "bob"]);

// Alice chooses her homeworld
const { err, state: s1, undo } = performAction(state, "CHOOSE_HOMEWORLD", {
  player: "alice",
  stars: [
    create.star({ color: "YELLOW", size: 2 }),
    create.star({ color: "RED",    size: 3 }),
  ],
  ships: [create.ship({ color: "GREEN", size: 3, owner: "alice" })],
});

if (err) {
  console.error(err);
} else {
  console.log(s1.board); // alice's homeworld system is on the board
}

API Reference

create

Factory helpers for game entities and state.

create.state(players: [PlayerId, PlayerId]): State

Returns a fresh game state. players is a two-element tuple of player IDs — Binary Homeworlds is strictly a two-player game. The first element takes the first turn.

create.ship(args: Ship): Ship

Normalises and returns a Ship object. Generates an id if none is provided.

| Field | Type | Required | |---------|------------|----------| | color | Color | yes | | size | Size | yes | | owner | PlayerId | yes | | id | string | no |

create.star(args: Star): Star

Normalises and returns a Star (a Piece without an owner).

| Field | Type | Required | |---------|---------|----------| | color | Color | yes | | size | Size | yes | | id | string| no |

create.system(args: System): System

Normalises and returns a System object.


validate.action(state, action, args)

Signature: validate.action(state: State, action: Action, args: ActionArgs): string | null

Checks whether action with args is legal in state. Returns an error message string if invalid, or null if the action is valid. Does not mutate state.


performAction(state, action, args)

Signature: performAction(state: State, action: Action, args: ActionArgs): PerformActionResult

Validates and executes an action. Returns a result object — state is never mutated.

interface PerformActionResult {
  err:       string | null;   // null on success
  state:     State;           // new state (or original state on error)
  undo:      UndoRecord | null; // use with undoAction to reverse
  gameOver?: GameOver;        // present when the game ends
}

On error err is set, state is the original state, and undo is null.


undoAction(state, record)

Signature: undoAction(state: State, record: UndoRecord): State

Reverses a previously performed action using the UndoRecord returned by performAction. Returns the prior state. Does not validate — the caller is responsible for applying records in reverse order.


types

Re-exported TypeScript type definitions. Import types directly:

import { types } from "homeworlds";
// types.State, types.Action, types.Ship, etc.

Or import from the package root with a type-only import:

import type { State, Action, ActionArgs } from "homeworlds";

Types Reference

Color

type Color = "RED" | "GREEN" | "BLUE" | "YELLOW";

Size

type Size = 1 | 2 | 3;

Action

type Action =
  | "ATTACK"
  | "BUILD"
  | "MOVE"
  | "TRANSFORM"
  | "CATASTROPHE"
  | "CHOOSE_HOMEWORLD"
  | "SACRIFICE_START"
  | "SACRIFICE"
  | "END_TURN"
  | "PASS"
  | "CONCEDE";

Color-to-action mapping

| Color | Action | Effect | |----------|-------------|-------------------------------------------| | RED | ATTACK | Capture an opponent ship of smaller size | | GREEN | BUILD | Place a new ship from the bank | | YELLOW | MOVE | Move a ship to a connected system | | BLUE | TRANSFORM | Change a ship's color to another in-system color |

ActionArgs

interface ActionArgs {
  player:  PlayerId;
  from?:   { id: string };   // MOVE — origin system
  to?:     System;           // MOVE — destination system
  ship?:   { id: string };   // ATTACK, MOVE, TRANSFORM, SACRIFICE_START
  system?: { id: string };   // ATTACK, BUILD, TRANSFORM, CATASTROPHE, SACRIFICE_START
  color?:  Color;            // ATTACK, BUILD, TRANSFORM, CATASTROPHE, SACRIFICE
  stars?:  Star[];           // CHOOSE_HOMEWORLD
  ships?:  Ship[];           // CHOOSE_HOMEWORLD
}

State

interface State {
  bank:         Bank;           // remaining pieces per color
  board:        System[];       // all active systems
  players:      string[];       // ordered player list
  activePlayer: number;         // index into players
  history:      HistoryItem[];  // completed actions
  turn?:        Turn;           // in-progress turn (sacrifice state, etc.)
  gameOver?:    GameOver;       // present when game has ended
}

GameOver

interface GameOver {
  winner: string | null;   // null on draw
  reason: "homeworld_destroyed" | "no_ships_at_homeworld" | "concede" | "draw";
}

License

MIT