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

nottpr

v1.0.3

Published

A Node.js JS/TS library for alttpr.com

Readme

nottpr

About

nottpr is a Node.js module for the ALTTPR API written in TypeScript. It is written with an object-oriented approach in mind, providing structured objects to make requests to ALTTPR's API be streamlined and easy to write.

Other features of nottpr:

  • Seed and sprite caching is local to the library. nottpr never writes to your file system unless you tell it to.
  • Patch seeds with any post-generation feature included on alttpr.com (even palette shuffle!)
  • Built-in preset management. Write it once, use it later.
  • A lightweight preset YAML definition that emphasizes modifications over boilerplate.

This module is based on v31 of the randomizer. If a major change to the randomizer causes something in this module to break, please open a new GitHub issue.

Note: nottpr is not currently considered legal for use in official races. This may be subject to change in the future based on TARC rulings.

Special Thanks

  • Synack: Most of nottpr's functionality is inspired by pyz3r, an API library for ALTTPR written in Python. You can check it out here.
  • clearmouse: Credit for prize packs/drops code in spoiler log.

Installation

nottpr is compatible with Node.js v22.0.0 and newer. nottpr has not been tested in Deno or Bun.

After setting up your Node environment, you can install this module with the command npm install nottpr.

nottpr is an ES module and can only be imported via ES import syntax. You cannot import nottpr with require.

/* OK! */
import ALTTPR, * as nottpr from "nottpr";
// or
const nottpr = await import("nottpr");
const { "default": ALTTPR } = nottpr;

/* WRONG! */
const { "default": ALTTPR } = require("nottpr");

Using nottpr

Seed Generation

nottpr offers two ways you can create payloads: the manual way or with a builder. All seed generation is done through the ALTTPR.generate method.

The manual way is similar to pyz3r and expects a complete payload:

import ALTTPR from "nottpr";

// Crosskeys 2023 settings
const seed = await ALTTPR.generate({
    accessibility: "locations",
    crystals: {
        ganon: "7",
        tower: "7"
    },
    dungeon_items: "full",
    enemizer: {
        boss_shuffle: "none",
        enemy_damage: "default",
        enemy_health: "default",
        enemy_shuffle: "none"
    },
    entrances: "crossed",
    glitches: "none",
    goal: "fast_ganon",
    hints: "off",
    item: {
        functionality: "normal",
        pool: "normal"
    },
    item_placement: "advanced",
    lang: "en",
    mode: "open",
    spoilers: "on",
    tournament: false,
    weapons: "randomized"
});

console.log(seed.permalink);

Builders are nottpr-native structures that initialize to default settings that mimic an open 7/7. If you're fine with a default setting as it is, you don't need to specify it later.

Builders come equipped with setter methods whose return value is the current object. As such, they can be chained.

import ALTTPR, {
    Accessibility,
    Entrances,
    Goals,
    Keysanity,
    SeedBuilder
} from "nottpr";

// Crosskeys 2023 settings
const builder = new SeedBuilder()
    .setAccessibility(Accessibility.Locations)
    .setDungeonItems(Keysanity.Full)
    .setEntrances(Entrances.Crossed)
    .setGoal(Goals.FastGanon);

const seed = await ALTTPR.generate(builder);
console.log(seed.permalink);

Both examples result in the same value being passed to the generator.

You can also create builder objects from API payload data by using the from static method:

import { SeedBuilder } from "nottpr";

// Hard enemizer
const builder = SeedBuilder.from({
    enemizer: {
        enemy_shuffle: "shuffled",
        boss_shuffle: "full"
    },
    item: {
        pool: "hard"
    }
});

Customizer Seeds

Customizer seeds are also generated through the ALTTPR.generate method. Like regular seeds, you can provide a complete payload or use a CustomizerBuilder.

import ALTTPR, {
    getDistrict,
    CustomizerBuilder,
    Accessibility,
    District,
    Goals,
    Item,
    ItemLocation,
    Keysanity
} from "nottpr";

// AD Keys Boots w/ vanilla CT smalls + GT-restricted GTBK
const preset = new CustomizerBuilder()
    .setAccessibility(Accessibility.Locations)
    .setCustom(custom => custom
        .setCustomPrizePacks(false)
        .setItemSettings(item => item
            .setItemCounts({
                [Item.BigKeyGT]: 0,
                [Item.SmallKeyCT]: 0
            })))
    .setDungeonItems(Keysanity.Full)
    .setEquipment(equipment => equipment
        .setStartingBoots(true))
    .setForcedItems({
        [Item.BigKeyGT]: getDistrict(District.GanonsTowerNoBK)
    })
    .setGoal(Goals.Dungeons)
    .setLocations({
        [ItemLocation.CTFirstFloor]: Item.SmallKeyCT,
        [ItemLocation.CTDarkMaze]: Item.SmallKeyCT
    });

const seed = await ALTTPR.generate(builder);

console.log(seed.permalink);
console.log(seed.hashCode);

