Colyseus - Multiplayer Game Client & Server

#12

v3.0-rc1
tagged on Jun 14, 2013 · 110 commits to master since this tag

So, yeah, all the many improvements to upstream LuaSocket haven’t made it to Defold. It would be nice if Defold removed all the socket stuff from builtin and just let the community maintain defold-luasocket and keep it up-to-date with upstream.

2 Likes

#13

This is likely to happen in the long-run but for now we need to live with the current system. I haven’t had a chance to test this properly, but I believe it might be possible to use socket.dns.getaddrinfo() to get a list of IPs to try and connect to:

self.sock_connect = function(self, host, port)
	assert(corunning(), "You must call the connect function from a coroutine")
	local addrinfo = socket.dns.getaddrinfo(host)
	for _,info in pairs(addrinfo) do
		if info.family == "inet6" then
			self.sock = socket.tcp6()
		else
			self.sock = socket.tcp()
		end
		self.sock:settimeout(0)
		self.sock:connect(host,port)

		local sendt = { self.sock }
		-- start polling for successful connection or error
		while true do
			local receive_ready, send_ready, err = socket.select(nil, sendt, 0)
			if err == "timeout" then
				coroutine.yield()
			elseif err then
				break
			elseif #send_ready == 1 then
				return true
			end
		end
	end
	self.sock = nil
	return nil, "Unable to connect"
end
1 Like

#14

I’ve verified this against an IPv6 only network at work and the code can connect to it properly. I’ve released a new version of defold-websocket that includes this change.

6 Likes

Firebase or other Backend service support
#15

I would like to share this here too. Because It is possible that other dependencies(like defold-websocket) or Defold’s cache may cause this problem:

I am just using default example. When server is not available, onError message “mostly” doesn’t triggered. Sometimes it works when I build and then rebuild the project, but I couldn’t find any clue or pattern about this. Its possible that other dependencies may cause this problem or maybe built in cache of Defold.

This is the client output when there isn’t any server and onError doesn’t triggered :

{
  roomStates = {
  }
  roomsAvailableRequests = {
  }
  requestId = 0,
  on = function: 0x0a1b70e0,
  connection = {
    emit = function: 0x0aaf9d60,
    _enqueuedCalls = {
    }
    on = function: 0x0aaf9d80,
    is_html5 = false,
    off = function: 0x0aaf9f40,
    _on = {
      close = {
        1 = function: 0x0aafa1f0,
      }
      error = {
        1 = function: 0x0aafa140,
      }
      message = {
        1 = function: 0x0aafa180,
      }
      open = {
        1 = function: 0x0aafa0a0,
      }
    }
    state = CLOSED,
    listeners = function: 0x0aaf9d40,
    endpoint = ws://localhost:8080/?colyseusid=xmjmMr3lo,
  }
  rooms = {
  }
  hostname = ws://localhost:8080/,
  connectingRooms = {
  }
  _on = {
  }
  emit = function: 0x0a1b7210,
  listeners = function: 0x0a1b71f0,
  off = function: 0x0a1b7100,
  id = xmjmMr3lo,
}

There isn’t any server and onError triggered :

