ACSUtils Wiki

An ACS library for ZDoom-based ports

User Tools

Site Tools


client_server_detection

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Next revisionBoth sides next revision
client_server_detection [2019/08/26 03:58] – created korshunclient_server_detection [2019/09/05 23:53] – [Writing robust multiplayer code] korshun
Line 1: Line 1:
-====== Clientside/Serverside detection ======+====== Clientside/serverside detection ====== 
 + 
 +===== Introduction =====
  
 You can check if a script is running serverside, clientside or in singleplayer using functions provided by ACSUtils. You can check if a script is running serverside, clientside or in singleplayer using functions provided by ACSUtils.
 +
  
 ===== Terminology ===== ===== Terminology =====
  
   * **Server** -- an engine instance that runs the gameplay code.   * **Server** -- an engine instance that runs the gameplay code.
-  * **Client** -- an engine instance that runs the rendering code and provides input to the server.+  * **Client** -- an engine instance that runs the rendering code and controls a player on the server.
  
 In singleplayer, the same engine instance is **both a server and a client**. Both ''IsServer()'' and ''IsClient()'' return true in singleplayer. In singleplayer, the same engine instance is **both a server and a client**. Both ''IsServer()'' and ''IsClient()'' return true in singleplayer.
  
 +In ZDoom and GZDoom multiplayer (but not Zandronum's), all players are both servers and clients, just like in singleplayer.
 +
 +Zandronum multiplayer emulation is singleplayer. Just like in singleplayer, the same engine instance is both a server and a client.
 +
 +In real Zandronum multiplayer, the server is only a server and clients are only clients, obviously.
 +
 +Yet, if Zandronum were to allow hosting non-dedicated servers, where a player allows others to connect to their singleplayer game without launching a separate engine instance, the hosting player would be both a server and a client, while other players in the game would be only clients.
 +
 +
 +===== Functions =====
 +
 +  * ''bool IsServer()'' -- returns true if the script is running on a **server**.
 +  * ''bool IsClient()'' -- returns true if the script is running on a **client**.
 +
 +  * ''bool IsServerOnly()'' -- returns true if the script is running on a **server that is not also client**.
 +  * ''bool IsClientOnly()'' -- returns true if the script is running on a **client that is not also server**.
 +
 +
 +===== Writing robust multiplayer code =====
 +
 +The definitions above enable writing ACS code that functions correctly in both singleplayer and multiplayer without singleplayer being a special case. Using ''IsClient'' and ''IsServer'' correctly ensures that your mod runs correctly in both singleplayer and multiplayer:
 +
 +<code acs>
 +if (IsServer())
 +{
 +    // Run serverside gameplay code.
 +}
 +if (IsClient())
 +{
 +    // Draw hud, spawn effects.
 +}
 +</code>
 +
 +You can also make sure that a serverside-only function is not called on the client, and a clientside-only function is not called on the server.
 +
 +<code>
 +function ServersideOnlyFunction(void)
 +{
 +    // writing if (IsClient()) would incorrectly display the warning in singleplayer.
 +    if (!IsServer())
 +        printbold(s:"Error: ServersideOnlyFunction must not be called clientside");
 +}
 +
 +function ClientsideOnlyFunction(void)
 +{
 +    // writing if (IsServer()) would incorrectly display the warning in singleplayer.
 +    if (!IsClient())
 +        printbold(s:"Error: ClientsideOnlyFunction must not be called serverside");
 +}
 +</code>
 +
 +===== How it works =====
 +
 +All detection of clients and servers is founded on two functions: [[zdoom>ConsolePlayerNumber]] and [[zan>IsNetworkGame]] (formerly known as ''IsMultiplayer'').
 +
 +''IsClient()'' simply checks if [[zdoom>ConsolePlayerNumber]] is not negative.
 +
 +''IsServer()'' is more complicated. It returns true if [[zdoom>ConsolePlayerNumber]] is negative. But if it's not negative, it needs to distinguish between multiplayer emulation and real multiplayer. It checks if the multiplayer is real using [[zan>IsNetworkGame]]. But calling this function in ZDoom/GZDoom crashes the engine. Therefore, before calling ''IsNetworkGame'', it checks if the engine is Zandronum using [[source_port_detection|IsZandronum]].
 +
 +If the engine is not Zandronum, the function returns true, because in ZDoom/GZDoom multiplayer all players run gameplay code.
 +
 +If the engine is Zandronum, the function returns false if it's real multiplayer, true if it's multiplayer emulation.
 +
 +''IsServerOnly'' and ''IsClientOnly'' simply return ''IsServer() && !IsClient()'' and ''IsClient() && !IsServer()'', respectively.
  
client_server_detection.txt · Last modified: 2019/09/05 23:54 by korshun