Author Topic: Is TNet right for my game (1v1, turn based strategy)?  (Read 3756 times)

Zivix

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Is TNet right for my game (1v1, turn based strategy)?
« on: June 10, 2017, 10:30:40 PM »
Hello,

I recently purchased Forge Networking for my game, only to discover a number of large issues. I'm working with the community there to try to help fix the asset, but I'd like to keep my options open and look into other potential solutions in the event that the efforts with Forge are either unsuccessful or too slow.

With that said, I'm curious to find out whether TNet could be applied to my game or not. I'm working on a turn based 1v1 (for now) tactics strategy game. From what I understand, TNet is client authoritative with one "host" client. For my game, authoritative logic and anti-cheat is important, as I'm hoping the game will have a strong competitive presence.

With this said, do I need a completely authoritative dedicated server using another solution, or would it be possible to meet my needs with TNet? If using TNet, would I have the clients send function calls to a modified server, which would contain the authoritative code and be responsible for sending the two players the resulting state change? Or would I need to find a way to have a headless linux client serve as the server/host, but set up in such a way that only the two players have objects and the server can perform all of the authoritative logic for those objects?

I hope that my questions aren't too similar to those that you regularly see. I made sure to check the forums and video tutorials for any relevant information, but I couldn't find anything conclusive. I would greatly appreciate it if you could provide feedback regarding my needs and whether or not there is a way to use TNet to meet them while maintaining the competitive integrity of the game.

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Is TNet right for my game (1v1, turn based strategy)?
« Reply #1 on: June 10, 2017, 11:40:26 PM »
If you're willing to modify the GameServer, then yeah you can make it server-authoritative. If you need Unity's physics (colliders, raycasts, rigidbodies, etc) to be server-authoritative too then the server will have to run inside a headless Unity client.

Your second approach could work as well (as I understand it): you have a "dummy" client connect to the server and act as Host. All logic runs on the Host. You could probably get this working with minimal rewriting.

The great thing about TNet is how well it's written and how extensible it is, in my opinion. If you want to do away with all the high-level QoL stuff you can still find extraordinary value in just the way sockets are set up and managed.

WolfTechGames

  • Newbie
  • *
  • Thank You
  • -Given: 6
  • -Receive: 4
  • Posts: 35
    • View Profile
Re: Is TNet right for my game (1v1, turn based strategy)?
« Reply #2 on: June 11, 2017, 11:27:48 AM »
Yes, this is do-able in TNet. Just as cmifwdll said you can create a headless unity client, I have done this for my game. I listen for the headless command argument when executing the game then I launch a server with the name being another argument. I contain all server info in my name split by (char)58 so for example: "name (char)58 map (char)58 mode" then when I read from the master server I just split the name and fill in all the details. Now once you have that headless client, there will only be one host. So you can simply do authoritative commands by sending RFC calls to the host and having him handle all the logic and stuff.

Zivix

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: Is TNet right for my game (1v1, turn based strategy)?
« Reply #3 on: June 11, 2017, 05:14:10 PM »
Thank you both for your answers! TNet definitely is a tempting solution at this point.

So, I just want to ensure I have the right idea due to my issues with Forge. My game will be pulling and storing certain player data (likely from PlayFab), such as each player's teams and units. Then when the game begins, those units will be available in a party outside of the game board. Players will alternate turns, during which they will largely be moving units from their party to the board, moving units to new hexes, attacking enemies, and healing friendly units.

With all of this said, would you recommend I aim to modify the server file to create an authoritative server, or should I aim for a headless dummy client? My gut feeling is telling me that I should create a modified gameserver file that takes RPCs, performs the functions (probably mostly A* pathfinding, line of sight calculations, and damage/healing calculations), and then sends the result to both clients (among other things).

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Is TNet right for my game (1v1, turn based strategy)?
« Reply #4 on: June 12, 2017, 01:24:58 AM »
Depends:
If you need Unity engine functionality (physics, pathfinding, etc) then I think it'd be easier for you to implement the few modifications it'd take for a headless client.
If you don't need Unity engine functionality, and I'm guessing maybe you don't given your note about rolling your own A* pathfinding - which I assume means you can handle collision detection & line of sight on your own too - then I think it'd be easier for you to implement some modifications to the server.

However, both approaches do require modifications to TNet itself. This means digging through TNet's code, understanding it, and rewriting it to work how you want it to. If that's what's offputting about Forge then I'm not sure if the switch would be a good idea for you. TNet is written really well and like I said earlier you'll still find value even if you strip it to its core, but work is work and you might not have the time or resources for these modifications.

To address your concerns more specifically, though, TNet works mostly through RFCs (aka RPCs, literally the same thing) by default. You decorate a function with the [RFC] attribute then use TNObject.Send(...) to call that function. TNet then takes the player ID (TCP connection UID, basically), channel ID, UID of the TNObject being used, the function name (or ID if an ID is used in the decoration), and the parameters you pass to it, then wraps this all up in a Buffer (TNet custom memory class w/ built in pooling) and sets a packet identifier (using a Packet enum, eg; Packet.ForwardToAll) before sending it off to the server. The server receives the Buffer, reads the packet identifier, and handles it accordingly. There exists functionality within TNet to use custom packet identifiers and custom packet handlers on both the client and server, so you can see how it might be easy for you to implement your server-authoritative logic. Additionally, there's functionality to write and send packets directly if you don't want TNet to wrap it up like an RFC. Under the hood, there's extraordinary serialization support for most (maybe all!?) data types, including Unity objects (literally entire GameObjects, including the Components!). Though, as a sufferer of micro-optimization-itus, I must recommend against sending an entire GameObject over the network.

Also, multiple channels can exist on a single server. Channels can be used to essentially network-LOD a very large world, or can be used like separate "rooms". So you might be able to cut down on server costs by packing as many channels (and players) into a server.

If you do decide to go with TNet, here's some tips on where to get started with understanding and rewriting it:
The Player and TcpProtocol classes mostly handle the low-level connection & packet handling. I believe the first step in the "game" connection process occurs in TcpProtocol, but other than that you shouldn't have to touch anything here.
TNManager is essentially a wrapper around GameClient, with some extra functionality sprinkled in.
GameClient handles the actual packet processing on the client. All packets are first processed here, even custom packets.
TNObject handles client-side RFC processing, after being pre-processed by GameClient. An RFC will execute on the same GameObject you send it from on each Client. Check TNObject.isMine if you need to determine if that GameObject is local or remote.
Channel class probably won't need to be modified - understand the concept (and its applications) before trying to understand the code.
GameServer class is meaty. All packets are processed here, even custom packets. Also contains connection & channel management and saving / loading. Take note of the delegates made available and hook up your listeners.
DataNode is a tree-based class with full local and network serialization support.
Buffer is kind of a pooled MemoryStream class, you can use it for stuff other than packet construction.
Serialization (not accessed directly, just a *ton* of extension methods) is meaty as hell. If you run into unexplainable errors, it's likely you'll find something here in the callstack. Make note of the IBinarySerializable interface declaration. I use this interface for everything.

Zivix

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: Is TNet right for my game (1v1, turn based strategy)?
« Reply #5 on: June 13, 2017, 07:38:19 AM »
Thank you very much for the thorough responses! I have decided I'm going to go ahead and purchase it. I'm sure this won't be an easy endeaver, but I'm excited to finally make some progress in my game again!