dev / templates / bot / src / __NAME__ / behaviors.cljs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
;; Behaviors: what the bot does inside a room beyond showing up. The game
;; clients carry their own stock brains (steer, climb, wander, co-sign), so a
;; game behavior only adds flavor; chat and board behaviors are the whole act.
;;
;; THE TWO-STACK SEAM: this namespace is shared by __NAME__.main (stack A,
;; peer-kit) and __NAME__.worker (stack B, rooms-kit) and therefore requires
;; NEITHER kit — every client object arrives inside the ctx argument. That is
;; the CLJS replacement for the TS `import type`-only rule: a kit require here
;; would drag the other stack's native WebRTC build into the process and abort
;; it (ThreadSafeCallback cancellation).
;;
;; The REGISTRY ships EMPTY — wiring behaviors is stage §4 of
;; docs/NEW-BOT-PROMPT.md. Keys are "<kind>:<name>" with a "<kind>:default"
;; fallback per kind; ctx is #js {:kind "chat"|"board"|"game" …} carrying the
;; joined client, :nick and the room-tagged :log. Worked examples (adapt,
;; then register):
;;
;;   ;; chat echo — mind the replicated-history trap: react only to messages
;;   ;; written after boot, or the bot replays years of history at every join
;;   (defn- chat-echo [^js ctx]
;;     (when (identical? (.-kind ctx) "chat")
;;       (let [^js chat (.-chat ctx)
;;             self (.-self ctx)
;;             boot-ts (js/Date.now)]
;;         (.on chat "message"
;;              (fn [^js m]
;;                (let [text (.-text m)]
;;                  (when-not (or (<= (.-ts m) boot-ts)
;;                                (identical? (.-from m) self)
;;                                (not (and (some? text) (not (identical? text ""))))
;;                                (.startsWith ^js text "echo:"))
;;                    (-> (.send chat (str "echo: " text) (.-thread m))
;;                        (.catch (fn [_] nil))))))))))
;;
;;   ;; board writes must be idempotent (bots rejoin rooms constantly):
;;   ;; on "ready", check (.elements board) for your own mark before adding it
;;
;;   ;; game flavor — the client already plays its stock brain:
;;   ;;   (.on room "host" (fn [h] …))  (.on room "receipt" (fn [rec] …))
;;
;;   (def REGISTRY
;;     #js {"chat:echo" chat-echo
;;          "chat:default" chat-echo})
(ns __NAME__.behaviors)

(def REGISTRY #js {})

(defn attach-behavior [name ^js ctx]
  (let [b (or (unchecked-get REGISTRY (str (.-kind ctx) ":" name))
              (unchecked-get REGISTRY (str (.-kind ctx) ":default")))]
    (when (some? b) (b ctx))
    js/undefined))

static mirror of HEAD · about · clone: git clone https://git.ardegazu.ro/dev.git