Command line
Reference47 min readUpdated
Every polestar command of the toolchain, with its usage as the command prints it.
On this page
- polestar changelog
- polestar codex
- polestar compile
- polestar data
- polestar dev
- polestar doctor
- polestar draft
- polestar dungeons
- polestar exploration
- polestar export
- polestar find
- polestar gear
- polestar i18n
- polestar install
- polestar itemdb
- polestar lint
- polestar maps
- polestar media
- polestar nav
- polestar new
- polestar pack
- polestar planner
- polestar play
- polestar playtest
- polestar preview
- polestar profession
- polestar qol
- polestar questdb
- polestar readme
- polestar record
- polestar regen
- polestar release
- polestar sim
- polestar talents
- polestar trainers
- polestar travel
- polestar version
Polestar's command line, the toolchain for guides, data and releases. Run a command as node tools/polestar.js <command> from a clone, or as polestar <command> after npm link. --help after any command prints its usage and runs nothing. Each entry below is that usage, as the command prints it.
| Command | What it does |
|---|---|
changelog | Changelog fragments in changes/: add, check, show, and build into CHANGELOG.md |
codex | Build Lookup's CodexLookup's database of items, mounts, pets, recipes, NPCs, rares, quests, zones, dungeons and treasures, with where each comes from (codex build, the Polestar_Codex addon). (data/forever/codex + the Polestar_Codex pack) |
compile | Compile a packAn addon of guides for Polestar, built by the compiler from a folder with a pack.json (the folder is a pack too); Polestar's own is Polestar_Guides (pack id guides). into its community addonEvery other pack, a separate addon made and supported by its author, listed under Community guides (GUIDE_PACKS.md). folder |
data | Build reference dataThe game facts in data/forever/*.json (quests, NPCs, objects, items, zones, map frames and more) that the compiler and the data builds read; built locally by data build. (data/forever/*.json) from the Era quest database, the community quest database, Blizzard map tables and recordings |
dev | Rebuild a pack into the game on every save |
doctor | Check Node, Lua, the reference data, the AddOns folder and pack.json |
draft | Generate a first-draft leveling route (.guideOne route, written as a .guide file and compiled to Lua; its id reads like forever/alliance/human/01-elwynn-forest.) from the reference data |
dungeons | Import DungeonJournal: dungeon data (data/forever/dungeons.json) |
exploration | Build or check the generated exploration guides |
export | Print the import string of one guide |
find | Look up quests, NPCs, objects, items, inns, flight points and guides as guide lines |
gear | Build the upgrade-advice data (Forever item stats, reward choices, stat weights) from installed addons and sims |
i18n | interface translations (status, check, sync, keys, import, fit, leaks), guide texts (guides) and the names addons (names) |
install | Install the addons into the Forever client |
itemdb | Build the Polestar_ItemDB data addonA companion addon that carries data, not code, mostly loaded on demand: Polestar_QuestDB, Polestar_ItemDB, Polestar_Codex, Polestar_Travel. (item stats) from client tables |
lint | Check .guide files without writing output |
maps | Build world map data (zone level ranges, zone art overlays) |
media | Regenerate the addon textures (tools/media/*.js -> addon/Polestar/Media) |
nav | Terrain navigation from the client geometry (build the grid, route between map points) and Polestar's walking router with its maps (Polestar_Nav) |
new | Start a pack in a new folder from the template |
pack | Build the release zips, or a community addon's zip |
planner | Plan routes: play a guide on the map and edit it (local page, MCP) |
play | Play with the real addon in the browser (local playgroundThe real addon running in a browser against a simulated world (node tools/polestar.js play).) |
playtest | Play a pack's guides to the end for every class |
preview | Render the guide windowThe small window that shows the current step and its goals while playing (UI/GuideFrame.lua)., picker and options to docs/preview/*.svg |
profession | Build professions.json; draft a crafting guide; build or check the generated gathering guides |
qol | Build the Quality of Life module data (spirit healers, flight masters, reagent vendors) |
questdb | Build the load-on-demand quest database addon (markers, tooltips) |
readme | Redraw the README's art: brand (docs/assets) and charts (docs/assets/charts) |
record | Polestar RecorderThe optional Polestar_Recorder addon that records play; record import turns its sessions into data/recordings. sessions: import, watch, draft guides, measure routes (report) |
regen | Regenerate committed files after merging contributor PRs (compile + i18n sync + preview + media) |
release | Release tooling: patch scope check, patch preparation, release notes |
sim | simulate and optimize leveling routes (docs/SIMULATION.md) |
talents | Build or check Talents/Builds.lua (talent plans) |
trainers | Build trainers.json and Core/ClassTrainers.lua (class trainers) |
travel | Build the travel network (flights, boats, inns, learned paths, zone crossings), import zone crossings, test routes and draft approach chains from recordings |
version | Show or set the release version (package.json, guides/pack.json and addon TOCs) |
polestar changelog#
Changelog fragments in changes/: add, check, show, and build into CHANGELOG.md
polestar changelog --helpusage: node tools/polestar.js changelog <add|check|show|build> [options]
Each change's changelog entry is its own file, changes/<slug>.md: front
matter naming its section, then the entry as CHANGELOG.md writes it, a
markdown list item wrapped at 78 columns (changes/README.md).
add <players|authors|contributors>
write a fragment for that section ("For players", "For
guide authors", "For contributors"). The entry is
--text or stdin; plain text becomes one list item,
wrapped. The file is named --name, else the entry's first
words; an existing file is never overwritten.
check every fragment has a known section and an entry starting
"- ", and CHANGELOG.md has no ## Unreleased section;
names each fault, exit 1
show print the entries the next release gathers, as a
## Unreleased section; writes nothing
build <version> add ## <version> (<date>) to CHANGELOG.md above the newest
release, with each section that has entries, in order, and
the entries by file name; then delete the fragments.
Refuses when CHANGELOG.md has that version already, when
there are no fragments or when one is faulty
options:
--root <dir> the checkout to work on (default the repository)
--name <slug> add: the fragment's file name, without .md
--text <entry> add: the entry (default stdin)
--date <date> build: the release date, YYYY-MM-DD (default today, UTC)polestar codex#
Build Lookup's Codex (data/forever/codex + the Polestar_Codex pack)
polestar codex --helpusage: node tools/polestar.js codex build [options]
node tools/polestar.js codex parity [--ours <dir>] [--against <dir>]
node tools/polestar.js codex attune [--addons <dir>] [--ours <dir>]
Builds Lookup's Codex: every item, mount, pet, recipe, NPC, rare, quest,
zone, dungeon and treasure, with where each item comes from, and the
Dungeons journal. Release-safe inputs only: the data/forever/*.json tables
(<era-db>, <quest-db> facts, recordings, corrections), the Forever client's
tables (the newest 1.60+ build <tables> lists, cached under
data/sources/<tables>/; meta.json records it), the installed <leveling-bis>
(MIT) and Polestar's own guides. Writes data/forever/codex/*.json and the
load-on-demand pack addon/Polestar_Codex with its LICENSE-DATA.txt; `pack`
ships that folder in the release zip.
--addons <dir> the Forever client's Interface/AddOns (default: detected)
--build <version> <tables> Forever build (default: newest listed)
--offline use cached client tables only (the newest cached build
holding every table the Codex reads)
--out <dir> JSON output (default data/forever/codex; with
--local-extras data/local/codex-extras)
--pack <dir> pack output (default addon/Polestar_Codex; with
--local-extras data/local/codex-extras/Polestar_Codex)
--local-extras also merge the installed <loot-db> (GPL-2.0), <rares-db>
(All Rights Reserved) and data/forever/dungeons.json
(DungeonJournal, no licence). For this machine only: the
pack's meta says local and `pack` refuses to ship it.
A release build also reads the <web-db> Forever facts cached in
data/sources/<web-db>/codex/ (tools/lib/codex/<web-db>.js), when present.
A release build compares itself with the last --local-extras build (when
data/local/codex-extras exists), entity by entity, writes
data/local/codex-parity.json and .md and records the match per kind in its
meta (`parity`). `codex parity` reruns that comparison on two built
folders (default ours data/forever/codex, against data/local/codex-extras).
`codex attune` compares the built Dungeons journal (--ours, default
data/forever/codex) with the installed Attune addon (no licence: read on
this machine only, never in a build): each dungeon's quests per side and
every journal quest's rewards, written to data/local/dungeon-quests-audit.md
(and .json), and the attunement chains to data/local/attunements-audit.md.
--ours <dir> parity: the release build (default data/forever/codex)
--against <dir> parity: the internal build (default data/local/codex-extras)polestar compile#
Compile a pack into its community addon folder
polestar compile --helpusage: node tools/polestar.js compile [<dir>] [options]
Compiles a pack's .guide files (docs/GUIDE_FORMAT.md) into its community
addon folder, as its pack.json describes it: the generated TOC, Pack.lua,
MapFrames.lua, Guides.lua and LICENSE-DATA.txt, plus the pack's LICENSE file
as LICENSE.txt when it has one. The pack is the one in <dir> (or
--pack), else the nearest folder holding a pack.json (this one or a parent),
else our guides/. Another pack is checked with our guides as context and
written to <pack>/dist/<folder>/; ours to addon/Polestar_Guides/. Nothing is
written when there are errors, nor without reference data (`data build`):
compile then stops with one error before reading any guide, unless --no-data
says to compile without it.
options:
<dir>, --pack <dir> the pack folder (holding pack.json)
--guides <dir> our pack's guide sources in another folder (default guides/)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context for another pack (default guides/)
--context-data <dir> reference data for the context (default data/forever/)
--no-data compile without reference data: every quest title,
NPC name and place must be given in the guide
--out <dir> pack folder (default addon/<folder>/ for ours,
<pack>/dist/<folder>/ for another pack)
--include-drafts also compile the pack's drafts/**
--format <f> diagnostics as text (default), json (one document on
stdout, no summary) or github (workflow annotations)
--quiet print errors onlypolestar data#
Build reference data (data/forever/*.json) from the Era quest database, the community quest database, Blizzard map tables and recordings
polestar data --helpusage: node tools/polestar.js data build [options]
Builds data/forever/*.json (quests, npcs, objects, items, zones, map-frames,
factions, meta) from <era-db> (MIT), <quest-db>'s Forever store (installed with
<quest-db> for the Forever client; read locally, facts only ship), Blizzard
Classic Era and Forever client tables (<tables> CSV) and
data/recordings/*.json. Precedence: recordings > <quest-db>-forever > <era-db>.
Also spawnz.json: every NPC and object spawn's height on Eastern Kingdoms and
Kalimdor from <server-db> <server-db> (GPL-3.0, facts), which the compiler gives
goals at an NPC or object; with --offline and no cached dump it is left out
with a warning. The same dump's quest_template gives the objective counts
<quest-db> and <era-db> lack (left null without it, with a warning).
Downloads are cached under data/sources/.
options:
--offline use cached sources only (no git, no HTTP)
--<era-db> <dir> use this <era-db> checkout as is (default: cache clone)
--<quest-db> <dir> <quest-db> folder (or the AddOns folder holding it)
(default: auto-detected in the Forever client, as `install` finds it)
--no-<quest-db> build without <quest-db>
--build <version> <tables> Classic Era build (default: newest listed)
--forever-build <v> <tables> Forever build (default: newest 1.60+ wow_classic_beta)
--no-forever skip the Forever client tables (zones and frames from Era only)
--no-web-xp skip quest XP lookups on <talents-site> / <changes-site>
for quests <quest-db> has no XP for (results cached in data/sources/webxp/)
--no-<web-db> skip <web-db> Forever's change notes (XP, levels) and its XP for quests
still without any (the zone lists cached in data/sources/<web-db>/,
when present)
--recordings <dir> recordings folder (default: data/recordings)
--out <dir> output folder (default: data/forever)
--sources <dir> source cache folder (default: data/sources)
--cap <n> max spawn points per entity per map (default 24)
--built-at <iso> timestamp for meta.json (default: now, or SOURCE_DATE_EPOCH)polestar dev#
Rebuild a pack into the game on every save
polestar dev --helpusage: node tools/polestar.js dev [<dir>] [options]
On a pack (<dir>, --pack, or run inside one): watches pack.json and
the pack's .guide files. On every save it lints, printing the diagnostics,
and without errors compiles the pack into <AddOns>/<folder>, then reloads
the playground when --play started one. In game, /reload shows the change;
a pack's first build needs one restart of the game. A folder in AddOns is
replaced only when it is empty or a generated build of the same pack.
Ctrl-C stops. Without reference data (`data build`) dev stops at once with
one error, unless --no-data says to build without it.
options:
--dest <dir> the Interface/AddOns folder (default: the one install finds)
--no-game do not write into AddOns (lint, and the playground)
--play also start the playground with the pack loaded (client
art and SavedVariables folder as play finds them)
--port <n> the playground's port (default 8077; 0 picks a free one)
--no-data build without reference data: every quest title, NPC
name and place must be given in the guide
<dir>, --pack <dir> the pack folder, holding pack.json (default: the nearest pack.json)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context (default guides/)
--context-data <dir> reference data for the context (default data/forever/)polestar doctor#
Check Node, Lua, the reference data, the AddOns folder and pack.json
polestar doctor --helpusage: node tools/polestar.js doctor [<dir> | --pack <dir>]
Checks what the Polestar tools need, one line per check (`ok` or `fix`,
with the fix for Windows, macOS and Linux):
node Node 24 or newer (every command)
lua a Lua 5.1 interpreter: lua5.1, LuaJIT, or a `lua` that is 5.1
(play, playtest and record import; $LUA picks one)
data the reference data, data/forever/ (every guide command)
addons the game's AddOns folder: $WOW_FOREVER_ADDONS, else the client
install finds (install and dev; or pass them --dest)
pack.json inside a pack (or given its folder), the pack's manifest
Exit code 1 when the Node or reference-data check fails, else 0.polestar draft#
Generate a first-draft leveling route (.guide) from the reference data
polestar draft --helpusage: node tools/polestar.js draft --faction <Alliance|Horde> --race <Race> --zone <name> [--zone <name>...] --levels <min>-<max> [options]
Generates an efficient first-draft route (docs/GUIDE_FORMAT.md) from the
reference data: hub-style accepts and turn-ins, objective areas ordered by
nearest neighbour + 2-opt over world distances, level gating by estimated XP.
options:
--class <Class> route for one class; otherwise class quests get "only <Class>"
--start-quest <id> begin at this quest's giver
--start <x,y> begin at these coordinates in the first zone
--id <guide id> default forever/<faction>/<race>/<zones>-<min>-<max>
--title <text> default "<zones> <min>-<max>"
--next <guide id> header "next"
--done <ids|file.guide> quests already turned in (comma list, or the turnins of a guide); repeatable
--trainer <Class>:<npc> a class trainer the data does not mark; repeatable
--keep-breadcrumbs end with optional accepts of breadcrumbs leading out of the area
--data <dir> reference data (default data/forever)
--out <file> write the guide here (default stdout)
--quiet no summary on stderr
Races: Human Dwarf Gnome NightElf Orc Troll Tauren Undead Skyborne; a new race
takes its bit as <Name>:<bit> (e.g. Newrace:512).polestar dungeons#
Import DungeonJournal: dungeon data (data/forever/dungeons.json)
polestar dungeons --helpusage: node tools/polestar.js dungeons build [options]
Reads the installed DungeonJournal addon (ForeverDungeonJournal) and writes
data/forever/dungeons.json: dungeons with levels, entrance and bosses, quests
with chains, XP, money, rewards, shareability and where they start and end
(docs/ARCHITECTURE.md). The Dungeons section of the hub reads it through the
Codex (`codex build`). DungeonJournal publishes no licence: the output is
gitignored and stays local.
--source <dir> the ForeverDungeonJournal folder (default: WOW_FOREVER_ADDONS,
else the Forever clients `install` detects)
--data <dir> reference data (default data/forever)
--json print the report as JSONpolestar exploration#
Build or check the generated exploration guides
polestar exploration --helpusage: node tools/polestar.js exploration build [options]
node tools/polestar.js exploration check [options]
build: rewrites guides/forever/exploration/*.guide, one guide per continent
and level range plus Zephras Isle, from the Forever client's map tables
(<tables> CSV, cached in <sources>/<tables>), data/forever (zones, map frames,
flight masters from travel.json) and the zone order in
tools/lib/exploration/spec.js. Run `compile` afterwards.
check: builds the same guides in memory and exits 1 when a committed guide
differs (writes nothing).
--offline use cached tables only
--build <version> <tables> build (default: newest listed)
--data <dir> reference data (default data/forever)
--sources <dir> source cache (default data/sources)
--stdout print the guides instead of writing them (build only)polestar export#
Print the import string of one guide
polestar export --helpusage: node tools/polestar.js export <file.guide> [options]
Prints the import string of the one guide in <file.guide>: a line of text a
player pastes into Polestar's Import page (/polestar import) to get the
guide without installing anything (docs/GUIDE_PACKS.md, "Import strings").
The guide belongs to a community pack: the nearest folder above the file
holding a pack.json, whose id is the guide id's prefix and whose license the
string carries. The pack is linted first, with our guides as context, and a
guide with errors is refused. A string holds one guide of at most
60 steps and 50000 characters; anything bigger, or a
set of guides, is a community addon (`polestar pack`).
The string goes to stdout, everything else to stderr, so
`polestar export my.guide > my.txt` keeps only the string.
options:
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context (default guides/)
--context-data <dir> reference data for the context (default data/forever/)
--quiet print errors onlypolestar find#
Look up quests, NPCs, objects, items, inns, flight points and guides as guide lines
polestar find --helpusage: node tools/polestar.js find <text> [options]
Searches the reference data (quests, NPCs, objects, items, inns and flight
points) and our guides. A number matches ids exactly; other text matches
names (and a guide's id and zone, an inn's or flight point's zone), ignoring
case. Each result prints as a guide line ready to paste, with what it is in
a comment. A quest also prints its turn-in line and its objectives (the
`quest <id>.<n>` of an objective goal); a guide prints who it is for and
the guide its own `next` offers; an inn prints the name `sethome` and
`hearth` take, a flight point the one `getfp` and `fly` take:
accept 7 # Kobold Camp Cleanup, level 2: Marshal McBride, Elwynn Forest 48.9,41.6
turnin 7 # Kobold Camp Cleanup: Marshal McBride, Elwynn Forest 48.9,41.6
# 7.1 = kill Kobold Vermin x10
sethome "Goldshire" # Innkeeper Farley (npc 295), Elwynn Forest 43.8,65.8
getfp "Sentinel Hill" # Sentinel Hill, Westfall, Alliance: Thor (npc 523), Westfall 56.6,52.7
next forever/alliance/02-westfall # Westfall (12-17), Alliance
# its next: forever/alliance/03-darkshore
`find --kind inn` and `find --kind flight` without a text list them all.
Exit code 1 when nothing matches.
options:
--kind <k> only quest, npc, object, item, inn, flight, guide
--faction <f> only what Alliance or Horde can use (quests by race,
NPCs and inns by who they are friendly to, flight points
by their side, guides by faction)
--race <r> only what this race can use (Human, Orc, Dwarf, NightElf, Undead, Tauren, Gnome, Troll, Skyborne):
quests by race, NPCs, inns and flight points by side,
guides by faction and race
--class <c> only what this class can use: quests and guides by class
--limit <n> at most n results (default 20; a full list of inns or
flight points: all)
--json print the results as a JSON array: every result has kind,
id, name and line; quests level, zone, x, y, starts, ends,
turnin and objectives; guides levels, zone, faction,
races, classes and next; inns (id: the innkeeper) names,
npc, npcName, zone, map, x, y; flight points node (the
full name), faction, npc, npcName, zone, map, x, y
--data <dir> reference data (default data/forever/)
--guides <dir> our guides (default guides/)polestar gear#
Build the upgrade-advice data (Forever item stats, reward choices, stat weights) from installed addons and sims
polestar gear --helpusage: node tools/polestar.js gear build [--addons <dir>]
node tools/polestar.js gear fetch
build: the data behind Polestar's upgrade advice:
addon/Polestar_ItemDB/Forever.lua <leveling-bis> (MIT): Forever item stats over
the Era table, and quest reward choices
addon/Polestar/Gear/SpecData.lua stat weight bands per spec and level (Polestar's
weights blended with <gear-sim>, MIT), racial traits
Reads the installed <leveling-bis> and the <gear-sim> cache under
data/sources/<gear-sim> (no network). Run `itemdb build` first.
fetch: refresh the <gear-sim> cache (pinned commits).
--addons <dir> the client's Interface/AddOns (default: detected)polestar i18n#
interface translations (status, check, sync, keys, import, fit, leaks), guide texts (guides) and the names addons (names)
polestar i18n --helpusage: node tools/polestar.js i18n <status|check|sync|keys|import|fit|leaks|names|guides> [options]
Polestar's interface translations (docs/TRANSLATING.md): one file per
locale, addon/Polestar/Locales/<locale>.lua, and the same for the Recorder,
addon/Polestar_Recorder/Locales/<locale>.lua. Locales: deDE, esES, esMX, frFR, koKR, ptBR, ruRU, zhCN, zhTW.
check and sync read both addons; status, keys and import read Polestar's
unless --addon names the other.
i18n status per locale: its language, status (reviewed or
ai), translators, and how many keys it
translates. --markdown prints a table for the
README and release notes.
i18n check [<locale>...] fails (exit 1) on a file Lua cannot load, a
stale key (one the code no longer has), a key
set twice, or a translation whose %s/%d/%1$s,
|4one:many; or |c/|r/|T escapes differ from the
English. Warns where a translation leaves out its
glossary's word (tools/lib/i18n/glossary). Missing
translations are fine: the English shows.
i18n sync [<locale>...] adds the keys the code gained to each file as
-- L["English"] = "" lines under their file's
group, and moves translations of keys it lost to
a commented block at the end. Never rewrites a
translation. A locale named that has no file
gets one, loaded from Core/Core.xml (the
Recorder's TOC lists its own).
i18n keys every interface key with where it is used.
i18n import <locale> <file.lua>...
merges translations written apart (a file that
returns { ["English"] = "translation" }, sets
L["English"], or calls ns.AddTranslations) into
the locale's file: only into keys not translated
yet; a broken format is refused; keys the code
lacks go to the commented block at the end.
i18n fit [<locale>[=<file>]...]
lays out every preview scene and every Options
page and tab in English and in each locale (or
those named; <file> stands in for the shipped
file, such as a pull request's), in the game
font and in Inter, and lists the text the
window cuts with an ellipsis, cuts after its
last line or lets cross its edge. Text cut the
same way in English (a long guide or item name)
is left out. Fails (exit 1) when a locale has
any. CJK is measured 1em wide.
i18n leaks [<locale>...] runs the addon on the client stub in each locale
(or those named) with its shipped translations,
names pack and guide texts, the client's own
names as placeholders, through every scene (or
those --scene names), and lists the English left
on screen: a Latin word of 3+ letters in a text,
tooltip, chat line or menu that none of the
locale's own texts uses and
tools/lib/i18n/leaks-allow.json does not allow,
grouped by where it came from (an untranslated
interface string or guide text, a name missing
from the names pack, a name Polestar.Names was
not asked for, English in the code). Fails (exit
1) on any, or on a scene that errors. Scenes
(--scene; default all):
guide, guides, welcome, picker, options, lookup,
dungeons, rares, talents, journey, tooltips,
slash, more, recorder.
i18n names [<locale>...] builds the names addons addon/Polestar_Names_<locale>:
the names of quests, NPCs, objects, items,
instances, encounters, factions and flight points
(and the objectives of dungeon event quests) in
each language. Per id, the first source with a
name wins: the Forever client's tables
(<tables>, &locale=), <web-db>'s Forever
database in that language (list pages and
tooltips, read only from what is already cached
in data/sources/<web-db>/names),
<names-db> (pinned commit and sha256s, cloned into
data/sources/<names-db>), then <era-db>'s db/<locale>.
Only the ids the compiled guides, the quest
database, the Codex's data and the travel data
name. A language left without names loses its
folder.
i18n guides sync [<locale>...]
writes a pack's texts in other languages
(docs/TRANSLATING.md, "Guide texts"):
<pack>/locales/<locale>/<guide path>.lua per
guide and _pack.lua for the pack's own texts,
each with every text that needs words, the
game's names as {kind:id} tokens, "" while not
translated. Keeps every translation; one whose
English the guide lost moves to a commented
block at the end. Without a locale: every
language the pack has a folder for.
i18n guides check [<locale>...]
fails (exit 1) on a texts file Lua cannot load,
a translation that leaves out or adds a name
token or a line break, a stale translation (its
English changed or went away: the new English
is named when it can be told) or a file no
guide has. Missing translations are fine.
i18n guides stats the texts to translate: unique texts, words and
characters (tokens left out), in all and by
guide folder; the names the compiler made
tokens, by kind and source; the notes dropped
for naming only their goal.
options:
--json status, check, keys, names, fit, leaks, guides: one JSON document on stdout
--scene <a,b> leaks: only these scenes
--guide <id,...> leaks: the guides the guide scene shows (default a few)
--jobs <n> leaks: runs at a time (default one per core)
--update-baseline leaks: write tools/lib/i18n/leaks-baseline.json: add the
names no source has that the runs showed in English,
drop the entries that no longer show
--slack <n> fit: measure every glyph n times wider (1.15: about the
client's own font)
--pack <dir> guides: the pack (default our guides/)
--data <dir> guides: the reference data (default data/forever)
--markdown status: a Markdown table
--no-<quest-db> names: leave <names-db> out (its base data is <quest-db>'s)
--no-tables names: leave the client tables out (otherwise a missing
table stops the build)
--offline names: no downloads; the cached clones and tables
--build <version> names: this Forever client build (default the newest <tables> lists)
--sources <dir> names: the client-table and <web-db> cache (default data/sources)
--ding <dir> names: this <names-db> checkout (default data/sources/<names-db>)
--<era-db> <dir> names: this <era-db> checkout (default data/sources/<era-db>)
--guides <file> names: the compiled guides (default addon/Polestar_Guides/Guides.lua)
--questdb <dir> names: the built quest database (default addon/Polestar_QuestDB)
--codex <dir> names: the Codex's data (default data/forever/codex)
--travel <file> names: the travel data (default addon/Polestar/Nav/TravelData.lua)
--chokepoints <file> names: the walking map's chokepoints, for the lifts' objects
(default addon/Polestar_Nav/Nav/Chokepoints.lua)
--out <dir> names: where the addon folders go (default addon/)
--addon <name> status, check, sync, keys, import: Polestar or
Polestar_Recorder onlypolestar install#
Install the addons into the Forever client
polestar install --helpusage: node tools/polestar.js install [<dir>] [options]
Installs addon/Polestar, addon/Polestar_Guides and addon/Polestar_Nav, plus
the data addons Polestar_QuestDB, Polestar_ItemDB, Polestar_Codex and the
names addons Polestar_Names_<locale> when they have been built (and with
--recorder, addon/Polestar_Recorder) into World of Warcraft: Forever's AddOns
folder.
Given another pack (<dir>, --pack, or run inside one) it lints and
builds that pack into <pack>/dist/<folder>/ instead and installs that
folder; an existing <AddOns>/<folder> is replaced only when it is empty or a
generated build of the same pack (its TOC's X-Polestar-Pack names this
pack's id). Without reference data (`data build`) it stops with one error,
unless --no-data says to build without it.
Destination, first match wins:
--dest <dir> the Interface/AddOns folder to install into
$WOW_FOREVER_ADDONS same, from the environment
auto-detect Wine/Proton/Faugus/Lutris/Bottles prefixes under your home
folder, and native installs (C:\Program Files (x86)\World of
Warcraft on Windows, /Applications/World of Warcraft on macOS);
a "_forever_" or "_classic_beta_" client folder whose
.flavor.info names Forever (wow_forever*) or the classic beta
options:
--link symlink the folders instead of copying (edit, then /reload)
--recorder also install Polestar_Recorder
--dry-run print what would happen, change nothing
--addons <dir> source folder holding the addons (default addon/)
--no-data a pack only: build it without reference data (every
quest title, NPC name and place given in the guide)
<dir>, --pack <dir> the pack folder, holding pack.json (default: the nearest pack.json)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context (default guides/)
--context-data <dir> reference data for the context (default data/forever/)polestar itemdb#
Build the Polestar_ItemDB data addon (item stats) from client tables
polestar itemdb --helpusage: node tools/polestar.js itemdb build [options]
Writes the load-on-demand data addon addon/Polestar_ItemDB (Items.lua + TOC):
stats of every equippable Classic Era item (item level, required level,
inventory type, armor, weapon damage and speed, primary stats and the equip
bonuses Polestar.Gear scores), from Blizzard client tables (<tables> CSV:
ItemSparse, Item, ItemEffect, SpellEffect). Size budget: 1024 KiB.
--offline use cached tables only
--build <version> <tables> Classic Era build (default: newest listed)
--sources <dir> source cache (default data/sources)
--out <dir> default addon/Polestar_ItemDBpolestar lint#
Check .guide files without writing output
polestar lint --helpusage: node tools/polestar.js lint [<dir>] [options]
Runs every compile check (syntax, data lookups, cross-guide validation) on a
pack without writing anything: the pack in <dir> (or --pack), else the nearest
folder holding a pack.json (this one or a parent), else our guides/. Exit
code 1 on errors. Another pack is checked with our guides as context (its
`next` and turn-ins see our chains; their own diagnostics are not shown).
When the simulator has cached a world (`sim`), also warns on leveling goals
its solo filter excludes. Without reference data (`data build`) lint stops
with one error before reading any guide, unless --no-data says to check
without it.
options:
<dir>, --pack <dir> the pack folder (holding pack.json)
--guides <dir> our pack's guide sources in another folder (default guides/)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context for another pack (default guides/)
--context-data <dir> reference data for the context (default data/forever/)
--no-data check without reference data: every quest title, NPC
name and place must be given in the guide
--sim <dir> simulator cache with world-<faction>.json (default
data/sim/, used only with the default --data)
--include-drafts also check the pack's drafts/**
--format <f> text (default), json (one document on stdout, no
summary) or github (workflow annotations)
--quiet print errors onlypolestar maps#
Build world map data (zone level ranges, zone art overlays)
polestar maps --helpusage: node tools/polestar.js maps <build|overlays> [options]
build: zone level ranges for the world map (hostile creature levels per zone,
spawn-weighted P10..P90; heuristic in tools/lib/maps/zonelevels.js) ->
addon/Polestar/Maps/ZoneLevels.lua.
--data <dir> data/forever (npcs.json, zones.json)
--lua <file> output (default: addon/Polestar/Maps/ZoneLevels.lua)
overlays: every world map overlay of every zone map (the explored-area
paintings), from the client's DB2 tables via <tables>, so the zone art shows
a map without fog of war -> addon/Polestar/UI/ZoneArtOverlays.lua.
--build <ver> client build (default: 1.60.1.70338, the Forever client)
--sources <dir> source cache folder (default: data/sources)
--offline use cached tables only
--lua <file> output (default: addon/Polestar/UI/ZoneArtOverlays.lua)polestar media#
Regenerate the addon textures (tools/media/*.js -> addon/Polestar/Media)
polestar media --helpusage: node tools/polestar.js media [generator ...]
Runs every generator in tools/media/ (or only the named ones) against
addon/Polestar and lists the files written.polestar nav#
Terrain navigation from the client geometry (build the grid, route between map points) and Polestar's walking router with its maps (Polestar_Nav)
polestar nav --helpusage: node tools/polestar.js nav build [--continents 0,1] [--force] [--offline] [--workers N] [--out <dir>] [--product <p>]
node tools/polestar.js nav path <map> <x>,<y> <map> <x>,<y> [--class C] [--level N] [--frame era|forever] [--json] [--dir <dir>]
node tools/polestar.js nav aids [--out <file>] [--lua <file>] [--report] [--continents 0,1] [--workers N] [--reference <file>] [--dir <dir>]
node tools/polestar.js nav pack [--cells N] [--date <YYYY-MM-DD>] [--dir <grid dir>] [--layers <dir>] [--out <dir>] | nav pack --check [--out <dir>]
node tools/polestar.js nav check [--out <dir>]
node tools/polestar.js nav eval [--nav <Polestar_Nav dir>] [--baseline <dir or eval .json>] [--routes <file>] [--sweep] [--style fastest|balanced|roads] [--out <file.json>]
node tools/polestar.js nav layers roads [--c 0|1] [--allowlist] [--offline] [--product <p>]
node tools/polestar.js nav layers hubs [--dir <grid dir>] [--offline]
build the navigation grid of every continent map-frames.json names (or
--continents): client geometry per ADT tile through the CASC cache
(data/sources/casc), walkable surfaces, links, regions and the
abstract graph, in worker threads, written to data/local/nav (--out).
A tile already built is kept unless --force; --offline only reads
cached client files.
path a route between two map points: <map> a uiMapID, <x>,<y> percent on
it (the Era frame unless --frame forever). Prints yards, seconds by
class, falls and the simplified points (map percent of the first
map); --json prints the whole result. --class (e.g. Druid) and --level
(default 10) choose the movement profile.
aids the arrow's aids from the grid (--dir, default data/local/nav;
tools/lib/nav/aids.js): zone crossings, open borders and approach
chains in the crossings schema, validated, written to aids.json in
the grid's folder (--out: another file). --lua writes
them as a Crossings.lua for a local test (never into
addon/Polestar_Travel); to build a test copy of the data addon:
node tools/polestar.js travel build --offline --crossings data/local/nav/aids.json --travel-addon <test folder> --json <test folder>/travel.json --lua <test folder>/TravelData.lua
Pockets are tested in --workers threads (default: up to 6).
--report also plans every consecutive pair of located goals in our
guides with the addon's planner without and with the aids and writes
aids-report.json and aids-report.md next to --out, comparing with the
reference crossings file (--reference, default
data/local/crossings.json; read only).
pack Polestar's walking maps of maps 0 (Eastern Kingdoms), 1 (Kalimdor)
and 2991 (Zephras Isle) from the grid (--dir, default data/local/nav;
it needs grid version 4: nav build --out data/local/nav4, then --dir
data/local/nav4) and the ground layers
(--layers, default data/local/nav-layers: roads and hubs, from nav
layers), in maps format 2: a ground class per surface (road, gentle
or steep slope, indoor, indoor city, Alliance and Horde hubs) and
every graph edge priced per faction (tools/lib/nav/pack.js, grown
from a port of Shortest Path Forever's (Cillian Berragan) gen_nav.py
and pack_nav.py),
with Chokepoints.lua (lifts, bridges, gates, tunnels, cave and building
mouths, passes; tools/lib/nav/chokepoints.js), into
addon/Polestar_Nav (--out): Nav/Nav<map>*.lua,
Nav/Chokepoints.lua, PACK.json (grid build, cells, date, sizes, sha256
of every file) and Nav/Nav.xml. --cells cuts each ADT tile into N x N
cells (default 128, 4.17 yd); --date dates the generated headers
(default today; the same grid, layers, cells and date give the same
bytes). --check only compares the folder with PACK.json.
check the walking maps match PACK.json and Nav/Nav.xml lists them.
eval the walking router run standalone (LuaJIT, else Lua 5.1; a folder
without its own Routing takes the repository's) on a folder's maps
(--nav, default addon/Polestar_Nav): the route corpus (--routes,
default tools/lib/nav/eval/routes.json) with each route's metrics
(yards, seconds, the share of the drawn line our grid at
data/local/nav3 cannot walk, off-road share, yards in hostile hubs,
steepest climb, indoor yards on data/local/nav4's indoor surfaces
outside the capitals, yards per zone, swumYards: yards over water;
a layer not built yet reads n/a) and expectations; a route with a
level (the character's) is priced with zone danger as the addon
prices it (x3 at 4+ levels above; more than 10 above x20; the
start's and goal's zones exempt; tools/lib/maps/zonelevels.js), and
a route's own danger ({ "<uiMapID>": multiplier }) is laid over it;
--sweep also
searches, per zone with located guide goals and per side, from the
zone's flight master (else its first goal) to every goal.
--baseline runs the same on another folder (or
reads an earlier --out report) and judges the acceptance checks
A1-A8; exit 1 when one fails. --style prices every search in a
route style (fastest, balanced or roads; default balanced), the
baseline's too. --out writes the whole report.
layers the ground layers under data/local/nav-layers. roads: per grid
column, the share of the ground the client paints with a road
texture (tools/lib/nav/layers/roads.js), from each tile's tex0 ADT
(its texture layers and alpha maps) and the reviewed allowlist
tools/lib/nav/layers/road-textures.json, texture names from the
wowdev community listfile (downloaded once to
data/sources/listfile; build time only), for maps 0 and 1 (--c: one
of them), into roads/<c>/<col>_<row>.bin. --allowlist instead
rewrites the allowlist from every texture both maps' tiles use (never
with --c):
one whose tileset path names a road, path, cobble, street or trail;
one naming dirt, footprint, brick or gravel, or listed under
reviewed, when its shape is a road's (most of its weight in long,
narrow, elongated strips); with every measure (review it).
hubs: each faction's towns and outposts (tools/lib/nav/layers/hubs.js):
its guards and service NPCs (quest givers, vendors, trainers, flight
masters, innkeepers, bankers, repairers) from the <server-db> <server-db>
spawns and creature templates, judged by the client's FactionTemplate
table, clustered, named by the AreaTable area under them (the grid's
area ids, --dir, default data/local/nav4), into hubs.json.polestar new#
Start a pack in a new folder from the template
polestar new --helpusage: node tools/polestar.js new [dir] [options]
Starts a pack in [dir] (default: the current folder), which must be
empty or missing (run it before `git init`: a folder holding .git is not
empty): pack.json, an example guide, README.md, LICENSE, .gitignore, VS Code
tasks, AGENTS.md / CLAUDE.md for AI assistants, the polestar-guide-pack skill
(skills/ in this clone) in .agents/skills/ and .claude/skills/, and a GitHub
workflow and a dev container that install Polestar from this clone's origin
remote. The origin must be an http(s) or SSH URL; it is written as https,
without a user name, password, query or fragment. With no origin, or any
other kind, those two are left out.
Asks for each value not given, unless --yes accepts the defaults; without a
terminal to ask in, it writes nothing and exits 1 unless --yes or all four
values are given.
options:
--id <id> pack id, e.g. joe-routes (default: from the folder name)
--title <text> pack title (default: from the id)
--author <name> author (default: git config user.name)
--license <spdx> licence, e.g. CC-BY-4.0, CC0-1.0, MIT, GPL-3.0-only
(default CC-BY-4.0)
--yes accept the defaults for every value not givenpolestar pack#
Build the release zips, or a community addon's zip
polestar pack --helpusage: node tools/polestar.js pack [<dir>] [options]
In the repository: compiles our guides, then writes dist/Polestar-<version>.zip
(Polestar, Polestar_Guides, Polestar_Nav, Polestar_Codex, the names addons
Polestar_Names_<locale>, and Polestar_QuestDB / Polestar_ItemDB when built),
dist/Polestar_Recorder-<version>.zip and
dist/SHA256SUMS. Polestar/ in the zip also carries LICENSE and README.txt
(install steps), Polestar_Recorder/ the LICENSE. The Codex must be built
first (`codex build`) from release-safe inputs: pack stops on a missing
Codex or a --local-extras one.
Given another pack (<dir>, --pack, or run inside one): lints and builds it with our
guides as context, then writes <pack>/dist/<folder>-<version>.zip holding its
addon folder, the version taken from pack.json. Both are byte for byte
reproducible. Without reference data (`data build`) pack stops with one
error; a pack can be built without it with --no-data.
options:
<dir>, --pack <dir> the pack folder, holding pack.json (default: the nearest pack.json)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context (default guides/)
--context-data <dir> reference data for the context (default data/forever/)
--guides <dir> our guide sources (default guides/; not with a pack folder)
--addons <dir> addon source folder (default addon/)
--dist <dir> output folder (default dist/, <pack>/dist/ for a pack)
--no-data a pack only: build it without reference data
(every quest title, NPC name and place given in the guide)polestar planner#
Plan routes: play a guide on the map and edit it (local page, MCP)
polestar planner --helpusage: node tools/polestar.js planner [<pack dir>...] [--port 8078] [--art <dir>] [--nav <dir>] [--open]
node tools/polestar.js planner art [--continents 0,1] [--no-zones] [--force] [--offline] [--concurrency N] [--out <dir>]
node tools/polestar.js planner mcp [<pack dir>...] [--port 8078] [--art <dir>] [--nav <dir>]
The route planner: a local page (http://127.0.0.1:8078) that plays a
guide on the real map, step by step, with the clock, the XP and the quest
log, and edits the .guide files (fields, steps, dragged waypoints): every
edit is written to the file at once. Our guides/ are always loaded; other
packs (a folder holding pack.json, as arguments or --pack) come after them.
Inspired by Nivek_Gaming (@Nivek_Gaming on X): thank you, Nivek.
--port <n> port on 127.0.0.1 (default 8078; 0 picks a free one)
--art <dir> the map art (default data/local/planner/art)
--nav <dir> the navigation grid walks are routed on (default data/local/nav;
built by node tools/polestar.js nav build; without it walks are straight lines)
--data <dir> reference data (default data/forever/)
--pack <dir> one more pack folder
--open open the page in the browser
planner art: fetch the Forever client's minimap blocks and zone maps from
<tables> (cached under data/sources/casc/) and build the art the page
draws into data/local/planner/art/ (never committed).
--continents <c,..> only these continents (map ids, e.g. 0,1; default all)
--no-zones skip the painted zone maps
--force rebuild files that exist
--offline use only cached downloads
--concurrency <n> parallel downloads (default 8)
--product <p> <tables> product (default wow_classic_beta)
--out <dir> output folder (default data/local/planner/art)
planner mcp: the planner's commands as an MCP server on stdin/stdout
(JSON-RPC, one message per line). It uses the planner running on --port, so
an agent's edits show live in the open page, else starts one itself.polestar play#
Play with the real addon in the browser (local playground)
polestar play --helpusage: node tools/polestar.js play [<dir>] [--port 8077] [--art <dir>] [--fresh]
Starts a local server running the real Polestar, Polestar_Guides and the
built data packs against the simulated world, and prints its URL. Click,
hover, scroll, drag and type in the game screen; the side panel sets the
character, moves them, plays guide goals and tweaks the look live.
Given another pack (<dir>, --pack, or run inside one) that pack is
linted, built into a temp folder and loaded after our guides.
--port <n> port on 127.0.0.1 (default 8077; 0 picks a free one)
--art <dir> local client art (default $POLESTAR_CLIENT_ART, else
/tmp/polestar-art when present); served locally only
--no-art draw without client art
--fresh forget the character and SavedVariables (data/play/, or
$POLESTAR_PLAY_DATA)
<dir>, --pack <dir> the pack folder, holding pack.json (default: the nearest pack.json)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, read as context (default guides/)
--context-data <dir> reference data for the context (default data/forever/)polestar playtest#
Play a pack's guides to the end for every class
polestar playtest --helpusage: node tools/polestar.js playtest [<dir>] [options]
Plays a pack's guides to the end in the real addon against a simulated
world (needs Lua 5.1; `doctor` checks): each guide once per class it
branches on (`only`) plus one class it never names, as each race that can
reach it. The pack is the one in <dir> (or --pack), else the nearest folder
holding a pack.json, else our guides/. Another pack plays with our guides
loaded too: a guide whose `next` names one of ours must land on it with
something to do, and the guide it lands on must apply to the character (its
race, class and faction). --filter plays only the guides whose file or id
contains its text.
One line per guide, race and class (only pairs that exist in the game):
ok joe/elwynn (Human Warrior)
stuck joe/elwynn (Human Paladin) at step 3 "Kobolds": goal 1 (kill "Kobold Vermin") stays active
stuck joe/elwynn (Human Mage) at hand-over to forever/alliance/02-westfall: <why>
stuck joe/elwynn (Human Mage) at hand-over to forever/alliance/dwarf-gnome/01-dun-morogh: no Human can follow it
fail joe/elwynn (Human Warrior): no location for step 2 goal 1: accept 33
Exit code 1 when any guide is stuck or fails, nothing was played, or the
pack does not compile.
options:
--filter <text> play only the guides whose file or id contains it
--class <c> play only this class (e.g. Warrior), in every guide
<dir>, --pack <dir> the pack folder (holding pack.json)
--data <dir> reference data (default data/forever/)
--context <dir> our guides, loaded beside another pack (default guides/)
--context-data <dir> reference data for the context (default data/forever/)polestar preview#
Render the guide window, picker and options to docs/preview/*.svg
polestar preview --helpusage: node tools/polestar.js preview [scene ...]
Runs the real Theme and UI Lua against a geometry-recording client stub
with sample guides and writes SVGs to docs/preview/. Scenes:
guide Guide window: a field step; a hub, one person at a time (first, then the second); the tip opened
guide-picture Step pictures: a community addon's screenshot under the step's tip, scaled to the window; a picture with no tip, at most 160 high (Polestar's own textures stand in for the screenshots)
skins-guide Skins: the guide window in Polestar, Halo and Hearth
skins-states Skins: a hub step, transparent and the header menu, in Halo and Hearth
guide-transparent Transparent mode over a bright world: at rest, and with the cursor over it
guide-compact Compact mode: standard and transparent
guide-states No guide open, guide complete, out-levelled banner, header menu
route-choice Choose your path: an Undead after Tirisfal Glades; the guide window while the choice waits
welcome The welcome, once per new character after login: Hello, Make it yours and Route style (on the account's first), Your first guide
guide-professions Profession and reputation guides: chosen trainer with alternatives, skill bar, reputation bar
guide-smart Smart logic: training reminder, an unavailable quest, a farm spot with alternatives
guide-along Along the way: the kobolds and wolf meat of an `along` step under the steps after it; with Up next open
journey The journey under the focus: walking to the Great Lift (36:48, 8.0k yd, the lift untimed); on the lift, timed; collapsed to its totals
guide-group Group content: elites and an author's group size; a dungeon run said once; the guide menu's Group chip
class-not-yet A Class guide opened too early: the guide window says from which level and who starts it; the guide menu's row says "From level 20"
picker-class Class guides in the guide menu: the details lead with what the chain gives and why (a mount spell; a choice of rare items; a demon and its soul bag)
report Report a problem (the guide window's bug button): what went wrong, the right spot to mark, the report for the Polestar Discord, or a filled-in issue on GitHub; the invite on its own (the sidebar's Discord mark)
guide-ellesmere With EllesmereUI: Polestar follows its accent and font by default; every colour stays editable
schemes Colour schemes on the guide window: Dusk (default), Night, Graphite, EllesmereUI; and your own ground, accent and brightness
schemes-options Options > Appearance in each scheme: Dusk, Night, Graphite, and EllesmereUI installed (its scheme, follow toggles, its font offered)
schemes-picker The guide menu in Dusk (default), Night, Graphite, and EllesmereUI with its purple accent
options Options: Guide (Window, Arrow & routes, Automation)
skins-options Skins: Options in Halo and Hearth (Guide, Window; Appearance, Windows with the Skin setting)
gamepad-guide Focus mode on the guide window (Browse the guide with the gamepad): the first open goal; down a line on a hub step; up into the navigator with PlayStation buttons
gamepad-options Options with a gamepad: the Gamepad page (a dropdown focused, D-pad left / right steps it), a binding row on its Key bindings tab (chips for buttons, chords and keys), and a slider with PlayStation buttons; B sits on the close button
gamepad-hub The guide menu with a gamepad: the focus starts on the selected guide (X loads it, LB / RB step the sections); a dropdown's choices in the shared menu, the current one focused
options-appearance Options: Appearance (Colour & type, Windows, Arrow); then a look of your own: an accent border 2px thick, no band, no shadow, your own arrow colours
options-modules Options: pages the modules fill: Map, Questing, Discovery, Quality of Life
options-more Options: Recorder and About, at the foot of the list
options-integrations Options: Integrations: <quest-db>'s section while <quest-db> is loaded; with no supported addon, one line says so
options-packs Options: Community guides: ours and a community addon on, one with problems and its report, one turned off, one too new; where suggestions come from
options-search Options: a module's registered controls, search across pages, and a crowded sidebar in the game font that scrolls clear of the version
skins-more Skins: the welcome, the journey and the route choice in Halo, then in Hearth
skins-dungeons Skins: the dungeon journal in Halo and Hearth
skins-picker Skins: the guide menu in Halo and Hearth
skins-new Skins: the welcome's Route style page, Options' Community guides, the gamepad's focus and hints, and the report window, in Halo and Hearth
skins-game-forever Skins: forever: the guide window (a hub step, the menu), Options (Guide, Appearance, Community guides, Gamepad), the welcome's Route style page and the report window
skins-game-blizzard Skins: blizzard: the guide window (a hub step, the menu), Options (Guide, Appearance, Community guides, Gamepad), the welcome's Route style page and the report window
skins-game-classic Skins: classic: the guide window (a hub step, the menu), Options (Guide, Appearance, Community guides, Gamepad), the welcome's Route style page and the report window
picker-levels Guide menu: Elwynn Forest selected for a level 4 Human at 1,800 of 2,100 XP, its levels chip hovered: the XP its turn-ins and kills give, a bar from level 4 into 5, what was counted; the same in the Halo skin, the Graphite scheme and an accent of your own; the guide set to start at 6: level 6 recommended, the sums from there
picker Guide menu: Home (Continue, Suggested) with the details; Leveling folders by faction and band
picker-packs Guide menu: a community addon under Community guides, its guide credited to its author
picker-views Guide menu: Current (the open tabs) and Recent (the last guides loaded)
picker-search Guide menu: Favourites (star on), and a search with its first result selected
picker-art Guide menu zone art: the Durotar starter at its first stop; The Barrens (19–24) open at step 13, on that step
hub The hub: sections on the rail (Guides, Lookup, Dungeons, Rares) with Options at its foot; the sidebar holds the wordmark, the search and the section's own index on one edge
lookup Lookup in the hub, over the sample Codex: "saber" with a vendor mount selected; the Winterspring Frostsaber, reputation or a limited vendor, its best source chosen; an empty search: the recent lookups
lookup-retired Lookup: "frostsaber" with the retired Reins of the Frostsaber last, dimmed with its chip; its details for reference, no guide
lookup-drop Lookup: Deathcharger's Reins for a level 4 character, a rare drop out of reach, saying why
lookup-missing Lookup without the Codex pack: opened; a search only the Codex could answer; a guide still found
picker-codex Guide search in the hub: the guides that match, then what the Codex holds (a few per kind) and a way into Lookup
gear-pick The reward pick under turn-in goals: an upgrade (chevron, gain) and, with nothing better, the best of the choices
quest-rewards The game's reward panel: a green arrow on each upgrade, the one to take framed in the accent; with no upgrade, the coin on the one that sells for most
xp-bar The game's XP bar with the level the guide wants you to reach: the next level; four levels away; the setting under Quality of Life, Trackers
quests-map Quest markers on the world map: givers, kill, item (drops, crate, vendor), object and exploration objectives, a turn-in; then a guide step highlighting its quests and dimming the rest
quests-minimap Quest markers on the minimap around the player: nearby objectives, givers and the turn-in; then with the guide step highlighted
travel Travel: the arrow (Arrow scale 160%) on a route into the next zone, its leg captioned ("Go to Westfall"), and the trail dots on the world map from the player to the zone crossing; then the arrow where the game gives no position (the Deeprun Tram)
nav-areas Spawn regions: Teldrassil's The Balance of Nature, the arrow on the Fel Moss. On the world map every place the step's mobs and objects spawn is a region: the Grells' woods west and north of Aldrassil and a lone Grell's place in the arrow's colour, the Nightsabers', Thistle Boars' and Gnarlpine Totems' regions fainter; on the minimap the Fel Moss region around the player, cut at the rim
dungeons Dungeons in the hub: Home for a level 20 Tauren (the dungeons for your level, faction filter Horde); Wailing Caverns, its Quests tab
dungeons-xp Wailing Caverns: the levels its quests are worth, the chip beside the name hovered: at 19,800 of 23,200 XP into level 20 they carry the Tauren into 21; at 27 the lowest gives a tenth of its XP
dungeons-bosses Wailing Caverns: the Bosses tab (kill order and the quests each serves) and the Map tab (the entrance and the quest givers near it); All dungeons with the filter on All
dungeons-attune The Attunement tab: Wailing Caverns' attunement with the first quest done and the second in the log, and "Guide me through it"; the Deadmines' keys with the filter on All
dungeons-small The hub at its smallest (menu scale 0.7): Wailing Caverns, Quests; without the Codex pack
rares Rares in the hub: Elwynn Forest's rares by zone, Thuros Lightfingers with its signature drop, its spawns and when it was last met; the Seen list
rares-toast The rare alert over the world: a rare on the minimap at its distance; a rare elite in sight; a treasurepolestar profession#
Build professions.json; draft a crafting guide; build or check the generated gathering guides
polestar profession --helpusage: node tools/polestar.js profession build [options]
node tools/polestar.js profession draft <Profession> [options]
node tools/polestar.js profession gathering build|check [options]
build: writes data/forever/professions.json from the Forever client's tables
(<tables> CSV, wow_classic_beta 1.60+: SkillLine, SkillLineAbility,
SpellName, SpellEffect, SpellReagents, SpellTotems, SpellCastingRequirements,
SpellFocusObject, ItemSparse, Item, ItemEffect, ItemXItemEffect; the newest
Classic Era build fills the spells and items they lack) and
data/forever/{items,npcs,objects}.json. Trainers come from a curated name
list checked against npcs.json.
--offline use cached tables only
--build <version> <tables> Forever build (default: newest listed)
--data <dir> reference data (default data/forever)
--sources <dir> source cache (default data/sources)
--out <file> default <data>/professions.json
draft: prints (or writes) a 1-300 guide for a crafting profession (Alchemy,
Blacksmithing, Enchanting, Engineering, Leatherworking, Tailoring): the
cheapest sensible recipe chain by expected crafts and material cost, with
trainer visits, recipes to learn, materials to buy or gather, and skill
checkpoints at 75/150/225/300.
--data <dir> reference data (default data/forever)
--out [file] write the guide (default guides/forever/professions/<name>.guide)
--quiet no plan summary on stderr
gathering build: rewrites the six generated guides in guides/forever/professions
(mining, herbalism, skinning, fishing, cooking, first-aid) from their specs in
tools/lib/professions/gathering/specs.js and data/forever (node spawns,
professions, items, npcs, objects). Run `compile` afterwards.
gathering check: builds them in memory and exits 1 when a committed guide
differs (writes nothing).
--data <dir> reference data (default data/forever)
--stdout print the guides instead of writing them (build only)polestar qol#
Build the Quality of Life module data (spirit healers, flight masters, reagent vendors)
polestar qol --helpusage: node tools/polestar.js qol build [--data <dir>] [--lua <file>]
--data <dir> data/forever (npcs.json, map-frames.json)
--lua <file> output (default: addon/Polestar/QoL/Data.lua)polestar questdb#
Build the load-on-demand quest database addon (markers, tooltips)
polestar questdb --helpusage: node tools/polestar.js questdb build [options]
Builds the load-on-demand quest database addon (addon/Polestar_QuestDB) from
data/forever: quests (levels, race/class masks, faction, givers, enders,
prerequisites, objectives), NPCs and objects (spawn clusters per map, covering
every known spawn; Era frames) and items (drop sources, objects, vendors).
Prints the Lua size and an estimate of the in-game memory it costs once
loaded.
--data <dir> data/forever (quests, npcs, objects, items, map-frames)
--out <dir> output addon folder (default: addon/Polestar_QuestDB)
--radius <yd> spawn cluster radius (default 70)
--droppers <n> NPC drop sources kept per item (default 8)
--json print the stats as JSONpolestar readme#
Redraw the README's art: brand (docs/assets) and charts (docs/assets/charts)
polestar readme --helpusage: node tools/polestar.js readme brand
node tools/polestar.js readme charts --draft <dir|git rev> [options]
brand: rewrites docs/assets/{banner-dark,banner-light,emblem,logo,download,avatar}.svg,
drawn in code from the emblem geometry and the wordmark fonts, and with
rsvg-convert (librsvg) installed the CurseForge listing's PNGs in
docs/curseforge/images (the avatar, the banner and the charts); without it,
prints the rsvg-convert commands to run. charts re-exports its two PNGs.
charts: rewrites docs/assets/charts/{levels,starts}.svg. Scores the guides
under the simulator's model (as `sim compare` does) against an earlier set
of them; the best route found and the consensus route are drawn when the
results in --sim were searched on the world being scored.
--draft <dir|rev> the earlier guides: a guides folder, or a git revision
whose guides/ is used. The README's charts use v0.1.0,
the first release.
--draft-label <text> how the charts name them (default: "Polestar <x.y.z>"
for a release tag vX.Y.Z, else "Earlier guides")
--sim <dir> simulator outputs: world, params, results, consensus
(default data/sim)
--guides <dir> the guides to score (default guides/)polestar record#
Polestar Recorder sessions: import, watch, draft guides, measure routes (report)
polestar record --helpusage: node tools/polestar.js record <subcommand> [options]
import Archive and convert the recorder's SavedVariables:
raw copy -> data/recordings/raw/<timestamp>-<account>.lua,
one JSON per session -> data/recordings/<session>.json
(a session already on disk keeps the longer event list);
--anonymize for a file a player sent in: no name or
realm (a hash keys the character), no raw copy
watch Import again whenever the client rewrites the file
(keeps sessions safe from the cold-start SavedVariables reset)
draft <session|file> Write a draft guide from a session key or JSON file
to <pack>/drafts/<faction>-<race>-<date>-<time>.guide: the
pack is --pack, else the nearest pack.json, else our
guides/; another pack's draft id starts with "<pack id>/"
list List imported sessions
report Measure the guides from recorded play (Polestar + Recorder):
per step passes, median/p75 time, XP, XP/hr, combat share,
deaths, turn-ins, travel; per guide time, levels, XP/hr;
the slowest steps, steps far over the guide's median step
time, and detours (far travel for little XP)
options:
--sv <file> SavedVariables file to use (repeatable); skips auto-detection
--wtf <dir> WTF folder to search (default: the detected Forever client's,
e.g. <Wine prefix>/drive_c/Program Files (x86)/World of Warcraft/_forever_/WTF;
POLESTAR_WTF overrides)
--out <dir|file> import/watch/list: recordings folder (default data/recordings);
draft: output .guide file or folder (default <pack>/drafts)
--pack <dir> draft: the pack the draft belongs to
--recordings <dir> draft/report: where sessions are read (default data/recordings)
--interval <ms> watch: polling interval (default 1000)
--force draft: overwrite an existing draft
--anonymize import: drop character names and realms (see import)
--guide <text> report: only guides whose id or title contains <text>
--top <n> report: length of the ranked lists (default 10)
--json report: print the report as JSONpolestar regen#
Regenerate committed files after merging contributor PRs (compile + i18n sync + preview + media)
polestar regen --helpusage: node tools/polestar.js regen [--no-compile] [--no-i18n] [--no-preview] [--no-media]
Regenerates the four sets of committed generated files that contributors
do not commit themselves:
compile addon/Polestar_Guides/Guides.lua from guides/ and data/forever
i18n sync locale files from the addon’s English strings
preview docs/preview/*.svg from the addon’s Lua (no reference data)
media addon/Polestar/Media/*.tga from tools/media/ (no reference data)
compile needs the reference data (data/forever); the rest do not.
Pass --no-<step> to skip a step.
Run this after merging contributor PRs that touch guides/ or the addon’s
Lua, and before every feature release.polestar release#
Release tooling: patch scope check, patch preparation, release notes
polestar release --helpusage: node tools/polestar.js release <scope|patch|notes> [args]
release scope [--base <ref>] [--root <dir>] [--files <path|->]
Prints each changed path a patch release may not carry, one a line, and
exits 1 if there is one. A patch may change only:
guides/**
addon/Polestar_Guides/**
tests/guides-*.test.js
tools/lib/data/corrections.json
CHANGELOG.md
changes/**
The paths are read from --files (one a line, - for stdin; `git diff
--name-status` lines work too), else from `git diff --name-only
<base>...HEAD` in --root, renames giving both paths. --base defaults to
the newest v* tag reachable from HEAD.
release patch <x.y.z> --root <dir> [--from <tag>] [--zip <file>] [--data <dir>] [--data-built]
Prepares a patch release on the hotfix/ checkout at --root with that
checkout's own tools: stops on paths the patch may not carry, or on a
changed tools/lib/data/corrections.json (run `data build` there first,
then --data-built); puts back Polestar_Codex and Polestar_QuestDB from the
release zip of --from (default the newest v* tag in --root; downloaded
with gh unless --zip names it); sets the version; lints and compiles; and
lists the compiled guides that differ from --from, warning about those
whose sources did not change.
--data <dir> reference data for lint and compile (default this
checkout's data/forever/, or --root's with --data-built)
release notes <x.y.z> [--root <dir>] [--out <dir>]
Writes the version's CHANGELOG.md section as dist/notes-<v>.md (GitHub),
dist/notes-curseforge-<v>.md and dist/notes-discord-<v>.txt. Each has a
placeholder for the intro, marked [[REPLACE, to replace before
publishing.
--root <dir> folder holding CHANGELOG.md (default the repository)
--out <dir> where to write (default <root>/dist/)polestar sim#
simulate and optimize leveling routes (docs/SIMULATION.md)
polestar sim --helpusage: node tools/polestar.js sim <command> [options]
sim world [--faction F] [--rebuild] build/cache the world model (data/sim/world-<faction>.json)
sim walks [--faction F] [--radius Y] [--workers W] route the world's walks with the walking router
(data/sim/walks-<faction>.json; run, robust, compare, bench and consensus use them)
sim calibrate [--fdj DIR] fit parameters to quest data and recordings
sim run --faction F [--race R] [--class C] [--paths N] [--workers W] [--seed S] [--dungeons]
[--jobs J] [--anneal A] [--max-paths M] [--objective time|smooth] [--param K=V ...] [--tag T]
sim robust --faction F [--race R] [--class C] [--draws K] [--top N] [--objective O] robustness of the top routes
sim compare --faction F [--race R] [--class C] [--guides DIR] [--pack DIR | DIR] [--to 10,20,30] [--with-optional]
[--objective O] Polestar's routes vs the best found, same model
sim bench --faction F [--race R] [--class C] bracket table: zones, levels, quests per 10 levels
sim export --result <file> --out <dir> zone-by-zone skeleton guides + visits.json for authors
sim consensus --faction F [--dungeons] [--evals N] [--objective O] one 12-60 route shared by the faction's starts (+ exports)
Without --race, run/robust/compare/bench cover every start of the faction
(Horde: Orc, Tauren, Undead, Skyborne; Alliance: Human, Dwarf, NightElf,
Skyborne). Class defaults to none ("any": class quests excluded, class factor
1); with --class the class's quests and kill-speed prior are used, and
compare/bench write their own files so the class-agnostic ones stay.
options:
--data <dir> reference data (default data/forever)
--sim <dir> simulator outputs (default data/sim)
--fdj <dir> calibrate: ForeverDungeonJournal folder (default: the installed one)
--class <name> Warrior, Paladin, Hunter, Rogue, Priest, Shaman, Mage, Warlock or Druid:
score for that class (run/robust/compare/bench); default none ("any")
--band <levels> level width of the world's quest packages (default 5; a new width rebuilds the world)
--guides <dir> compare: Polestar guides folder to score (default guides/), e.g. an old copy
--pack <dir> compare: also score this pack's chain (or name the pack folder
as the one argument; default: the nearest pack.json); after our chain
up to its first level when it starts above 1;
written to data/bench/compare-<faction>-<race>-<pack id>.json
--to <levels> compare: levels to show time to (default 10,20,30,40,50,60)
--with-optional compare/bench: also score the guides' optional goals (default: only what
a guide requires; elite and dungeon quests stay out either way)
--jobs <n> run: search jobs per round (default 32)
--anneal <n> run: annealing evaluations per job (default 6000)
--max-paths <n> run: hard cap on evaluated routes (default 3x --paths)
--dungeons run/robust/consensus: the dungeon-inclusive family (needs data/forever/dungeons.json)
--objective <o> run/robust/compare/consensus: what the search optimises (default time):
time = the fastest route; smooth = fewer zone changes, returns into zones
left earlier and returns to spots already worked (docs/SIMULATION.md);
smooth results are their own files (horde-orc-any-smooth.json)
--param <k=v> run/robust/compare/consensus: set a model parameter (params.js), after the
objective's preset; repeatable (--param grindWeight=6 --param zoneReturn=0)
--tag <name> run/robust/compare/consensus: a result file variant, e.g. --tag g6 writes
horde-orc-any-smooth-g6.json (and robust/compare/consensus read and write it)
--radius <yards> walks: route every pair of points up to this far apart (default 4000)
--no-walks run/robust/compare/bench/consensus: walk the straight line × detour even
when data/sim/walks-<faction>.json is there
--offline never download the QuestXP table
--quiet less outputpolestar talents#
Build or check Talents/Builds.lua (talent plans)
polestar talents --helpusage: node tools/polestar.js talents build|check [options]
Resolves the talent plans in talents/forever/*.json (one file per class, one
pick per level, by talent name) against the Forever client's trait tables (<tables>, build
1.60.1.70450, cached under data/sources/<tables>/), replays every pick under the
client's rules (one point a level from 10, tier gates, arrows; arrows need
their source at full rank), and writes every class into addon/Polestar/Talents/Builds.lua.
check rebuilds in memory and fails if the file differs or a plan breaks a rule.
options:
--plans <dir> plan sources (default talents/forever/)
--out <dir> output folder (default addon/Polestar/Talents/)
--sources <dir> download cache (default data/sources/)
--build <ver> client build (default 1.60.1.70450)
--offline use cached tables onlypolestar trainers#
Build trainers.json and Core/ClassTrainers.lua (class trainers)
polestar trainers --helpusage: node tools/polestar.js trainers build [options]
Builds data/forever/trainers.json, the class trainers `train class` picks from:
every `train <npcId> only <Class>` goal under guides/, recorded trainer visits
in data/recordings (by the recording character's class), and Polestar's curated
list of capital and starting-town trainers, each verified by name and map
against npcs.json. Without the file, compile uses the curated list alone.
Also writes addon/Polestar/Core/ClassTrainers.lua: one trainer per town and
class, with positions and map frames, for the class-training reminder, and
every class trainer's npc id by class, for Engine.IsClassTrainer.
options:
--guides <dir> guide sources (default guides/)
--data <dir> reference data, also the output folder (default data/forever/)
--recordings <dir> normalized recordings (default data/recordings/)
--out <file> output file (default <data>/trainers.json)
--lua <file> Lua output (default addon/Polestar/Core/ClassTrainers.lua)polestar travel#
Build the travel network (flights, boats, inns, learned paths, zone crossings), import zone crossings, test routes and draft approach chains from recordings
polestar travel --helpusage: node tools/polestar.js travel build [options]
node tools/polestar.js travel route --from <map,x,y> --to <map,x,y> [options]
node tools/polestar.js travel chain --to <map,x,y> [options]
node tools/polestar.js travel import --<crossings> <ZoneConnections.lua> --source <text> [options]
build: the flight network (Blizzard Classic Era TaxiNodes/TaxiPath/TaxiPathNode
via <tables>), boats/zeppelins/tram (plus the ships WoW Forever added, from
the Forever client's TaxiPathNode), inns, learned walking paths and zone
crossings learned from recordings -> data/forever/travel.json,
addon/Polestar/Nav/TravelData.lua and the flights' tracks in
addon/Polestar/Maps/FlightPaths.lua. The shipped crossings file
(tools/lib/travel/crossings.json, from "travel import") goes into TravelData.lua.
With the optional local crossings file (data/local/crossings.json, validated)
it also writes the local data addon addon/Polestar_Travel (installed when
built, never packaged).
--offline use cached <tables> tables only
--build <version> Classic Era build (default: newest listed)
--forever-build <v> WoW Forever build (default: newest 1.60+ listed)
--data <dir> data/forever (map-frames, zones, npcs, objects)
--recordings <dir> data/recordings
--sources <dir> data/sources (<tables> cache)
--shipped <file> the shipped crossings file (default: tools/lib/travel/crossings.json; "none" to leave it out)
--grid <dir> the navigation grid (default: data/local/nav4; "none" to leave it out): a ship's end
lying in the water gets a board point, the nearest dry deck within 30 yd; without a grid, none
--crossings <file> the local crossings file (default: <data>/../local/crossings.json)
--travel-addon <dir> Polestar_Travel output (default: addon/Polestar_Travel)
--json <file> travel.json output (default: <data>/travel.json)
--lua <file> TravelData.lua output (default: addon/Polestar/Nav/TravelData.lua)
--flight-lua <file> FlightPaths.lua output (default: addon/Polestar/Maps/FlightPaths.lua;
with --lua, FlightPaths.lua beside that file)
route: run the addon's own planner (Nav/Travel.lua + TravelData.lua, plus
Polestar_Travel when built) under Lua 5.1 between two Era-frame map points
and print the legs.
--from <map,x,y> start (uiMapID, map percent)
--to <map,x,y> target
--faction <name> Alliance | Horde (default Alliance)
--known <ids|names> flight master node ids or names; repeatable, or separated by ";" or ","
("Sentinel Hill, Westfall" matches the full node name first)
--speed <yd/s> run speed (default 7)
--hearth <location> bind location, Hearthstone ready
--data <dir> data/forever (map-frames, zones, travel.json)
--lua <file> TravelData.lua (default: addon/Polestar/Nav/TravelData.lua)
--crossings-lua <f> Polestar_Travel's Crossings.lua (default: addon/Polestar_Travel/Crossings.lua when built; "none" to skip)
--json print the legs as JSON
chain: a candidate approach chain (a cave, a climb) for the local crossings
file, from the recorded walks that reach a target: where each walk leaves the
straight line to the target, and the walked path from there simplified into
nodes with radii and a first caption. Walks from several sides meet at the
mouth, so the shortest chain is printed. A walk that keeps to the straight
line is reported but does not stop the draft (recordings have no height: it
may have followed the arrow onto the hill above a cave). Check it in game
before using it.
--to <map,x,y> the target (uiMapID, Era map percent)
--name <text> the place ("Fargodeep Mine"): the chain's name, id and first caption
--id <id> the chain's id (default: from --name, else recorded-chain-<map>-<x>-<y>)
--within <yd> how far back from the target a walk is followed; shorter walks
do not count (default 300)
--tolerance <yd> how far the walk may stray from the line between two nodes (default 8)
--session <id> draft from this session's walks only (repeatable)
--reverse count each walk's way out, reversed, as a way in too
--data <dir> data/forever (map-frames, zones)
--recordings <dir> data/recordings
--json print only the chain entry
import: the shipped crossings file from <crossings>'s Classic Era zone
connections (<crossings>/Data/classic/ZoneConnections.lua in
github.com/IrcDirk/<crossings>-Classic, GPL-3.0): its walks between zones
(two-way unless marked one way), validated, with the arrival radius given.
The open borders of the file it replaces (from the navigation grid, not
<crossings>) are kept.
--<crossings> <file> <crossings>'s ZoneConnections.lua
--source <text> where it came from (repository and commit), kept in the file
--radius <yd> arrival radius of every end (default 30)
--data <dir> data/forever (map-frames, zones)
--out <file> output (default: tools/lib/travel/crossings.json)polestar version#
Show or set the release version (package.json, guides/pack.json and addon TOCs)
polestar version --helpusage: node tools/polestar.js version [<x.y.z>] [options]
Without a version, prints package.json's version and names guides/pack.json
or any addon TOC whose version differs (exit 1 if one does). With one, writes
it to package.json, to guides/pack.json (compile takes Polestar_Guides'
version from it) and to the ## Version line of every addon/<Name>/<Name>.toc
present. Data addons built later take the version from package.json.
options:
--root <dir> folder holding package.json (default the repository)
--addons <dir> addon folder (default <root>/addon/)