Skip to content

Instantly share code, notes, and snippets.

@julianrubisch
Last active February 2, 2025 19:04
Show Gist options
  • Save julianrubisch/686fddcd703ca4b9e756716c9f049bca to your computer and use it in GitHub Desktop.
Save julianrubisch/686fddcd703ca4b9e756716c9f049bca to your computer and use it in GitHub Desktop.
DragonRuby "Async" Multiplayer Sync via HTTP
class Game < HttpRouter
def initialize(players: [])
@players = players
@http_debounce = 0
route do |routes|
@players.each do |player|
routes.get "/#{player.id}/progress" do |req|
if @current_scene_name == :host_scene
req.respond 200, "{ \"progress\": #{player.progress} }"
end
end
routes.post "/#{player.id}/step" do |req|
if @current_scene_name == :host_scene
player.progress += 1
player.progress = player.progress % player.course.coords.size
req.respond 200
end
end
end
end
end
def tick
super
poll_progress unless @current_scene_name == :host_scene
end
private
def poll_progress
return if @http_debounce.elapsed_time < 30
@http_debounce = Kernel.tick_count
@players.each do |player|
@progress_result[player.id] ||= GTK.http_get "http://localhost:3000/#{player.id}/progress"
# wait until response is complete
if @progress_result[player.id] && @progress_result[player.id][:complete]
if @progress_result[player.id][:http_response_code] == 200
new_progress = GTK.parse_json(@progress_result[player.id][:response_data])["progress"]
# ... handle state update in "player" scenes
end
end
end
end
end
class HttpRouter
VERSION = "0.1.0"
attr_gtk
def initialize
@_routes = Routes.new
@_request = {}
@_response = {}
end
def tick
process_http
end
def route
yield @_routes
end
private
def process_http
inputs.http_requests.each do |r|
@_routes.match(r.uri, r.method).call(r)
end
end
end
class Routes
def initialize
@_routes = {}
end
def match(path, method)
@_routes[path][method]
end
def get(path, &block)
@_routes[path] ||= {}
@_routes[path]["GET"] = block
end
def post(path, &block)
@_routes[path] ||= {}
@_routes[path]["POST"] = block
end
end
@julianrubisch
Copy link
Author

note you'll have to call GTK.start_server! port: 3000, enable_in_prod: true somewhere in the host scene

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment