4e07f38

Bowmap · bowmap.git · Tickets

Branches > main > 4e07f38 > files

Keep track of state with a relational data structure

Grahp, 2026-10-04

Commit: 4e07f384b215c73a1f29c48738b06b3db1cadf2b
Parent: 0d6765e

4 changed files:

deps.edn modified (view file)

@@ -12,5 +12,5 @@   nrepl/nrepl {:mvn/version "1.7.0"}   dev.weavejester/medley {:mvn/version "1.10.0"}   org.clojure/data.json {:mvn/version "2.5.2"}-  datascript/datascript {:mvn/version "1.8.1"}+  com.wotbrew/relic {:mvn/version "0.1.7"}   io.netty/netty-buffer {:mvn/version "4.1.111.Final"}}}

src/net/bowmap/server/game/handle.clj modified (view file)

@@ -1,6 +1,6 @@ (ns net.bowmap.server.game.handle   (:require-   [datascript.core :as d]+   [com.wotbrew.relic :as rel]    [net.bowmap.server.game.player :as player]    [net.bowmap.server.game.server :as server]    [net.bowmap.server.network.connection :as connection]@@ -12,45 +12,50 @@    [net.bowmap.server.protocol.serverbound-packets :as serverbound]))  (defmulti handle-packet-  "Handles a packet from a player given their connection uuid.-   Returning a sequence of response packets."-  (fn [connection-uuid packet]+  "Handles a packet from a player given their connection uuid. Takes the game+   state, and returns a vector of nil or a state value, followed by 0 or more+   response packets."+  (fn [state connection-uuid packet]     (::packet/id packet))) -(defmethod handle-packet :default [_ _])+(defmethod handle-packet :default [_ _ _]) -(defmethod handle-packet ::serverbound/status-request [_ _]-  [{::packet/id ::clientbound/status-response+(defmethod handle-packet ::serverbound/status-request [state _ _]+  [nil+   {::packet/id ::clientbound/status-response     ::p/version-name "26.3"     ::p/protocol 777     ::p/motd {::component/text "Bowmap!"               ::component/color "#9f9f9f"}-    ::p/online-player-count 0+    ::p/online-player-count (count (state ::server/players))     ::p/max-player-count 1000}]) -(defmethod handle-packet ::serverbound/ping-request [_ {::p/keys! [timestamp]}]-  [{::packet/id ::clientbound/pong-response+(defmethod handle-packet ::serverbound/ping-request [_ _ {::p/keys! [timestamp]}]+  [nil+   {::packet/id ::clientbound/pong-response     ::p/timestamp timestamp}]) -(defmethod handle-packet ::serverbound/login-start [connection-uuid {::p/keys! [uuid username]}]-  (d/transact! server/conn-               [{::player/uuid uuid-                 ::player/username username-                 ::connection/connection-uuid connection-uuid}])--  [{::packet/id ::clientbound/login-success+(defmethod handle-packet ::serverbound/login-start [state connection-uuid {::p/keys! [uuid username]}]+  [(rel/transact state+                 [:insert ::server/players+                  {::player/uuid uuid+                   ::player/username username+                   ::connection/connection-uuid connection-uuid}])+   {::packet/id ::clientbound/login-success     ::p/game-profile {::p/uuid uuid                       ::p/username username                       ::p/game-profile-properties []}     ::p/session-uuid connection-uuid}]) -(defmethod handle-packet ::serverbound/login-acknowledged [_ _]-  [{::packet/id ::clientbound/known-packs+(defmethod handle-packet ::serverbound/login-acknowledged [_ _ _]+  [nil+   {::packet/id ::clientbound/known-packs     ::p/known-packs [registry/core-data-pack]}]) -(defmethod handle-packet ::serverbound/known-packs [_ {::p/keys! [known-packs]}]+(defmethod handle-packet ::serverbound/known-packs [state _ {::p/keys! [known-packs]}]   (if (= [registry/core-data-pack] known-packs)-    (conj registry/registry-packets-          {::packet/id ::clientbound/finish-config})+    (cons state+          (conj registry/registry-packets+                {::packet/id ::clientbound/finish-config}))     (throw (ex-info "Client does not support the core datapack"                     {:known-packs known-packs}))))

src/net/bowmap/server/game/server.clj modified (view file)

@@ -1,11 +1,15 @@ (ns net.bowmap.server.game.server   (:require-   [datascript.core :as d]-   [net.bowmap.server.game.player :as player]-   [net.bowmap.server.network.connection :as connection]))+   [clojure.spec.alpha :as s]+   [com.wotbrew.relic :as relic]+   [net.bowmap.server.game.player :as player])) -(def schema-  {::player/uuid {:db/unique :db.unique/identity}-   ::connection/connection-uuid {:db/unique :db.unique/identity}})+(s/def ::players (s/coll-of ::player/player :kind set?))+(s/def ::server (s/keys :opt [::players])) -(defonce conn (d/create-conn schema))+(def players-by-uuid+  [[:from ::players]+   [:unique ::player/uuid]])++(defonce state (atom (relic/mat {}+                                players-by-uuid)))

src/net/bowmap/server/runtime/connections.clj modified (view file)

@@ -3,6 +3,7 @@    [net.bowmap.server.game.handle :as handle]    [net.bowmap.server.network.connection :as connection]    [net.bowmap.server.network.server :as server]+   [net.bowmap.server.game.server :as state]    [net.bowmap.server.protocol.packet :as packet]    [net.bowmap.server.protocol.packet-serialization :as serialize]    [net.bowmap.server.protocol.phase :as phase]@@ -30,8 +31,11 @@               packet (serialize/decode-frame client frame)               client' (apply-packet client packet)]           (assert (compare-and-set! client-atom client client'))-          (let [packets (handle/handle-packet connection-uuid packet)]-            (run! send-packet! packets)))+          (loop [state @state/state]+            (let [[state' & packets] (handle/handle-packet state connection-uuid packet)]+              (if (or (nil? state') (compare-and-set! state/state state state'))+                (run! send-packet! packets)+                (recur @state/state)))))         (recur)))))  (defn handle-connections!