Using a Top 10 High Score list as an example, this tutorial will attempt to demonstrate the following.
To set up a server listening on a network requires only one command. This command sets up a network called myNetwork using the client name Server and listens for TCP connections on port 4100. For connections coming in to the server from the Internet, you will have to set up your router to forward that port to the machine running your server app.
INetID = HostNetwork("myNetwork", "Server", 4100)
Now that we are listening on the network, we need to add a little maintenance routine to clean up after clients that have disconnected. This routines checks to see if a client that was previously connected has disconnected, and it deletes the associated client ID making room for the next client connection.
for x = 1 to 50 if x = 1 id = GetNetworkFirstClient(iNetID) else id = GetNetworkNextClient(iNetID) endif if id = 0 then exit if GetNetworkClientDisconnected(iNetID, id) = 1 DeleteNetworkClient(iNetID, id) endif next x
Now we are ready to check for incoming messages. We'll ask the network if there are any in the queue and grab it if there are. Then check the client ID to make sure it's coming from a client and not the server. (the server uses client ID 1)
When we have received a packet, we check the first data item, which in this case happens to be a float. We are using that float to determine what action to take. For this app, if the float equals 1.0, then we are sending the high score list to the client. If it equals 1.1, then the client has sent a high score to the server to be considered for placement in the top 10.
msg = GetNetworkMessage(iNetID) if msg > 0 ClientID = GetNetworkMessageFromClient(msg) if ClientID > 1 f# = GetNetworkMessageFloat(msg) if f# = 1.0 // Send High Score List newMsg = CreateNetworkMessage() AddNetworkMessageFloat(newMsg, 1.0) for x = 1 to 10 AddNetworkMessageString(newMsg, HiScores[x].init$) AddNetworkMessageInteger(newMsg, HiScores[x].score) next x SendNetworkMessage(iNetID, ClientID, newMsg) DeleteNetworkMessage(newMsg) endif if f# = 1.1 // Receive Score from Client temp$ = GetNetworkMessageString(msg) score = GetNetworkMessageInteger(msg) // See if the submitted score is high enough for the top 10 // If it is, place it where it belongs and shuffle the rest // of the scores down one position. for x = 1 to 10 if score > HiScores[x].score then exit next x if x < 11 for y = 10 to x+1 step -1 HiScores[y].init$ = HiScores[y-1].init$ HiScores[y].score = HiScores[y-1].score next y HiScores[x].init$ = init$ HiScores[x].score = score endif endif endif DeleteNetworkMessage(msg) endif
For the sake of simplicity I'll only be showing the subroutines that handle network communications. It will be up to you to create the game that ultimately feeds this the player's initials and score.
For the client to connect to the server requires just one command. It specifies the IP address of the server, the port, and a client name. The client name when connecting to a server must be different than any other client name currently connected to the server, so we're using a Random number to keep it unique.
InetID = JoinNetwork("192.168.100.5", 4100, "Client"+str(Random()))
Then we enter a loop that checks to see if we have connected, and times out in 4 seconds if we don't. Remember to give enough time for a connection to happen. On devices such as cell phones, congestion and poor signal, are very common and can produce long delays.
// If we don't connect within 4 seconds, print an error and exit t# = timer() do c = GetNetworkNumClients(iNetID) if c > 1 then exit if timer() - t# > 4.0 print("Server could not be reached.") exit endif sync() loop
Once the connection is established, we assemble the network packet, and send it off to the server.
If c > 1 ServerID = GetNetworkServerID(iNetID) newMsg = CreateNetworkMessage() AddNetworkMessageFloat(newMsg, 1.1) // Add the packet identifier AddNetworkMessageString(newMsg, init$) // Add the player's initials AddNetworkMessageInteger(newMsg, score) // Add the player's score SendNetworkMessage(iNetID, ServerID, newMsg) // Send it to the server DeleteNetworkMessage(newMsg) CloseNetwork(iNetID) endif
The first part of this routine is identical to the SendHighScore subroutine.
InetID = JoinNetwork("192.168.100.5", 4100, "Client"+str(Random())) // If we don't connect within 4 seconds, print an error and exit t# = timer() do c = GetNetworkNumClients(iNetID) if c > 1 then exit if timer() - t# > 4.0 print("Server could not be reached.") exit endif sync() loop
Once the connection is established, we send off just the float in a packet by itself. This tells the server we want it to send the full high score list. Then we enter a loop waiting for the packet to arrive from the server.
If c > 1 ServerID = GetNetworkServerID(iNetID) // get server's ID newMsg = CreateNetworkMessage() // add the packet identifier AddNetworkMessageFloat(newMsg, 1.0) // send it to the server SendNetworkMessage(iNetID, ServerID, newMsg) DeleteNetworkMessage(newMsg) msg = 0 t# = timer() while msg = 0 msg = GetNetworkMessage(iNetID) if timer() - t# > 2.0 then exit sync() endwhile if msg > 0 f# = GetNetworkMessageFloat(msg) if f# = 1.0 for x = 1 to 10 HiScores[x].init$ = GetNetworkMessageString(msg) HiScores[x].score = GetNetworkMessageInteger(msg) next x endif endif DeleteNetworkMessage(msg) CloseNetwork(iNetID) endif