aboutsummaryrefslogtreecommitdiff
path: root/internal/world/room.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/world/room.go')
-rw-r--r--internal/world/room.go23
1 files changed, 23 insertions, 0 deletions
diff --git a/internal/world/room.go b/internal/world/room.go
index f4390da..3783a73 100644
--- a/internal/world/room.go
+++ b/internal/world/room.go
@@ -1,6 +1,7 @@
package world
import (
+ "fmt"
"strings"
"gopkg.in/yaml.v3"
@@ -122,6 +123,28 @@ type RoomObject struct {
}
func (ro *RoomObject) UnmarshalYAML(value *yaml.Node) error {
+ // yaml.v3's Node.Decode builds a fresh decoder that does NOT inherit
+ // KnownFields(true), so a misspelled key inside a room's objects: entry
+ // (inroom_description, onlook, ...) would be silently discarded even
+ // though the top-level room file is decoded strictly. Reject unknown
+ // keys here so the startup validator's "unknown field is an ERROR"
+ // guarantee extends to the region authors edit most.
+ if value.Kind != yaml.MappingNode {
+ return fmt.Errorf("room object must be a mapping")
+ }
+ allowed := map[string]bool{
+ "id": true, "wander_rooms": true, "wander_interval": true, "hidden": true,
+ "name": true, "aliases": true, "color": true, "inroom_description": true,
+ "removal_item": true, "description": true, "on_use": true, "steal": true,
+ "gather": true, "talk": true, "safespot": true, "on_look": true,
+ }
+ for i := 0; i+1 < len(value.Content); i += 2 {
+ key := value.Content[i].Value
+ if !allowed[key] {
+ return fmt.Errorf("unknown room object field %q", key)
+ }
+ }
+
type rawRef struct {
ID string `yaml:"id"`
WanderRooms []int `yaml:"wander_rooms"`