Recent

Author Topic: Tabletop Game Server/Client guidance needed.  (Read 837 times)

TomTom

  • Full Member
  • ***
  • Posts: 133
Tabletop Game Server/Client guidance needed.
« on: July 16, 2022, 09:42:36 pm »
Hi. I have close to non knowledge about networking. I know that there are some protocols, ports, etc. but I have no idea what they are exactly. But... I would like to now.
I have this project on my mind, I don't know if its big or not.
So, I would like to create a client/server app for playing Four Against Darkness (Tabletop RPG, dungeon crawling game in form of book, I would paste a link but I dont know if Im allowed to do that here).
What I have in mind. There's this one app that is server and client app at the same time. User runs the app and can choose if he/she wants to host a game session or join session hosted by someone else. In case user wants to host a session he/she sets some properties (Game Rules, maybe password, set of image tiles which will be used to display dungeo, etc). If user decides to join a game session he/she enters the IP of the host (password if needed) and joins the session. Oh and The Host also can play the game he/she is hosting. Users/Players can send text messages visible to all in session and can send simple commands like changing position of character in dungeon, casting a spell or attacking, rolling a dice. So I'm guessing this would be just sending also text messages converted to integer when needed. When every player sends his/hers action, then the server calculates everything
- how dungeon looks - when rooms is empty/monsters are dead then player roll 2d6 dice and result of that roll is the number of room in the pool of rooms)
- fight results,
- events
- etc
When everything is calculated server sends all this to players (how many monsters the slayed, how much damage they recived etc).

So, How do I approach this? What should I use (what components, what protocols)? Where can I read about stuff that can help me in this project? I know I need to learn a lot but I don't know where to start.

What I think I need to now. How to connect to other PC in the network/internet. Send/Recive data (I don't know what kind of data it will be. Propably arrays containg information about action_type, some random integers).

Can You guide me where could I start learning all that could help me in this?

Thanks in advance




MarkMLl

  • Hero Member
  • *****
  • Posts: 5136
Re: Tabletop Game Server/Client guidance needed.
« Reply #1 on: July 16, 2022, 10:26:28 pm »
Gut feeling: don't start messing around with low-level network protocols unless you really have to. For that matter, do not automatically assume that you need to do any sort of conventional programming yourself.

Instead, research what is already available for distributed Multi-User Dungeons (MUDs). You might find that there is already generic higher-level software, to which you would need to describe your game in the same way that e.g. Zork was written in a descriptive language.

In any event, keep us updated :-)

MarkMLl

Xref to older thread: https://forum.lazarus.freepascal.org/index.php/topic,55335.0.html
« Last Edit: July 16, 2022, 11:33:29 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TomTom

  • Full Member
  • ***
  • Posts: 133
Re: Tabletop Game Server/Client guidance needed.
« Reply #2 on: July 17, 2022, 12:20:21 am »
As a total newbie what I think would be suffucient for my needs.
1. What protocol to use? My best guess TCP/IP
2. Know how to connect 2-4 users where one of them is host and player at the same time
3. Assuming I have done code for dungeon building, how to send information between users how this dungeon looks? Dungeon is build while game progress and consists of rooms (can be a corridor). After clearing a room (defeating monsters, solving a puzzle etc) one of the players roll 2d6 for a number of next room. Rooms (can be of corridor type) are stored in an array so rolled number is the index of that array. When shape/type of next room is determined  player can decide where to place it (entrance must be connected to exit of current room). Each room can be also an 2D array (1 for wall, 0 for floor).
4. How to send/recieve simple data such as strings/integers.



af0815

  • Hero Member
  • *****
  • Posts: 1022
Re: Tabletop Game Server/Client guidance needed.
« Reply #3 on: July 17, 2022, 08:21:30 am »
For communication, look at first for chat programs written with Lazarus. This a good start, because it shows how the component works.

indy,lnet and synapse are some high level limbs for this
regards
Andreas