{
  roomStates = {
  }
  roomsAvailableRequests = {
  }
  requestId = 0,
  on = function: 0x12f4f0e0,
  connection = {
    ws = {
      step = function: 0x13892d10,
      sock_close = function: 0x13892860,
      on_close = function: 0x13892880,
      send = function: 0x13892c30,
      on_disconnected = function: 0x13892d70,
      sock = tcp{client}: 0x13893630,
      sock_send = function: 0x138928a0,
      close = function: 0x13892cc0,
      on_connected = function: 0x13892d50,
      on_message = function: 0x13892d30,
      connect = function: 0x138929f0,
      state = CLOSED,
      sock_connect = function: 0x13892830,
      sock_receive = function: 0x138928c0,
      receive = function: 0x13892c80,
    }
    emit = function: 0x13891d60,
    _enqueuedCalls = {
    }
    on = function: 0x13891d80,
    is_html5 = false,
    off = function: 0x13891f40,
    _on = {
      close = {
        1 = function: 0x138921f0,
      }
      error = {
        1 = function: 0x13892140,
      }
      message = {
        1 = function: 0x13892180,
      }
      open = {
        1 = function: 0x138920a0,
      }
    }
    state = CONNECTING,
    listeners = function: 0x13891d40,
    endpoint = ws://localhost:8080/?colyseusid=xmjmMr3lo,
  }
  rooms = {
  }
  hostname = ws://localhost:8080/,
  connectingRooms = {
  }
  _on = {
  }
  emit = function: 0x12f4f210,
  listeners = function: 0x12f4f1f0,
  off = function: 0x12f4f100,
  id = xmjmMr3lo,
}

0 Likes

#16

I just test the defold-websocket and I can confirm that it works as expected.

ws:on_connected() returns an error with ‘closed’.

0 Likes

#17

Also ws:on_connected returns ‘closed’ on colyseus (connection.lua)

