Files
Questie-X/handoff.md
T
Xurkon 164584ca87 fix: Sunstrider pin regression, ghost pins, and learner zone normalization
- Fix: isSunstrider block in _MergeSpawnEvidence now checks IsAscensionProtected
  before writing learner data to npcDataOverrides. Without this guard, each Mana
  Wyrm kill overwrote AscensionDB's z1241=5 data with learner z3431 coords.

- Fix: Clustering disabled for zone 1241 (Sunstrider Isle) in _DrawObjectiveIcons
  so all 5 AscensionDB spawn pins display individually instead of collapsing to 2.

- Fix: Ghost pin loop in AvailableQuests.lua -- 'while frames[i]' was iterating a
  string-keyed table with a numeric index (never iterated). Changed to pairs().

- Fix: NormalizeSpawnZoneKey now uses ZoneDB.areaIdToUiMapId for all zones so
  learner evidence is stored under map IDs (e.g. 1241) not area IDs (e.g. 3431),
  matching AscensionDB's key space. Applied in LearnNPC and _StoreGuidSpawnEvidence.

- Fix: isSunstrider detection in _MergeSpawnEvidence updated from hardcoded
  zoneId==3431 check to IsSunstriderNativeZone() since zone IDs are now normalized
  to map IDs at storage time.
2026-05-25 19:02:56 -05:00

142 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Questie-X Learner Module — Pin Collapse Handoff
**Session**: 2025-05-25
**Repo**: `C:\Users\kance\Documents\GitHub\Questie-X`
**File**: `Modules/QuestieLearner.lua`
---
## Problem Statement
Killing multiple Mana Wyrms (npcId ~15274) on Sunstrider Isle (zoneId 3431) at distinct map coordinates still results in only **2 map pins** rendering instead of 3+ distinct pins. The collapse is caused by the coordinate **bucketing** logic in `_MergeSpawnEvidence` and `InsertIfNewBucket`.
---
## Two Identified Bucketing Layers
### Layer 1 — `_MergeSpawnEvidence` lines ~10461048
Groups all per-GUID evidence into buckets by rounding `(x, y)` to 2 decimal places:
```lua
local rx = floor(evidenceX * 100 + 0.5) / 100
local ry = floor(evidenceY * -100 + 0.5) / 100
local key = entry.zoneId .. "|" .. rx .. "|" .. ry
```
Each unique 2-decimal `(rx, ry)` becomes one evidence group. If two distinct kill locations fall within the same 0.01×0.01 square, they merge into one evidence group here — **before** `InsertIfNewBucket` is even called.
### Layer 2 — `InsertIfNewBucket` lines 205221
For Sunstrider, uses `grid = 0.5`. Checks if any existing spawn in the zone falls in the same `floor(x/0.5)*0.5` bucket:
```lua
local bx, by = floor(x / grid) * grid, floor(y / grid) * grid
```
Two kills at x=50.54 and x=50.55 both land in bucket 50.5 → first is inserted, second is rejected as duplicate. This is the **documented intentional collapse** — but it's killing genuinely distinct spawn points that a 0.5 grid rounds to the same bucket.
---
## Fixes Already Applied
1. **`GetCoordGridForZone` hoisted outside evidence loop (line ~1114)**
Grid is now computed once before the Sunstrider promotion loop. Previously it was computed inside `InsertIfNewBucket` via `customGrid` parameter.
2. **`NormalizeCoordPair` comment (line 958959)**
Updated to document that it handles native 01, already-scaled 0100, and buggy 010000 input formats.
3. **`QUESTIE_LEARNER_debug` log comment (line 963964)**
Noted it is commented out — re-enable for live debugging if needed.
---
## Recommended Next Step: Remove Bucketing Entirely
**The fix in this session did not resolve the 2-pin collapse.** The next agent should:
1. In `_MergeSpawnEvidence` (~line 10461048): **comment out or replace** the 2-decimal rounding entirely. Instead of grouping by `(zoneId|rx|ry)`, use the raw normalized coordinates directly. This makes every distinct kill location a separate evidence group.
2. In the Sunstrider promotion block (~lines 11111121): **bypass `InsertIfNewBucket`** entirely for Sunstrider. Instead of bucketing, insert the raw coordinates of every evidence group into `zoneSpawns` directly.
### Exact Changes to Make
**`_MergeSpawnEvidence` (~line 10451048) — REMOVE 2-decimal rounding:**
Replace:
```lua
-- Round to 2 decimal places for grouping
local rx = floor(evidenceX * 100 + 0.5) / 100
local ry = floor(evidenceY * 100 + 0.5) / 100
local key = entry.zoneId .. "|" .. rx .. "|" .. ry
```
With:
```lua
-- Use raw normalized coordinates as group key (no bucket collapse)
local rx = evidenceX
local ry = evidenceY
local key = entry.zoneId .. "|" .. rx .. "|" .. ry
```
**Sunstrider loop (~lines 11141121) — DIRECT INSERT (bypass `InsertIfNewBucket`):**
Replace:
```lua
local grid = GetCoordGridForZone(topEvidence.zoneId)
for _, spawnEvidence in pairs(evidence) do
if InsertIfNewBucket(zoneSpawns, spawnEvidence.x, spawnEvidence.y, grid) then
promoted = promoted + 1
else
duplicates = duplicates + 1
end
end
```
With:
```lua
-- Directly insert every distinct evidence coordinate without bucketing
for _, spawnEvidence in pairs(evidence) do
tinsert(zoneSpawns, { spawnEvidence.x, spawnEvidence.y })
promoted = promoted + 1
end
duplicates = 0
```
**Rationale**: Bucketing was designed to reduce noise from GPS drift — but on Sunstrider with a 0.5 grid, it collapses spawn points that are legitimately different. Removing bucketing entirely ensures every distinct kill location gets its own pin.
---
## Key Code Locations
| Function | Lines | Purpose |
|---|---|---|
| `NormalizeCoordPair` | ~168197 | Scales coords to 0100; handles buggy inputs |
| `CoordBucket` | ~200201 | Bucket key for (x, y) using COORD_GRID |
| `InsertIfNewBucket` | ~205224 | Inserts coord only if no existing in same bucket |
| `GetCoordGridForZone` | ~108113 | Returns 0.5 for Sunstrider (zones 1241/3431), else 2.0 |
| `_StoreGuidSpawnEvidence` | ~9421012 | Stores per-GUID kill evidence; calls NormalizeCoordPair |
| `_MergeSpawnEvidence` | ~10141140 | Groups evidence → promotes top groups to npcDataOverrides |
---
## Debug Log
Re-enable this block (`_StoreGuidSpawnEvidence`, lines ~963964) to verify normalized coordinates during gameplay:
```lua
Questie:Debug(Questie.DEBUG_LEARNER,
"[QuestieLearner] _StoreGuidSpawnEvidence: spawnUID=", spawnUID,
"zoneId=", zoneId, "nx=", nx, "ny=", ny)
```
Expected log output after `/reload`:
```
entry.x=58.68 entry.y=43.19 (not "5868,4319")
```
---
## Files Modified
- `Modules/QuestieLearner.lua` — lines 958959, 1114 (already patched prior to this handoff)
- `Tests/QuestieLearner_spec.lua` — (unchanged; legacy reference)