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>
This commit is contained in:
parent
48d968a9d7
commit
5a42c2b881
3 changed files with 37 additions and 8 deletions
|
|
@ -123,9 +123,12 @@ def build_system_prompt(
|
|||
custom,
|
||||
context_line,
|
||||
"",
|
||||
"Rules: Reply in ONE short sentence. Under 15 words. Talk like a normal person.",
|
||||
"If asked what you are doing, answer based on your current activity above.",
|
||||
"Plain text only. Do not start with your name.",
|
||||
"STRICT RULES:",
|
||||
"- ONE short sentence. Under 15 words.",
|
||||
"- NEVER invent things you have or did. You have NOTHING unless told otherwise.",
|
||||
"- NEVER mention items, builds, or contraptions unless the context says you have them.",
|
||||
"- If asked what you are doing, use ONLY the 'Right now' context above. If no context, say not much.",
|
||||
"- Plain text only. No name prefix.",
|
||||
]
|
||||
|
||||
return "\n".join(p for p in parts if p)
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ class GoalManager:
|
|||
self._age = age
|
||||
self._goals: list[dict] = []
|
||||
self._completed_goals: list[str] = [] # names of recently completed goals
|
||||
self._goal_cooldowns: dict[str, float] = {} # name → last completion time
|
||||
self._max_goals = 5 # Don't pile up too many goals
|
||||
|
||||
def has_any_goals(self) -> bool:
|
||||
|
|
@ -227,6 +228,10 @@ class GoalManager:
|
|||
"""Add a goal from templates."""
|
||||
if self.has_goal(name):
|
||||
return
|
||||
# Cooldown: don't re-add same goal within 30 seconds
|
||||
last_done = self._goal_cooldowns.get(name, 0)
|
||||
if time.time() - last_done < 30:
|
||||
return
|
||||
if len([g for g in self._goals if g["status"] == "active"]) >= self._max_goals:
|
||||
# Remove lowest priority active goal
|
||||
active = [g for g in self._goals if g["status"] == "active"]
|
||||
|
|
@ -311,6 +316,7 @@ class GoalManager:
|
|||
if g["name"] == name and g["status"] == "active":
|
||||
g["status"] = "complete"
|
||||
self._completed_goals.append(name)
|
||||
self._goal_cooldowns[name] = time.time()
|
||||
if len(self._completed_goals) > 20:
|
||||
self._completed_goals.pop(0)
|
||||
log.info(f"Goal complete: {g['description']}")
|
||||
|
|
|
|||
|
|
@ -297,15 +297,35 @@ class DougBrain(QObject):
|
|||
# ── Need-driven tasks ──
|
||||
|
||||
def _survival_task(self) -> Task | None:
|
||||
"""Handle immediate survival threats."""
|
||||
"""Handle immediate survival threats — fight or flee based on bravery."""
|
||||
b = self._behaviors
|
||||
bravery = b._traits.get("bravery", 50)
|
||||
|
||||
# Flee from nearby hostiles
|
||||
hostile = self._nearest_hostile(12)
|
||||
hostile = self._nearest_hostile(10)
|
||||
if hostile:
|
||||
dist = hostile.get("distance", 99)
|
||||
|
||||
# FIGHT if: brave enough AND health is ok AND mob is close
|
||||
should_fight = (
|
||||
bravery > 30
|
||||
and b.health > 8
|
||||
and dist < 6
|
||||
)
|
||||
|
||||
if should_fight:
|
||||
return Task(
|
||||
name="combat",
|
||||
priority=Priority.CRITICAL,
|
||||
action="attack_nearest_hostile",
|
||||
params={"range": 6},
|
||||
description=f"Fighting {hostile.get('type', 'mob')}!",
|
||||
timeout=12,
|
||||
interruptible=False,
|
||||
)
|
||||
else:
|
||||
return self._flee_task(hostile)
|
||||
|
||||
# Critical health with no hostiles — stay still and eat if possible
|
||||
# Critical health with no hostiles — eat if possible
|
||||
if b.health <= 6:
|
||||
food = self._find_food()
|
||||
if food:
|
||||
|
|
|
|||
Loading…
Reference in a new issue