self.ws:on_connected(function(ok, err)
    self.state = self.ws.state
    
    if err then
      pprint(err) -- <- returns closed
      self:emit('error', err)
      self:close()
0 Likes

#18

Ok. Does this mean that self:emit(“error”, err) doesn’t work or?

0 Likes

#19

Yes, looks like emit is not working as expected. Sometimes it work sometimes not.

0 Likes

#20

Ok, makes sense than. Have you opened a ticket in the Colyseus repo?

0 Likes

#21

Yes, in the colyseus-defold repo #

1 Like

#22

Fixed: https://github.com/gamestdio/colyseus-defold/issues/6#issuecomment-427810381

2 Likes

#23

Hello, I’m trying to make a game with syncronous multiplayer with Colyseus and Defold and I have perfomance issues.
At first I was using state sync and messages from server to sync clients. State sync was working on 30 FPS and whole game has around 10 FPS on HTML5, Android, Windows and Mac versions because of

local new_state = msgpack.unpack( utils.byte_array_to_string(self._previousState) )

in room.lua Room:patch.

Then I turned off room patch by copying library to my project and commenting room.lua:87

self:patch(message[2])

and sending state info by message from server to clients every frame at 30 FPS. One message contains array of 6-10 elements like this

2 = {
    segmentRadius = 32,
    skin = cat,
    id = 2,
    segments = {
      1 = {
        y = -316,
        x = -85,
      }
      2 = {
        y = -308,
        x = -93,
      }
      3 = {
        y = -303,
        x = -82,
      }
      4 = {
        y = -295,
        x = -90,
      }
      5 = {
        y = -290,
        x = -79,
      }
      6 = {
        y = -285,
        x = -68,
      }
      7 = {
        y = -277,
        x = -76,
      }
      8 = {
        y = -272,
        x = -65,
      }
      9 = {
        y = -264,
        x = -73,
      }
      10 = {
        y = -259,
        x = -62,
      }
    }
    name = Jessica Jones,
    isolationTimer = 23,
  }

On Windows, Mac and Android it works perfect, but on HTML5 game works at stable 30 FPS around 3-4 seconds and after that Colyseus client freezes and receives no messages from server or client have no resources to decode them: print in room.lua:38 in

 self.connection:on("message", function(message)

works only 3-4 seconds.

Where can I tweak or optimize my system to solve this perfomance issue?

1 Like

#24

Is the game still running (ie animations playing etc) or is the whole app frozen?

2 Likes

#25

game is still running without FPS problems

0 Likes

#26

Oh, well, not sure why then. Perhaps @endel has some ideas on how to best debug connectivity issues?

Btw, @nik.dreml have you created an issue on the Colyseus Defold GitHub page?

2 Likes

#27

No, I’ve created only topic on Colyseus’s forum, I thought it can be my mistake or misunderstanding, not Colyseus’s issue.
Now I’m going to create a issue on the Colyseus Defold GitHub page :slight_smile:

1 Like

#28

@endel can you advise something?

0 Likes

#29

Hi @nik.dreml, do you mind providing an example where I can see the issue happening? Would be easier to inspect the problem this way. Thanks!

3 Likes

#30


Yeah, of course, I’ve sent you a PM.

1 Like

#31

I see many different questions about Colyseus and Defold in various chats/places. And looks like very little lands on the forum. So I’ll try to collect that scattered experience and I inspire others to copy/paste useful bits to the forums, so it is searchable to others.

Here’s a nice chat from Defold’s slack:

totebo [11:00 AM]
Has anyone here had experience with the Colyseus multiplayer server?
sven [11:01 AM]
Not yet, I want to try it but haven’t had the time
Looks promising though!
evangelist [11:03 AM]
guess @SelimAnac is an expert: Colyseus - Tic Tac Toe Multiplayer Example
also @cytherabbit poked around it, to my knowledge
Selim Anac [11:14 AM]
@evangelist @totebo not an expert :slightly_smiling_face: Just made some tryouts with it. Feel free to ask anything, I’ll be glad if I can help.
totebo [11:16 AM]
Thanks guys! I’m researching the possibility of creating a four-player turn based game. Is Colyseus the closest to a plug-and-play option for Defold currently? (edited)
totebo [11:19 AM]
@Selim Anac How well does Colyseus handle multiple servers and scalability?
Selim Anac
[11:21 AM]
Yes Colyseus is very very closest to a plug-and-play. It is easy to use. It is a practical solution for a small size games. (edited)
totebo [11:22 AM]
Nice! I’m looking for a solution that can SCALE if needed, though. :slightly_smiling_face:
Selim Anac [11:23 AM]
It can scale but honestly I don’t recomended it for large projects.
http://colyseus.io/docs/api-server/#optionspresence
colyseus.io
Server - Colyseus v0.9.x
Documentation for Colyseus Multiplayer Game Server for Node.js
http://colyseus.io/docs/api-presence/
colyseus.io
Presence - Colyseus v0.9.x
Documentation for Colyseus Multiplayer Game Server for Node.js
totebo [11:24 AM]
That looks good, similar to a solution I used for No Brakes io. Is the reason you can’t recommend it the single point of failure? Or something else?
britzl [11:31 AM]
@Selim Anac Why don’t you recommend it for large projects?
Selim Anac [11:33 AM]
First of all it is a Node.js app :smile: (edited)
It is expensive to use on server side.
Defold version of Colyseus is using a msgpack-lua algorithm cause frame drops: Colyseus - Multiplayer Game Client & Server
Which is why I’m working on C++ NE with threads for handling websocket connection and binary serialiation.
(expensive because of the cpu and mem usage)
I didn’t test it’s scaling features.
So I can’t say anything about it, sorry.
totebo [11:38 AM]
The frame drops is mainly because it’s a synchronous game? The one I’m planning to make is asynchronous.
Selim Anac [11:44 AM]
I think so. Heavy realtime calculations may cause this issue. It may suit well for asynchronous game.
Your game’s logic is very important there. If it is a puzzle game… like a word game, you can do whatever you want. Colyseus with Defold is more than enough for it. (edited)
But if you are planning something like this: Family Age
You can’t handle it with Colyseus. Actually you can, but your server costs go higher and higher.
Selim Anac [11:58 AM]
One more thing; there isn’t build in matchmaking solution in Colyseus. It has matchmaking cycle but you should implement your logic. Matchmaking is a totally other and complex subject
totebo [11:58 AM]
Ok great info.
The game I’m making is for Facebook Instant. So I think I can let Facebook deal with that.
Selim Anac [12:01 PM]
Ah this is great. But highly recommend to test it is performance first. Html build in FB Canvas may cause other problems.
A specially on mobile

2 Likes