Add player actions to world core

This commit is contained in:
lpf
2026-03-16 12:04:55 +08:00
parent d9671892f3
commit 5bce2cfdef
7 changed files with 267 additions and 73 deletions

View File

@@ -27,6 +27,12 @@ func (e *Engine) EnsureWorld(state *WorldState) {
if state.Locations == nil || len(state.Locations) == 0 {
state.Locations = DefaultWorldState().Locations
}
if strings.TrimSpace(state.Player.PlayerID) == "" {
state.Player = DefaultWorldState().Player
}
if strings.TrimSpace(state.Player.CurrentLocation) == "" {
state.Player.CurrentLocation = "commons"
}
if state.GlobalFacts == nil {
state.GlobalFacts = map[string]interface{}{}
}
@@ -81,14 +87,15 @@ func (e *Engine) NextTick(state *WorldState) int64 {
return state.Clock.Tick
}
func (e *Engine) BuildUserEvent(state *WorldState, input, locationID string) WorldEvent {
func (e *Engine) BuildUserEvent(state *WorldState, input, locationID, actorID string) WorldEvent {
e.EnsureWorld(state)
locationID = firstNonEmpty(locationID, "commons")
actorID = firstNonEmpty(actorID, "user")
return WorldEvent{
ID: fmt.Sprintf("evt-user-%d", time.Now().UnixNano()),
Type: "user_input",
Source: "user",
ActorID: "user",
ActorID: actorID,
LocationID: locationID,
Content: strings.TrimSpace(input),
Tick: state.Clock.Tick,
@@ -367,6 +374,7 @@ func (e *Engine) Snapshot(state WorldState, npcStates map[string]NPCState, recen
WorldID: state.WorldID,
Tick: state.Clock.Tick,
SimTimeUnix: state.Clock.SimTimeUnix,
Player: state.Player,
Locations: state.Locations,
NPCCount: len(npcStates),
ActiveNPCs: active,

View File

@@ -44,6 +44,12 @@ func DefaultWorldState() WorldState {
LastAdvance: now,
TickDuration: 30,
},
Player: PlayerState{
PlayerID: "player",
DisplayName: "Player",
CurrentLocation: "commons",
Status: "active",
},
Locations: map[string]Location{
"commons": {
ID: "commons",
@@ -89,6 +95,12 @@ func (s *Store) LoadWorldState() (WorldState, error) {
if state.Locations == nil {
state.Locations = DefaultWorldState().Locations
}
if strings.TrimSpace(state.Player.PlayerID) == "" {
state.Player = DefaultWorldState().Player
}
if strings.TrimSpace(state.Player.CurrentLocation) == "" {
state.Player.CurrentLocation = "commons"
}
if state.GlobalFacts == nil {
state.GlobalFacts = map[string]interface{}{}
}

View File

@@ -47,6 +47,7 @@ type WorldEvent struct {
type WorldState struct {
WorldID string `json:"world_id"`
Clock Clock `json:"clock"`
Player PlayerState `json:"player"`
Locations map[string]Location `json:"locations,omitempty"`
GlobalFacts map[string]interface{} `json:"global_facts,omitempty"`
Entities map[string]Entity `json:"entities,omitempty"`
@@ -54,6 +55,14 @@ type WorldState struct {
RecentEvents []WorldEvent `json:"recent_events,omitempty"`
}
type PlayerState struct {
PlayerID string `json:"player_id"`
DisplayName string `json:"display_name,omitempty"`
CurrentLocation string `json:"current_location,omitempty"`
Status string `json:"status,omitempty"`
LastActionTick int64 `json:"last_action_tick,omitempty"`
}
type GoalSet struct {
ShortTerm []string `json:"short_term,omitempty"`
LongTerm []string `json:"long_term,omitempty"`
@@ -112,6 +121,7 @@ type WorldDelta struct {
type WorldTickRequest struct {
Source string `json:"source,omitempty"`
ActorID string `json:"actor_id,omitempty"`
UserInput string `json:"user_input,omitempty"`
LocationID string `json:"location_id,omitempty"`
CatchUpTicks int `json:"catch_up_ticks,omitempty"`
@@ -130,6 +140,7 @@ type SnapshotSummary struct {
WorldID string `json:"world_id,omitempty"`
Tick int64 `json:"tick,omitempty"`
SimTimeUnix int64 `json:"sim_time_unix,omitempty"`
Player PlayerState `json:"player,omitempty"`
Locations map[string]Location `json:"locations,omitempty"`
NPCCount int `json:"npc_count,omitempty"`
ActiveNPCs []string `json:"active_npcs,omitempty"`