micro-rpg-engine / engine /engine.py
luizbarbedo's picture
Upload folder using huggingface_hub
7fe39f3 verified
Raw
History Blame Contribute Delete
2.53 kB
"""The turn loop.
GameEngine ties the pieces together:
player action ─▢ build prompt from GameState ─▢ model.chat() ─▢ parser
◀─ narrative + updated state β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
It also enforces a couple of rules the model should not be trusted with:
* if the model forgets to make a defeated enemy stop attacking, combat still ends
when enemy HP hits 0 (handled in the parser);
* a guaranteed enemy counter-attack option exists even if the model is lazy
(the engine never *adds* damage on its own β€” it only ever clamps).
"""
from __future__ import annotations
from .game_state import GameState
from .llm import Backend
from . import prompts, parser
class GameEngine:
def __init__(self, backend: Backend, state: GameState | None = None):
self.backend = backend
self.state = state or GameState()
self.history: list[parser.TurnResult] = []
# ------------------------------------------------------------------ public
def start(self) -> parser.TurnResult:
"""Generate the opening scene."""
user = prompts.build_opening_prompt(self.state.context_snapshot())
return self._turn(user)
def act(self, player_action: str) -> parser.TurnResult:
"""Process one player action."""
if self.state.game_over:
return parser.TurnResult(
narrative="Your tale has ended. Start a new adventure to play again.",
choices=[],
applied=[],
raw="",
)
action = player_action.strip() or "look around"
user = prompts.build_turn_prompt(self.state.context_snapshot(), action)
return self._turn(user)
def reset(self) -> "GameEngine":
self.state = GameState()
self.history.clear()
return self
# ----------------------------------------------------------------- internal
def _turn(self, user_message: str) -> parser.TurnResult:
try:
raw = self.backend.chat(prompts.SYSTEM_PROMPT, user_message)
except Exception as exc: # network/model errors shouldn't crash the UI
return parser.TurnResult(
narrative=f"(The mists swirl β€” the storyteller faltered: {exc})",
choices=["Try again."],
applied=[],
raw="",
)
result = parser.run_turn(self.state, raw)
self.history.append(result)
return result