feat(engine): add faction system for social emergence

- Add Factions model (optimists/fearful/neutral)
- Implement classify_faction() based on stance thresholds
- Add update_factions() to track faction distribution
- Add apply_faction_influence() for faction→mood feedback
- Integrate faction system into tick flow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
empty
2025-12-30 11:03:52 +08:00
parent 554d37fd4c
commit 296e65ff95
4 changed files with 85 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ from .models import (
from .global_events import GLOBAL_EVENT_POOL, GlobalEvent
from .opinions import generate_opinions
from .social_influence import apply_social_influence
from .factions import update_factions, apply_faction_influence
MAX_EVENTS = 20
MAX_MEMORY_PER_AGENT = 3
@@ -90,6 +91,12 @@ def process_events(state: WorldState, events: List[Event]) -> WorldState:
# 应用社交影响
apply_social_influence(state)
# 更新派系分布
update_factions(state)
# 派系影响世界情绪
apply_faction_influence(state)
return state
@@ -126,6 +133,12 @@ def check_and_trigger_global_event(
# 应用社交影响
apply_social_influence(state)
# 更新派系分布
update_factions(state)
# 派系影响世界情绪
apply_faction_influence(state)
result = GlobalEventResult(
triggered=True,
event=global_event.to_info()

View File

@@ -0,0 +1,40 @@
"""派系系统 - 基于立场分类角色并影响世界"""
from typing import Dict
from .models import WorldState, AgentState, Factions
# 派系分类阈值
OPTIMIST_THRESHOLD = 0.6
FEARFUL_THRESHOLD = 0.6
def classify_faction(agent: AgentState) -> str:
"""根据 stance 分类角色所属派系"""
if agent.stance.optimism > OPTIMIST_THRESHOLD:
return "optimists"
elif agent.stance.fear > FEARFUL_THRESHOLD:
return "fearful"
else:
return "neutral"
def update_factions(state: WorldState) -> None:
"""统计各派系人数并更新 world_state"""
counts = {"optimists": 0, "fearful": 0, "neutral": 0}
for agent in state.agents.values():
faction = classify_faction(agent)
counts[faction] += 1
state.factions = Factions(**counts)
def apply_faction_influence(state: WorldState) -> None:
"""派系分布影响世界情绪"""
optimists = state.factions.optimists
fearful = state.factions.fearful
if optimists > fearful:
state.town_mood = min(10, state.town_mood + 1)
elif fearful > optimists:
state.town_mood = max(-10, state.town_mood - 1)
# 平局时不变化

View File

@@ -44,6 +44,13 @@ class Stance(BaseModel):
fear: float = Field(default=0.5, ge=0.0, le=1.0)
class Factions(BaseModel):
"""派系分布"""
optimists: int = 0
fearful: int = 0
neutral: int = 0
class AgentState(BaseModel):
emotion: Emotion = Emotion.CALM
goal: str = ""
@@ -63,6 +70,7 @@ class WorldState(BaseModel):
events: List[str] = Field(default_factory=list)
global_meter: GlobalMeter = Field(default_factory=GlobalMeter)
world_effects: List[WorldEffect] = Field(default_factory=list)
factions: Factions = Field(default_factory=Factions)
class Event(BaseModel):