2b2af058b8
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>
33 lines
768 B
Python
33 lines
768 B
Python
"""add game monsters (DM-only HP tracking)
|
|
|
|
Revision ID: d4b2c8a09e51
|
|
Revises: c9a1d5e7f316
|
|
Create Date: 2026-09-01 17:00:00.000000
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = 'd4b2c8a09e51'
|
|
down_revision: Union[str, None] = 'c9a1d5e7f316'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column(
|
|
'games',
|
|
sa.Column(
|
|
'monsters', postgresql.JSONB(astext_type=sa.Text()), nullable=False,
|
|
server_default='[]',
|
|
),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column('games', 'monsters')
|