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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>