Commit graph

28 commits

Author SHA1 Message Date
a3e3d9f6ea Fix inventory: window_id 'inventory' now maps to bot.inventory
Root cause: Bedrock sends inventory_content with window_id as string
("inventory", "armor", "offhand") but bot.inventory has numeric id 0.
The getWindow() lookup failed silently, so inventory was never populated.

Fix: check for string window_id values and map them to bot.inventory
directly, bypassing the numeric ID lookup.

This fixes:
- bot.inventory.items() returning empty
- Auto-equip not detecting items
- "item not in inventory" errors for equip commands
- Inventory check command returning empty

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 21:12:15 -05:00
1872d0b89a Add task IDs (T-1, T-2, ...) for tracking and debugging
Every PrimaryTask and SubTask gets a unique auto-incrementing ID.
All log messages now include the task ID:

  T-1 NEW: Following GavRocket (stack depth: 1)
  T-2 INTERRUPT: Fighting spider
  T-2 COMPLETE: Fighting spider
  T-1 RESUMED: Following GavRocket
  T-3 NEW: Checking inventory (stack depth: 2)
  T-1 PAUSED: Following GavRocket
  T-3 COMPLETE: Checking inventory
  T-1 RESUMED: Following GavRocket

Makes it easy to track which task is which and debug the stack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:49:20 -05:00
7363e8589f Fix combat loop: blacklist entities for 30s after engagement
The core problem: attacks don't deal damage (protocol issue), so
mobs never die. entityGone fires spuriously, combat "ends", then
the 2-second scan finds the same mob and re-engages endlessly.

Fix: after combat ends for ANY reason, the entity ID is blacklisted
for 30 seconds. The scan loop skips blacklisted entities. This
prevents the infinite re-engage loop.

