Adds an MCP tool wrapping the inventory-service /search/items endpoint with include_all_characters=true, so questions like 'find me a bracelet with Legendary Acid Ward on any unequipped char' resolve in ONE tool call instead of looping get_inventory over 60+ chars (which timed out at 120s). - agent/tools.py: search_items_global wrapper - agent/mcp_overlord.py: register new tool with detailed schema doc - agent/claude_wrapper.py: include in --allowed-tools whitelist; bump timeout 120s -> 240s - nginx/overlord.conf: bump /api/agent/ proxy timeout 180s -> 300s - CLAUDE.md: brief Claude to USE search_items for cross-char searches
181 lines
No EOL
9.9 KiB
Markdown
181 lines
No EOL
9.9 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Dereth Tracker is a real-time telemetry service for game world tracking. It's a FastAPI-based WebSocket and HTTP API service that ingests player position/stats data via plugins and provides live map visualization through a web interface.
|
|
|
|
## Key Components
|
|
|
|
### Main Service (main.py)
|
|
- WebSocket endpoint `/ws/position` receives telemetry and inventory events
|
|
- Routes inventory events to inventory service via HTTP
|
|
- Handles real-time player tracking and map updates
|
|
|
|
### Inventory Service (inventory-service/main.py)
|
|
- Separate FastAPI service for inventory management
|
|
- Processes inventory JSON into normalized PostgreSQL tables
|
|
- Provides search API with advanced filtering and sorting
|
|
- Uses comprehensive enum database for translating game IDs to readable names
|
|
|
|
### Database Architecture
|
|
- **Telemetry DB**: TimescaleDB for time-series player tracking data
|
|
- **Inventory DB**: PostgreSQL with normalized schema for equipment data
|
|
- `items`: Core item properties
|
|
- `item_combat_stats`: Armor level, damage bonuses
|
|
- `item_enhancements`: Material, item sets, tinkering
|
|
- `item_spells`: Spell names and categories
|
|
- `item_raw_data`: Original JSON for complex queries
|
|
|
|
## Memories and Known Bugs
|
|
|
|
* Fixed: Material names now properly display (e.g., "Gold Celdon Girth" instead of "Unknown_Material_Gold Celdon Girth")
|
|
* Fixed: Slot column shows "-" instead of "Unknown" for items without slot data
|
|
* Fixed: All 208 items in Larsson's inventory now process successfully (was 186 with 22 SQL type errors)
|
|
* Added: Type column in inventory search using object_classes enum for accurate item type classification
|
|
* Note: ItemType data is inconsistent in JSON - using ObjectClass as primary source for Type column
|
|
|
|
## Recent Fixes (September 2025)
|
|
|
|
### Portal Coordinate Rounding Fix ✅ RESOLVED
|
|
* **Problem**: Portal insertion failed with duplicate key errors due to coordinate rounding mismatch
|
|
* **Root Cause**: Code used 2 decimal places (`ROUND(ns::numeric, 2)`) but database constraint used 1 decimal place
|
|
* **Solution**: Changed all portal coordinate checks to use 1 decimal place to match DB constraint
|
|
* **Result**: 98% reduction in duplicate key errors (from 600+/min to ~11/min)
|
|
* **Location**: `main.py` lines ~1989, 1996, 2025, 2047
|
|
|
|
### Character Display Issues ✅ RESOLVED
|
|
* **Problem**: Some characters (e.g., "Crazed n Dazed") not appearing in frontend
|
|
* **Root Cause**: Database connection pool exhaustion from portal error spam
|
|
* **Solution**: Fixed portal errors to reduce database load
|
|
* **Result**: Characters now display correctly after portal fix
|
|
|
|
### Docker Container Deployment
|
|
* **Issue**: Code changes require container rebuild with `--no-cache` flag
|
|
* **Command**: `docker compose build --no-cache dereth-tracker`
|
|
* **Reason**: Docker layer caching can prevent updated source code from being copied
|
|
|
|
## Current Known Issues
|
|
|
|
### Minor Portal Race Conditions
|
|
* **Status**: ~11 duplicate key errors per minute (down from 600+)
|
|
* **Cause**: Multiple players discovering same portal simultaneously
|
|
* **Impact**: Minimal - errors are caught and handled gracefully
|
|
* **Handling**: Try/catch in code logs as debug messages and updates portal timestamp
|
|
* **Potential Fix**: PostgreSQL ON CONFLICT DO UPDATE (upsert pattern) would eliminate completely
|
|
|
|
### Database Initialization Warnings
|
|
* **TimescaleDB Hypertable**: `telemetry_events` fails to become hypertable due to primary key constraint
|
|
* **Impact**: None - table works as regular PostgreSQL table
|
|
* **Warning**: "cannot create a unique index without the column 'timestamp'"
|
|
|
|
### Connection Pool Under Load
|
|
* **Issue**: Database queries can timeout when connection pool is exhausted
|
|
* **Symptom**: Characters may not appear during high error load
|
|
* **Mitigation**: Portal error fix significantly reduced this issue
|
|
|
|
## Equipment Suit Builder
|
|
|
|
### Status: PRODUCTION READY
|
|
|
|
Real-time equipment optimization engine for building optimal character loadouts by searching across multiple characters' inventories (mules). Uses Mag-SuitBuilder constraint satisfaction algorithms.
|
|
|
|
**Core Features:**
|
|
- Multi-character inventory search across 100+ characters, 25,000+ items
|
|
- Armor set constraints (primary 5-piece + secondary 4-piece set support)
|
|
- Cantrip/ward spell optimization with bitmap-based overlap detection
|
|
- Crit damage rating optimization
|
|
- Locked slots with set/spell preservation across searches
|
|
- Real-time SSE streaming with progressive phase updates
|
|
- Suit summary with copy-to-clipboard functionality
|
|
- Stable deterministic sorting for reproducible results
|
|
|
|
**Access:** `/suitbuilder.html`
|
|
|
|
**Architecture Details:** See `docs/plans/2026-02-09-suitbuilder-architecture.md`
|
|
|
|
### Known Limitations
|
|
- Slot-aware spell filtering not yet implemented (e.g., underclothes have limited spell pools but system treats all slots equally)
|
|
- All spells weighted equally (no priority/importance weighting yet)
|
|
- See architecture doc for future enhancement roadmap
|
|
|
|
## Technical Notes for Development
|
|
|
|
### Database Performance
|
|
- Connection pool: 5-20 connections (configured in `db_async.py`)
|
|
- Under heavy error load, pool exhaustion can cause 2-minute query timeouts
|
|
- Portal error fix significantly improved database performance
|
|
|
|
### Docker Development Workflow
|
|
1. **Code Changes**: Edit source files locally
|
|
2. **Rebuild**: `docker compose build --no-cache dereth-tracker` (required for code changes)
|
|
3. **Deploy**: `docker compose up -d dereth-tracker`
|
|
4. **Debug**: `docker logs mosswartoverlord-dereth-tracker-1` and `docker logs dereth-db`
|
|
|
|
### Frontend Architecture
|
|
- **Main Map**: `static/index.html` - Real-time player tracking
|
|
- **Inventory Search**: `static/inventory.html` - Advanced item filtering
|
|
- **Suitbuilder**: `static/suitbuilder.html` - Equipment optimization interface
|
|
- **All static files**: Served directly by FastAPI StaticFiles
|
|
|
|
### DOM Optimization Status ✅ COMPLETE (September 2025)
|
|
* **Achievement**: 100% DOM element reuse with zero element creation after initial render
|
|
* **Performance**: ~5ms render time for 69 players, eliminated 4,140+ elements/minute creation
|
|
* **Implementation**: Element pooling system with player name mapping for O(1) lookup
|
|
* **Monitoring**: Color-coded console output (✨ green = optimized, ⚡ yellow = partial, 🔥 red = poor)
|
|
* **Status**: Production ready - achieving perfect element reuse consistently
|
|
|
|
**Current Render Stats**:
|
|
- ✅ This render: 0 dots created, 69 reused | 0 list items created, 69 reused
|
|
- ✅ Lifetime: 69 dots created, 800+ reused | 69 list items created, 800+ reused
|
|
|
|
**Remaining TODO**:
|
|
- ❌ Fix CSS Grid layout for player sidebar (deferred per user request)
|
|
- ❌ Extend optimization to trails and portal rendering
|
|
- ❌ Add memory usage tracking
|
|
|
|
### WebSocket Endpoints
|
|
- `/ws/position`: Plugin telemetry, inventory, portal, rare events (authenticated)
|
|
- `/ws/live`: Browser client commands and live updates (unauthenticated)
|
|
|
|
---
|
|
|
|
## Overlord Assistant Mode
|
|
|
|
When invoked through the dashboard's chat window (the **🤖 Assistant** button) or through `/api/agent/ask`, you are acting as the **Overlord Assistant** — answering ad-hoc questions for the user about their live multi-account Asheron's Call setup.
|
|
|
|
**You have MCP tools** (from `.mcp.json`) for live game data. **Always use them** instead of guessing or apologising for not having data:
|
|
|
|
- `get_live_players` — current online characters with positions/kills/state
|
|
- `get_recent_rares` — rare item finds in the last N hours
|
|
- `query_telemetry_db` — read-only SQL on the telemetry DB for ad-hoc analysis
|
|
- `search_items` — **cross-character** inventory search (use this instead of looping `get_inventory` per character — single call is much faster)
|
|
- `get_inventory` / `get_inventory_search` — single-character inventory
|
|
- `get_player_state` / `get_combat_stats` / `get_equipment_cantrips` — per-character lookups
|
|
- `get_quest_status` / `get_server_health` — global state
|
|
- `suitbuilder_search` — armor optimization (slow, only on explicit request)
|
|
|
|
### Behaviour rules
|
|
|
|
1. **Use tools, don't speculate.** If the user asks "how many chars are online" — call `get_live_players`. Don't say "I'd need to check" — just check.
|
|
1a. **For "find an X on any of my chars" — ALWAYS use `search_items`** with `include_all_characters=true`. Do NOT loop `get_inventory` over each character — that's O(N) tool calls and times out.
|
|
2. **Be concise.** The user is glancing at a chat window, not reading a report. 2-5 sentences for most answers. Use markdown tables for tabular data.
|
|
3. **No code unless asked.** This mode is about *operating* the system, not editing it. Don't open files or write code unless the user explicitly asks.
|
|
4. **Real numbers, real names.** Cite actual character names and counts from tools — never make up sample data.
|
|
5. **Read-only.** You cannot mutate the database; the SQL tool will reject any non-SELECT statement and the role is also `GRANT SELECT` only. If a question requires a write, say so.
|
|
6. **Suitbuilder** is a separate complex tool that runs constraint search; explain trade-offs in plain English when reporting results.
|
|
7. **Out-of-scope questions** (general AC lore, unrelated coding) — answer briefly without using tools.
|
|
|
|
### Available data tables (for `query_telemetry_db`)
|
|
|
|
- `telemetry_events` (hypertable, 30-day retention) — position/state snapshots every ~2s per character
|
|
- `rare_events` — rare item find log
|
|
- `spawn_events` (hypertable, 7-day retention) — monster spawn observations
|
|
- `portals` — discovered portal coords (1h dedup window)
|
|
- `char_stats`, `rare_stats`, `rare_stats_sessions` — lifetime/session aggregates
|
|
- `character_stats` — latest full stats JSON per character
|
|
- `combat_stats`, `combat_stats_sessions` — combat tracking
|
|
- `server_status` — current Coldeve game-server state (single row)
|
|
|
|
If asked about something not covered above, look in `db_async.py` for the schema or just try a query and report what you see. |