Add monster HP tracking, separate from the game-ending logic
Only the player character's HP was tracked before, so a monster's death was never detected — only the DM's own (unenforced) narration of it. Add a new update_monster_hp tool the DM calls whenever an NPC/monster is introduced or takes damage, stored as DM-only bookkeeping on Game (never exposed via GameRead, since HP/AC of NPCs is meant to stay secret from players). The tool reports back "defeated": true once HP drops to 0 so the DM can react to it — but unlike a character dying, this does NOT auto-end the session; whether a monster's death should end the game is a separate decision left to the DM's own end_game call, or to a future rule. Building an isolated test for this caught a real bug along the way: the update mutated the matched monster's dict in place before reassigning the list, which made SQLAlchemy's old-vs-new JSONB comparison see identical content and silently skip writing the change. Fixed by building fresh dicts instead of mutating shared ones. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import ForeignKey, String, Text, UniqueConstraint, func
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.db import Base
|
||||
@@ -24,6 +24,9 @@ class Game(Base):
|
||||
)
|
||||
status: Mapped[str] = mapped_column(String(length=20), nullable=False, default="active")
|
||||
ended_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
# DM-only bookkeeping (name/current_hp/max_hp per monster) — never serialized to any
|
||||
# API response, since HP/AC of NPCs is meant to stay secret from players.
|
||||
monsters: Mapped[list] = mapped_column(JSONB, nullable=False, default=list)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
server_default=func.now(), nullable=False, index=True
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user