The underlying damage issue still needs investigation, but at least
Doug won't get stuck in an endless combat loop anymore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:36:05 -05:00
9869181071 Fuzzy item matching + periodic inventory check for auto-equip
- equipBestWeapon uses fuzzy substring matching on item names
- equipBestArmor uses .includes() instead of .startsWith() for tiers
- Both strip minecraft: prefix before comparing
- Added periodic inventory check every 5 seconds (playerCollect
  doesn't fire on Bedrock) — detects new items and auto-equips
- evaluateEquipment logs full inventory contents for debugging
- All name comparisons are case-insensitive

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:22:08 -05:00
aa0a937171 CORE REFLEX: Auto-combat and auto-equip baked into bridge
Architecture change — 3 layers:
  CORE (bridge): Combat + equipment evaluation — ALWAYS runs, interrupts everything
  PRIMARY (brain): Player-given or self-directed goals
  SUBTASK (brain): Steps within primary tasks

Core reflexes in bridge (run independently of Python brain):
- Auto-combat: scans for hostiles every 2s, engages nearest
  - Equips best weapon before fighting
  - Chases target, attacks every 450ms
  - Detects death via entityGone event
  - 15s safety timeout per engagement
  - Sends combat_started/combat_ended events to Python

- Auto-equip: evaluates gear when items are picked up
  - Equips best weapon (netherite > diamond > iron > ...)
  - Equips best armor in each slot
  - Waits until combat ends before evaluating
  - Sends equipment_changed event to Python

Brain changes:
- Brain PAUSES all task execution during combat (waits for combat_ended)
- Brain no longer manages combat — only flee for cowardly Dougs (bravery < 30)
- Combat events logged: COMBAT: Fighting zombie, COMBAT: Ended (target_dead)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:12:56 -05:00
c4e1416f5f Fix item name matching: handle minecraft: prefix in inventory
- equip_item now tries: exact → stripped prefix → fuzzy substring match
- If item not found, error message lists actual inventory contents
- get_inventory strips minecraft: prefix from item names
- Fixes "diamond_sword not in inventory" when item exists as
  "minecraft:diamond_sword"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:42:56 -05:00
c2b996947a Fix combat loop, add equipment management
Combat:
- Track entityGone event to detect mob death (not just entity check)
- Auto-equip best weapon before fighting
- 10-second cooldown between engagements (was 5)
- Better target death detection

Equipment system:
- equipBestWeapon(): finds and equips highest-tier sword/axe
- equipBestTool(blockType): picks right tool for block (pickaxe for stone, etc.)
- equipBestArmor(): equips best armor in each slot
- Auto-equip armor when new armor pieces appear in inventory
- Weapon tiers: netherite > diamond > iron > golden > stone > wooden
- Tool type mapping: pickaxe for ores, axe for wood, shovel for dirt

New bridge actions: equip_best_weapon, equip_best_tool, equip_armor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:39:47 -05:00
413d18d997 Fix combat spam: don't stack interrupts, 5s cooldown after combat
- Don't create new combat/flee interrupt if one is already active
- 5-second cooldown after combat before re-engaging
- Prevents Doug from attacking dead mobs repeatedly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:34:38 -05:00
5297ac664a Fix: behaviors.py import Task → PrimaryTask for new task_queue
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:33:36 -05:00
1c8e2a7c90 Wire TaskStack into brain — tasks persist and resume
Brain rewritten to use TaskStack instead of TaskQueue:
- Combat/flee use interrupt() — temporary, don't affect the stack
- Player commands use push() — go on top, pause current task
- When task completes, previous task RESUMES automatically
- Self-directed goals push at SELF_DIRECTED priority (bottom)
- "follow me" is open_ended — stays active until cancelled or new command

Flow example:
  Doug exploring (self-directed)
  → Player says "follow me" → exploring paused, following starts
  → Zombie attacks → interrupt: fight → following resumes
  → Player says "stop" → following cancelled, exploring resumes

Command parser updated to create PrimaryTask objects via make_task()
All command tasks marked source="player" for priority handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:32:10 -05:00
61c4a919d2 Redesign: stack-based task system with subtasks and persistence
TaskStack replaces TaskQueue:
- Tasks are a STACK — new tasks push on top, completed tasks pop
- Interrupted tasks are PAUSED and RESUMED when the interrupt ends
- Combat/flee are temporary INTERRUPTIONS that don't affect the stack
- Each PrimaryTask has a list of SubTasks (sequential steps)
- Open-ended tasks ("explore together") stay active until cancelled
- Max stack depth of 5 — oldest self-directed tasks drop off
- Player commands always push as HIGH priority
- Self-directed goals sit at the bottom

Helper functions:
- make_task() — create single-step primary tasks
- make_interrupt() — create temporary combat/flee interrupts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:24:19 -05:00
e6d4c8d377 Add equip/inventory commands, report results without AI
New commands:
- "Doug, equip your sword" → equips item, reports "Equipped sword."
- "Doug, what do you have?" → lists actual inventory items
- "Doug, check your inventory" → same

Key change: command results now report DIRECTLY to chat without
going through AI. No more hallucinated responses about items
Doug doesn't have. Commands execute → report real result.

AI is ONLY used for conversation, not for task responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:18:41 -05:00
5a42c2b881 Fix: fight vs flee (bravery), goal cooldowns, stop AI lying
Combat:
- Brain now decides fight vs flee based on bravery trait
- Bravery > 30 + health > 8 + mob within 6 blocks = FIGHT
- Otherwise flee. Combat tasks are non-interruptible.

Goals:
- 30-second cooldown after completing a goal before it can respawn
- Prevents "check out something interesting" loop

AI Prompt:
- STRICT rules against inventing items/builds/contraptions
- "You have NOTHING unless told otherwise"
- Must use ONLY the context provided for current activity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:13:55 -05:00
48d968a9d7 FIX COMBAT: swing_source='attack' required for damage registration
The Bedrock server requires the animate packet to have
has_swing_source=true and swing_source='attack' for the
inventory_transaction attack to actually deal damage.

Without this, the server accepts the packets silently but
never registers the hit. This was discovered by monitoring
what a real client sends vs what our bot sends.

Confirmed: skeleton took damage 20 → 19 → 18 → 17 HP

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:05:57 -05:00
195ef2d860 Major overhaul: combat fix, smart brain, Ollama stability, crafting
COMBAT:
- Fixed attack serialization: proper heldItemToNotch() for empty hand
- Attack now looks at target before swinging (server validates aim)
- Player position includes eye height in attack packet
- Click position calculated relative to target entity

INTELLIGENCE (complete rewrite):
- NeedsSystem: Sims-like needs (safety, hunger, social, shelter, boredom)
  that decay over time and drive behavior priorities
- GoalManager: Long-term goals broken into steps (gather_wood,
  explore_area, find_food, check_container, go_home)
- SpatialMemory: Remembers locations of containers, crafting tables,
  interesting blocks, and home position
- DailyRoutine: Morning/day/evening/night phases with trait-influenced
  activity selection
- Brain now WAITS for tasks to complete instead of piling on new ones
- Goal-based decision making replaces random wander

OLLAMA:
- Pre-warm model on deploy (loads into GPU before first chat)
- Keep-alive pings every 2 minutes (prevents model unload)
- Adaptive timeouts: 60s cold, 15s warm, 90s retry
- Auto-retry on timeout failure

CRAFTING:
- Quantity parsing ("craft 5 sticks", "craft a wooden pickaxe")
- Number words supported ("craft three planks")
- Smarter item name extraction with preposition stopping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:07:23 -05:00
7199acf149 Fix attack crash: provide empty item when hand is empty
The inventory_transaction packet for attacks includes held_item.
When Doug has nothing in his hand, bot.heldItem is null, causing
"Cannot read properties of null (reading 'network_id')".

Fix: provide a proper empty item object with network_id=0 when
heldItem is null. Attacks now send successfully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 15:14:19 -05:00
b60cc8a987 Add combat debug logging (gameMode, target id, distance)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:25:24 -05:00
513507e941 Smart crafting: walk to table, check materials, report results
Bridge craft_item now:
- Fuzzy-matches item names (wooden_pickaxe, wood_pickaxe, etc.)
- Searches for crafting table within 32 blocks
- Walks to crafting table if found but not close enough
- Checks if materials are available
- Reports specific failure reasons to chat:
  "I need a crafting table" / "I don't have the materials"
- Reports success: "Done! Crafted 1 wooden pickaxe."

Brain now:
- Reports craft success/failure to in-game chat
- Reports any HIGH priority task failure to chat
- Handles craft_item as async (waits for pathfinding + crafting)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:53:48 -05:00
813f8704bb Smarter craft command parsing — stops at prepositions
- Craft regex captures full text, then parser extracts item name
- Strips filler words (a, an, some, the)
- Stops at prepositions (with, from, using, in, for)
- Takes max 3 words for item name
- "craft sticks with wood" → "sticks"
- "craft a wooden pickaxe" → "wooden_pickaxe"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:47:52 -05:00
09464043bf Fix: task executes before response, craft parses single word
- Commands now get a quick "On it" / "Got it" acknowledgment
- No AI call before task runs — Doug does the task FIRST
- Craft regex captures single word only ("sticks" not "sticks with")

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:37:53 -05:00
9c7ae89dd2 Fix craft parsing, sustained combat, combat cooldown
- Craft regex now captures only 1-2 words (not entire sentence)
- Mine regex same fix
- Combat is now sustained: bridge keeps attacking every 500ms until
  target dies, leaves range, or 10s timeout
- Combat has 12-second cooldown to prevent spam
- Bot chases target if too far for melee during combat

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:34:34 -05:00
3832094a5c Remove old behaviors package dir conflicting with behaviors.py
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:26:13 -05:00
be4476ce4d Phase 3b: Command parsing, AI context, player instructions
- CommandParser: regex-based parsing for follow, stop, go, chest,
  craft, mine, give, attack, look commands
- Commands converted to high-priority tasks in the brain's queue
- AI prompt now includes real-time context: current action, health,
  nearby players, hostiles, time of day
- Doug answers "what are you doing?" truthfully based on actual state
- Player commands get personality-appropriate AI acknowledgments
- Brain's wants_ai_chat signal wired for unprompted chat

Supported commands:
  "Doug, follow me" → follow_player task
  "Doug, stop" → stop task
  "Doug, open that chest" → open_chest task
  "Doug, sort the chest" → sort_chest task
  "Doug, craft a pickaxe" → craft_item task
  "Doug, mine some stone" → find + dig task
  "Doug, attack that" → attack_nearest_hostile task

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:15:59 -05:00
b609d4c896 Phase 3: Task queue, behavior engine, trait-driven decisions
- TaskQueue with 6 priority levels (IDLE → CRITICAL)
- BehaviorEngine generates tasks based on persona traits:
  - Survival: flee (bravery-weighted), eat, seek shelter (anxiety)
  - Combat: attack hostiles (bravery threshold)
  - Social: follow players (sociability), approach for interaction
  - Exploration: read signs, check containers, wander (curiosity range)
  - Organization: inventory management (OCD quirk)
  - Idle: look around, unprompted chat (chatty_cathy)
- Brain rewritten to use scan → generate → execute loop
- New bridge actions: open_chest, close_container, transfer_item,
  scan_surroundings, find_blocks, attack_nearest_hostile,
  list_recipes, craft_item, use_block, drop_item
- Traits influence: flee distance, wander range, combat willingness,
  social approach frequency, container curiosity
- Brain passes persona traits from database to behavior engine
- Unprompted AI chat via wants_ai_chat signal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 12:48:15 -05:00
8f616598fd Fix chat, brain stability, MariaDB reconnect, suppress warnings
- Listen on raw 'text' packet for Bedrock chat (pattern-based chat event
  doesn't fire reliably on Bedrock)
- Brain: add safety reset for stuck pending_status flag
- MariaDB: add retry-on-disconnect for all query methods
- Suppress harmless punycode deprecation warning from Node.js
- Add mineflayer-bedrock lib packages (mineflayer, prismarine-chunk,
  prismarine-registry) for movement support
- Exclude minecraft-data from git (278MB, installed via npm)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 12:33:17 -05:00
d0a96ce028 Rebuild bridge on mineflayer-bedrock — real movement!
- Replace raw bedrock-protocol packets with mineflayer-bedrock
- Movement uses pathfinder (setGoal/GoalNear) — works on server-auth BDS
- No cheats, no OP, no teleports — Doug walks like a real player
- Bridge is now plain JS (no TypeScript) with Node 22
- Brain uses move_to with pathfinder instead of fake teleport steps
- Fix MariaDB connection timeout with auto-reconnect
- Tested: bot spawns and walks on vanilla BDS 1.26.11

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 11:56:56 -05:00
9aa0abbf59 Phase 1+2: Doug connects, chats, brain loop (movement WIP)
- Hybrid Python/Node.js architecture with WebSocket bridge
- PySide6 desktop app with smoky blue futuristic theme
- bedrock-protocol connection (offline + Xbox Live auth + Realms)
- Ollama integration with lean persona prompt
- 40 personality traits (15 sliders + 23 quirks + 2 toggles)
- Chat working in-game with personality
- Brain loop with decision engine
- Movement code (needs mineflayer-bedrock for proper server-auth)
- Entity tracking framework
- RakNet protocol 11 patch for newer BDS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:30:39 -05:00
13f5c84069 Phase 1 complete: Doug connects, chats with personality
- Hybrid Python/Node.js architecture with WebSocket bridge
- PySide6 desktop app with smoky blue futuristic theme
- Dashboard, Create Doug, Settings screens
- bedrock-protocol connection to BDS (offline + Xbox Live auth)
- Realm support (auth flow with device code + browser auto-open)
- Ollama integration with lean persona prompt (~95 tokens)
- 40 personality traits (15 sliders + 23 quirks + 2 toggles)
- SQLite + MariaDB database with 12 tables
- Chat working in-game with proper Bedrock text packet format
- RakNet protocol 11 patch for newer BDS versions
- jsp-raknet backend (native crashes on ARM64 macOS)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 02:03:25 -05:00