Depending on the settings used, a manual payload may be preferred over a builder due to the large amount of settings in the customizer.

Fetching Previously Generated Seeds

Seeds are fetched according to their hashes. Seeds are cached locally upon generation or retrieval in the ALTTPR.seeds object. nottpr does not cache to the file system.

import ALTTPR from "nottpr";

const seed = await ALTTPR.fetchSeed("ry08zA75y5");
console.log(seed.hashCode);

Fetching Sprites

Sprites are cached in the ALTTPR.sprites object to allow for easy retrieval. The ALTTPR.fetchSprites static method can be used to fetch all sprites on alttpr.com. The cache will be empty on program initialization, so it must be populated first by fetching from the API.

import ALTTPR from "nottpr";

await ALTTPR.fetchSprites();
const sprite = ALTTPR.sprites.get("Angel");
const buffer = await sprite.fetch(); // You can even download the sprite as buffered data!

Adding custom sprites to the cache is currently unsupported. You can still pass your own .zspr files when patching a seed though.

Patching

nottpr allows you to patch randomizer seeds yourself with the Seed.patch instance method. Be advised that when patching a ROM, it is returned as a memory buffer. It will not create a new file on your system. How the buffered data is handled is up to the implementer.

You can also retrieve a seed's spoiler log by using the Seed.spoilerLog instance method. It accepts an optional boolean parameter to output additional information about prize packs. By default, this behavior is disabled.

import * as fs from "fs/promises";
import ALTTPR, {
    SeedBuilder,
    BossShuffle,
    HeartColor,
    HeartSpeed,
    Keysanity
} from "nottpr";

// MC boss with pseudoboots
const builder = new SeedBuilder()
    .setDungeonItems(Keysanity.Mc)
    .setEnemizer({
        boss_shuffle: BossShuffle.Full
    })
    .setPseudoboots(true);

const seed = await ALTTPR.generate(builder);
const patched = await seed.patch(pathToJp10Rom, {
    heartSpeed: HeartSpeed.Half,
    heartColor: HeartColor.Green,
    quickswap: true,
    msu1resume: true,
    sprite: (await ALTTPR.fetchSprites()).get("Dark Boy"),
    reduceFlash: true
});

await fs.writeFile(`./seeds/${seed.hash}.sfc`, patched);
await fs.writeFile(`./seeds/logs/spoiler_${seed.hash}.json`, seed.spoilerLog(true));

Presets

You can save created presets directly to your local install of nottpr by using Presets.save. You can load saved presets by using Presets.load. Some default presets are included for the most commonly played modes like adkeys, casualboots, and crosskeys.

import { Presets, SeedBuilder, WorldState, ItemPool } from "nottpr";

// Main Tournament 2021 (StandHard)
const preset = new SeedBuilder()
    .setWorldState(WorldState.Standard)
    .setItem({
        pool: ItemPool.Hard
    });
Presets.save("mt21", preset);

// ...

import ALTTPR, { Presets } from "nottpr";

const preset = Presets.load("mt21");
const seed = ALTTPR.generate(preset);

You can export a builder's settings as a preset YAML by using the toYAML instance method on SeedBuilder and CustomizerBuilder objects.

import * as fs from "fs/promises";
import { SeedBuilder, Goals, Keysanity, WorldState } from "nottpr";

// Inverted AD Keys
const preset = new SeedBuilder()
    .setDungeonItems(Keysanity.Full)
    .setGoal(Goals.Dungeons)
    .setWorldState(WorldState.Inverted);

await fs.writeFile("./inv_adkeys.yaml", preset.toYAML());
meta:
  source: nottpr
  branch: main
settings:
  dungeon_items: full
  goal: dungeons
  mode: inverted

nottpr YAMLs work differently from SahasrahBot YAMLs. nottpr YAMLs only record the changes that you have made in the builder, resulting in a partial preset. You can reimport the YAML using the from static methods on the SeedBuilder and CustomizerBuilder classes. However, saving the preset to nottpr is more preferred compared to saving the preset locally.

import * as fs from "fs/promises";
import ALTTPR, { SeedBuilder } from "nottpr";

const file = await fs.readFile("./presets/hard_enemizer.yaml");
const preset = SeedBuilder.from(file.toString()); // The file string is parsed as a yaml file

const seed = await ALTTPR.generate(preset);
console.log(seed.permalink);

Partial presets are not compatible with SahasrahBot. However, you can create a complete preset by passing true as an argument in the toYAML method. Complete presets are SahasrahBot-compatible.

SahasrahBot

Most existing SahasrahBot YAMLs are compatible with nottpr. Presets for door randomizer and other external branches of the randomizer are not supported.

alttpr.com

Customizer JSON files created on alttpr.com can be converted to a builder through the CustomizerBuilder.convertJSON static method.

All presets on the website (except open) can be loaded using Presets.load. These preset names are:

  • beginner
  • crosskeys
  • nightmare
  • owg
  • superquick