;; Bot configuration: one JSON file, one suite identity, many rooms.
;; The merge semantics mirror bot.git's TS-era spreads exactly: shallow
;; top-level merge, one-level-deep merges for social/fleet/learning,
;; matchmaker under fleet, rooms replaced wholesale (and dropped unless an
;; array).
(ns __NAME__.config
(:require ["node:fs" :as fs]))
(def DEFAULTS
#js {:name "__NAME__"
:dataDir "/var/lib/ardegazu-__NAME__"
:origin "https://chat.ardegazu.ro"
:social #js {:enabled true :autoAcceptFriends true :autoJoinInvites true}
:fleet
#js {:siblings #js []
:matchmaker
#js {:enabled false
;; games the fleet self-plays — only games peer-kit ships a
;; host sim for can run in a bot-only room
:games #js []
:maxConcurrentSelfPlay 1
:cooldownMs 60000
:jitterMs 30000
:partners 4
:inviteTimeoutMs 60000
:matchTimeoutMs 900000
:maxHumanRoomsForSelfPlay 2
:inviteHumans 1
:humanInviteCooldownMs 2700000}}
:learning
#js {:modelDir "/var/lib/ardegazu-__NAME__/models"
:reloadMs 60000
:epsilonSelfPlay 0.1
:epsilonHuman 0.02}})
(defn load-config [path]
(let [^js raw (js/JSON.parse (fs/readFileSync path "utf8"))
^js out (js/Object.assign #js {} DEFAULTS raw)
^js raw-fleet (.-fleet raw)
^js def-fleet (.-fleet DEFAULTS)]
(set! (.-social out) (js/Object.assign #js {} (.-social DEFAULTS) (.-social raw)))
(set! (.-fleet out)
#js {:siblings (let [s (some-> raw-fleet .-siblings)] (if (some? s) s #js []))
:matchmaker (js/Object.assign #js {} (.-matchmaker def-fleet)
(some-> raw-fleet .-matchmaker))})
(set! (.-learning out) (js/Object.assign #js {} (.-learning DEFAULTS) (.-learning raw)))
(set! (.-rooms out) (if (js/Array.isArray (.-rooms raw)) (.-rooms raw) #js []))
out))