BetaTest Information
--------------------

There are three room types when you create a multi player game.

* Raw
* TurnBased
* Lock

Raw
---
This room-type doesn't have any logic on the server-side. You need to do all the logic on your client(s).
This type is used in physics simulation where the active client is acting as the Server for the logic.

GameTypes:
* Games that do not have interaction between other players. 
  Like sports games where you are in separate lanes or item collecting games
  Score and animation/position data usually are send to other clients in a room
* Split screen games, for instance Dual Tetris / PacMan / break-out / Sokoban
* See Also: Client-As-A-Server 

TurnBased
---------
You can initiate a next turn and the server will find the next player.
When client leaves room or connection is lost between server and client the server will initiate a next-turn.

TO BE DONE: Timeout = force next turn when player didn't make a turn. 
This can be needed when you put a mobile game in back-ground thus stopping logic of the client.
Usually you handle non-player-input and forcing next-turn on the client.

Game-types:
* Strategy
* Card
* Puzzle

Lock
----
With this room-type the server keeps the roomdata in a Map.
So for instance "0,0" = "1". Where 0,0 is the key of the Map and "1" is the value.
There is a lock mechanism on the data to make sure only one client can make a change at a time.

The client can check the state of the lock mechanism.
* Accept
* Deny
* Out-Of-Sync
* TimeOut  < TO BE DONE

Game-types:
* Grid Based Levels/Rooms
* RPG games
* Adventure Games


Accept
------
When the previous-value from the client matches the value of the server.
In that case the key on the server Map is locked for the client. And the value is changed on the server.
The key on the server is then unlocked and the 'Accept' state is send to the client.
Inside the wrapper block the client knows that the new value is accepted and stored on the server.

Deny
----
This occurs when the client wants to alter data that is currently locked by another client


Out-Of-Sync
-----------
The server is checking for the old value from the client and if the old value does not match the current value on the server
it sends 'out-of-sync' to the client.
Inside the wrapper block the client can react on this out of sync. Usually the client will then need to
request all data from the room in order to synchronize the client-state with the server-state.

For example

Server: (Map data)
Key "0,0"          Value "1"

client:
"0,0" Value "2"  <- this is the data that is last seen from the server (And you can see it is out of sync with the data on the server "1")

Client wants to change "0,0" to Value "3" and sends the old-value it has to the server.
send "0,0",2,3

Server receives "0,0", 2, 3
Server Map Key "0,0" results in 1 and is not the same as 2. 
Thus value 3 is not used to alter the key but an "Out-Of-Sync" is send back to the client.

--------------------------------------------------------------------------------------------------------------------------


CLIENT-AS-A-SERVER
==================
Best multi player games are the ones where the game-logic is done on server-side.
The client only sends inputs to the server and the server calculates the position / collision / physics reactions.
Those results are send to the clients. Using techniques as server and client side prediction calculations.

Since the server is typically running on a non Stencyl computer with no graphics context it is difficult to make such a server.

The idea that I had is to let one of the clients act as a server and do the computation. Realizing that the client is always behind.
This has one big benefit of offloading the server-code to one of the clients. A regular multi player server consumes a 
lot of CPU to make all those calculations for all the game-sessions that are running at the same time.
The biggest downside of this is that it requires an extra round-trip of data to the server.
This is not real Player to Player communication because the colyseus-server is a kind of proxy for the data.
The client that is acting as a server sends and gets the data from the colyseus Server.
Real player to player or peer-to-peer networks connect two devices/computers to each other.
The Colyseus Extension requires a server. Technically this can be your own computer but you have to run the server inside a Docker or Virtual Machine.
If you want to allow other users to play your game you need to make changes to your infrastructure (router) to allow other players 
from the internet to access your computer.


The technique I used in the sample games is to hide all the regular actor types which have collision / physics settings on them.
Creating new actor types for the hidden actors that are shown on the clients. But you have to remove all collision and physics effects on them
and essentially remove any collision groups on them.
No logic can exist on the visible actor types. They will purely be used to display the state of the 'server'. 
'Server' is in quotes because it is in fact the client that started the game session.

You can see this kind of technique in Pong or the Physics Demo game.

