Releases: danielcosta42/lodestar
Releases · danielcosta42/lodestar
Release list
v2.1.0
Lodestar
v2.1.0 (2026-09-23)
Full Changelog Previous Releases
- chore(release): v2.1.0
- Merge pull request #8 from danielcosta42/feat/libchehulquest
feat(quest): coletor vira LibChehulQuest, e repassa o "onde" pela malha - feat(quest): coletor vira LibChehulQuest, e repassa o "onde" pela malha
O companion pede token de guilda, então na prática só um ou dois oficiais o
têm — e a base que anda pelas zonas novas é o resto da guilda. A coleta sai do
ForeverScan e vira lib autocontida via LibStub, cópia verbatim para os outros
addons da família: o membro colhe igual e sussurra para quem anunciaqsink.
Só o "onde" atravessa a malha (quest, NPC, mapa, coordenada, ~35 bytes): o
sink completa o resto pedindo o id ao servidor, que cai no WDB dele. Repasse é
opt-in (shareQuests, off), a colheita local não depende de nada disso, e o
nome de quem mandou é descartado na chegada.
ForeverScan fica com o que é do Lodestar:/ls scane o status.
v2.0.0
Lodestar
v2.0.0 (2026-09-21)
Full Changelog Previous Releases
- chore(release): v2.0.0
- Merge pull request #6 from danielcosta42/feat/forever-only
Lodestar 100% Forever: dropar TBC e abrir a camada de dado - feat(forever): decoder do Cache/WDB — os ids-alvo que nenhuma API dá
tools/wdb.py lê questcache/creaturecache/gameobjectcache do cliente e
devolve JSON no schema que o roteador já consome. 23/23 registros parseiam
byte a byte no build 69913.
Por que isto importa mais do que parecia: o texto de objetivo do Forever
usa placeholder de servidor ("Kill $1oa Galak Centaurs, $2oa Galak
Outrunners"), então a regex de contagem do router NUNCA vai recuperar
quantos matar pelo texto. Oamountdecodificado do WDB é a única fonte
que existe. Sem isto, todo objetivo de conteúdo novo viraria passo sem
contador.
Extrai com confiança: name, questLevel, reqLevel, zoneOrSort, nextInChain,
faction (derivada da máscara de raça), objText, details, e objectives com
{type, id, amount, text} — mais objCreatures/objItems/objObjects.
Conferido contra valores conhecidos: 745 "Sharing the Land" nível 8, zona
215, criaturas 2949/2950/2951 x 10/8/5; NPC 2949 = "Palemane Tanner";
objeto 3656 = "Bonfire".
O que NÃO extrai, e por quê (cada um marcado com ponytail: no arquivo):- giver/ender e qualquer coordenada: o cache guarda a quest, nunca quem a
entrega. Isso é do /ls scan. - specialFlags fica 0: o Flags do cliente não é o specialFlags do Questie,
e mapear errado dispararia o teste& 3de repetível/evento do router. - startItems fica vazio: o SrcItemId é o item que o giver FORNECE, não o
que inicia a quest ao ser lootado. Semântica diferente, passo bogus.
fix(consumables): os 15 itens do checklist de raide eram de Outland e
NENHUM existe no ItemSparse do 69913 — conferido item a item. O /ls check
marcava tudo como faltando, para sempre. Trocados pelos equivalentes
vanilla, todos confirmados presentes no mesmo build.
Dado morto de Outland que sobra em FlightData/TransitData/Trainers/
ZoneData fica, e está documentado: é inalcançável (nenhum guia rota para
lá), e sai quando essas tabelas forem regeradas para o Forever.
- giver/ender e qualquer coordenada: o cache guarda a quest, nunca quem a
- fix(forever): parar de consumir o dado raspado, não só de raspá-lo
O commit anterior removeu tools/fetch_forever.py mas o import_forever.py
seguia lendo build/forever_quests.json do cache — 441 quests. Ou seja: a
posição estava no README e não no código, e o README afirma que nada é
raspado. Agora é verdade.
O passo de ingestão da Wowhead saiu do importador. Custo honesto: 4.391
quests em vez de 4.829. Aquelas 441 voltam pelo /ls scan e pelo WDB, que
são nossos e limpos — e a Wowhead tinha 1 quest em Riverglades e 0 em
Shen'dralas, que é o que de fato importa.
ForeverData.lua regenerado contra o 69913 (estava com dado do 69893):- 0 guias sem conteúdo, o que confirma que a deleção dos 106 foi completa
- 380 quests removidas em guias vivos, igual a antes
- foreverUnknown vai a 2.824 ids: não desconta mais o que a Wowhead sabia
Correção de um erro meu na doc: eu havia tirado a figura "2.824" alegando
que não era reproduzível. É — o gen_forever.py a calcula. A baseline é o
Anniversary 2.5.6.69795, não o Classic Era (1.795) nem o corte por id
= 30000 (2.844). As três estão na doc agora, com a base declarada.
import_forever.py também passa a comparar contra o 69913. - feat(forever): coletor colhe no gossip, e para de engolir título vazio
O ForeverScan agora rende muito mais por sessão e grava os campos que o
roteador exige.
Bug corrigido:q.name = q.name or GetTitleForQuestID(qid). Em Lua "" é
VERDADEIRO, então um título vazio grudava no registro e a varredura nunca
voltava a pedir aquele id — o dado ficava permanentemente pela metade. Agora
título só entra se for string não vazia, eHaveQuestDataé o teste de
cache em vez do nome gravado.
Frente nova, a de maior rendimento por esforço: colheita no GOSSIP_SHOW e
QUEST_GREETING.C_GossipInfo.GetAvailableQuests()devolve TODA quest que
o NPC oferece, com id e nível, sem aceitar nenhuma. Um clique num NPC rende
o NPC inteiro — antes só se colhia o que o jogador abrisse.
Campos que faltavam e o roteador indexa:factionvia GetQuestFactionGroup (não existe API de facção exigida; este
global legado é a única fonte)uiMapvia GetQuestUiMapIDrepeatable,waypointText, eleveldo GetInfo do log, que é melhor
fonte que GetQuestDifficultyLevel
Identidade de NPC passa por ns.UnitNpc, com preferência pelo token
"questnpc" na janela de quest. Registro que tem id de NPC não é mais
sobrescrito por um que não tem.
Cada colheita agora se identifica (build, interface, locale, facção). Sem
isso, mesclar contribuição de terceiros é adivinhação: build diferente tem
id diferente e facção decide a rota.
ok == falseno QUEST_DATA_LOAD_RESULT é tratado como AMBÍGUO — pode ser
id inexistente, recusa ou throttle. Não marca nada como inexistente.
tools/forever-scan.lua: 26 checks contra o arquivo de verdade, incluindo o
título vazio, a colheita no gossip e a proveniência.
- feat(forever)!: Lodestar passa a ser WoW: Forever e só
Dropa TBC/Anniversary por inteiro. O addon mira interface 16001 (token de
TOCCamelot) e nada mais.
O que sai:- 106 guias cujo conteúdo aquele cliente não tem (Outland, Quel'Thalas,
Azuremyst/Bloodmyst, atunações e dailies de TBC), com as entradas
correspondentes nos dois XML de include - Attunements.lua, RaidAttuneData.lua, TalentBuilds.lua, Talents.lua —
painel de raide e de talento eram de TBC (419 linhas) - o ramo dual-client do Compat.lua, e o mecanismo de guia-morto do
Guide.lua: guia sem conteúdo agora não é arquivo, não é lista escondida - avisos de montaria: os níveis do Forever não são públicos, e chutar é
pior que calar
Os 174 guias que sobrevivem FICAM. São rota vanilla, que é conteúdo válido
do Forever, e apagá-los antes de existir substituto deixaria o addon sem
nada. A troca por guias gerados do Forever é trabalho separado.
Deletar os 106 arquivos deixou 6 ponteirosnextpendurados, o que
DEGRADARIA o encadeamento: antes o guia morto ainda carregava e a cadeia
pulava através dele; com o arquivo fora, ela terminaria ali. Os 6 foram
religados no primeiro guia vivo da cadeia, e NextGuideKey agora encerra de
propósito em ponteiro pendurado em vez de estourar.
EntraC_Secrets.ShouldUnitIdentityBeSecretcomo pré-teste de identidade
(ns.UnitNpc). Na prática este cliente devolve id e nome de NPC limpos — o
que é secreto é estado de combate — mas a doc gerada marca UnitGUID e
UnitName com predicado condicional, então perguntamos antes.
tools/fetch_forever.py sai. A ToU da Fanbyte proíbe baixar conteúdo por
qualquer mecanismo que não seja navegador, e o robots.txt da Wowhead
bloqueia coletor automático por nome. Não dá pra semear dado aberto com
aquilo, e o valor era marginal: a Wowhead tem 1 quest em Riverglades e 0
em Shen'dralas.
Correções de fato: build corrente é 69913 (não 69893); Darkspear Islands é
Battleground 15v15, não zona de quest; a contagem de quests novas passa a
declarar baseline (2.844 ids >= 30000, ou 1.795 contra o Classic Era) — a
figura "2.824" não era reproduzível.
tools/forever-guides.lua reescrito para um cliente só: 22 checks passando
contra os arquivos de verdade, incluindo o encadeamento com ponteiro
pendurado e o pré-teste de Secret Values.
BREAKING CHANGE: o addon não carrega mais no TBC Anniversary.
Closes #5
- 106 guias cujo conteúdo aquele cliente não tem (Outland, Quel'Thalas,
- feat(forever): collect the quests this client is the only one that knows
The new Forever content is server-side. The DB2 tables carry quest ids and
almost no POIs (54 blobs), Questie has no Forever quest data yet, and Wowhead
knows 441 of the 2,824 ids — zero of them in Riverglades, Zephras Isle,
Darkspear Islands or Shen'dralas. So the data comes from two places.- tools/fetch_forever.py pulls Wowhead. The whole index costs ~70 requests
(?filter=minle=N;maxle=N); each quest page carries level, side, zone and the
start/end/objective points with NPC ids and coordinates. The site refuses bulk
collection (403 after ~130 pages at 1/s), so 403 and 429 mean stop, requests
are 4s apart and only ids the index knows are fetched. Everything is cached. - ForeverScan.lua collects from the client itself, which is the only source for
the new zones. /ls scan asks the server id by id (RequestLoadQuestByID); while
you play it records who gives and who takes each quest with NPC id, map and
coordinate, the objectives, and the waypoint the server itself points at. It
writes LodestarDB.scan and does nothing on Anniversary, where this is known. - tools/import_forever.py merges both with the Questie base into build/forever/,
dropping what Forever does not have. The router reads it unchanged: Ashenvale
comes out with 68 routed quests, 27 of them new; Feralas 71 with 27 new.
No guide file changed yet: how a zone's two variants coexist is still open.
tools/forever-s...
- tools/fetch_forever.py pulls Wowhead. The whole index costs ~70 requests
v1.5.0
Lodestar
v1.5.0 (2026-07-17)
Full Changelog Previous Releases
- chore(release): v1.5.0
- feat(guides): kill-to-loot steps, class-guide fix, wider quest coverage
Regenerated guides with several generator improvements:- kill->loot: items dropped by a mob (or a chest that spawns after a
kill) emit kill/click/collect with elite/raid tags, Zygor-style;
circular {dropsfrom} tips dropped; new {spawnsafter} tip. - class guides: correct the class bitmask (Shaman/Mage/Warlock/Druid
were shifted a bit — Druid held Warlock quests and Shaman had no
guide) and keep class quests with questLevel<=0. - coverage: place object-started (click) and item-started
(loot-to-start) quests, and dilute capital-city quests into leveling
guides by level. ~5259 quests covered, up from ~4423.
docs/ (internal specs) is now gitignored.
- kill->loot: items dropped by a mob (or a chest that spawns after a
- feat(guides): inline prerequisite chains; retire the prereq banner
A guide that references a quest gated by a chain it doesn't teach now
splices the missing chain in as native steps — harvested from the guide
that teaches it, or synthesized from the quest giver — instead of the old
"do this first" banner. Injection is static and deterministic, so step
indices and saved progress stay stable, and completed chain steps
auto-hide via CheckProgress. Also fixes the redundant same-guide prompt. - fix(questitem): resolve the use-item button from the quest's special item first
The "use quest item" secure button (LodestarQuestItem, shown above the guide) now
detects the item via GetQuestLogSpecialItemInfo BEFORE the explicituse ##id
path. The new "use ##" steps carry the target creature's id
(not an item id); with the old order, a creature id that collided with a held
item could be mis-read as the item to use. Now the quest's provided item
(wrangler/salve/bomb) is found first, and the explicit path only fires for a bare
use <item>##itemIDstep with no |q binding. - feat(guides): item-collect steps show what/how-many/where + which mobs drop it
"Collect item" quests used to say "Kill " with the count buried in the
note. Now they read like Zygor: the action names the item and quantity, the arrow
points to the best (common, non-rare) source, and a tip lists every mob/node it
drops from. E.g.:
before: kill Abyssal Flamebringer##19973 |q 11025 |goto Blade's Edge 28.84,81.09
after: collect 5 Apexis Shard##32569 |q 11025 |goto Blade's Edge 28.84,81.09
|tip Drops from: Abyssal Flamebringer, Wrath Hound, Hemathion
Count is parsed from the objective text (~900 of ~2000 item quests); the "drops
from" list is common-first, capped at 3. Vendor-only items say "Buy".
Use-item-on-creature quests (wrangle/capture/tame/tag/"use X on") now use the
"use" verb instead of the misleading "kill", with a tip to use the quest item —
but only when the objective isn't actually a kill ("Kill Zuluhed... use the Key
on the Chains" correctly stays a kill; the "use" there is on a separate object).
New tip tokens TIP_DROPSFROM/TIP_USEIT (enUS + ptBR). Verified: validate_guides
0 hard blocks; audit 0 real OBJTGT (taught it thatusemay target a creature);
luacheck 0 errors across all regenerated guides. - fix(guides): strip BETA test quests + resolve dangling object-turnins
Guide-integrity sweep (new tools/guide_integrity.py: accept/turnin balance,
orphan objectives, dangling quests, empty steps, missing arrows, coord jumps):- BETA pollutants: quests named "BETA ..." (9342 Crust Bursters, 10059 Zeth'Gor,
10088 Mine's a-Rockin', 10100 The Mastermind) have no giver in the DB, so they
leaked in as orphan |q kill steps that never complete. Now filtered out via
is_placeholder("^(OLD|BETA) "). Their real equivalents (q9355, q10792/10895,
q10079, q10099) are already in the guides, so no content is lost. - Dangling object-turnins: 3 quests turned in by clicking a spawn-less object
(The Master's Glaive/Scrying Bowl, Find the Gems, Draconic for Dummies) were
accepted but never had a turnin step emitted (emit_turnin bailed when the end
object had no coords). Now the turnin is emitted anyway, arrow falling back to
the giver's location.
Verified: validate_guides 0 hard blocks; audit 0 real OBJTGT/name/coord issues
(also taught audit that aget ##idcraft step's id is an item, not an NPC);
integrity DANGLING 3 -> 0. Remaining orphan/qnoacc entries are item-started
quests (no NPC accept expected) and event/daily quests with no DB start.
- BETA pollutants: quests named "BETA ..." (9342 Crust Bursters, 10059 Zeth'Gor,
- fix(release): pre-release hardening — interface ver, /ls check, consumable prices
Pre-release validation pass (luacheck across all 278 guides + code = 0 errors,
TOC integrity, locale coverage, guide validator, two runtime-bug reviews):- Interface: 20505 -> 20506 to match the current TBC build (was flagged
out-of-date; siblings Questie/PartyLens are on 20506). - /ls check now opens the pre-raid consumables checklist as advertised. It was
shadowed by an earlier "check" -> CheckProgress branch; that manual re-scan is
renamed to /ls rescan. - Consumables price lookup used PH.TSM:GetItemPrice(name), which only resolves
crafting materials (via PH.Materials) — finished consumables returned nil, so
the price column was always empty. Switched to PH.TSM:GetItemPriceByID(id).
- Interface: 20505 -> 20506 to match the current TBC build (was flagged
- feat(squad): richer PartyLens hand-off + public ns.API.CurrentObjective
The "Find group" button now hands the current quest context to PartyLens'
recruitment (PL.API.StartQuestGroup: activity type raid/any + a label from the
step) so the group is pre-filled, instead of just opening the finder. Falls back
to PL:Toggle() on older PartyLens, then the native finder — all pcall-guarded,
fully standalone-safe.
Also exposes a stable read-only surface for sibling addons:
_G.Lodestar.API.CurrentObjective() -> { guide, step, total, questID, label,
zone, needGroup, needRaid }. No side effects; nil when no guide is active.
v1.4.1
Lodestar
v1.4.1 (2026-07-16)
Full Changelog Previous Releases
- chore(release): v1.4.1
- fix(mesh): pace + bound the realm YELL flush so it can't trip the chat rate limit
LibChehulMesh v4. The realm bus rides YELL, which is PUBLIC chat governed by the
client's strict chat-message rate limit — a limit ChatThrottleLib does NOT model
(it only paces the addon byte-throttle). FlushRealm used to dump the ENTIRE realm
queue in one frame, and the queue was unbounded and keyed by payload when a caller
passed no coalesceKey, so a chatty per-item feed piled up and flushed as a YELL
burst that spammed "The number of messages that can be sent is limited".- FlushRealm now emits at most YELL_PER_FLUSH (4) yells per cycle, one at a time
spaced YELL_GAP (2s) apart, off a size-bounded queue (REALM_QUEUE_MAX 40). - The flush ticker is re-bound to the current version's FlushRealm on upgrade
(cancel + recreate) so a superseded instance's burst-y ticker can't linger. - Ship this file identical across the Chehul family; VERSION 3 -> 4.
- FlushRealm now emits at most YELL_PER_FLUSH (4) yells per cycle, one at a time
- fix(guides): craft-and-deliver quests say "craft it", not "kill a random dropper"
"Craftsman's Writ" quests give you a writ and ask you to CRAFT (profession) a
named item and deliver it — you don't loot it. But item_source resolved the
item to whatever mob happens to also drop it, producing nonsense waypoints:
- Rugged Armor Kit (leatherworking) -> "kill Rabid Blisterpaw in Tanaris"
- Major Mana Potion (alchemy) -> "kill Grimtooth in Alterac Valley (BG!)"
and several others just pointed at the writ item itself with no source.
router now detects "Craftsman's Writ ..." quests and emits a plain
get ## |q |tip Craft this (or buy it), then deliver it.
with no misleading map arrow. The objText note still lists what to deliver.
~15 writs across Argent Dawn (A/H). Validator: 0 hard blocks.
Also adds tools/zygor_check.py: a programmatic cross-check of every quest step
against the installed Zygor guides (giver / ender / kill-target / objective
location, on the dimensions that share an ID space). This pass confirmed our
giver/ender/kill/item-source values are all Questie-authoritative; remaining
divergences are curation/route/city-map differences (in a few, e.g. q2098, our
spawn pick is the more accurate one).
v1.4.0
Lodestar
v1.4.0 (2026-07-14)
Full Changelog Previous Releases
- chore(release): v1.4.0
- feat(guides): warn when a step needs a group (elite mob) + party-finder hook
Quests that require fighting an Elite (e.g. the Ogri'la prep bosses Grulloc/
Maggoc/Slaag, the Ring of Blood chain) gave no hint they need a group — you'd
just die solo with no explanation. Now every kill step whose target is elite is
flagged, with a warning banner and a one-click hand-off to the party finder.
Detection (Questie NPC rank, field 6): rank 1/2 (elite/rare-elite) -> |elite
"group recommended"; rank 3 (world boss) -> |raid. Gated by level so a trivial
gray elite in a high-level zone isn't flagged. Cross-checked against Zygor,
which tags exactly the same mobs via free-text tips (Grulloc/Maggoc/Slaag/
Vim'gol/Skulloc, Ring of Blood) — confirming the mob-rank signal is right.
785 elite + 758 raid steps tagged across all guides.
UI: an amber banner on elite/raid steps ("This step has an Elite enemy — a group
is recommended" / "World boss — you'll need a raid") with a "Find group" button,
plus an inline [Elite]/[Boss] badge on the step. The button hooks PartyLens (the
sibling ChehulNet party-finder) via _G.PartyLens:Toggle(); standalone-safe —
falls back to the native group finder, then a hint.
Also fixes 22 item-objective steps that pointed at a rare/world-boss dropper
(unreliable — rarely up) when a common mob drops the same item: most strikingly
q7634 pointed at Azuregos (a raid world boss); "The Crystals" (11025) pointed at
the rare Hemathion. item_source now prefers a common mob, then a world node/
object, and only falls back to a rare/boss when it's the sole source.
Validator: 0 hard blocks. audit.py: 0 real OBJTGT mismatches. - fix(guides): point item-objective steps to the item SOURCE, not the delivery/giver
"collect item" quests (objItems) were emittingget <questName> |goto <giver>,
which pointed the arrow at where you TURN IN the item, not where you GET it
(e.g. "Get Maggoc's Treasure Chest" pointed at Mog'dorg, the delivery NPC).
Now every objItem resolves through items.json (Questie tbcItemDB: npcDrops /
objectDrops / vendors, + a "'s ..." owner-name fallback) and the step
emits kill/collect/buy on the real source with its own spawn coords, e.g.:
get Maggoc's Treasure Chest |goto 55.49,44.86 -> kill Maggoc##20600 |goto 58.59,60.8
The objText note still explains the full "retrieve X and deliver to Y".
Lands across all 241 guides (leveling + reputation/class/attunement/dungeon/
daily/event). Validator: 0 hard blocks. audit.py taught about item-sources
(549 expected item-source steps -> 0 real OBJTGT mismatches). - fix(guides): gate Ogri'la ground-camp quests (Banish the Demons/Wrangle Aether Rays/A Special Thank You) behind the 'Ogre Heaven' unlock — the DB records no prereq, so they were ordered before the NPC would offer them. Now ordered after the unlock + detour warns if reached early
- fix(guides): show HOW to do each leveling quest too — generate_zone now emits objText note + |q-tracked step for objItems/no-spawn quests; write_xml preserves raid-ready includes
- fix(guides): show HOW to do each quest — emit objText note + |q-tracked objective step for every quest with an objective (was accept->turnin with nothing between). Fixes reputation/class/attunement/dungeon/daily/event guides
- feat(raidprep): pre-raid consumables checklist (/ls check) — flask/pots/food/water/bandages have-vs-need from bags, with prices via Profession Helper (PH.TSM)
- feat(gather): hand off to Profession Helper's gathering route (/ls gather or Settings) — detects the char's gathering profs via PH; friendly hint if PH absent
- feat(squad): party/guild route sync over ChehulNet (LSGuide) — broadcast level+guide+step, show who's leveling with Lodestar. Open via /ls party or Settings
v1.3.0
Lodestar
v1.3.0 (2026-07-13)
Full Changelog Previous Releases
- chore(release): v1.3.0
- feat(raidprep): Raid Readiness panel — attunement status per raid (attuned/in-progress/not-started) with a link to each guide; finalQuestIds match GuildOS. Open via /ls raids or Settings
- feat(prereq): 'Rota' button on the prereq banner points the arrow to the giver (ns.questGiver from gen_prereq) — the 'onde pegar' half of the detour
- feat(net): join the ChehulNet mesh as node "ls" — vendor LibChehulMesh stack + presence, broadcast leveling progress on the HELLO caps (standalone-safe, version-guarded)
v1.2.2
Lodestar
v1.2.2 (2026-07-13)
Full Changelog Previous Releases
- chore(release): v1.2.2
- fix(ci): dispatch release.yml on the new tag instead of packaging in the branch job (workflow_dispatch bypasses the packager's 'future tag' guard)
v1.0.0
Lodestar
v1.0.0 (2026-07-13)
Full Changelog Previous Releases
- ci: auto changelog (conventional-changelog); checkout tag before packaging
- ci: fetch new tag before packaging so the release is versioned
- ci: auto-versioned releases from conventional commits
- Publishing setup: CurseForge deploy, gitignore, README, license