Playing Multiplayer Tag in FlexSim!
This is a side project to show off some fun things FlexSim can do using sockets. Sockets are just one possible way that one instance of FlexSim can communicate with another. In its simplest sense, a socket is just a port number and an IP address that computers use to send information to each other. For example, whenever a computer visits a website, it uses sockets to create a connection to the webserver's IP address on port 80 (HTTP) or port 443 (HTTPS). All of this occurs within the framework of the TCP/IP network. Similarly, FlexSim can establish socket connections to communicate with another FlexSim as long as you know the IP address and choose a port for both instances to connect on.
Establish Socket Connection
In this game of tag, the model that acts as the server uses these commands to set up socket connection with the client:
- socketinit();
- servercreatemain(8002);
- serveraccept(0);
Note: All of the commands in this article can be found in the documentation
The client then runs the following to connect to the server. The HostIP should be the IP address of the device running the server model (or 127.0.0.1 if running both client and server on the same machine).
- socketinit();
- int a = clientcreate();
- int a_con = clientconnect(a, HostIP, 8002);
On both the client model and server model, these commands are in the OnRunStart trigger and the server creates 5 socket connections for each player. 4 for inputs (up, down, left, right) and 1 for passing in their player name from the client. The server model will freeze and wait for all sockets to be set up. For example, if there are 3 players, the server model will wait until 3 clients have successfully ran the client model and connected.
After all clients have connected to the server, we can use clientsend() and serverreceive() to send information from client to server.
An example of this is sending movement inputs from client to server. This is what that looks like:
Client
- // MOVE
- if (iskeydown(87)){
- clientsend(2, "up");
- }
- if (iskeydown(83)){
- clientsend(3, "down");
- }
- if (iskeydown(65)){
- clientsend(4, "left");
- }
- if (iskeydown(68)){
- clientsend(5, "right");
- }
Server
- string up1 = serverreceive(token.Rank * 5 - 3, NULL, 100, 1);
- string down1 = serverreceive(token.Rank * 5 - 2, NULL, 100, 1);
- string left1 = serverreceive(token.Rank * 5 - 1, NULL, 100, 1);
- string right1 = serverreceive(token.Rank * 5, NULL, 100, 1);
- // token.Rank is the number of the player (1,2,3 etc.) and is used to reference the right
- // socket for each player's inputs
- //reset coordinates
- te.X = 0;
- te.Y = 0;
- te.Stop = 0;
- if (up1 != ""){ // up W meaning the server received an input on this socket
- te.Y = 1; // this accounts for getting multiple messages from client like "upupup"
- }
- if (down1 != ""){ // down S
- te.Y = -1; // this label is later used in a travel activity
- }
- if (left1 != ""){ // left A
- te.X = -1;
- }
- if (right1 != ""){ // right D
- te.X = 1;
- }
Note: In a typical game environment, the server is also sending information back to the clients, but in this example, all visuals and logic occur on the server.
Game Logic
All game logic is found on the server process flow.
Setup and Order of Models
To play Tag, follow these steps:
Note: If there are certain firewalls or security groups on your network that doesn't allow traffic into FlexSim outside local networks you may be limited on who can connect to play tag
1. Open TagServer model and change NumPlayers parameter to the desired number of players
2. Open TagClient model and change both global variables (HostIP and EnterNameHere). Again, if everything is running on the same device, use 127.0.0.1 as the HostIP global variable value.
3. Reset and Run the TagServer model first
4. Reset and Run the TagClient model. You should get this output if connection was successful
5. Run clients one at a time for each player until all players have connected and the server will run automatically. This is the output on the server upon successful connection
6. Enjoy!