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

@soulfiremc/beat-game

v2.10.0

Published

Effect-first beat-the-game runner for the official SoulFire SDK.

Readme

@soulfiremc/beat-game

@soulfiremc/beat-game is SoulFire's Effect-first progression application. It composes the official SDK's observations, direct actions, pathfinding, control leases, generic tasks, and plugin APIs into checkpointed single-bot and multi-bot runs.

SoulFire remains the remote Minecraft client. This package owns game policy.

Install

bun add @soulfiremc/sdk @soulfiremc/beat-game effect

Run one bot

import { SoulFire } from "@soulfiremc/sdk/node";
import { beatGame } from "@soulfiremc/beat-game";
import { Effect, Stream } from "effect";

const program = Effect.scoped(
  Effect.gen(function* () {
    const soulfire = yield* SoulFire.connect({
      baseUrl: "https://soulfire.example.com",
      token: process.env.SOULFIRE_TOKEN,
    });
    const bot = soulfire.instance(instanceId).bot(botId);
    const run = yield* beatGame(bot);

    yield* Effect.forkScoped(
      run.events.pipe(
        Stream.runForEach((event) => Effect.logInfo(event.type)),
      ),
    );

    return yield* run.awaitCompletion;
  }),
);

const result = await Effect.runPromise(program);

Every run uses a checkpoint store. When no store is supplied, the package creates an isolated InMemoryBeatGameCheckpointStore.

Persist a run locally

The JSON store is available from the Node-only entry point. It uses compare-and-set revisions, per-run locks, atomic replacement, and file-system sync before reporting a successful save.

import { JsonFileBeatGameCheckpointStore } from
  "@soulfiremc/beat-game/node";

const run = yield* beatGame(bot, {
  runId: "survival-01",
  checkpointStore: new JsonFileBeatGameCheckpointStore("./runs"),
});

Pass the same runId, bot, instance, team ID, and store after a process restart. The runner validates and restores the checkpoint before resuming. The checkpoint keeps the current action ID and last stable result. Durable tasks receive deterministic idempotency keys and deadlines, so a restarted worker can reattach instead of submitting the same task twice.

Run a team

import { beatGameTeam } from "@soulfiremc/beat-game";

const team = yield* beatGameTeam(
  botIds.map((botId) => soulfire.instance(instanceId).bot(botId)),
  {
    teamId: "release-run",
    checkpointStore,
    coordinator,
  },
);

const results = yield* team.awaitCompletion;

The default coordinator assigns roles deterministically, aggregates requirements, shares discoveries, elects a fenced leader, expires claims, and limits concurrent End entry. Implement BeatGameCoordinator when runs need a shared Redis, Postgres, or other multi-process backend.

Customize policy

Hooks replace one policy action while keeping the normal timeout, retry, claim, checkpoint, and control lifecycle.

const run = yield* beatGame(bot, {
  hooks: {
    fightEnderDragon: ({ driver, strategy }) =>
      customFight(driver, strategy).pipe(Effect.as(true)),
  },
});

A hook can call a typed plugin companion SDK. The plugin remains opt-in and SoulFire core stays independent of the game plan.

const combatPlugin = yield* soulfire.plugins.require(combatPluginModule);

const run = yield* beatGame(bot, {
  hooks: {
    fightEnderDragon: ({ checkpoint }) =>
      combatPlugin.fightDragon(checkpoint.botId).pipe(Effect.as(true)),
  },
});

Promise API

import { beatGame } from "@soulfiremc/beat-game/promise";

const run = await beatGame(bot, { checkpointStore });

for await (const event of run.events) {
  console.log(event.type);
}

const result = await run.awaitCompletion();

The Promise API wraps the same Effect runtime. It does not contain a second planner.

Reusable behavior exports

Behavior programs can be used without starting a full run:

  • resource and world work: acquire, collectBlocks, excavate, explore, fish, farm, and breed;
  • combat and safety: attackEntity, attackNearest, rangedAttack, flee, guard, eatWhenNeeded, respawnAndRecover, equipBestArmor, and keepTotemEquipped;
  • inventory workflows: craft, craftItem, smelt, brew, trade, transferContainerItems, and maintainLoadout;
  • progression primitives: buildStructure, buildNetherPortal, castNetherPortal, enterPortal, throwEnderPearl, throwEyeOfEnder, triangulateStronghold, activateEndPortal, and fightEnderDragon.

These functions use public SDK calls. Game-specific names do not correspond to core SoulFire RPCs.

Public modules

  • @soulfiremc/beat-game: Effect runtime, models, behaviors, in-memory checkpoint store, coordinator, driver, errors, and planner functions.
  • @soulfiremc/beat-game/promise: Promise lifecycle and async iterables.
  • @soulfiremc/beat-game/node: crash-safe JSON checkpoint storage.

See docs/beat-game-architecture.md for the server and application ownership boundary.