The writer
Contributor56 min readUpdated
How a route becomes guides: what goes in, the shipped layout, and keeping the guides’ own lines and tips.
On this page
- Written for how Polestar plays
- What goes in
- The shipped layout
- One shared route
- How it works
- 1. Read v1's lines, typed
- 2. Put the goals in the route's order
- 3. Fix-ups (src/post.rs)
- 4. Travel
- 5. Engine features
- Text: what the writer writes itself
- Running it
- Into the addon pack
- When something goes wrong
- Tests
- The writer gate
The writer turns a route into guides. A route is the simulatorThe earlier JavaScript route model that made the routes up to 0.2.x, kept for sim compare, lint's solo filter and the planner's clock (legacy/SIMULATION-js.md); Forge's model is forge/model.md.'s improved quest order for one start (see How a route is made). The writer puts that order into v1's guides, the current guides Polestar ships. It keeps v1's own lines, tips and layout wherever it can. The result is a normal guides folder. The compiler lints it and builds it into the addon's 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)., and the judge compares it with v1 (see The judge).
The writer is the forge-writer crate (rust/crates/forge-writer). It runs
as forge writer apply-route, and forge build runs it as its guides stage
for every start. The compiler is forge-guide (forge guide compile|lint).
See Polestar Forge for the whole pipeline.
Written for how Polestar plays#
A route is only as good as the way the addon plays it, so the writer writes for the engine
(addon/Polestar/Core/Engine.lua, Guide format):
One area, all its work
loop: its gotos become one search circuit for every goalOne thing to do in a step, as a verb and its arguments (accept 783, kill, goto, turnin...). in
the step.On the way
along until <label>
step for it (up to six listed at once; only goals the game counts anywhere: quest kills,
collects, interacts and uses, bag counts, accepts and hand-ins).Pick up what you stand next to
join and pickup pass).No pointless trips
One sweep per hub
forge judge check holds every build to these (merge, along, arrow-order, next-to,
dup-trip, bounce, hub-order, walked-past, left-ready).
What goes in#
| Input | What it is | Default |
|---|---|---|
| route | <start>.json from the routes stage: faction, start, dataHash, order, diff.added, diff.dropped, and v1's and the improved hours | required |
| world | world-<faction>.json, the simulator world whose point ids the route uses | required (--world) |
| walk store | walks-<faction>.bin, walking yards between world points (around hills, not straight lines) | beside the world file |
| v1's guides | a guides folder holding forever/ | <root>/guides |
| game data | quests.json, npcs.json, objects.json, items.json, zones.json, map-frames.json and the compiler's data | <root>/data/forever |
| fix records | data/places.json (arrow points, roads, objectives' own lines) and data/guide-fixes.json (tips, level gates) | <checkout>/data/ (--checkout, default --root) |
Each order item is one event: t is accept, turnin, task (work on an
objective), train, level (with its fractional grind target) or ride
(riding training at the trainer npc). It also has the quest q, the world
point pt, the level lvl before the event, the travel items that lead to
it (walks, flights, rides, hearths, binds, flight paths), and from. from
is the v1 line the event came from (guides/forever/....guide:LINE),
inserted for a quest the route added (or a riding trainer v1 has no line
for: a Riding trainer step, or a grind top-up), or train stop for an added
training stop. A level line is written at its target. A top-up the route
inserts (a level item with no v1 line, at the point the planner chose: after
the work at a camp, before a hub's hand-ins; min its model minutes) is a step
of its own there, which a player already at that level skips, unless (with
route travel, after the area steps are made):
- the step right before it works quest objectives for everyone: its
levelline goes into that step, and the player kills on there until the level; - a top-up step was kept before it in the zone stay, with no flight, hearth or boat between: the two become the later one, when the earlier gates no accept and the two come to at most 15 minutes (right after one another, always);
- it is under 5 minutes and gates no accept: its
levelline goes into the next farm step of the stay (within 8 steps), else it is left out (quest XP mostly covers it, the rest goes to the next top-up).
c14's Human route wrote about 90 Level steps, one per piece of each split
grind, before this.
The route's dataHash must equal the world's. A route found on one world uses
that world's point ids, so the writer refuses a different world.
The shipped layout#
v1's leveling guides are laid out like this, and the writer keeps the layout:
- Start guides belong to one start's races (
race Orc,Troll) and live under the race's folder, for exampleforever/horde/orc-troll/01-durotar.guide. - The shared chain is the faction's guides with no
raceheader, for exampleforever/horde/02-the-barrens.guideto07-ashenvale.guide, then30-40/,40-50/and50-60/. Every race of the faction plays them. nextlinks each guideOne route, written as a .guide file and compiled to Lua; its id reads like forever/alliance/human/01-elwynn-forest. to the one after it. A start's last guide hands over to the shared chain. The writer follows v1'snextlines to find the chain, and changes them in one case only: a start's own guide just before the shared chain that has no line of the start's route (Orc and Troll'sorc-troll/02-the-barrens, whose quests the shared route takes in the shared guides) keeps only its class steps and class lines (the shared guides do not carry those races' class chains); with none, it is left out of the written guides and the guide before it hands over to the shared chain, with the start's arrival at its end.- A shared guide in a start's own part.When a start's route plays a
shared guide before the join (Night Elves do Darkshore to about 14 as part
of their own start), its run's writing of that guide becomes one of the
start's own guides,
<start folder>/<NN>-<stem>(forever/alliance/nightelf/02-darkshore), with the start'sraceheader, between the start's guide before it and the join guide. The shared guide stays the same for the other starts. train classsends the player to the nearest trainer of their own class, picked by the addon at runtime. A route's training stop is written as a stepClass trainerwithtrain class, unless v1's next steps train there anyway (not past an added quest's event away from the stop: Korran at the Crossroads between the Orgrimmar training and Regthar, c19p, trains in Orgrimmar first). One trainer visit per route training: v1's own training steps the route did not place, in the events after it up to about a level and a half on, come with it (Orgrimmar for most classes, Thunder Bluff for Druids and Paladins), on the trainer's continent, and a step with other work than training only from the trainer's own town (the Druids' Heeding the Call stays at Dolanaar); the route's own line is then only for the classes they leave out. Those steps are at the stop: the route's way on leaves after them, and classes flown off to their own trainer fly on from there to where the way on's flight lands, the others' wayonlytheirs (Orgrimmar -> Thunder Bluff -> Crossroads for Druids and Paladins, not back to Orgrimmar first). A v1 step that only travels to a trainer and trains, left over where the route plans its training elsewhere, goes. v1's training line the route trains by in another city (its Stormwind trainer for v1's Ironforge line) is written at the route's trainer when the rest of v1's step is the route's elsewhere. At a route training stop in a town with no trainer for some classes (Razor Hill has no Mage trainer), those classes train at the route's next pass by one of theirs within a level and a half (Sen'jin Village), else as before; a class that trained at most two levels before gets no trip of its own from there (the Rogues and Warlocks at Thunder Bluff at 28.7, trained in Orgrimmar at 26.8). A stop where the route already stands (within 300 yd) reads the zone the step before named (Thunder Bluff's Shaman stop is on Mulgore's map, and said Mulgore in the city), and a class trained once in a town visit (no flight, hearth or goto step between) is not trained again there (the route's Shaman stop, then v1's Spirit Rise step).- Riding at 40 (
post::riding_at_level, on the guides as written, the travel repair's ways and the adopted shared guides included): a step that trains at a riding trainer (the data's "... Riding Instructor" or "... Riding Trainer", the Gnomes' "Mechanostrider Pilot") holds only from level 40 (when level>=40): the planner plays riding at 40 or later only (c19p: 42.5 to 50 in every start's model, about 43 in the check's walk), but a player can be behind the model; so does a "Riding at 40" step with notes alone (the Skyborne's, whose trainer is on Zephras Isle). A riding line in a step with other work goes into a "Riding at 40" step of its own right after it, with the step'sonlyand zone. The way there and back for its characters is gated with it: the travel-only steps right before it with itsonly, and right after it, else further on up to everyone's next step the travel-only steps of theirs or of some of their classes, past steps for other races or for some classes of every race (the Taurens' flight back to Gadgetzan after the Undead's and the Druids' trips; the Undead's ways back from Brill, the Paladins', the Warlocks' and the others'); with no way back before everyone's next step (the Humans' walk to Eastvale), the way there alone: under 40 they stay with everyone. A step between for theirs and another race's, or another step of theirs that is not travel, leaves the riding step as it was: gated alone it left them where the way there ends, and the next way failed. - Route fixes' optional quests (
post::optional_by_fixes, the guides as written): each goal line but the hand-in of a questdeliberate.optionallists (the rare-drop chains: The Green Hills of Stranglethorn and its chapters, Study of the Elements: Rock) is writtenoptional, so no step waits on the drop; the hand-in applies only to a player who has the quest done. - Weapon skills (forgeThe Rust pipeline that makes the leveling routes from the installed game and the guides (each race's start zone, then one shared route per faction), writes the leveling guides and plays them through the route check (forge build, FORGE.md).-writer
weapons.rs, #655): where a guide already stops in Stormwind, Ironforge, Darnassus, Orgrimmar, Thunder Bluff or Undercity at level 10 or later, each class with a weapon skill that city's weapon master teaches gets a step after the last step it plays there beside the master (within 60 yd), else after its last step there (before it, when that step ends on the way out; Ansekhwa after Eyahn on Thunder Bluff's central rise, not after Elder Rise and back):train <master>withwhen money>=10s(Polearmswhen level>=20,when money>=1g) andwhen !skill "<Skill>" 1, so a character who cannot pay, starts with the skill or learned it earlier never sees it. Warriors: Two-Handed Axes, Maces, Swords, Polearms; Paladins: Two-Handed Swords, Axes; Hunters: Staves, Polearms; Rogues: Swords; Priests and Warlocks: Staves (Forever's trainer data: Sayoc teaches no Staves, Ansekhwa no Guns). Each skill once per class in a start's own guides and once in the shared guides; a visit only some races make offers it to them, a later one to the rest. The level is the route's at the quests everyone does there; never a trip of its own.
Read the rest of this section120 words
A shared guide is played by every race, but a route is for one start. In a
shared guide the writer marks its changes only <the route's races> and leaves
v1's lines for the other races. A hearth the route's races are not bound for
goes for them. For everyone else v1's line stays. Two lines for complementary
race lists become one line for everyone.
A route of the faction's shared route (shared in the route) is the same for
every start from its joinAt guide on (the Barrens, Westfall: a guide stem in
any folder). The shared guides whose route steps all come at or after that
guide's first step are written for everyone, the same for every start.
One shared route#
With the route's own legs (src/shared.rs), every start of a faction gets the same shared guides,
byte for byte, as forge guide publish needs: one shared route per faction. The writer reads the
faction's routes beside the one it writes (routes/<Start>.json, the same shared.canonical) and
builds one shared order:
- the canonical start's tail from
shared.joinStep, its events in its own race guide moved to the same line of the shared guide (Orc and Troll's own Barrens guide ends at the Crossroads at 12), an event with no such line written as an added one; - every other start's quest events after the shared event they follow there, without their travel, when they stand within 400 yards of the shared events around them. A quest a start carries in from its own guides whose shared-route events need a detour is left out for that start (the log names them: the planner's to put on the shared route). An event whose later chain event (same quest or same group) already stands earlier in the shared order goes no later than that one: at the last slot back from there where the player stands at a shared accept or hand-in beside its place, never before a shared hand-in its start made before it (Alba's Testing the Wells at the first Sentinel Hill stop beside Scout Galiaan, not after its own vials; Tauren's Monogrammed Sash before The Captain's Cutlass another start's route added, c18g). Nearness is judged where the chain puts an event; where starts disagree on an event's slot, it goes where most of them have it (ties: the earlier start), and each start's own chain is kept in order around that (Testing the Wells handed in after Blanchy's oats, as the Dwarves, Gnomes and Skyborne have it).
Read the rest of this section707 words
The canonical start's run on that order writes the shared guides, its travel repair and engine
passes included (the chain they play runs on through the start's own guide the route has no line in
any more, Orc's own Barrens guide, to the shared ones); each start's run writes its own guides on its
share of it and takes the shared guides from the canonical run. A quest only some
starts do there, or one the data's race mask closes to some races, gets only <their races> (added
to a line's own classes); a line of a quest ahead of its accept on the shared chain, or of one some
starts carry in, goes to a step when onquest Q. The travel steps that open the join guide go to the
end of the start's own last guide; a start's own way to the join (its hearth, the zeppelin's tip)
is its own route's, not the canonical start's, and leads to the shared order's first event, wherever
the start's own first shared event falls (the Gnomes' tram leads to the Jansen Stead, not to Ozwin at
Saldean's Farm after the walk in). That way is written at the end of the start's own guide, before
v1's steps waiting there for a place it passes, which it takes at their places along it, the flight
paths it walks by learnt there first (the tram to Stormwind, Stormwind's flight master, the class
quests there, the Mages' Mirror Lake on the walk on to Westfall).
Each race's and class's own way is written for them alone: the shared guides are played as every
race of the faction (from its v1 start guides on; a v1 start-guide step whose quest lines the shared
guides now have learns no flight path there, as the shared guides learn it: Orc and Troll's Ratchet,
c18g), and as each class some shared line is only, and
each travel failure (the honest playtestPlaying a pack's guides to the end in the real addon, once per class they branch on (node tools/polestar.js playtest).'s R1) gets that player's way, only <race> or only <race>,<class>, as the travel repair writes it; a travel line that is not theirs is only the
others. For a class's way the others include its races' other classes: a line the Orcs alone see
becomes only Orc,!Shaman for the Orc Shamans' way, and a line others see too stays theirs on a
line of its own beside it (only Troll,Tauren,...); such lines side by side with the same classes
are then one line for all their races. only lists are read one way everywhere, the writer's
repair and the judge alike (forge_guide::conditions::Audience: races, classes and factions each
one-of, all three together, !Class every class but that one). A race's riding trainer or the Undercity zeppelin for one race's quest is never everyone's
walk. In a run of such travel steps, the same step for several races with the same classes is one
step only all of them, and a step for every race is everyone's. Travel steps alike but for their
audiences (the step's only and the goals' own) whose audiences together are every character of the
faction are one step for everyone, at the first one's place, else the last one's, when no character
passes a step of its own on the way (the per-race and per-class copies of one Tirisfal goto and
zeppelin out of the Eastern Plaguelands). The starts are played twice when the first pass wrote ways,
so a start played before another's way changed a line it plays is played on it again; and on a
shared guide a flight from no flight master is repaired even where the start's v1 breaks there too
(the Dwarves' fly "Astranaar" from Maestra's Post).
forge build writes a faction's starts at once (the routes stage's written check, the guides
stage) with one native::SharedCache per faction: the canonical start's run, the races' and
classes' ways on the shared guides and the walk store are made once, by the first start that needs
them, and every other start waits for them instead of making them again (the canonical start
claims its run before it makes it, so the other starts' own runs go on beside it). Each is kept by
its exact inputs, so every start's tree is the one it writes alone.
How it works#
1. Read v1's lines, typed#
Each guide is read as a header plus steps. Each step line is typed by its first
word (src/guide.rs):
| Kind | Head words | Split rule |
|---|---|---|
| goal | accept, turnin, complete, kill, collect, goto, talk, interact, use, sethome, hearth, getfp, fly, train, buy, vendor, level, note, skill, learn, craft, rep, explore, achieve, die, enter, equip | moves with the route |
| every piece | only, when, zone, loop | repeated on every piece of a split step |
| first piece | tip, label, along, image | kept on the first piece only |
| other | anything else | stays with its step |
Every line keeps its exact text and where it came from (file and line). The writer moves v1's lines; it does not re-render them. That is why its output can be compared byte for byte with the old JavaScript writer.
2. Put the goals in the route's order#
- The hub tour (with route legs,
src/hub.rs) first walks each town or camp the way leveling guides players trust do (#736, #737, #739, #740). A hub is the route's quest NPCs linked within 120 yd. On a walk between two events, a giver or ender with a ready accept, hand-in or talk within 50 yd of the straight leg is visited on the way (Simmer's Fields of Grief between Calvin and Gordo). At each visit to a hub, the hub's later accepts and hand-ins that are ready join it, and so do its talks the route comes back for after leaving (200 yd away): Dillinger's A Putrid Task with Holland and Zygand, Aramis' A Light in the Darkness on the way back from the cave. Ready is an accept on level (in a start zone a level over its minimum: the model runs ahead of real play there, Gordo's Task) with every prerequisite handed in, taken by the route within 1.5 levels (1 on the way), or a hand-in with every task done; never ahead of an event the route fixes'deliberateoroverridespairsput before it, and a hand-in taken on the way never ahead of a hand-in such a pair puts first (Testing the Wells after Blanchy's oats, c18g). A hand-in the route comes back for after leaving, at an NPC outside the hub but within 200 yd of where the visit stands, joins the visit too (Ozwin's isosprings at the Saldean's Farm stop, 160 yd off, not after the walk to Furlbrow's and back, c19), unless the route comes back to that NPC later anyway. A task done with an item at a hub NPC's own spot (within 10 yd: Kaga Wildhoof's campfire, Gremlock's cooking lesson) is part of the visit. Then the visit's NPCs are walked in the shortest order from where the route comes in to where it goes next, each NPC once unless the quests' own order makes a second stop shorter, the pairs kept; a delivery whose item runs out within 15 minutes (the Scalding Mornbrew) is handed in first. A bind goes with the visit's event nearest the inn. Events move only earlier and, but for the next rule, only among one v1 guide's events; a line a class's own step waits for goes last in its visit, after every stop that does not wait for it, so the class step closes the visit (Perrine's Chest after Brill's turn-ins); a hearth or flight stays the visit's way in. A visit of other starts' events alone (their quests in the shared order) takes nothing: Scout Galiaan's hand-in stays at the Humans' own Sentinel Hill stop, not at the Dwarves' stop for Alba's vials. Ready where the travel leaves you: before that, at the flight master a flight of the route leaves from, and where a flight, a deathskip or a hearth lands the player when the event it is for is more than 120 yd away, each hand-in ready then at an NPC within 120 yd of that spot, which the route comes back for only after leaving, is done there (from any guide of the chain): before the flight, or on landing, the travel going with the first of them, and with them the follow-ups they open at the same NPC, however much later the route takes them (Sen'jin Village's hand-ins on the deathskip's landing before Kolkar Crag; Nathaniel Dumah's beside Chillwind Camp's flight master before the flight to Southshore, with A Plague Upon Thee's second part, c19). The log names each moved event (hub tour: ...). - The chain is v1's: from the guide holding the route's first line, through
each guide's
next. - Steps split.v1's goal lines go in the route's order. Consecutive lines of one v1 step stay one step. A goal line the route does not name goes with the next line of its step that the route names (NPC lines between two named lines the route does in the other order go with the one it does later: the class scrolls and training between Sarvis' Rattling the Rattlecages and Elreth's The Damned stay with Sarvis); a collect of an item that a named kill of its step drops goes with that kill (the Warlocks' Rattlecage skulls with Rattling the Rattlecages, #345), when the route takes its quest before it. An optional line the route does not model goes after the step's first piece; an optional collect, after the piece nearest where its item drops; an optional accept or hand-in, after the route's last piece nearest its NPC, never between two lines at one NPC (Clavicus' cloth donations, c16 Stormwind). A step with no named lines goes whole before the piece holding the next named line (for a class's own steps, the line of that step the route does first). Such a step far (more than 300 yd) from the town visit it would split, with a stop of that visit after it, goes after the visit's last stop, with the steps of its kind written after it (the Shamans' flight to Islen and hearth back; Dokimi's crates between two Ratchet stops), not past one of its quests' lines nor the route's travel. A v1 step that only buys what the route buys at a line of its own, or only learns a flight path or binds (not a guide's last step), is not written. A guide is not cut between two pieces at one place with no travel between (it costs four pieces left out of their guide). A later piece the route works more than 400 yd from the step's first piece is named for its own area (else its target), not for v1's place. A piece titled for an NPC of v1's step that none of its lines is at, its first line at another NPC, is named for that NPC (Deputy Willem's accept, not "Eagan Peltskinner"). Pieces of the same place that end up next to each other become one step, unless the first travels on or is for some characters only, or the second has a tip, label, condition or zone of its own. A first piece that ends with v1's boat or zeppelin goto still joins; the goto goes last, after the town's last piece. With route legs, within one town visit (300 yd, no travel between), a training whose classes a later training of the visit covers goes: one training stop per visit, the later one.
- Added quests get their own steps where the route puts them:
accept Qat the giver, each objective once at its first task, thenturnin Q. If v1 treats the turn-in as optional, the work for it isoptionaltoo. An added quest whose items have no source in the world is not written, and the summary names it. - A goal worked at v1's optional line ("kill them on the way"), whose required line v1 writes later, is required at the route's line: the later line is written once only (Mazzranache's four parts, all optional at the route's work and the finishing step gone).
- Dropped quests lose all their lines. A quest v1 offers only after an optional start the route does not take is kept, for the player who finds that start.
- Guide boundaries go where the fewest lines land outside their own v1
guide. Each guide keeps its header. A piece in another zone gets a
zoneline. A piece the cut moves out of a shared guide into a guide only the route's races play keeps a copy at the start of its own guide for the other races (only <them>). - Tasks the guide leaves to the turn-in (a bag hand-in, an item with no source): their travel goes on to the route's next event, which is reached by way of it. A task index the world has no objective for writes nothing.
- One leg per route event.An event whose task is several objective lines takes its travel with its first line; the others follow there, not after the same leg again (The Hammer May Fall's ogres and Boulder'gor).
- The header reads the route, not the seed.
levelsis the route's level where the guide begins to where it ends (the highest level reached by then, a grind's target too), each rounded: a start's own part of a zone the shared route visits later (the Night Elves' Darkshore) reads 12-14, not the shared guide's 16-21; a guide with nothing of the route's reads the level it is played at (Troll's class stop at the Crossroads, 12-12). The shared guides read the canonical start's levels. A short comment says Forge's route search and guide writer made the guide and where fixes go (data/route-fixes.json, data/guide-fixes.json, forever-db corrections), with the quests added and left out there. The seed's notes above the first step, which describe how the hand-made guide was put together, are not written; its section rules are.
3. Fix-ups (src/post.rs)#
- An item that runs out (a timed item) keeps its chain together: events between getting it and handing it in move after the turn-in. When the getter is a task of the spender's own quest and the route passes its place (within 300 yards of the straight walk) on the way to the spender's next events, the getter goes there instead (Kerlonian's chest, its horn good for 25 minutes, taken where the route escorts him, not at 19 with a walk back).
- An item-started accept goes right after the step that collects the item.
- A line that works or hands in a quest the route does not take, and landed before its accept, moves to right after the accept (a hand-in, to the next step by its ender). An optional hand-in with no later step by its ender is not written, nor the rest of its quest: next to the accept it made a trip of its own (c17 Horde: the OOX-17/TN and OOX-09/HL rewards flown to Booty Bay from Tanaris and the Hinterlands, the escort after the hand-in).
- A quest started by an item that only drops, rarely or at an unknown chance, is optional: its collect and its accept, and the accepts of the quests after it in its chain (Nibbled-On Book, then Book Inventory); their hand-ins wait only for a player who holds them. A quest the route adds that a dropped item starts (Message in a Bottle) gets the item's collect first, and its accept is optional.
- A line of a class quest in a step for everyone gets its classes (
only Priest). With route legs, a step whose every goal is then some classes' is theirs (only Shaman, the Brine hand-in in the Barrens between two Ashenvale steps), and the next step for everyone names the zone the others are in (else they read Alonso's goto in the Barrens, #383). - A quest the route does not take itself (a class's own chain) whose accept is
written before the hand-in of a prerequisite (the data's
pre, all of them, andpreAny, one of them; not itsparent, which stays in the log: Chapter I-IV inside The Green Hills of Stranglethorn) goes after that hand-in with every line of the quest before it (with thelevelline gating its accept), in steps of their own after the hand-in's step and the steps right after it that are everyone's accepts and hand-ins at its NPCs (Darsok's Letter to Jin'Zil before the Warlocks' Ken'zigla trip), each with its v1 step's title,onlyand zone; the step after them names the zone it read before (a flight's step: the zone it lands in). Its follow-ups follow the same way, so the chain keeps the seed's order (Call of Fire 1526, then 1527; The Binding after Creature of the Void). This runs last, after every other move. An objective line written twice is written once only when the two are for some of the same characters (the Paladins' own Shadowvale elixir bottles, 95314). v1's accept or hand-in for other characters than the route's line of the same event goes after it only into a step its characters see (not the Paladins' accept of 99152 into theonly !PaladinHilda step); a line'sonlyis read before a closingoptionaltoo. - An untimed item whose vendor (the
npcof v1's buy line) stands at the route's visit of the buy line's step, within its last 12 pieces, is bought in that visit, not where the world puts its task (the Southshore Stout in Tarren Mill before Valik). - A class's own step whose lines all wait for a level (held) gets no trip of
its own there and back (the Rogues' flight from Ratchet to Orgrimmar for
Shenthul at 19); a held accept's later lines from another v1 step keep that
step's title,
onlyand zone (Ken'zigla's hand-in of 1510 not in Gazrog's step). - An item turn-in that the chain reaches before any line that gets the item moves after the last such line, unless the route works the quest itself (also where the guide leaves the work to v1's optional bag turn-in, the Scourgestones). The route's accepts after it in its step that need it handed in go with it (The Final Message to the Wildhammer after the feathers).
- v1's
levelgrind the route does not name, at a point where the route is more than a level below it (it reaches the level later, on quests), is written at the route's level there: a catch-up for a player behind, not a grind ahead of the route. With route legs, v1'slevelgrind lines the route does not name are not written at all, nor a v1 step left with only such lines and notes. - Hearths and duplicate
onlylines are fixed per audience (see the layout above). - A tip or note carried from a guide played at riding level (40) into one played below it no longer tells you to ride: "ride" becomes "head", "riding" becomes "walking". Rides on boats, zeppelins, trams and flights stay, and so does learning to ride (the riding trainer, the skill, a mount). v1's own lines of that guide are not touched.
- Steps left with no goal go. With route legs, so does a section rule
(
# ---- Menethil Harbor) with no step under it before the next rule, and a step's tip that another tip of the step already says word for word at its start ("Captain Stoutfist stands in Menethil Keep."). - With route legs, a tip sentence that walks the player back along the road
("Walk back west along the road") right after a step that flew them on goes.
A plain
sethome/getfpin a step where v1's line with its NPC says the same goes (one bind line at Goldshire, not two). - v1's bind stop (a step that only binds, learns a flight path and travels) that the route has already left, when v1's order reaches it, goes: the route binds where it means to (Ironforge's "the last guide binds here" after the route flew on from Aerie Peak to Southshore's boat).
- With route legs, a seed note that a quest is not on the route or to skip it
(
note ... Skip it., "not on this route") goes where the route takes that quest: in the step that accepts it, or for any quest the route takes. - With route legs, a
train classin the step right after one that trains the same classes or more goes (the route's Ironforge trainer, then v1's Kharanos step; three Orgrimmar steps in a row, each training); a step it leaves with only some classes' lines is theirs (only Hunter,Shaman,Priest), one it leaves with nothing goes. A class the route's training stop has no trainer for, with no pass by that class's trainer within 1.5 levels, trains at the route's next training event instead. - With route legs, consecutive steps that work quest objectives (kill,
collect, interact; each target a camp of three spawns or more, also one only
some characters work, which keeps its
only, though it alone never makes a step's own two quests an area step; events and bag counts ride along, and so do one object or a race's own objective, at their own points; section comments and along steps between them go before, unless the along list ends at one of them) whose targets share the ground become one step,<Area>: kill these as you meet them, with all their tips and goals: two of their spawns within 150 yards near the route's work points for them (those within 700 yards; the ground of every step merged so far; spawns on the live map count too, Redridge's gnolls; a line with no objective number is worked at its target's task), or the later one's targets in numbers on the earlier one's ground, worked there (the eggs on the makrura's beach). A step's zone is its zone line, else where its work is. Accepts stay in their place among the goals; a step with a hand-in is not merged (the oats stay with Verna's hand-in, #621), but a stop at an NPC on the merged ground that hands in none of the group's quests does not break the merge (Lakeridge Highway's camps around a Three Corners stop). The first step's label stays, and references to the others' go to it. Every goal keeps its own place: no search circuit, which would move each goal's camp (the compiler's low-band, not-strays and object-spawn choices, #385, #289) to shared spots. - With route legs, consecutive steps whose every goal is an accept or turn-in at one and the same NPC are one step, the first's (Teeri's two steps).
- With route legs, a step right after one with the same title and the same
only(section comments between), with no travel, label, condition, loop or along list of its own, whose first placed goal stands within 200 yards of the other's, is the same place: one step, the first's. Its tips lose their way in ("Follow the road north to Razor Hill"): the player is there. (Not v1's "Stormwind class quests" pieces at Agent Kearnen in Westfall and Rohan in Ironforge: titled alike, far apart.) - With route legs, consecutive steps at one hub are one visit, the
first's: every goal an NPC's (an accept, a hand-in, a training, a bind, a
flight path, a vendor or a buy), each later step with a giver or ender within
120 yards of the visit's, for the same characters, with no travel, label,
condition, loop or along list of its own. Their lines keep the hub tour's
order; later tips lose their way in; an
alonglist between two of them goes after the visit (Brill's Holland, Dillinger, Johaan and Zygand, written from v1's four steps, #740). - Then, with route legs, a step's field goals (kill, collect, interact for a
quest objective, for everyone, not optional; not in a loop or along step)
run as a sweep from where the step is entered: the nearest target's ground
first, then the nearest from there, so the arrow leads to the nearest work.
A named target (fewer than three spawns) that is elite, or three levels over
the easiest mobs of the step's camps, goes last (Maggot Eye at 11 on the far
hill, after the Rot Hides just north of Brill, Fitz). Area steps are always
swept; other steps when the first goal is more than the judge's
arrow-orderslack (200 yards) farther than another, or a hard target comes before a camp. Only lines with no other goal between them move among themselves: an accept or hand-in between stays, and so do the goals on each side of it (Yaw Sharpmane's hunts in turn). A quest with aninteractkeeps its goals' order; a tip naming a target follows its target. A goal of a quest the step itself accepts stays after that accept (the Felbind after the Flute of Xavaric's accept in Jadefire Run). A goal for a whole quest, with no objective number (kill 423 quest 246), is a field goal too (Lakeridge Highway's gnolls, poachers and thrashers).
4. Travel#
The route's own legs are written between two route events: walks to nodes,
flights (back-to-back flights become one fly), boats, zeppelins, trams,
portals and hearths. A lift counts as part of the walk.
- Where the route kept v1's order, v1's travel lines stay.
- Where the route changed the order, v1's travel lines in that gap
(
fly,hearth, boat and zeppelingotos, waypoint steps) become the other races'. The exceptions: v1's line for the route's own flight stays, and the route writes no second one; a waypoint step within 250 yards of the place the next piece works (a cave's mouth, Shadowthread Cave's, #328) stays: it is the way in. v1'sflyto where the route already stands (within 300 yards of the flight master) is the other races'; a step that is only a goto to the same place as the next one's goto goes. - A route deathskip (
--deathskips) is aDeathskip to <graveyard>step before the way there: a tip naming the mobs and spot to die at (a death elsewhere may go to another graveyard), thendie "<graveyard>"at its Spirit Healer. The way after it is written as for a walk: a player without "Use deathskips" passes the step and travels on from where they are. - A v1 step the route did not place is written where a leg passes its zone, and walked to when it is in another zone or far away; far in the same zone of a guide other races share, it is not (its own goals lead there; a goto step for the route's races alone was a bare bounce between the others' steps).
- A class-only detour into another zone (a flight to a class trainer, say) comes back before the next route step, and before everyone's next leg of the route's way, where it starts, also when that is in the next guide (the Shamans' Ironforge trainer at the end of Duskwood). Classes that walked off follow everyone's walk from where they are. The way back is from the flight master it flew to, else the known flight master nearest the route, else on foot; a flight back to a flight master away from where the route goes on walks on to it, and a class that flew to the flight master the route goes on from stays there; one nearer where it goes on than the flight master back walks from there (the Paladins flown from Thelsamar to Ironforge, the route at its gates). When the route's own way goes to a class's own stop (the Warriors' flight to Ratchet for The Affray), the other classes stay where they were and come on the same way before the route goes on. The classes away over the route's training stop come back to where the route goes on from it, not to the trainer (the Warlocks from Stormwind to Rainer, not via Goldshire).
- A class's own v1 step that the route's order leaves away from its place, with no travel of its own, gets that class's flight there (Spirit Rise in Thunder Bluff after the Crossroads), or the boat or zeppelin when its place (else its zone's flight master) is over the sea, with a flight toward the dock first when that saves the walk, else the walk into the dock's zone; one that flies from where no flight master is gets the walk to the nearest one first. Classes away on a detour of their own are left as they are; a class that flew off to the other continent is not flown back over the sea. A class's own v1 hearth back to the inn everyone is bound at stays: it is that class's way back (the Shamans' hearth to Grom'gol after Islen).
- A step's gotos after its last named line are its way out, written with its last piece, also when another line (a vendor) comes before them: a goal the route moved elsewhere does not take v1's travel with it.
- With route legs, v1's accept of a quest the route does not take itself (a
class's or race's own: Venya's imp quest, Sarvis' scroll for Aramis) goes
to the earliest step with a goal within 40 yards of its giver (the line's
npc, else the quest's one giver) where it is takeable: the route's level there is its minimum or more, its prerequisites are handed in before, and the step is for the same characters. Itsonly(the step's, when the line has none) goes with it. Its hand-in goes to the first step after the accept and its work (with the hand-ins of the quests taken inside it, its children byparent: The Green Hills of Stranglethorn after its chapters) with a goal by the ender, when that is earlier. A step left with no goal and no label goes. Run twice, so a moved hand-in opens its follow-up there too (Aramis' Holy Light). - A class's own accept (a class step, or a line
only <classes>) the route is not yet level for waits, with its quest's lines after it, for the route's next step in the giver's zone at that level (the Paladins' Tome of Divinity, level 12, not at Goldshire at 10). A class step of such accepts waits the same way for the route's next event in its zone at that level. Neither waits into a guide for other players: in a start's own guide before the shared guides it stays where it is, behind alevel <need>line (the Dwarf Paladins' Tome of Divinity in Dun Morogh), since the shared guides are the canonical start's writing. - A v1 step the route did not place goes before the route's next v1 line, but when that line is in another zone than the step's own place, on the route's nearer pass through the step's zone: a recent one (any one, over the sea, or one at most two levels back: v1's Orgrimmar training step at the route's Orgrimmar stop, not after the Feralas work that followed it) where its quests are taken by then, else the next one at most two levels on (the Undead Paladins' Bandarion Keep quests before the Barrens, the Paladins' Undercity trainer at the route's Undercity stop). v1's way steps and travel only steps stay where they are; a step whose work the route did or dropped elsewhere leaves no travel behind (the Barrens' Kolkar camps goto). A step that names its zone is walked to at its lines in that zone only (v1's Orgrimmar training step, whose Warrior quest has a giver in Thunder Bluff too, is no walk to Thunder Bluff); a way into a zone the route is already in goes (the Great Lift between two Mirage Raceway stops). A city beside or under the route's zone, within 600 yd, counts as the same place (the Undercity's Magic Quarter from the Ruins of Lordaeron). It does not go back past a piece written since that has a line of one of its quests (the Druids' Body and Heart hand-in stays after the Moonkin Stone). Over the sea, with no pass there, it goes before the route's crossing: after the route's last piece on its continent when only the way over is written since, or when its v1 step before is written there, recently, and the route is within a top-up of its level (the Druids' Cat Form run from Auberdine, not after the boat and Stormwind's work). A step handing in a quest whose work is an earlier v1 step not yet written waits for the route's first pass through its zone after that step's place (the Warlocks' Binding at Gakin after the Heartswood, at the next Stormwind stop, not a boat there and back).
- v1's quests the planner left out for their value or a chain the route does
not open (
<Start>.skips.jsonbeside the route, reasonslow-valueandchain-not-open) that no route event takes are not written (Swelling Forces); optional ones and class or race steps stay. An untaggedcollectoruseline (noquest) belongs to the accept before it in its step, else to the step's one quest: it goes when that quest is dropped (The Blackwood Corrupted's bowl and samples). - Such a step that the route leaves away from its place goes back to the route's piece at that place, when one is near: for a step at an NPC only the route's piece just before it; for field work with no NPC (Perrine's Chest at the Scarlet camp, found by where its target spawns) any of the last eight, with no travel or line of its quests between. It also goes right after v1's step before it that accepts its quest (the Warriors' Singed Scales right after Uzzek's Far Watch accept, not after the Crossroads).
- An accept of a quest the route does not take, ahead of a prerequisite handed in in a later guide for the same players, goes there with its quest's lines, after that hand-in; the quests its own hand-in opens follow it, and the quest's lines already in that guide before the hand-in go after it too (News of Dogran and Ken'zigla's Draught after Gan'rul's hand-in in the next guide).
- A v1 step the route did not place with nothing for everyone, only some races' lines (and a flight path), is those races' step: no walk there for the rest (v1's "To the Undercity" for the Skyborne's Sylvanas).
- v1's steps waiting on the way are written in the zone they are for, when the route's path gets there (after a hearth, at the inn before the way on); a class's own flight off is written at the flight master the path walks away from, when that flight master flies there. A step for other races than some of the route's does not gate the route's way to it.
- The route's own boat or zeppelin step replaces v1's goto to the same pier written since the last travel line in a step for everyone: it is the last thing in that town.
- A walk to an island (Feathermoon Stronghold) is written as the flight toward its boat, then the boat. At a guide's start the walk is from where the route was in the guide before; a leg to where the guide before already left everyone is not written again.
- A walk from one zone into another goes over the zone crossings it passes
(the world's crossings:
data/crossings.jsonunder the routes' rule, see How a route is made): when the straight arrow would cross a border with no way over it, or is longer than 4,000 yards, each crossing's end in the zone it leads into is written first as anInto <zone>goto step (the Timbermaw tunnel's Winterspring mouth on the walk from the Emerald Sanctuary to Everlook: the way in, not a stop out to one side). Only a walk that is one: such a walk that a flight between known flight paths, or the tram or a boat on the continent, makes quicker by the route's estimates (a walk at 7 yd/s over the crossings, a flight at 25 yd/s plus a minute) goes that way (Stormwind to Menethil for the Lightforge Ingots is flown, not walked through Redridge, Riverglades and Loch Modan). A route walk through a flight master the path only walks by (a waypoint of the sim's network, not where it flies from) is one walk when the walk straight on, over the zone crossings, is no longer and it leads to no boat (Camp Taurajo to the Shady Rest Inn, not north by Brackenwall Village's master and back south); one where the path learns that master's flight path (itsgetfp), far from the leg's end, stops there: the walk's goto step is the master's, with thegetfp(Gadgetzan's on the way from Freewind Post to Steamwheedle Port). The travel repair's own walks cost at least the way over the crossings, a walk no crossing joins is no walk (Azshara into Winterspring), and its walks get the same steps. - A walk into Riverglades, a zone players do not find the way into on the map, gets a tip naming Redridge Pass; a walk out of it names the way into the zone it goes to (the Swamp of Sorrows by Redridge Pass, the Badlands north of Twilight's Shroud, Redridge, the Burning Steppes by Blackrock Pass: Warcraft Wiki's Riverglades, adjacent regions).
- An item-started accept the route takes before the rest of its v1 step, moved to that step's next event, leaves its travel to the event that now comes first (the tram and the Ironforge flight to Southshore go before Marshal Redpath, not a second way of v1's by Menethil's boat with the route's flights after it).
- Travel to an event from elsewhere than the event before it in the same v1 step stays: that event was done where the player stood (the cloth hand-ins at Thunder Bluff after the bag tasks: the Light's Hope flight, the Undercity zeppelin and the Orgrimmar flight are written). Unless the event is where the event before leaves the player (same zone, within 1,500 yards: a walk no flight beats): then it is a hop within the step too (the Tainted Ooze jars at Jaedenar stay in the Oozes step). The step after a flight's step reads the zone it lands in.
- A route leg that starts more than 600 yards from where the guide leaves the player (or on another continent) is never replayed from its own start: none when it ends within 600 yards of the player, else the way from the player's place (the crossing, the flight, else the walk).
- A bag hand-in the route does where it stands (a task of v1's
optionalline with no travel of its own, whose point, the item's drop camp, the route's next leg does not leave from: the leg leaves from where the route stood before it) is not walked to: written where the route stands when v1 places it in that zone, else, when v1 places it in the zone the leg ends in, right before the leg's event, which it then takes (the Ironforge cloth donations after the tram from Stormwind, not walks to the Wetlands and Searing Gorge). - In a shared guide, v1's lines of a quest the route takes in its races' own guide (the Orcs' and Trolls' Barrens quests) are the other races'.
- A
getfpis written at each flight master the route reaches, in anInn and flight masterstep when it arrives there. v1'sgetfpfor other races alone (the Skyborne's Rut'theran Village) is not the route's: its own is still written. - v1's step that only learns a flight path, over the sea from where the route is, gets no crossing (v1's Ratchet stop between Theramore and Booty Bay, which the route reaches by air): the route learns that flight path where its own way passes. Nor is v1's hand-in of a quest the route does not take (optional, or not in its order) written in another zone than the route's (The Collector to Marshal Dughan in Goldshire, in mid-Westfall).
- The repair's flight away from the next goal (its flight master, then the goal
farther than from where it left) goes, and its
Fly tostep with it when the flight master's goto is all that is left; a flight to a training stop (train classnext) is for the training and stays (Thorium Point to Ironforge). - The repair's way on from where a class trip left the player is that trip's
classes': when the last step the player plays before it is some classes' own
(
only Warrior,Hunter,..., v1's Orgrimmar training) and the other classes went their own way meanwhile (a step of theirs alone with travel), the way isonlythe trip's classes (the flight from Orgrimmar to the Crossroads after the training, not shown to the Druids and Paladins already back at the Crossroads from Thunder Bluff, c19 Horde 30-40/03-arathi-highlands:449).
--no-route-legs writes the old JavaScript writer's travel instead. It then
runs that writer's travel repair: the honest playtest's R1 (see
The judge) plays the written chain as a Warrior of the route's race,
and a travel line that starts where the player is not goes to the other races.
--no-repair turns the repair off.
5. Engine features#
The newer addon engine (Polestar 0.2.6, pack format 4) reads lines that v1's
guides predate. The writer adds them where the route needs them
(src/engine.rs). These R-numbers are the writer's own, in order of how much
they matter to the player. They are not the judge's honest rules.
R1 along until <label>
merge
overlap, 150 yards, of a required field goal of a step for the same
characters, not a loop, when or along step) goes into that step,
beside its nearest goal, and the list ends there: the Rot Hide Graverobbers
and their ichor north of Brill are worked in the Doom Weed step. Not ahead
of an order the route fixes keep.R2 use <item>
use line, at
the item's place nearest the route's work. A use that gives no credit itself
(a bowl filled at a moonwell) is not bound to the objective; one that makes
an item a line collects goes right before that line (the empty bowl at the
Auberdine moonwell, not at the furbolg camp after the filled bowl, #302).R3 guards
when onquest, except a step that also trains, learns a flight path or
binds, or holds lines for some races or classes only (the Ironforge training
is everyone's). So do the hand-ins of quests the player may have passed by:
one taken optional, from an item that drops (accept Q item N, or a quest
only an item starts), or listed along the way, and every quest that needs one
of those first. A step that only hands them in (and walks there) gets when onquest; beside other work, the hand-in lines become a step of their own
with the step's title, when onquest, in the same place, and the rest of the
step goes on after it (a hand-in already optional there never holds the
step and stays). A hand-in of such a quest at the NPC another goal of the
step is at (an accept or hand-in there) stays in the step, optional: the
player stands there anyway. A hearth to an inn bound in an earlier guide gets
when bound "<inn>", and a walk there when !bound "<inn>" follows as a fallback.
A way step for everyone into the zone of a when onquest step right after
it (past other way steps) becomes that step's first goal, so only those on
the quest walk it (the walk into Ashenvale for Forest Song after the flight
to Talrendis Point).R4 fractional levels
level line keeps
its fraction (level 15.91), unless a quest the route takes before its next
grind needs more than that.R9 where
-- note, on a step's first goal at it: "below ground" (a cellar, a basement,
a cave), "inside Fargodeep Mine" (a cave's or mine's area name), "upstairs",
"on the top floor", "inside" (not at a trainer, vendor, innkeeper or flight
master), "underwater". The walking grid's floors at the spawn's height decide
it (an indoor floor with the open ground over it, walkable or under a
building's floor, is below ground; one with a building's floors under it is
upstairs), the height from the server database (spawnz.json), else from the Forever
server's own spawns (data/sources/forever-tdb/extract.json). A goal at an
NPC who walks around (moves.json; the compiler circles his walk on the map)
gets "<name> walks around <area>: look inside the circle on the map"; an
accept, hand-in or talk at an NPC found at a few places within 150 yards of
each other (the compiler's spawn spots) gets "<name> walks around <area>: the
map marks where to look". A note
that says it already, a step tip that says he walks, and the capitals (all of
the Undercity is below ground) get none.R10 warnings
data/local/mechanics/quest-notes.json) that warn of an ambush, an attack
when you loot or click, stealthed mobs or adds go on the first step that
does the quest's work, as one tip Careful: <the notes> (at most two, ambushes
first, server data before players' reports; never a note about a follow-up).Groups
groups, each
order entry's group; How a route is made) are asked. Every
step that is not along and holds a line of a family's quest (accept, work,
hand-in, in any guide of the chain) gets when group <root>: in place when
the step holds only that family's lines and no when, else those lines move
to a copy of the step right after it, headed when group <root> (R5's
placement; several families, in the step's order: Sprogger's hand-in of
8553 before his accept of 8554). The family's work is never listed along the way. Its first step
that does the root's work (else its accept step) gets one tip: "These are
elite mobs: grouping up is encouraged, look for people to do it with." then
how hard (size 1: "Sarkoth is a level 10 elite: most classes solo it at
level 12, but you may need help."; size 2 or more: "Sarkoth (level 10 elite)
needs a group of 3.", several mobs "A, B and others (level 10 elites) need a
group of 3.", no mob placed: the quest's title, "Challenge Overlord
Mok'Morokk needs a group of 3.") and "Skip it if you are alone: the route has
you grind the XP back.". With size 2 or more the family's kill and
collect lines get group N. Each soloFallback becomes a step right after
the step holding its order entry after: written as a grind top-up (step
Level N.FF, at the camp of the work before it, never an elite one or a
family's), its first line when !group <root>, its tip "If you skipped
<title>, grind here to level N.FF to stay on the route's plan."; one step per
family, never folded with the route's top-ups. With no camp by the player
or in their zone (a city stop), it goes after the route's next work at a
camp, there. Fallbacks one after another at one camp, with only group
players' steps between, are one step at the highest level, its tip naming
every title (with several families, no `when !group`: it holds for whoever
is under its level). The group player is at that level already, so it does
nothing for them. On by default (`forge build`);
`--no-groups` turns it off. Under `--format-0-3`, R5 still asks the other
group and dungeon quests.
Read the rest of this section251 words
--format-0-3 adds the pack format 5 lines (Polestar 0.3.0): R5 when group,
R6 task and cast, R7 abandon when the log would pass 40 (the game's quest log), R8 skipto over
blocks kept for one carried quest. --no-engine writes none of these and uses
no route legs: the old JavaScript writer's output, byte for byte.
--no-along, --no-use, --no-when, --no-level, --no-tips (R9),
--no-warnings (R10) and --no-groups turn off single rules.
R2 and R6 read the checkout's quest-mechanics files under data/local/mechanics/
when they are there, R10 its quest notes. R6's cast reads spell names from the
game's data under data/sources. Without these files those rules write
nothing; R9 writes nothing without the walking grid (data/local/nav4) but the
walk notes.
Before the engine features the writer applies the fix records to the guides it
wrote, by anchor (a quest's goal), so a hand fix survives every re-cut. A fix's
tip is its step's tip: it replaces the step's first tip, and the step's other tips go. Each
record comes back applied, redundant (the guides already say it),
not for this start, stale (its quest is in the route, but no line anchors
it) or conflicting; forge writer apply-route prints the counts and the lines
it changed, and forge build writes them to guides/<start>.fixes.json for the
fixes ledger (Polestar Forge has the formats).
With the engine features on, the writer ends with a travel check: the judge's honest R1 on the written chain. It logs each R1 failure v1 does not have, then the count.
Text: what the writer writes itself#
Titles, tips and notes are v1's, moved with their lines. A held class step is
titled for its giver in the step's zone (the line's npc, else the giver with a
spawn there). A tip sentence or clause naming an NPC of another piece of the same
v1 step goes to that piece, from any of the step's tip lines, starting with a
capital. Apart from the riding
fix above, v1's text stays exactly as written, so its translations under
guides/locales/ still match: they are keyed by the English text. The writer's
own words are R9's notes and R10's warnings (above); new lines follow these
fixed patterns:
| For | Lines written |
|---|---|
| added accept / turn-in | step titled with the giver's or ender's name (else the quest title, else Quest Q); accept Q / turnin Q |
| added objective | step titled with the quest title; kill, collect, interact or talk <id> quest Q.N @x,y map M at the spawn nearest the route's point; an event objective is goto x,y and complete Q |
| training stop | step Class trainer; train class |
| zone change | zone <Zone> |
| flight | goto x,y "<Name> flight master" (when not standing there), fly "<Destination>" |
| hearth | hearth "<Inn>"; with R3: step Hearth to <Inn> + when bound "<Inn>", then step To <Inn> + when !bound "<Inn>" + goto |
| ride | goto x,y "<Boat or zeppelin>" at the dock |
| arrival | step Inn and flight master; getfp "<Name>" |
| engine rules | along until <label>, label <label>, when onquest Q, use <item> quest Q.N, when group Q, task "Emote at <target>" / task "Wait for <target>", cast <spell> "<target>", abandon Q, skipto <label> when !onquest Q |
| where and walks (R9) | the goal's note -- <Name>, upstairs (or the phrase alone, or after the author's note with ; ); -- <Name> walks around <area>: look inside the circle on the map |
| warnings (R10) | tip Careful: <the quest notes' words> after the step's opening lines |
| grind | level N.FF (the share of the level, whole percent) |
grind top-up (inserted level) | step Level N.FF; when level<N.FF, tip Top up here to level N.FF before the hand-ins at <place>: they take you to level N+1., goto x,y "<the mob worked before it>" at the route's point, level N.FF -- grind on <mob>. The camp: hostile mobs no more than 6 levels under the player (of an item's droppers, the one nearest the work's place), by the player or the route's nearest in their zone, else the route's next camp; never a capital city's map |
| group family | when group <root> on its steps, tip These are elite mobs: ... on its first work step, group N on its kills and collections (size 2 or more) |
| solo fallback | step Level N.FF; when !group <root>, when level<N.FF, tip If you skipped <title>, grind here to level N.FF to stay on the route's plan., goto x,y "<mob>", level N.FF -- grind on <mob> |
Lines that changed have no translation until a translator adds one. Lint lists them as warnings. That is expected after a rewrite.
Running it#
forge writer apply-route out/routes/Orc.json --world out/.forge/sim/world-horde.json --root out/.forge/root --out out/try/Orc
forge writer apply-route out/routes/Human.json --world out/.forge/sim/world-alliance.json --root out/.forge/root --out out/try/Human --format-0-3| Flag | Meaning |
|---|---|
<route.json> or --route FILE | The route |
--world FILE | The simulator world the route was found on |
--out DIR | The written guides folder. It is deleted and rewritten: v1's whole folder is copied there, then the changed guides are written over the copies |
--guides DIR | v1's guides (default <root>/guides) |
--data DIR | The game data (default <root>/data/forever) |
--root DIR | The checkout whose data/forever, data/sources and data/local are read (default: the nearest folder above here with data/forever) |
--walks FILE | The walk store (default walks-<faction>.bin beside the world) |
--format-0-3 | Add the pack format 5 lines (R5-R8) |
--no-engine | No engine lines and no route legs (the old writer's output) |
--no-along, --no-use, --no-when, --no-level, --no-tips, --no-warnings | Turn off one engine rule |
--no-route-legs | The old writer's travel, then its travel repair |
--no-repair | With --no-route-legs: no travel repair |
After a forge build --out out, out/.forge/root and out/.forge/sim hold the
exact root, world and walk store that build used, and out/routes/ holds the
routes. forge build itself writes each start to out/guides/<start>/.
forge writer apply-routes <out>/routes --sim <out>/.forge/sim --root <out>/.forge/root --out <dir>
writes every start of a build's routes the way the guides stage does: the
default options, each faction's shared guides made once for its starts, and the
two factions at once. It writes <dir>/<Start>/, <Start>.fixes.json,
<Start>.log and <Start>.status (ok, or why the start was not written).
--starts Orc,Human writes only those. It is the writer-only rewrite of a
round's routes, and the writer gate uses it.
The command prints a summary:
apply-route: <n> guides rewritten in <out>; <n> quests added, <n> dropped, <n> goals moved between guides, <n> route lines not placedOn stderr it logs the rest: lines it could not place, the engine rule counts
(engine: R1 along …, R2 use …, and how many passing legs the walk store
confirmed), and the travel check (travel check: <n> R1 failures v1 does not have on the route's chain). Without a walk store it says so and uses straight
lines.
The library entry is forge_writer::run(&RunInputs, &RunOpts). It does no file
access, so it also builds for the browser planner. forge_writer::native::run_paths
reads the files and writes --out.
Into the addon pack#
The written folder is an ordinary guides folder. Lint it, compile it, then judge it:
forge guide lint --guides out/guides/Orc --data out/data/forever
forge guide compile --guides out/guides/Orc --data out/data/forever --out out/addon/Polestar_Guides
forge judge report --route out/routes/Orc.json --guides out/guides --root out/.forge/root --sim out/.forge/sim --out out/reviewRun forge guide inside a Polestar checkout. It finds the checkout by
addon/Polestar/Polestar.toc and guides/pack.json, or you pass --root. It
reads the pack's manifest from <root>/guides/pack.json.
| Flag | Meaning |
|---|---|
compile / lint | Write the addon files / only check |
--guides DIR | The guides folder (default <root>/guides) |
--data DIR | The game data (default <root>/data/forever) |
--out DIR | The pack's main addon folder (default <root>/addon/Polestar_Guides, the checkout's own pack). Race parts are written next to it, and its translations into the language folders (Polestar_deDE, …) beside the game's names |
--format text|json|github | How diagnostics print (github: annotations for CI) |
--quiet | Hide warnings |
--force | Write the files even with errors |
--sim DIR | Lint only: read world-<faction>.json's excluded quests for the solo policy |
--time | Print phase times |
compile writes the TOC, Pack.lua, MapFrames.lua, Guides.lua, the race
parts and the texts addons. Its output is byte-identical to the old JavaScript
compiler's. Both commands exit 1 on any error. Their last line is the summary
(lint ok: … files, … guides: 0 errors, … warnings or
compiled … guides (… steps) from … files; … warnings). The full rules are in
Guide format ("Validation") and the pack layout is in
Community guide format.
When something goes wrong#
the route was cut on another world (dataHash …)
out/.forge/sim/world-<faction>.json), or find the route again.apply-route: no guide <file>
from lines name a guide
missing from --guides. The route was found on other v1 guides. Find it again
on the guides you pass.Many "route lines not placed"
quests added (… not written: no source for their items)
A new honest R1 on a continent change with no travel line
Lint errors after writing
forge guide lint --guides <written>.
Lines the writer moved keep their text, so an error usually means a moved line
now sits before what it needs, such as a turn-in before its accept. Find which
pass moved it with --no-engine, --no-route-legs or one of the --no-…
rule flags.Lint warnings about stale translations
Changing the writer
src/apply.rs, the passes in
src/post.rs, travel repair in src/travel.rs, engine lines in
src/engine.rs, the where-notes and warnings in src/tips.rs. --no-engine output must stay byte-identical to the old
JavaScript writer's, so new behavior goes behind an option that is on by
default, the way RunOpts and engine::Opts work now.Tests#
cd rust && cargo test --release -p forge-writerThe apply-route and engine tests run on small guides. The travel-repair tests need the game's data in the checkout and skip without it, naming the missing input.
The writer gate#
No writer change merges unless the gate passes. The unit tests run on small guides; most writer bugs only show on a whole route: a pass that moves lines another pass placed, travel that misses a ride, a hand-in in another start's shared guide. The gate writes the saved routes of the last finished rounds with the writer before the change and with the changed one, judges both with the same judge, and fails when the change adds a blocker.
rust/scripts/writer-gate.sh # this checkout against routes-opt, the 3 newest rounds
rust/scripts/writer-gate.sh --sets c17 --starts NightElf,Skyborne-alliance # a quick look while working
rust/scripts/writer-gate.sh --base <commit> # against another writerRead the rest of this section569 words
It reads each round's out/routes (the saved search's routes), out/.forge/sim
(world and walks) and out/data, and the guides at the commit in the round's
commit.txt. Nothing is searched again. Both writers apply this checkout's
places, guide fixes and route fixes. Each start is written as forge build's
guides stage writes it (forge writer apply-routes, the shared guides once per
faction). Then forge judge check and forge judge seed-tests run on every
start's tree. forge writer gate-diff compares the two runs per start by what
each finding is, not by where it sits:
- a judge blocker: rule, guide file, the text of the line it names and its message. Line numbers, coordinates, yards and minutes are left out of the key, so a blocker that only moved is the same blocker, and another quest or place is a new one;
- a player-report check that fails on the start's tree;
- a places or guide-fixes record that no longer applies (
stale,conflicting); - a start the writer refused (an error, or a tree the pack check refuses).
A finding the new writer has more often than the old one, or for more classes,
fails the gate. Findings that went away are listed too. Warnings are counted per
rule and shown, but they never fail the gate. The report is
<run>/gate.md (and gate.json). The exit code is 0 for a pass, 1 for a fail
and 2 when the gate could not run.
One forge process runs at a time. Each one uses every core: the writer runs the
two factions on threads, and the judge uses --threads 16, holding about 10 GB
for ten starts. If its memory-capped slot kills it, it runs again on 6 threads.
Everything runs at nice 19 through the machine's slot scripts. The previous
writer's binary, trees and judging are cached under $GATE (default
scratch/Routes/gate), keyed by its commit, the records and the judge's code.
An older commit without apply-routes is built with this checkout's command
line on top of its own writer. After the first run, a gate run only writes and
judges the new writer's trees. On an idle machine that takes about 8 minutes of
writing, 1 minute of checking and up to 8 minutes of player-report checks per
round. The player-report checks run only for starts whose tree changed. Use
--sets c17 --starts … while working, and all three rounds before a merge.
A start the previous writer refused, for example a crash on that round's route, has no baseline. The new writer's findings there are listed under "Not compared" and do not fail the gate. The refusal that went away is listed under "Gone".
The gate catches what a change breaks on routes the writer has already written. It does not catch a bug that only a new route brings out: c17's OOX hand-ins were the c16 writer's behavior, met for the first time on c17's routes. Those are caught by the round's check and its review. Once they are fixed, that round's routes become a gate set and hold the fix.
A new blocker is either a bug the change brought in, or a fix that is right and
shows a real problem the old writer hid. Read each new line in gate.md.
Fix the first kind. Name the second kind in the change's commit message. New
rounds become gate sets as soon as they are built (the newest three by default).