# WarBoard Changelog

## 1.7.3

### Player-kill fronts now show in your objective tracker
- **The zone's player-kill objective auto-tracks the whole time you're in that zone.** Fly into
  Ashenvale (with War Mode on) and *"Battle for Ashenvale"* pops into Blizzard's objective tracker and
  follows your kills live; leave the zone and it clears. No popup, no fuss — just the tracked quest,
  the whole time you're somewhere it can be earned. Works for every player-kill front (Ashenvale,
  Badlands, Eversong, the weekly-flip zones, etc.). It shows in exactly the places a kill would count,
  so what you see and what you're credited for never disagree.

### Your gold can never go below zero
- **No more "I earned 150 gold but my balance still says 0."** WarBoard used to carry a hidden *debt*
  when spending outran your recorded earnings (usually after a crash dropped a session's records), and
  new gold silently paid that debt down before your balance moved — so rewards looked like they
  vanished. That's gone. Your balance simply never drops below 0: a shortfall is written off on the
  spot, and the very next reward shows in full. Any debt you were carrying from a previous version
  clears itself the first time you log in on this build.
- **Double-spend protection.** The one situation that could ever miscount gold was spending in the
  first few seconds after login, before a crashed session's costs finished re-syncing from other
  players (your balance briefly reads high). Posting a bounty now waits until your War Board has synced
  up — normally just a moment — and tells you *"still syncing after login — try again in ~Xs"* if you're
  quick on the button. Everything else (earning, tracking, alerts) works instantly as always.

### Bounty tracking is a lot steadier
- **Fixed tracking that would freeze for a while, then jump.** A tracked target's location could stop
  updating for up to a minute and then catch up all at once — and cancelling and re-tracking was the
  only way to force it. The cause was the addon flooding its own network channel: every position update
  was being sprayed far wider than it needed to be, clogging the pipe until it backed up. Position
  updates now go straight to the hunters tracking you, with the wider backup send happening only
  occasionally. You should see smooth ~5‑second updates again.
- **Tracking now heals itself.** If a target's updates stall out, WarBoard quietly re-establishes the
  connection on its own — no more manually cancelling and clicking Track again to unstick it.

### Fewer hitches / freezes
- **Fixed the frame stutters (and memory spikes) around busy areas.** In crowded spots — capital cities,
  login waves — memory could balloon from ~5 MB to 60–70 MB for a second or two and cause a hitch. The
  culprit was WarBoard rebuilding the same catch-up data separately for every nearby player who asked
  for it at once. It now builds that data a single time and shares it with everyone, so the spikes are
  gone. Also trimmed how hard the catch-up data is compressed to lighten the load further.
- The built-in `/wb perf` diagnostic got smarter: it now reports network traffic and memory churn, so
  this kind of issue can be pinpointed instead of showing up as an unnamed hitch.

### Lua errors fixed
- **Fixed errors that popped up in raids, arenas, and battlegrounds.** Mousing over players or their
  nameplates inside instanced content could spam Lua errors (about "secret" values). WarBoard's NPC
  dialogue helpers now stand down completely inside any instance, where they've got nothing to do
  anyway — no more error spam.

All client-side and safe to mix versions — no rules change this release, so no community-wide update is
required (though everyone benefits from having it).

## 1.7.1

### New objective: Breaking Badlands (foot race)
- **A repeatable, no-mounts foot race in the Badlands, for both factions.** Speak to a Demolitions
  Analyst II near Fuselight-by-the-Sea to start — a 3‑2‑1 countdown, then a mad dash to the finish
  line on foot before a 45‑second timer runs out. Mounts, vehicles, flying, and flight paths are all
  off-limits; dying or leaving the course fails the run.
- **Rewards 150 gold and 75 war credit**, with the same 10% repeat rule as other objectives (and the
  active-warfront bonus when the Badlands is the day's warfront). It's an elite objective on the War
  Board, with its start pinned on the zone map.
- **Quality of life:** an "X marks the spot" marker drops at the finish line the moment you accept,
  you're auto-dismounted on start, the objective tracker shows a live countdown, and the start option
  is locked out unless you're right next to the analyst. Failing plays a quest-failed sting; finishing
  plays the completion jingle.

### Supply runs: turn-in marked on the map
- **Your delivery NPC is now flagged while you're carrying.** Start a supply run or steal enemy
  cargo and your faction's quartermaster (Tweedle / Apprentice Boulian) gets an "X marks the spot"
  marker on the zone map, so you always know where to deliver. It clears once you hand it in or lose
  it, and survives a `/reload` mid-run.

New content adds a rules version, so update the whole community: older clients hold the race's records
aside until they're on this version, then score them normally.

## 1.7.0

### Gold no longer gets minted from nothing
- **Fixed a bug that could restore gold you'd already spent.** If a session ended without saving
  (a crash or forced close), the bounty-placement costs from that session dropped off your local
  ledger — so at next login your balance looked higher than it should, you could place bounties you
  couldn't actually afford, and when those old costs re-synced from peers the resulting negative was
  silently zeroed out. That zeroing *created gold that never existed.* Now an overspend is carried as
  visible **debt** instead: gold shows 0, `/wb diag` reports the shortfall, and new earnings pay it
  down before any gold shows. The books always balance — a lost save can no longer print money.
  (Gold already created by the old behaviour is baked in and can't be retroactively removed.)

### Rally to your faction's supply runs
- **Same-faction supply runs now raise a "join them" alert.** When someone on your side starts a
  supply run, you get a green chat announcement — *"[Player] has started a supply run for the
  Horde/Alliance! Join them and help!"* — and a matching card in the Alerts tab.
- **A JOIN button instead of TRACK.** The allied alert shows a **JOIN** chip; clicking it requests an
  invite to their group (leaving your current party first if needed, exactly like a Call to Arms
  answer). Enemy runners still show TRACK as before — friendly runners are never treated as theft
  targets, never tracked on the map, and their alert clears when the run ends.

All client-side. The allied alert only needs viewers on this version to appear (same-faction clients
already received the broadcast — they just used to ignore it); mixed versions still sync fine.

## 1.6.9

### Combat never pays for sync (micro-stutter fixes)
- **The sync protocol now stands down while you're fighting.** Ledger record batches, sync digests,
  dump requests, campaign results, and directory updates are the heavy background work (a single
  synced batch pays decompress + deserialize + per-record validation + ledger adds in one frame) —
  and it was running mid-fight. In combat, WarBoard now processes **only** the live World-PvP traffic:
  bounties, supply-runner and objective alerts, tracking pings, deserter notices, and kill reports /
  rewards / tallies. Everything else queues and drains gently once the fight ends. Big payloads park
  *before* they're even decompressed, so the decompression itself never hits a combat frame.
- **Ledger fingerprints are computed once, not over and over.** Each record's sync hash is now
  memoized — a record is hashed a single time when it first arrives, instead of being re-hashed from
  scratch every time the digest rebuilt (which happened constantly on a busy day). This was the real
  source of the "hashing" CPU behind the stutter.
- **More background jobs now wait out combat too.** A community-roster walk (triggered mid-fight by
  assault alerts, which fire on kills), the hidden channel-roster scan, a campaign rollover's result
  lock + old-record trim, the post-login record re-validation, and the bounty-board reconcile were all
  full-ledger or roster scans that could land during a fight. They now defer until combat ends —
  none is time-sensitive, and each reconciles itself afterward, so nothing is lost.

### Diagnostics
- **`/wb perf` no longer costs FPS to run.** The profiler was polling the game's whole-addon CPU
  meter every single frame (a call that walks every loaded addon), which shaved frames while you were
  measuring. It now samples a few times a second — plus an immediate sample on any hitch, so
  attribution stays accurate. (The optional `scriptProfile` deep mode still has the game's own
  built-in overhead; turn it back off with `/console scriptProfile 0` + `/reload` when you're done.)

All client-side and wire-compatible: deferred messages are the same messages, just processed a moment
later, and the hash is byte-identical — mixed versions still sync and converge exactly as before.

## 1.6.8

### Tracking & cargo fixes
- **Supply-runner tracking no longer freezes on the map.** A tracked runner's pin could get stuck at
  one spot while they kept moving — the hunter was ending the track whenever a carrier alert went stale,
  even though the live position pings were still arriving (and those alerts lag or miss cross-faction).
  Runners now report their carry state in every position ping, so a track only ends when the runner
  actually says they've stopped carrying. The pin follows them live.
- **A runner who already delivered can't be "robbed."** After a turn-in, a lost "ended" alert used to
  leave the runner flagged as a carrier indefinitely — so they kept showing as a runner and every later
  killing blow "stole" cargo they no longer had. Carrier flags now expire on a timer (and clear the
  instant a runner reports they've delivered), so a delivered runner drops off the map and yields
  nothing on a kill.

Client-side and wire-compatible; both fixes work hunter-side even against a runner on an older build.

## 1.6.7

### Kills no longer live in the activity ledger
- **World-PvP kill credit moved to its own lightweight tally.** Every kill still awards +1 War Credit
  and shows on the Leader Board and War Contribution bar exactly as before — but instead of writing a
  record into the shared ledger (the highest-volume event by far at population), kills now sync as one
  small evolving value per player per campaign. That's a big cut to the record churn, sync traffic,
  and repeated full-ledger scans behind the micro-stutter, especially with lots of people out killing.
- **It can't undercount.** The tally only ever merges *upward* (a stale or lost update leaves a peer
  briefly behind, never below the true count), it's kept out of the ledger so trimming can't touch it,
  and each campaign's kill credit is baked into the locked result at finalization — so past results
  can't change. Your personal total and rank still include every kill.
- Trade-off, stated plainly: this slice is now a trusted aggregate rather than a hash-verified record,
  so kill credit isn't tamper-proof the way gold/objectives/bounties still are. Being upward-only, the
  only possible abuse is a cheater inflating their *own* number — never harming anyone else's.

### Leaner ledger
- **Ledger cap lowered to 3,000 records** (from 10,000). With kills gone, a campaign's ledger footprint
  is small, so this holds many campaigns before it ever trims — while keeping the cap-trim spike tiny.
- **Old records auto-trim.** Records from campaigns that ended more than ~2 hours ago are dropped
  automatically (their results are long locked by then, so nothing changes); your own earnings are
  banked first so lifetime totals never move, and everyone trims the same set deterministically.
- **The sync fingerprint no longer spikes.** Hashing the ledger's sync digest used to process up to
  700 records in one synchronous burst (~18ms — a visible hitch on a busy ledger) and ran its first
  slice inline; it's now hashed in small slices fully spread across frames, so it never stalls a frame
  regardless of ledger size.

### Diagnostics
- **`/wb ledger`** — prints how many records currently live in your ledger, by type (a quick way to
  watch the churn drop).
- **`/wb perf` now reports ledger inflow** — records/min and which types dominate, so you can measure
  the record load directly during a busy session.

All client-side and wire-compatible: existing kill records already in ledgers still count and age out
normally, and older clients simply won't see the new kill-tally sync. Mixed versions still talk fine.

## 1.6.6

### Anti-cheat: a second port-out escape is now caught
- **Bench-porting out of a fight (Exit Lorewalking) is now flagged too.** The 1.6.5 anti-cheat only
  caught the quest-abandon teleport; leaving a Lorewalking bench mid-fight to escape now gets the
  exact same treatment — marked a DESERTER (stacking, no earnings while marked), publicly announced
  to both factions, and if you were bountied, the reward is handed to one random hunter who was
  tracking you.
- **It only triggers in PvP combat.** Exit Lorewalking is a normal, legitimate spell, so it's flagged
  only when cast while actually fighting a hostile player — using a bench normally is never touched.

### Performance — micro-stutter fixes
- **The objective tracker no longer relayouts on every kill/spawn.** Each objective update (every
  kill, every proximity in/out) was forcing a full relayout of Blizzard's *entire* tracker — so
  farming with mobs streaming in, or the start of a player fight, spiked. Those are now coalesced
  into a single relayout, which should smooth out the "lag when things load in" hitching.
- **Dropped a periodic guild-roster scan.** Peer selection was walking your whole guild roster every
  few seconds to dedupe sends — pointless work (the guild broadcast reaches everyone anyway). Removed;
  no more O(guild-size) hitch on big guilds.
- **Live tracking pings no longer decode twice.** A fast-path tracking packet and its reliability
  backstop were each being decompressed on arrival; the backstop is now skipped once the fast copy
  is handled.

### New: `/wb perf` — micro-stutter diagnostic
- **A built-in profiler to find what's causing a stutter.** Turn it on, reproduce the hitch, and it
  names the WarBoard function at fault (and flags garbage-collection pauses). Off by default with zero
  overhead; `/wb perf` for options. It's how the fixes above were pinned down.

All client-side and wire-compatible — mixed versions still talk fine.

## 1.6.5

### Anti-cheat: the port-out escape now has consequences
- **Fleeing a fight with the quest-abandon teleport ("port out") marks you a DESERTER — always.**
  It's detected on the escapee's own client, publicly announced to both factions, and stacks another
  hour per offense (capped at 10h). While marked you bank no gold or war credit.
- **If you were bountied when you ported, your bounty is handed to a hunter.** The reward goes to one
  random player who was *actively tracking* you (never one of the bounty's own posters), and a second
  announcement line names who received it. So porting out no longer wipes your bounty for free — it
  pays whoever was on your trail.

### New: micro-stutter / FPS-spike diagnostic — `/wb perf`
- **A built-in profiler that finds out whether WarBoard is behind a stutter, and which part.** Turn it
  on, reproduce the hitch, and it prints the culprit live (e.g. *"stutter WB.UI.RefreshLeaderboard
  took 22 ms"*) and in a ranked report. It also flags hitches that coincide with a garbage-collection
  pass, and can use the game's `scriptProfile` for exact whole-addon CPU. Off by default with zero
  overhead; see `/wb perf` for options. Honest by design — if nothing in WarBoard took measurable
  time during your stutter, it says so, and we look elsewhere.

### Smaller
- **Live tracking refreshes twice as often** — a tracked target's position now broadcasts every 5s
  instead of every 15s, so the map dot keeps up better.
- **Shorter chat tag.** WarBoard's chat lines are now just tagged `[WarBoard]` instead of
  `[WarBoard vX.X.X]`; the version is printed once at login.

Mixed versions still talk fine: the bounty hand-off is a normal claim record everyone already
understands, so hunters get paid regardless — but update to see the new public announcements.

## 1.6.4

### Tracking is near-instant now
- **Bounty and supply-runner tracking connect and follow immediately.** The ack + live-position
  pings were queued behind sync traffic; they now send at top priority AND take a raw fast path that
  skips the message-throttle queue entirely, with the normal path kept as a reliable backstop
  (whichever copy lands first wins). Map-following a target should feel instant.
- **"Supply Runner Spotted" alerts land faster** too (same fast-path treatment) — so do war-objective
  assault alerts.

### New
- **`/wb channel on|off`** — opt in/out of WarBoard's hidden realm sync channel. It never showed in
  your chat, but it does occupy a channel slot; turn it off if you'd rather WarBoard not join a
  channel (sync still works over guild, whispers, and peers). On by default.

All client-side; nothing changes on the wire, so mixed versions still talk fine.

## 1.6.3

Performance pass — all client-side, no wire/version impact. Follows the same idea as 1.6.2's board
gate: stop doing background work you can't see.

### Fewer background rebuilds
- **The Active Bounties and Alerts panels no longer rebuild while the board is closed.** Like the
  Leader Board fix in 1.6.2, these were quietly rebuilding on every event that touched them (each
  tracked target's position, the presence poll, every bounty post/accept/abandon, cargo theft, the
  alert ageing tick) — even with the board shut. They now rebuild only when it's actually open.
- **Bounty board rebuilds from sync are coalesced.** A burst of synced bounty events used to trigger
  a full O(ledger) rebuild per event; a burst now collapses into a single rebuild.

### Cached the heavy ledger scans
- Gold/War-Credit totals, the Leader Board, the War Contribution bar, and the Activity feed each
  re-scanned the whole ledger (up to 10k records) on every request — and some ran several times per
  refresh. They're now cached and only recomputed when the ledger actually changes (or the
  anti-cheat re-judges a record), turning repeated scans into instant lookups.

### Smoother objective farming
- **Killing objective NPCs no longer relayouts the game's objective tracker on every kill.** Rapid
  or AoE farming was forcing a full Blizzard objective-tracker relayout per kill; the intermediate
  progress ticks are now batched (a few times a second) while completions still show instantly.

## 1.6.2

### Stolen cargo
- **You can now turn stolen cargo in.** Your quartermaster (Tweedle / Apprentice Boulian) offered
  no delivery option once your *daily* run was already done — it only looked at the daily state and
  showed its "thank you" dialogue. It now recognizes stolen cargo (which has no daily limit) and
  offers the hand-in regardless.
- **"Stolen Cargo!" popup + objective.** Seizing an enemy's cargo now flashes a center-screen
  "Stolen Cargo!" banner and adds an objective-tracker step telling you to deliver it to your
  quartermaster (no War Effort card). It clears itself on turn-in / loss and survives a `/reload`.
- **The victim's map icon no longer lingers.** When a tracked runner dies, delivers, or loses their
  cargo, their icon is dropped immediately instead of sitting at the spot for up to ~2 minutes.
- **Tracking follows the cargo.** If you were tracking a runner and someone steals their cargo, your
  track now **auto-switches to the thief** — you follow the supplies instead of losing them at the
  corpse, no need to re-TRACK.
- **You're told when your cargo is stolen.** If a player seizes cargo you were carrying, you now get
  a chat line naming who took it (the thief already saw their own confirmation).
- **Completion jingle.** Completing a Supply Run and turning in stolen cargo now play the same
  "quest completed" sound as other objectives.

### Bounties
> **Everyone should update** for consistent scoreboards — an out-of-date client won't apply the fix.
- **Fixed two hunters both getting credit for one bounty.** A bounty can only be claimed once, but a
  near-simultaneous claim-race (e.g. a group killing the target) could let two hunters both score it.
  Claims are now de-duplicated on a strict "first claim wins" rule — corrected live as soon as both
  claims have synced, and enforced deterministically in the campaign audit so the final result is
  always right. (No wire change; a mixed-version network still stays in sync, it just won't correct
  the score until each client updates.)

### Anti-cheat
- Added an always-on guard that **ejects the player from the "Magical Snow Sled" and the Lorewalking
  "Bench"** the instant either is detected (as a vehicle or a pet). Runs the whole session, event-
  driven with a light backstop.

### Performance (micro-stutter)
- **Board panels no longer rebuild while the board is closed.** The Leader Board and Activity feed
  are O(ledger) rebuilds that were being triggered by *every* background peer-sync burst even with
  the board shut. They now only rebuild when the board is actually open (one catch-up rebuild on
  open). This was the biggest sync-time hitch.
- **World-map icons no longer rebuild every second.** Live bounty/carrier icons now redraw only when
  a position arrives and reposition themselves as you pan; a slow sweep just expires stale ones.
- **Duplicate messages are dropped before decoding.** The fanout delivers the same message over
  several channels at once; byte-identical copies are now skipped before the (costly) decompress +
  deserialize instead of being processed each time.

## 1.6.1

> **Everyone should update.** The bounty tracking fix works both when you track *and* when
> you're the one being tracked — an out-of-date client can still fail to answer a tracker.

### Fixes
- **Bounty TRACK no longer gets stuck on "Locating…".** The target's client was only recognizing
  a tracker's request by GUID, but a bounty's GUID is captured from the community roster when it's
  posted and can differ from the target's current character — so the target silently ignored the
  request and never shared its location. It now recognizes a track request by **GUID *or*
  name+realm** (the same way it already detects a bounty on itself), so tracking connects reliably.
  This is why supply-runner tracking worked while bounties didn't — a supply runner reports its own
  live identity, so it always matched.
- Hardened the track handshake generally: the request is now sent to every valid address for the
  target (stored + roster-resolved), and realm names are normalized so a display-form realm
  ("Area 52") can't silently break the whisper the request rides on.
- **Supply Run objective card now shows on the War Effort panel.** A load-order race meant the run
  wasn't resolved yet when the panel was first built, so the card was skipped.

### Added
- `/wb commdebug` — toggle a comm / tracking RX-TX trace for diagnosing tracking issues.

## 1.6.0

### New: Supply Run (daily World PvP delivery event)
A new daily event that turns a supply haul into open-world PvP bait. There's a separate Horde and
Alliance version — you only see and run your own faction's.

- **Horde** — talk to Overseer Gorthak at Warsong Lumber Camp, then haul the lumber on foot to
  Tweedle at Hellscream's Watch.
- **Alliance** — talk to Faldreas Goeth'Shael in Astranaar, then carry the ironwood beams on foot
  to Apprentice Boulian at Forest Song.
- Multi-page quartermaster dialogue (fake gossip), an objective card, a map pin at the pickup, and
  an objective-tracker step guide the run.
- **On foot only** — mounting, flying, druid Travel/Flight Form, taxis, and vehicles are all
  blocked while carrying the shipment (you're too heavily loaded).
- **Daily, per character** — once completed *or* failed, it's locked for that character until the
  next daily reset.
- **Fails** on death, logging out mid-run, taking a taxi, or crossing a loading screen.
- **Reward** — a completed run pays **300 gold + 150 war credit**.

### New: Supply Runner intel, opt-in tracking & cargo theft
Supply runners are visible to the enemy, and their cargo can be stolen.

- While you carry a shipment, a lightweight **alert** is broadcast to the enemy faction
  ("SUPPLY RUNNER SPOTTED"). No precise location is shared by default.
- Enemies can click **TRACK** on the alert to opt into live location tracking, drawing a flag
  icon on the world map (reuses the bounty location transport — only trackers who opt in ever see
  the position).
- **Cargo theft** — landing the killing blow on an enemy supply runner **steals their cargo**. You
  become a stolen-cargo carrier ("STOLEN SUPPLIES MOVING"), subject to the same on-foot rule, and
  can turn it in at your own quartermaster with **no daily cooldown**.
- Stolen cargo is **lost** on death (your killer steals it in turn), logout, loading screen, or
  taxi; it **survives a `/reload`**. You can carry multiple stolen shipments at once.
- **Reward** — each turned-in stolen shipment pays the same as a Supply Run: **300 gold + 150 war
  credit**.

### Rewards are now banked & synced
- Supply Run completions and stolen-cargo turn-ins now write a real, synced **`supply_run` ledger
  record** — they count toward your gold/war-credit totals, the leaderboard, and the war
  contribution bar, and are validated by the anti-cheat verifier like any other activity.
- Added a canonical `WB.SUPPLY_REWARD` (300 gold / 150 war credit) as the single source of truth
  shared by the run layer, the cargo layer, and the verifier.
- Rules version bumped to **6** for the new `supply_run` activity type, so out-of-date clients
  safely abstain on (and keep relaying) the new records until they update, rather than rejecting
  them.

### Fixes
- **Bounty TRACK now reliably locates online targets.** Pressing TRACK on a bounty whose target
  was clearly online could still fall through to "Failed to obtain." That's fixed — TRACK now
  correctly obtains their location. (Targets who don't have the addon, or have it disabled, still
  correctly can't be tracked, but no longer cause a false handshake.)
- **Supply runner map flag no longer lingers after a run ends.** When a tracked runner fails,
  delivers, or loses their cargo, the flag icon now disappears on the next location update: the
  tracker verifies they're still a carrier and, if not, stops tracking and tells them to stop
  broadcasting (unless they're also an active bounty).

### Removed
- `/wb testsupplyalert` and `/wb teststolenalert` (dev-only fake-alert previews).
- `/wb resetsupply` (dev-only Supply Run state reset).

### Performance
- Reduced micro-stuttering during peer sync: the ledger sync digest is now computed
  time-sliced across frames, online-peer lookups are cached briefly, and HELLO handling uses the
  async digest — so busy comm traffic no longer causes frame spikes.