TomTom

  • Full Member
  • ***
  • Posts: 133
Re: Tabletop Game Server/Client guidance needed.
« Reply #4 on: July 17, 2022, 10:54:13 am »
I'm looking at examples right now and one thing makes me worried. For example in this one https://stackoverflow.com/questions/26629513/how-to-set-up-a-simple-connection-between-tidtcpclient-and-tidtcpserver-to-send#26633619 there is TIDSync mentioned. I don't have it and I can't find it. There is also TidNotify (or sth like that) mentioned in other post. I don't have it either.  What I installed using Online Package Manager:
Indy 10
Synapse
LNet
And I cant(don't know how to) use IDSync/TidNotify ...

For communication, look at first for chat programs written with Lazarus. This a good start, because it shows how the component works.

indy,lnet and synapse are some high level limbs for this


Warfley

  • Hero Member
  • *****
  • Posts: 911
Re: Tabletop Game Server/Client guidance needed.
« Reply #6 on: July 17, 2022, 08:25:53 pm »
There are a few things you need to consider when designing such a network protocol. Do you want to have a dedicated server, player hosted or peer to peer (from your first post it looks like you want a player hosted game) and the question if the players are in a local network or you need to connect over the internet.

Generally I would recommend you a dedicated server approach, the dedicated server can than be hosted by one of the players, but this generally makes it easier to have game clients and game server logic separated. If the host wants to join the game, they are just another client for the server.
Also for the beginning I would recommend you for now to focus on local network, as this is much easier for a beginner.

Then the question is requirements you have to the handling of the connection and the flow of the game. Is you game very structured, e.g. turn based (e.g. chess where each player can only continue after the other has made their move) or is it a more chaotic real time where the game is going forth if the players react or not. Then how are your delay requirements and can you deal with package loss, e.g. in chess delay doesn't matter and if your move "get's lost" you get into trouble, while in a first person shooter, delay is crucial, and if one shot of you is lost it doesn't matter as much as you can just shoot again.
From this you can then select your protocols. general rule of thumb: Low latency -> UDP, structured and reliable -> TCP. You can also of course use higher level protocols, e.g. you could use Websockets if you want a TCP based event driven but connection based flow (so where each client has one persistent connection), or HTTP if you have a stateless request-response flow (for most games not realy fitted as most games the server might want to initiate communication and in HTTP the server can only send data to the client as a response to a request from the client)

From my understanding tabletop games are usually more a structured game, where a situation occurs and every player choses their moves and then the  reacts to those moves. So you could go with a very simpe TCP based system where each client connects to the server and then when it's their turn, the server just awaits data from them, and because no one else is able to do anything during this players phase, the server can pretty much just sit and wait for that players client to make their move. This is rather easy to build with raw TCP.

But you might want to have multiple channels for connections anyway, for example if you want to have a chat function, best to create a new connection for the chat which simplifies dealing with distinquishing between the different kinds of data (with different formats).

Lastly there is the question on how much you trust your participants. If you don't a naive approach (like described above) might open the door for exploitation, e.g. looking at the example above, a malicious player could literally just waste time by not sending any data, while all other clients have to wait. So you might need additional security mechanisms.

For the beginning I would keep it simple, start with a local network TCP based apporach and look how far you come. Simple TCP communication can be done using the "ssockets" unit, which provides everything you need to get started with a TCP client-server architecture.
A very simple server with ssockets looks like this:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   classes, Generics.Collections, ssockets;
  7.  
  8. type
  9.   TPlayerMove = record
  10.     // Player move information
  11.   end;
  12.  
  13.   TConnectionList = specialize TThreadList<TInetSocket>;
  14.  
  15.   { TGameHandler }
  16.  
  17.   TGameHandler = class(TThread)
  18.   private
  19.     FClients: TConnectionList;
  20.  
  21.     function ConnectedPlayers: Integer;
  22.     function GetConnection(AIndex: Integer): TInetSocket;
  23.   protected
  24.     procedure Execute; override;
  25.   public
  26.     constructor Create;
  27.     destructor Destroy; override;
  28.     procedure ClientConnected(Sender: TObject; Connection: TSocketStream);
  29.   end;
  30.  
  31. const MAX_PLAYERS = 4;
  32. const MIN_PLAYERS = 2;
  33.  
  34. { TGameHandler }
  35.  
  36. function TGameHandler.ConnectedPlayers: Integer;
  37. var
  38.   clients: specialize TList<TInetSocket>;
  39. begin
  40.   clients := FClients.LockList;
  41.   try
  42.     Result := clients.Count;
  43.   finally
  44.     FClients.UnlockList;
  45.   end;
  46. end;
  47.  
  48. function TGameHandler.GetConnection(AIndex: Integer): TInetSocket;
  49. var
  50.   clients: specialize TList<TInetSocket>;
  51. begin
  52.   clients := FClients.LockList;
  53.   try
  54.     Result := clients[AIndex];
  55.   finally
  56.     FClients.UnlockList;
  57.   end;
  58. end;
  59.  
  60. procedure TGameHandler.Execute;
  61. var
  62.   Player: TInetSocket;
  63.   NextMove: TPlayerMove;
  64. begin
  65.   while ConnectedPlayers < MIN_PLAYERS do
  66.     Sleep(100); // Wait for enough players to start
  67.   // Game loop here
  68.   // e.g.
  69.   Player := GetConnection(0); // get first player
  70.   Player.Read(NextMove, SizeOf(NextMove)); // get next move from player, will wait until information is sent
  71.   // Do something with next move
  72.   // etc
  73. end;
  74.  
  75. constructor TGameHandler.Create;
  76. var
  77.   clients: specialize TList<TInetSocket>;
  78. begin      
  79.   clients := FClients.LockList;
  80.   try
  81.     while clients.Count > 0 do
  82.     begin
  83.       clients[0].Free;
  84.       clients.Delete(0);
  85.     end;
  86.   finally
  87.     FClients.UnlockList;
  88.   end;
  89.   FClients := TConnectionList.Create;
  90.   inherited Create;
  91.   FreeOnTerminate := True;
  92. end;
  93.  
  94. destructor TGameHandler.Destroy;
  95. begin
  96.   FClients.Free;
  97.   inherited Destroy;
  98. end;
  99.  
  100. procedure TGameHandler.ClientConnected(Sender: TObject; Connection: TSocketStream);
  101. begin
  102.   if ConnectedPlayers < MAX_PLAYERS then
  103.     Connection.Free
  104.   else
  105.     FClients.Add(Connection); // Additional code to handle new players here
  106. end;
  107.    
  108.  
  109. var
  110.   Server: TInetServer;
  111.   GameHandler: TGameHandler;
  112. begin
  113.   GameHandler := TGameHandler.Create;
  114.   GameHandler.FreeOnTerminate := True;
  115.   Server := TInetServer.Create('0.0.0.0', 1337); // 0 IP -> All ips can be bound, port 1337
  116.   try
  117.     Server.OnConnect:=GameHandler.ClientConnected;
  118.     Server.StartAccepting;
  119.   finally
  120.     Server.Free;
  121.   end;
  122. end.
  123.  

TomTom

  • Full Member
  • ***
  • Posts: 133
Re: Tabletop Game Server/Client guidance needed.
« Reply #7 on: July 23, 2022, 09:52:57 pm »
Wow thank You for such detailed answer :). It helps :) Yes, I guess LAN will do for my project (some Virtual LAN software could be used with this? I mean similar to Hamachi...?)
Game is turn based, there is no need for haste. Game is/could be a little bit like classic pen &paper RPG (Dungeons&Dragons etc.).
Purpose of my project  is to provide a GUI for players. 4AD (Four Against Darkness) is based on d6 rolls. Everything is made with results of rolling a six sided dice and comparing the result with various tables. For example.
At start player rolls 2d6  and gets 2 digits, 3 and 4 so that forms number 34. Player looks in proper table in book that room nr 34 has this shape and he draws it on graph paper. Also player can decide where to put the room on the map (connect to other existing room). Then player rolls 1d6 for content of this room. Player gets 4. 4 in other table means there is a swarm of wasps in this room.  Then player rolls 2d6 to know how many wasps there are etc. etc. All these rolls are sent (somehow) to Server. Server use all this rolls results to generate  image of dungeon (topdown 2d Image). Players decide what to do, attack or try sth else.  If the attack then their statistic are compared to statistics of monsters in the room to see if the attack was a success (players are attacking one after another, but I need to figure out if this will work for my project). Then server sends image of dungeon to players, and sends back the information if the succeded in their actions (attack or sneak/escape etc). So server needs to generate and send image (PNG?) and simple text for example in log window to show results of actions. I hope all that makes sense :P. I need to figure out many aspects, how to translate this Pen&Paper game to virtual tabletop game because 4AD was actually designed as a solo game with just a "possibility" to play with others, but the rules for multiplayer version are just roughly descirbed in the book (I can make my own rules for that I guess).
Generating images, writing code for rules, drawing from the tables etc., all that  that I can do myself (I guess). What I need is to learn how to send all this to 4 people connected to the game, and to learn all that, I need to start very simple, with just connecting/disconnecting and sending/reciving text messages. So thank You for your answer :).


