Skip to content

Instantly share code, notes, and snippets.

@mrosati84
Created June 11, 2024 07:13
Show Gist options
  • Save mrosati84/eadcb68267cc1e5c91e1f3e49479c16e to your computer and use it in GitHub Desktop.
Save mrosati84/eadcb68267cc1e5c91e1f3e49479c16e to your computer and use it in GitHub Desktop.
local ColyseusClient = require "colyseus.client"
local client
local room
-- {"8dh34=fg" = "/gameobject1"}
local players_gameobjects = {}
-- ---------------
-- LOCAL FUNCTIONS
-- ---------------
-- support function, Lua does not support natively non-linear tables length
local function get_table_length(t)
local count = 0
for _ in pairs(t) do
count = count + 1
end
return count
end
local function register_messages()
--#IF HEADLESS
-- -----------------------------------------------
-- *AUTHORITY* COLYSEUS MESSAGES CALLBACK
-- these are only executed in the server authority
-- -----------------------------------------------
room.state.players:on_add(function(player, session_id)
-- spawn a player, if session_id match, it's always not controllable because here we are in the game server
local player_gameobject_id = nil;
if not player["is_authority"] then
-- spawn a gameobject as long as it's not the authority
player_gameobject_id = factory.create("/spawner#factory", vmath.vector3(480, 320, 0), vmath.quat(), { controllable = false })
end
if player_gameobject_id then
players_gameobjects[session_id] = player_gameobject_id
end
end)
room.state.players:on_remove(function(player, session_id)
local goid_to_remove = players_gameobjects[session_id]
if goid_to_remove then
go.delete(goid_to_remove)
players_gameobjects[session_id] = nil
end
end)
-- Listen for changes in the colyseus state - AUTHORITY
room.state.players:on_change(function(value, index)
if value and get_table_length(players_gameobjects) > 0 then
-- send a message to the correct player script, to indicate that
-- it needs to move
local session_id = value.session_id
local moving_x = value.moving_x
local moving_y = value.moving_y
if players_gameobjects[session_id] then
msg.post(hash(players_gameobjects[session_id]).."#player", "moving", { moving_x = moving_x, moving_y = moving_y })
end
end
end)
--#ELSE
-- -------------------------------------------
-- *GAME CLIENT* COLYSEUS MESSAGES CALLBACK
-- these are only executed in the game clients
-- -------------------------------------------
room.state.players:on_add(function(player, session_id)
-- spawn a player, if session_id match, it needs to be controllable because it's me.
local player_gameobject_id = nil;
local pos = {
x = player.position.x,
y = player.position.y
}
if session_id == room["sessionId"] then
player_gameobject_id = factory.create("/spawner#factory", vmath.vector3(pos.x, pos.y, 0), vmath.quat(), { controllable = true })
else
if not player["is_authority"] then
-- we don't want to spawn a player for the authority
player_gameobject_id = factory.create("/spawner#factory", vmath.vector3(pos.x, pos.y, 0), vmath.quat(), { controllable = false })
go.set(player_gameobject_id, "position", vmath.vector3(player.position.x, player.position.y, 0))
end
end
if player_gameobject_id then
players_gameobjects[session_id] = player_gameobject_id
end
end)
room.state.players:on_remove(function(player, session_id)
local goid_to_remove = players_gameobjects[session_id]
if goid_to_remove then
go.delete(goid_to_remove)
players_gameobjects[session_id] = nil
end
end)
-- Listen for changes in the colyseus state - GAME CLIENT
room.state.players:on_change(function(value, index)
-- state has changed, we must update the player velocity
if value and get_table_length(players_gameobjects) > 0 then
-- send a message to the correct player script, to indicate that
-- it needs to move
local session_id = value.session_id
local x = value.linear_velocity.x
local y = value.linear_velocity.y
if players_gameobjects[session_id] then
go.set(hash(players_gameobjects[session_id]).."#collisionobject", "linear_velocity", vmath.vector3(x, y, 0))
go.set(hash(players_gameobjects[session_id]), "position", vmath.vector3(value.position.x, value.position.y, 0))
end
end
end)
--#ENDIF
end
local function join()
client = ColyseusClient.new("ws://localhost:2567")
client:join_or_create("my_room", {}, function(err, _room)
if err then
print("Join error")
pprint(err)
return
end
print("Successfully joined room")
room = _room
register_messages()
end)
end
-- ------------
-- DEFOLD HOOKS
-- ------------
function init(self)
--#IF HEADLESS
join()
--#ENDIF
end
function on_message(self, message_id, message, sender)
-- -------------------
-- CONNECTION MESSAGES
-- -------------------
if message_id == hash("join") then
join()
end
if message_id == hash("disconnect") then
if room then
for _session_id, _goid in pairs(players_gameobjects) do
go.delete(_goid)
end
players_gameobjects = {}
room:leave()
print("Room left")
end
end
-- -----------------------
-- VELOCITY UPDATE MESSAGE
-- -----------------------
if message_id == hash("linear_velocity") then
if get_table_length(players_gameobjects) then
local session_id = nil
for _session_id, _goid in pairs(players_gameobjects) do
if hash(_goid) == hash(message.goid) then
session_id = _session_id
end
end
room:send("linear_velocity", {
linear_velocity = {
x = message.linear_velocity.x,
y = message.linear_velocity.y
},
position = {
x = message.position.x,
y = message.position.y
},
moving_x = message.moving_x,
moving_y = message.moving_y,
session_id = session_id
})
end
end
-- ------------------
-- KEY PRESS MESSAGES
-- ------------------
if message_id == hash("pressed_up") then
if room then
room:send("pressed_up")
end
end
if message_id == hash("released_up") then
if room then
room:send("released_up")
end
end
if message_id == hash("pressed_down") then
if room then
room:send("pressed_down")
end
end
if message_id == hash("released_down") then
if room then
room:send("released_down")
end
end
if message_id == hash("pressed_right") then
if room then
room:send("pressed_right")
end
end
if message_id == hash("released_right") then
if room then
room:send("released_right")
end
end
if message_id == hash("pressed_left") then
if room then
room:send("pressed_left")
end
end
if message_id == hash("released_left") then
if room then
room:send("released_left")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment