Hello, my name is Artur and I am 3rd year IT student from Poland. For my final task before finishing my university I took something I always dreamed about but never got to work on, MMORPG. The whole journey with programming and IT overall started because of one simple MMORPG Tibia. It might sound ridiculous but I was fascinated and amazed with this game so much that I wanted to learn stuff to be able to change their open source code as I please and create amazing Open Tibia Server which could also become a good income. Well, as time goes on I learned many things and I graduated from being able to edit simple XML script to create new functionalities inside the source code. As now I am, I already wrote some simple games in Javascript, C++ using SFML. In free time I used to solve tasks on SPOJ, I got back to this like 5 days ago as well and am doing pretty well as for beginner.
That's it for story and introduction. I always dreamed of creating great game but never actually had enough of determination to sit down and do it. Now I decided that there is no way back and it's time for something big. To learn good programming habits, to make something what I could show my employer as show for what I am capable of. My last project to graduate from my university with engineer degree is MMORPG written in C++ using SFML library.
I managed to write simple Tic-Tac-Toe multiplayer using Tcp Sockets so I have some experience with networking but it's not client-server architecture. So the whole MMO in MMORPG stands for Massive Multiplayer Online. Massive means that even up to 500-1000 clients might be connected to server at one time. Here goes the question or advice. How to do it ? I already managed to get hold of basics and read about Quake UDP Client-Server Architecture. Here is my idea of how it works/could work:
Client:
1. We click on Start Game for example.
2. We type our username/password.
3.a) We are biding socket to connect with server.
3.b) We are sending "Handshake" message to server and wait for response.
3.c) We receive response (or we don't, then after X time we get problem with connection message)
4. We send our username/password to server.
5. We receive message (username/password not correct or our character/account data to render).
6. We render what we got (Character select menu for example)
7. We try to login to the game server so we send request to the server and wait for response again.
8. We receive data about our character and map which we need to render our game window.
9. We are sending requests/receiving replies all the time(update on npc movement, update on server time, update on chat, movement etc.)
Server:
1. We are loading everything to game world (map,monsters,database connection, spells, items,scripts)
2. We are binding socket to desired port.
3. We are waiting for connections/data requests(?)
4. We add verificated clients to our vector of clients / prepare replies for data requests.
//Here is something I am not sure about, we are receiving new connections in one thread and send data to those who connected already in other thread ? We use one thread for both like, first we check for other connections, send handshakes, save client to vector of clients and then check data requests ? Or maybe just use switch and depending on request, do something ? But then how to manage it with saving ip and port of clients to vector ?
Should it work like that? :
a) We wait for any packet
b) We make switch for packet byte and depending on what we receive, we do other thing ?
So we know then that if it's handshake then player is sending on other data his ip and port, if it's movement request then he sends only which direction he wants to move, if it's using something then other action etc.
But then it would be like
packet>>id_handshake>>client_ip>>client_port // for Handshake
packet>>id_movement>>enum Direction//for Movement
So should it work like this then?
packet>>id_handshake>>message [client_ip+client_port] // Handshake
packet>>id_movement>>message [enum Direction] // Movement
and using char/string functions should I extract data I need to their respective types ?
How do we send like whole map of objects, layers and stuff then ? It's complicated. It's really interesting but complicated for someone who is throwing himself into deep water as well.
Also why we need Selectors ? We have many clients but one socket which we bind into one port, right ?
sf::UdpSocket socket;
socket.bind(port);
socket.receive(packet,ip,port);
socket.send(packet,ip,port);
It doesn't work for many clients like this?:
for(int i=0;i<client_vector.size();i++)
{
socket.receive(packet,client_vector[i].getIp(),client_vector[i].getPort());
//Prepare packet depending on last request
socket.send(packet,client_vector[i].getIp(),client_vector[i].getPort());
}
I am new at it but I think that I am not too far off and in one year I will be able to complete my task and make my little dream come true. So far, so good. I managed to make simple client-server where server receives every client's IP and Port with information that client wants to connect to the server and sends back confirmation of connection. I have a lot to do but time is on my side. I will appreciate any valuable information, advice and clue. Thanks in advance !