There are a few things you need to consider when designing such a network protocol. Do you want to have a dedicated server, player hosted or peer to peer (from your first post it looks like you want a player hosted game) and the question if the players are in a local network or you need to connect over the internet.

Generally I would recommend you a dedicated server approach, the dedicated server can than be hosted by one of the players, but this generally makes it easier to have game clients and game server logic separated. If the host wants to join the game, they are just another client for the server.
Also for the beginning I would recommend you for now to focus on local network, as this is much easier for a beginner.

Then the question is requirements you have to the handling of the connection and the flow of the game. Is you game very structured, e.g. turn based (e.g. chess where each player can only continue after the other has made their move) or is it a more chaotic real time where the game is going forth if the players react or not. Then how are your delay requirements and can you deal with package loss, e.g. in chess delay doesn't matter and if your move "get's lost" you get into trouble, while in a first person shooter, delay is crucial, and if one shot of you is lost it doesn't matter as much as you can just shoot again.
From this you can then select your protocols. general rule of thumb: Low latency -> UDP, structured and reliable -> TCP. You can also of course use higher level protocols, e.g. you could use Websockets if you want a TCP based event driven but connection based flow (so where each client has one persistent connection), or HTTP if you have a stateless request-response flow (for most games not realy fitted as most games the server might want to initiate communication and in HTTP the server can only send data to the client as a response to a request from the client)

From my understanding tabletop games are usually more a structured game, where a situation occurs and every player choses their moves and then the  reacts to those moves. So you could go with a very simpe TCP based system where each client connects to the server and then when it's their turn, the server just awaits data from them, and because no one else is able to do anything during this players phase, the server can pretty much just sit and wait for that players client to make their move. This is rather easy to build with raw TCP.

But you might want to have multiple channels for connections anyway, for example if you want to have a chat function, best to create a new connection for the chat which simplifies dealing with distinquishing between the different kinds of data (with different formats).

Lastly there is the question on how much you trust your participants. If you don't a naive approach (like described above) might open the door for exploitation, e.g. looking at the example above, a malicious player could literally just waste time by not sending any data, while all other clients have to wait. So you might need additional security mechanisms.

For the beginning I would keep it simple, start with a local network TCP based apporach and look how far you come. Simple TCP communication can be done using the "ssockets" unit, which provides everything you need to get started with a TCP client-server architecture.
A very simple server with ssockets looks like this:

« Last Edit: July 23, 2022, 10:06:40 pm by TomTom »


 

TinyPortal © 2005-2018