🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

TCP, login and database on a realtime world

Started by
4 comments, last by HyrTheWinter 4 years, 10 months ago

Hi there!

I've recently started to be very interested by multiplayers and the architecture of real-time worlds.

To start with, I have started a little tactical rpg (2d iso). Using TCP for everything (and to start small), no need 50ms movements.
Besides, I am starting to see how I could implement the "login/password" stuff.

I have read some things about it, but I'm not still unsure on how to implement it, I've got some questions and please correct me if I'm wrong! :)

  • The client establishes a TCP connection with the server (login server or world server)
  • The client sends login+password to the same server, using a secure way.
  • The server checks the database, loads the user and returns an encrypted token (I could do something similar to a JSON Web Token I guess)
    • Does the server keep in memory (in a dictionnary or something similar) all the user data associated to the socket id?
  • The client gets the token, launch the gui stuff, the player pushes his left arrow key, the client sends a message with an arrow key pressed
    • As TCP in a tunnel between two entities, does the client need to send the token in each message? Or is the TCP socket id enough (is it secure to use it?) to retrieve the correct user?
  • The servers checks the dictionnary to get the player previous position, and returns the new one based on the arrow key pressed.
    • When the server persists the player data in database? After X seconds if it's dirty? Or every request?
  • The client updates the player object with the new position

If I'm not wrong, the server keeps the current state of the world in memory and persists it every X seconds to the database to avoid billions of requests?

I'm having hard times to see the boundaries between the login/token stuff and the one-one TCP connection, and how the two work together in a "mmorpg" world.

Many thanks, for the answers and your time!

HyrTheWinter

Advertisement

Yes, you can use something like JWT. Another option is something like a Kerberos ticket. Another option is something like a web session cookie token.

The GAME server generally keeps the state of the player in RAM as long as the player is connected. When the connection drops, and occasionally when the player does something worthwhile (gains experience, or gains important loot, or whatever) the server typically checkpoints the state back to the storage system.

Note that the JWT should not contain the actual player state (as found in the database) because that would allow someone to log in and get token A, then log in and get token B, then play on token B, and if something bad happens, re-use token A to revert state back to the old state. The token should only implement authentication, and the actual data is transferred on the back-end between the game server and the storage system (database, file server, three-tier web service back-end, or whatever.)

A TCP connection is believed to be hard to hijack unless you have nation-state level access to the network, or are part of the ISP/transit chain for the connection. A TCP socket running TLS is believed to be hard to hijack even for those kinds of actors. Thus, if you either trust that the NSA or Chinese government don't care about your game, OR if you're using TLS for your TCP connection, using the socket as a persistent identifier for the player for as long as the connection is alive, is reasonable.

Also, for real-time games, you shouldn't think of each key press or action as a "request." Instead, think of the world as a large state machine, that evolves based on inputs/stimuli, where one such input is the passage of game time (tied to real time.) Player commands are messages that provide inputs to this state machine. The player object state is a subset of the large world state machine, and changes to the player state are communicated using messages going back to the client machine. An important architectural realization here is that there is no direct 1:1 (or even M:N) relationship between "input messages sent by the client" and "world change updates sent to the client" -- they are separate, unidirectional real-time message streams. Some of the individual messages may, at a higher level, end up being in the request/response form, but those are to be viewed as one of many patterns on top of the two directional message streams.

enum Bool { True, False, FileNotFound };

Many thanks for your huge answer! It helps me a lot.

You found exactly what I wanted to know about TCP.

However, if TCP is a reliable way to identify a player, what is the point of having a token? I just have to keep in memory server-side that the X tcp connection corresponds to the Y player and that's it, no?

Interesting, I didn't see it that way but you are right, it seems much more simpler and logic to see the world as a state which pushes notifications to clients where something in their scope changes.

There is no way to identify players across multiple/different connections.

When the TCP connection first comes in, you need to identify the player. You can do this by requesting the name and password, and check those against some data store, or you can have some other service that checks name/password and issues a token, and the new connection then verifies the token (rather than having to verify name/password.)

Which model works best for you depends on specifics.

enum Bool { True, False, FileNotFound };

Yes I was saying this in the case where I have only one server/one TCP connection which handles everything for a given player, but you are completely right.

Thanks for your time!

This topic is closed to new replies.

Advertisement