A list of actors is used to keep track of the hidden actors. 
The server itself is also a client so when I use 'client' in this context it will also display the data 'from itself' once it gets it from the server.
I didn't attempt to optimize the code to update the visible actor types BEFORE sending the data. 
I didn't do that because it allows to test the client and the server on the same instance. 
For 'real' test you would start another session of the game on your computer.
This is kind of the only way to test multi player as a single developer.
Or you need to randomize input and simulate 'bots'. 
Another approach would be to make an A.I. that can react more as a player. 
That approach could also be fun when your players of your game play without having to have another human around.

When a client receives the hidden actor data it will only show the data. No client-side detection/reaction is done to ensure that there will not be an out-of-sync-client.

This approach appears to work as you keep in mind about the LAG. (See LAG description)
For instance if you turn on Enable Debug Drawing with your game when the physics objects are hidden you 'see' the rectangles/circles of the physics objects.
This drawing, on the server, shows the difference between the objects and the positions they will have once the data is received from the server.

In fact the server is always in the future in regards to the clients. 

There are techniques to do prediction and I encourage you to look into the amazing work of merrak relating to the physics tools extension:
http://community.stencyl.com/index.php?topic=44858.0

I warn you : it is merely impossible to get a perfectly synchronized state across multiple computers/devices.

So during game-design you have to factor-in this lag.



Physics and Collision logic
----------------------------
Most of the near-real-time requests from Stencyl users are in relation of physics based games.
Platformer games and shooters are the most requested types of games.
Those are the hardest games to make into multi player games.
But hopefully the 'Client-As-A-Server' approach can deliver a kind of Proof Of Concept.
If you have a successful proof of concept and you want to optimize and improve performance it is easier
for server-side developers to make a dedicated server for your game.
Emphasis on 'EASIER' because creating a dedicated server for a multi player game is a lot of hard work.

The benefit of creating a proof of concept game using the Colyseus Extension is that once the proof is 
actually working and you have gained enough confidence that it will be a successful game you can reach out to
the Colyseus community to work with them to make a dedicated server.
Most of the logic you designed is easier to convert into a server as you have proven with the POC that it can 
be done with the Colyseus Server.



===========================================================================

Network Client to Server LAG
----------------------------
As an Extension user you need to keep in mind that there will be always a lag between the clients and the server.
If testing on your local computer this lag will be minimum (10 to 50 ms)
If testing on your LAN this lag will be bigger (depending on your switches and connection on your networks) 
If testing on your remote server this lag will be even bigger.
If testing on your remote server that is in another country the lag will be even bigger and when on another continent it could result in an unplayable game.


============================================================================

Experiments:
============

TimeBased actions
-----------------
You can use Server time to synchronize actions on clients. During testing there are slight 
differences that result in different physics/collision and positions.
After some investigations it appears that these are mostly caused by differences 
between different platforms regarding floating point calculations.
Running on the same platform KIND OF work. You have to carefully test this if you want 
to use the same approach.



Pure Collision Type Games
-------------------------
Currently there is no pure 'collision' detection on the Server. I am not sure if we need one.
For Physics based collisions the 'client-as-a-server' concept can be tried.
Depending on the need for this I could persue this at some time.



============================================================================

Extension does not work on Flash

Confirmed:
* Android
* HTML5 (Chrome on Windows / Safari on iOS 11 / Firefox/Chrome on Android)
* Windows




Known Issues / Enhancement Requests / To Be Done
---------------------------------
Turn.TimeOut force next turn when timeout between client occurs
Lock.TimeOut implementation on the server
Lock.Wrapper blocks are currently 
All.isActive block indicating if current client is the active player
Roomplayer-list is inconsistent as well as the number of players in room. (RoomPlayer list works again. But how about number of players?)
RoomList    Currently on roomtype. That works fine with only one game but you need to filter on room-name when on a server that handles more game(types)
			This is no problem if you run server for only one game. But if you are running for multiple games as the ColyseusDemoServer then it is necessary.

I'm not sure if I want to split the room-types into separate Extensions. (Raw,TurnBased,Lock)
A benefit would be to have only block that matter to the game type but you would have to install / maintain more extensions if you want to make more games.
Not sure what is best.

			

TODO
----
A.I. : Players in between
Animation data in Client-As-A-Server
Client-As-A-Server  : Look into actortype -list/ Map with actortype	to show  .. A visible actortype (Can that be pure physics actor? Even with animations) ?
getroomlist (check for non-null rooms / no player in room )

			

----
Ping time client as a server:
* The Netherlands   : 30 - 50
* U.S.A. West Coast : 200 - 300
* Local LAN         : 30 - 50


			