diff options
| author | historia <[not public]> | 2026-07-09 05:27:10 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-09 05:27:10 -0400 |
| commit | c705ae942573984784ef501bf8198f61f5206ddd (patch) | |
| tree | c964066f3a244002bf75cb50a877630f46496f81 /internal/world | |
| parent | 74153c7814fc4cef988066ef04e38731a943bc12 (diff) | |
| download | thehouseoficarus-c705ae942573984784ef501bf8198f61f5206ddd.tar.gz | |
refactor: simplify yaml, remove support for old scalar fields
Diffstat (limited to 'internal/world')
| -rw-r--r-- | internal/world/grid_test.go | 38 | ||||
| -rw-r--r-- | internal/world/insert_remove_test.go | 68 | ||||
| -rw-r--r-- | internal/world/mob.go | 2 | ||||
| -rw-r--r-- | internal/world/room.go | 26 | ||||
| -rw-r--r-- | internal/world/room_test.go | 9 | ||||
| -rw-r--r-- | internal/world/trigger.go | 4 | ||||
| -rw-r--r-- | internal/world/trigger_store.go | 24 |
7 files changed, 62 insertions, 109 deletions
diff --git a/internal/world/grid_test.go b/internal/world/grid_test.go index c777f90..005f60f 100644 --- a/internal/world/grid_test.go +++ b/internal/world/grid_test.go @@ -39,9 +39,9 @@ func hasConflictKind(conflicts []GridConflict, kind string) bool { func TestBuildGridConflictsClean(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n south: 3\n east: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n south: 4\n") - writeGridTestRoom(t, dir, 3, "exits:\n east: 4\n") + writeGridTestRoom(t, dir, 1, "exits:\n south: {room: 3}\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n south: {room: 4}\n") + writeGridTestRoom(t, dir, 3, "exits:\n east: {room: 4}\n") writeGridTestRoom(t, dir, 4, "name: corner\n") w := New(dir) @@ -52,9 +52,9 @@ func TestBuildGridConflictsClean(t *testing.T) { func TestBuildGridConflictsOverlap(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n south: 3\n east: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n south: 5\n") - writeGridTestRoom(t, dir, 3, "exits:\n east: 4\n") + writeGridTestRoom(t, dir, 1, "exits:\n south: {room: 3}\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n south: {room: 5}\n") + writeGridTestRoom(t, dir, 3, "exits:\n east: {room: 4}\n") writeGridTestRoom(t, dir, 4, "name: four\n") writeGridTestRoom(t, dir, 5, "name: five\n") @@ -67,9 +67,9 @@ func TestBuildGridConflictsOverlap(t *testing.T) { func TestBuildGridConflictsTwist(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n south: 4\n east: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n east: 3\n") - writeGridTestRoom(t, dir, 4, "exits:\n east: 3\n") + writeGridTestRoom(t, dir, 1, "exits:\n south: {room: 4}\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n east: {room: 3}\n") + writeGridTestRoom(t, dir, 4, "exits:\n east: {room: 3}\n") writeGridTestRoom(t, dir, 3, "name: three\n") w := New(dir) @@ -81,8 +81,8 @@ func TestBuildGridConflictsTwist(t *testing.T) { func TestBuildGridConflictsDiagonalClean(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n northeast: 2\n") - writeGridTestRoom(t, dir, 2, "name: two\n exits:\n southwest: 1\n") + writeGridTestRoom(t, dir, 1, "exits:\n northeast: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "name: two\n exits:\n southwest: {room: 1}\n") w := New(dir) if conflicts := BuildGridConflicts(1, loadGridRoom(w)); len(conflicts) != 0 { @@ -97,8 +97,8 @@ func TestBuildGridConflictsDiagonalClean(t *testing.T) { // confirm the (clean) post-edit world has no conflicts. func TestBuildGridConflictsHypotheticalInsert(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "name: one\nexits:\n east: 2\n") - writeGridTestRoom(t, dir, 2, "name: two\nexits:\n west: 1\n") + writeGridTestRoom(t, dir, 1, "name: one\nexits:\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "name: two\nexits:\n west: {room: 1}\n") w := New(dir) newRoom := &Room{Name: "new", Exits: map[ExitDir]ExitDef{ @@ -145,12 +145,12 @@ func TestBuildGridConflictsHypotheticalInsert(t *testing.T) { // (1,1,0). The helper must report an overlap without anything being written. func TestBuildGridConflictsHypotheticalRemoveOverlap(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n south: 4\n") - writeGridTestRoom(t, dir, 2, "exits:\n east: 3\n west: 1\n") - writeGridTestRoom(t, dir, 3, "exits:\n south: 6\n west: 2\n") - writeGridTestRoom(t, dir, 4, "exits:\n east: 5\n north: 1\n") - writeGridTestRoom(t, dir, 5, "exits:\n west: 4\n") - writeGridTestRoom(t, dir, 6, "exits:\n north: 3\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n south: {room: 4}\n") + writeGridTestRoom(t, dir, 2, "exits:\n east: {room: 3}\n west: {room: 1}\n") + writeGridTestRoom(t, dir, 3, "exits:\n south: {room: 6}\n west: {room: 2}\n") + writeGridTestRoom(t, dir, 4, "exits:\n east: {room: 5}\n north: {room: 1}\n") + writeGridTestRoom(t, dir, 5, "exits:\n west: {room: 4}\n") + writeGridTestRoom(t, dir, 6, "exits:\n north: {room: 3}\n") w := New(dir) load := func(id int) (*Room, bool) { diff --git a/internal/world/insert_remove_test.go b/internal/world/insert_remove_test.go index 3be3222..15d752e 100644 --- a/internal/world/insert_remove_test.go +++ b/internal/world/insert_remove_test.go @@ -9,8 +9,8 @@ const insertSentinel = 9999 func TestInsertGridConflictsCleanNSEW(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n west: 1\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n west: {room: 1}\n") w := New(dir) if c := InsertGridConflicts(1, East, 2, insertSentinel, loadGridRoom(w)); len(c) != 0 { t.Errorf("clean east insert: expected no conflicts, got %+v", c) @@ -19,8 +19,8 @@ func TestInsertGridConflictsCleanNSEW(t *testing.T) { func TestInsertGridConflictsCleanDiagonal(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n northeast: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n southwest: 1\n") + writeGridTestRoom(t, dir, 1, "exits:\n northeast: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n southwest: {room: 1}\n") w := New(dir) if c := InsertGridConflicts(1, Northeast, 2, insertSentinel, loadGridRoom(w)); len(c) != 0 { t.Errorf("clean NE insert: expected no conflicts, got %+v", c) @@ -29,8 +29,8 @@ func TestInsertGridConflictsCleanDiagonal(t *testing.T) { func TestInsertGridConflictsCleanUpDown(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n up: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n down: 1\n") + writeGridTestRoom(t, dir, 1, "exits:\n up: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n down: {room: 1}\n") w := New(dir) if c := InsertGridConflicts(1, Up, 2, insertSentinel, loadGridRoom(w)); len(c) != 0 { t.Errorf("clean up insert: expected no conflicts, got %+v", c) @@ -73,14 +73,14 @@ func TestInsertGridConflictsCleanUpDown(t *testing.T) { // beyond-set (reachable from 1 via south, not via east/2), so it's an overlap. func TestInsertGridConflictsOverlap(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n south: 4\n") - writeGridTestRoom(t, dir, 2, "exits:\n east: 3\n west: 1\n") - writeGridTestRoom(t, dir, 3, "exits:\n west: 2\n") - writeGridTestRoom(t, dir, 4, "exits:\n east: 5\n north: 1\n") - writeGridTestRoom(t, dir, 5, "exits:\n east: 6\n west: 4\n") - writeGridTestRoom(t, dir, 6, "exits:\n east: 7\n west: 5\n") - writeGridTestRoom(t, dir, 7, "exits:\n north: 8\n west: 6\n") - writeGridTestRoom(t, dir, 8, "exits:\n south: 7\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n south: {room: 4}\n") + writeGridTestRoom(t, dir, 2, "exits:\n east: {room: 3}\n west: {room: 1}\n") + writeGridTestRoom(t, dir, 3, "exits:\n west: {room: 2}\n") + writeGridTestRoom(t, dir, 4, "exits:\n east: {room: 5}\n north: {room: 1}\n") + writeGridTestRoom(t, dir, 5, "exits:\n east: {room: 6}\n west: {room: 4}\n") + writeGridTestRoom(t, dir, 6, "exits:\n east: {room: 7}\n west: {room: 5}\n") + writeGridTestRoom(t, dir, 7, "exits:\n north: {room: 8}\n west: {room: 6}\n") + writeGridTestRoom(t, dir, 8, "exits:\n south: {room: 7}\n") w := New(dir) // Sanity: the pre-edit world must be clean. @@ -101,11 +101,11 @@ func TestInsertGridConflictsOverlap(t *testing.T) { // insert helper must surface a twist conflict. func TestInsertGridConflictsTwist(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n south: 4\n") - writeGridTestRoom(t, dir, 2, "exits:\n east: 3\n west: 1\n") - writeGridTestRoom(t, dir, 3, "exits:\n west: 2\n south: 5\n") - writeGridTestRoom(t, dir, 4, "exits:\n east: 5\n north: 1\n") - writeGridTestRoom(t, dir, 5, "exits:\n north: 3\n west: 4\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n south: {room: 4}\n") + writeGridTestRoom(t, dir, 2, "exits:\n east: {room: 3}\n west: {room: 1}\n") + writeGridTestRoom(t, dir, 3, "exits:\n west: {room: 2}\n south: {room: 5}\n") + writeGridTestRoom(t, dir, 4, "exits:\n east: {room: 5}\n north: {room: 1}\n") + writeGridTestRoom(t, dir, 5, "exits:\n north: {room: 3}\n west: {room: 4}\n") w := New(dir) c := InsertGridConflicts(1, East, 2, insertSentinel, loadGridRoom(w)) @@ -120,7 +120,7 @@ func TestInsertGridConflictsTwist(t *testing.T) { // geometrically clean insert. func TestInsertGridConflictsOneWayFarReciprocal(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n") writeGridTestRoom(t, dir, 2, "exits:\n") // no west exit back to 1 w := New(dir) if c := InsertGridConflicts(1, East, 2, insertSentinel, loadGridRoom(w)); len(c) != 0 { @@ -131,9 +131,9 @@ func TestInsertGridConflictsOneWayFarReciprocal(t *testing.T) { func TestRemoveGridConflictsCleanPull(t *testing.T) { dir := t.TempDir() // 1 east→2 east→3, with reciprocals. Removing 2 pulls 3 to (1,0,0). Clean. - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n east: 3\n west: 1\n") - writeGridTestRoom(t, dir, 3, "exits:\n west: 2\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n east: {room: 3}\n west: {room: 1}\n") + writeGridTestRoom(t, dir, 3, "exits:\n west: {room: 2}\n") w := New(dir) if c := RemoveGridConflicts(1, East, loadGridRoom(w)); len(c) != 0 { t.Errorf("clean pull should produce no conflicts, got %+v", c) @@ -142,9 +142,9 @@ func TestRemoveGridConflictsCleanPull(t *testing.T) { func TestRemoveGridConflictsDiagonalPull(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n northeast: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n northeast: 3\n southwest: 1\n") - writeGridTestRoom(t, dir, 3, "exits:\n southwest: 2\n") + writeGridTestRoom(t, dir, 1, "exits:\n northeast: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n northeast: {room: 3}\n southwest: {room: 1}\n") + writeGridTestRoom(t, dir, 3, "exits:\n southwest: {room: 2}\n") w := New(dir) if c := RemoveGridConflicts(1, Northeast, loadGridRoom(w)); len(c) != 0 { t.Errorf("clean diagonal pull should produce no conflicts, got %+v", c) @@ -155,12 +155,12 @@ func TestRemoveGridConflictsDiagonalPull(t *testing.T) { // removing 2 pulls 6 onto 5's cell. func TestRemoveGridConflictsOverlap(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n south: 4\n") - writeGridTestRoom(t, dir, 2, "exits:\n east: 3\n west: 1\n") - writeGridTestRoom(t, dir, 3, "exits:\n south: 6\n west: 2\n") - writeGridTestRoom(t, dir, 4, "exits:\n east: 5\n north: 1\n") - writeGridTestRoom(t, dir, 5, "exits:\n west: 4\n") - writeGridTestRoom(t, dir, 6, "exits:\n north: 3\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n south: {room: 4}\n") + writeGridTestRoom(t, dir, 2, "exits:\n east: {room: 3}\n west: {room: 1}\n") + writeGridTestRoom(t, dir, 3, "exits:\n south: {room: 6}\n west: {room: 2}\n") + writeGridTestRoom(t, dir, 4, "exits:\n east: {room: 5}\n north: {room: 1}\n") + writeGridTestRoom(t, dir, 5, "exits:\n west: {room: 4}\n") + writeGridTestRoom(t, dir, 6, "exits:\n north: {room: 3}\n") w := New(dir) if c := BuildGridConflicts(1, loadGridRoom(w)); len(c) != 0 { @@ -177,8 +177,8 @@ func TestRemoveGridConflictsOverlap(t *testing.T) { // world this cannot introduce a conflict. func TestRemoveGridConflictsDeadEnd(t *testing.T) { dir := t.TempDir() - writeGridTestRoom(t, dir, 1, "exits:\n east: 2\n") - writeGridTestRoom(t, dir, 2, "exits:\n west: 1\n") + writeGridTestRoom(t, dir, 1, "exits:\n east: {room: 2}\n") + writeGridTestRoom(t, dir, 2, "exits:\n west: {room: 1}\n") w := New(dir) if c := RemoveGridConflicts(1, East, loadGridRoom(w)); len(c) != 0 { t.Errorf("dead-end removal should produce no conflicts, got %+v", c) diff --git a/internal/world/mob.go b/internal/world/mob.go index a9e2f7e..45b0fb8 100644 --- a/internal/world/mob.go +++ b/internal/world/mob.go @@ -645,7 +645,7 @@ func (s *MobStore) RollIdleDescription(inst *MobInstance) { inst.WanderTickCounter = 0 } -func (s *MobStore) SpawnTransient(def *MobDef, cfg *SpawnMobConfig, roomID int, owner string) *MobInstance { +func (s *MobStore) SpawnTransient(def *MobDef, cfg *behavior.SpawnMobConfig, roomID int, owner string) *MobInstance { s.mu.Lock() defer s.mu.Unlock() diff --git a/internal/world/room.go b/internal/world/room.go index 08e18a4..8ae2d13 100644 --- a/internal/world/room.go +++ b/internal/world/room.go @@ -83,19 +83,6 @@ type ExitDef struct { AlwaysBlocked bool `yaml:"always_blocked,omitempty"` } -func (e *ExitDef) UnmarshalYAML(value *yaml.Node) error { - if value.Kind == yaml.ScalarNode { - var n int - if err := value.Decode(&n); err != nil { - return err - } - e.Room = n - return nil - } - type raw ExitDef - return value.Decode((*raw)(e)) -} - type Room struct { ID int `yaml:"id"` Name string `yaml:"name"` @@ -117,19 +104,6 @@ type RoomMob struct { WanderInterval float64 `yaml:"wander_interval,omitempty"` } -func (rm *RoomMob) UnmarshalYAML(value *yaml.Node) error { - if value.Kind == yaml.ScalarNode { - var s string - if err := value.Decode(&s); err != nil { - return err - } - rm.ID = s - return nil - } - type raw RoomMob - return value.Decode((*raw)(rm)) -} - // RoomObject is either a reference to a file-backed object definition (only // `id`/wander fields set) or a fully local object definition (Local != nil). // An entry is treated as local when it carries any passive content field diff --git a/internal/world/room_test.go b/internal/world/room_test.go index 1ad974e..855eba5 100644 --- a/internal/world/room_test.go +++ b/internal/world/room_test.go @@ -27,11 +27,13 @@ objects: - id: workbench - name: window hidden: true - description: "A small window." + description: + - text: "A small window." - id: control name: instrument panel aliases: [cockpit] - description: "A panel." + description: + - text: "A panel." ` // rebuild the path index so LoadRoom can find the room file writeRoom(t, dir, body) @@ -98,7 +100,8 @@ func TestExitDefUnmarshalAlwaysBlocked(t *testing.T) { north: room: 5 always_blocked: true - south: 3 + south: + room: 3 east: room: 7 hidden: true diff --git a/internal/world/trigger.go b/internal/world/trigger.go index e7f3b75..de07c18 100644 --- a/internal/world/trigger.go +++ b/internal/world/trigger.go @@ -2,10 +2,6 @@ package world import "thehouseoficarus/internal/behavior" -// SpawnMobConfig is an alias for the behavior.SpawnMobConfig so callers that -// historically referenced world.SpawnMobConfig continue to compile. -type SpawnMobConfig = behavior.SpawnMobConfig - type TriggerDef struct { ID string `yaml:"id"` OnPlayerFlag string `yaml:"on_player_flag"` diff --git a/internal/world/trigger_store.go b/internal/world/trigger_store.go index 04d77f4..e50ae81 100644 --- a/internal/world/trigger_store.go +++ b/internal/world/trigger_store.go @@ -9,6 +9,7 @@ import ( "gopkg.in/yaml.v3" "thehouseoficarus/internal/behavior" + "thehouseoficarus/internal/engine" ) type TriggerStore struct { @@ -262,7 +263,7 @@ func (ts *TriggerStore) valueMatches(want, got any) bool { if want == nil { return true } - return valuesEqual(want, got) + return engine.ValuesEqual(want, got) } func (ts *TriggerStore) SnapshotPlayerSeqs() []*PlayerTriggerSeq { @@ -311,27 +312,6 @@ func (ts *TriggerStore) AllGlobalTriggers() []*TriggerDef { return out } -func valuesEqual(a, b any) bool { - ai, aok := numericValue(a) - bi, bok := numericValue(b) - if aok && bok { - return ai == bi - } - return a == b -} - -func numericValue(v any) (float64, bool) { - switch x := v.(type) { - case int: - return float64(x), true - case int64: - return float64(x), true - case float64: - return x, true - } - return 0, false -} - func (ts *TriggerStore) AllRoomTriggers() map[int][]*TriggerDef { ts.mu.Lock() defer ts.mu.Unlock() |
