Working on major restructuring

This commit is contained in:
2025-12-20 15:30:24 -07:00
parent f4c5ba1f14
commit 645a47b98a
53 changed files with 226 additions and 1407 deletions
View File
View File
View File
+11
View File
@@ -0,0 +1,11 @@
module GameServer
module Domain
class Player
attr_reader :money
def initialize
@money = 1000
end
end
end
end
View File
View File
View File
View File
+8
View File
@@ -0,0 +1,8 @@
module GameServer
class App
def self.start
world = Simulation::World.new
Server::WebSocketServer.new(world).start
end
end
end
+18
View File
@@ -0,0 +1,18 @@
module GameServer
module Logging
module Context
def self.with(data)
old = Thread.current[:log_ctx]
Thread.current[:log_ctx] = data
yield
ensure
Thread.current[:log_ctx] = old
end
def self.current
ctx = Thread.current[:log_ctx]
ctx ? ctx.map { |k,v| "#{k}=#{v} " }.join : ""
end
end
end
end
+11
View File
@@ -0,0 +1,11 @@
require "time"
module GameServer
module Logging
class Formatter
def call(severity, time, _, msg)
"[#{time.utc.iso8601}] #{severity} #{Context.current}#{msg}\n"
end
end
end
end
+19
View File
@@ -0,0 +1,19 @@
require "logger"
module GameServer
module Logging
def self.setup
FileUtils.mkdir_p("log")
file = File.open("log/development.log", "a")
file.sync = true
@logger = Logger.new(file)
@logger.level = Logger::DEBUG
@logger.formatter = Formatter.new
end
def self.logger
@logger
end
end
end
View File
View File
View File
View File
View File
+27
View File
@@ -0,0 +1,27 @@
require "json"
module GameServer
module Server
class Connection
def initialize(ws, world)
@ws = ws
@world = world
@router = MessageRouter.new(world)
end
def run
Logging.logger.info "connection opened"
while msg = @ws.read
data = JSON.parse(msg)
response = @router.handle(data)
@ws.write(JSON.dump(response)) if response
end
rescue => e
Logging.logger.error e.message
ensure
Logging.logger.info "connection closed"
end
end
end
end
+61
View File
@@ -0,0 +1,61 @@
module GameServer
module Server
class MessageRouter
def initialize(world)
@world = world
end
def handle(data)
case data["type"]
when "hello"
hello
when "query"
query(data)
when "command"
command(data)
else
error("UNKNOWN_TYPE")
end
end
def hello
{
type: "update",
domain: "world",
payload: {
time: @world.time,
game_speed: Settings::GAME_SPEED
}
}
end
def query(data)
if data["domain"] == "player"
{
type: "update",
domain: "player",
payload: { money: 1000 }
}
else
error("UNKNOWN_DOMAIN")
end
end
def command(data)
{
type: "update",
domain: "command",
payload: { status: "accepted" }
}
end
def error(code)
{
type: "error",
domain: "system",
payload: { code: code }
}
end
end
end
end
+33
View File
@@ -0,0 +1,33 @@
require "async"
require "async/websocket"
module GameServer
module Server
class WebSocketServer
def initialize(world)
@world = world
end
def start
Async do |task|
task.async { simulation_loop }
Async::WebSocket::Server.open("0.0.0.0", Settings::PORT) do |ws|
task.async { Connection.new(ws, @world).run }
end
end
end
def simulation_loop
last = Time.now
loop do
now = Time.now
delta = (now - last) * Settings::GAME_SPEED
@world.advance(delta)
last = now
sleep Settings::SIMULATION_STEP
end
end
end
end
end
View File
View File
View File
View File
View File
+15
View File
@@ -0,0 +1,15 @@
module GameServer
module Simulation
class World
attr_reader :time
def initialize
@time = 0.0
end
def advance(delta)
@time += delta
end
end
end
end
View File