--- # nuzlocke-tracker-rfg0 title: Core encounter processing status: todo type: task priority: normal created_at: 2026-02-11T08:43:12Z updated_at: 2026-02-11T08:43:33Z parent: nuzlocke-tracker-bs05 blocking: - nuzlocke-tracker-gkcy --- Implement the core logic that transforms raw PokeDB encounter records into our internal format. ## Checklist - [ ] **Filter by game version**: Given a target game slug, select only encounters where `version_identifiers` includes that game - [ ] **Parse level strings**: Convert "2 - 4" → min_level=2, max_level=4; "67" → min_level=67, max_level=67 - [ ] **Handle rate variants per generation**: - Gen 1/3/6: use `rate_overall` directly as `encounter_rate` - Gen 2/4: `rate_morning`, `rate_day`, `rate_night` — flatten to max or average for `encounter_rate` - Gen 5: `rate_spring` through `rate_winter` — flatten similarly - Gen 8 Sw/Sh: `weather_*_rate` fields — flatten to max - Gen 8 Legends Arceus: `during_*` / `while_*` booleans — convert to a presence-based rate - Gen 9 Sc/Vi: `probability_*` fields (spawn weights, not percentages) — normalize to percentages - Preserve raw variant data in a way that nuzlocke-tracker-oqfo can use later - [ ] **Aggregate encounters**: Group by (pokemon, method, location_area) and merge level ranges / rates where appropriate (same logic as the Go tool's aggregation) - [ ] **Group by location area**: Collect all encounters for a location area into a route structure - [ ] **Handle parent/child routes**: Multi-area locations (e.g. Safari Zone) should produce parent routes with children, matching the existing hierarchical format ## Notes - Rate parsing needs to handle percentage strings like "40%" as well as bare numbers - The Go tool aggregates encounters with the same pokemon+method at a location into a single entry with merged level ranges — replicate this