Hogwarts_SBox_AI-RPG / systems /alignment_system.py
cereeenn120's picture
Refactor llm and game engine integration
afc984a
Raw History Blame Contribute Delete
5.33 kB
import logging
from game.logging_config import event, get_logger
from game.model_config import (
get_background_model, # ← Arka plan görevi için hızlı modeli al
)
logger = get_logger("alignment")
# ----------------------------
# ALIGNMENT SYSTEM
# Single background API call returning 4 integer shifts.
# ----------------------------
def evaluate_alignment(client, user_input, last_context=""):
"""
Evaluates the player action and returns four integer shift values in one API call:
ld_shift : Light/Dark (-5 to +5)
oc_shift : Order/Chaos (-5 to +5)
not_shift : Trouble Level (-5 to +5)
rep_shift : Reputation (-5 to +5)
Model choice is always the fast background model from model_config.
"""
model_name = get_background_model()
event(logger, logging.DEBUG, "alignment.scoring_started", model=model_name, action=user_input)
eval_prompt = f"""You are scoring player actions in a Harry Potter school RPG.
Story context: "{last_context[-200:]}"
Player action: "{user_input}"
Return EXACTLY 4 integers separated by commas. No other text.
AXIS 1 — Light/Dark (-5 to +5):
+score: compassion, helping others, healing spells, self-sacrifice
-score: cruelty, Unforgivable Curses, deliberate bullying, harming someone
0: everything else
AXIS 2 — Order/Chaos (-5 to +5):
+score: ONLY IF the player explicitly obeys a direct teacher order, performs prefect duty, or reports a rule-breaker to authority
-score: ONLY IF the player explicitly does one of these specific acts: sneaks out AFTER CURFEW, physically enters the Restricted Section, lies directly to a professor's face, cheats on an exam, or casts a forbidden spell in class
0: ALL other actions — following an NPC, exploring hallways during the day, having conversations, attending class, looking around, creating a small distraction, choosing a story option, going somewhere
AXIS 3 — Trouble Level (-5 to +5):
+score: being caught breaking a rule, causing loud public disruption, casting forbidden magic where witnesses are present
-score: using an Invisibility Cloak, actively hiding from authority, magically silencing footsteps
0: everything else
AXIS 4 — Reputation / Social Standing (-5 to +5):
Reputation tracks what OTHER PEOPLE observe and judge — not inner morality, but public perception.
+score: visible acts of kindness (others watching), standing up to a bully publicly,
saving someone in front of others, winning a public duel with good sportsmanship,
helping a struggling classmate in a shared space
-score: being caught breaking rules where others see, insulting classmates or teachers openly,
cheating visibly, spreading rumours about someone, using dark magic where witnessed,
publicly humiliating another student
0: private actions without witnesses, studying alone, exploring quietly,
attending class normally, casting spells in solo practice
RULE: Most player actions score 0, 0, 0, 0. Only score non-zero when the action EXPLICITLY
and UNAMBIGUOUSLY matches the description. When in doubt → 0.
Axis 4 (Reputation) ONLY shifts when there is clear social visibility — someone present
can observe and judge. Private heroism = 0. Witnessed kindness = +score.
Examples:
"Follow the prefect down the corridor" → 0, 0, 0, 0
"Ask Hermione for advice on the map" → 0, 0, 0, 0
"Attend Potions class" → 0, 0, 0, 0
"Study quietly in the library" → 0, 0, 0, 0
"Help a crying first-year (hallway, others watching)"→ 2, 0, 0, 2
"Help a friend with homework (just the two of you)" → 1, 0, 0, 0
"Win a Quidditch match for your house" → 1, 0, 0, 3
"Sneak into Restricted Section at midnight" → 0, -3, 2, 0
"Restricted Section — Filch catches you" → 0, -3, 2, -2
"Lie to Professor Snape's face" → -1, -2, 1, -2
"Stand up to Malfoy bullying a first-year (crowd)" → 2, 0, 0, 3
"Cast Crucio on a Slytherin student (witnessed)" → -5, -4, 4, -5
"Spread a rumour about a Hufflepuff student" → -2, 0, 0, -3
"""
try:
# Arka planda hızlıca puanlama yapması için temperature=0 kullanıyoruz
response = client.chat.completions.create(
model=model_name,
messages=[{"role": "user", "content": eval_prompt}],
max_tokens=15,
temperature=0.0
)
result = response.choices[0].message.content.strip()
event(logger, logging.DEBUG, "alignment.scoring_raw", result=result)
parts = result.split(',')
ld_shift, oc_shift, not_shift, rep_shift = (max(-5, min(5, int(p.strip()))) for p in parts)
event(logger, logging.INFO, "alignment.scoring_completed", light_dark_shift=ld_shift, order_chaos_shift=oc_shift, trouble_shift=not_shift, reputation_shift=rep_shift)
return ld_shift, oc_shift, not_shift, rep_shift
except Exception as e:
logger.exception("alignment.scoring_failed reason=%r", str(e))
return 0, 0, 0, 0