Is it possible to avoid threads in multiplayer Hangman game? - c++

I wish to implement a simple multiplayer Hangman game with the rule slightly bended.
Rule:
All the players have to guess the alphabets in the word at the same time. Whoever player guesses a correct alphabet gets a point, and the player who puts the ending alphabet gets bonus points.
This will be about speed. The faster correct guess gets you ahead of others.
I intend to have a Qt/QML based GUI and the programming language will be C++. Platform will be Linux.
I am thinking I'll need:
- One thread for handling user typing.
- Second thread for parallel display of what other players are typing.
- Third thread for parallel display of scores of every player on every player's screen.
Do I need these 3 threads or I am barking the wrong tree?

It sounds like you're planning to have this game communicating over the network, where each player is using their own computers and running a copy of the program.
You should only need one thread for the application, but you might decided that more threads will make it easier on you.
You can easily connect signals from player's typing (either use an event handler, or connect your widget's "editingDone" signal.) to the appropriate logic for updating the scores and showing the other player's answers.
I think you'll run into the most problems with deciding on how to properly network the application to all instances, assuming that that's what you're trying to do. But the Qt network stack can allow you to do asynchronous network communication without having to manually create new threads.

Related

Advice on software design of project

I plan to hook up a raspberry pi to a 64x64 led matrix, and writing a sort-of boot loader software written in c++. I would like the software to be plug-and-play with custom games I make. That is, I put all the compiled code for the games into a directory and the boot loader will recognize them and, using fork() and execvp() calls, run the selected games. I want there to be different states to the loader such as: start_state, game_selection_state, preview_state, idle_state to name a few. Each state would do their own thing and a transition from state to state based on input from a input device or idle time.
Now I do not know the best way as far as the architecture to set this up. I am not even sure that a state machine is the best way to handle this. But so far, what I have come up with is I would have 2 threads.
Thread 1:
Handles all the functionality and sanity of the states. This would include starting, stopping, and data of each state. It would also include function calls to transition from state to state.
Thread 2:
Parses input from the input Device (game controller) and makes sure a transition is valid. Then using a thread 1's function calls change the state accordingly. I planned on using a message queue to send any input that is not reserved for transitioning to the current state. (E.g A & B signify transitioning, but Y is pressed and would be sent to current state) This way the state can do what ever it wants with these button presses.
Now where this gets a little fuzzy is when the user picks a game a fork() call will be made inside a thread and I have read this can cause issues. If I did do it this way I would need a way to terminate or halt thread 2 until execvp() call ends.
Now what I want to know is this a valid or best way of implementing something like this.

Sleep or wait that doesnt stop the whole program?

So I'm pretty new with programming from scratch, have mainly used unity for a few years up untill now so my general programming knowledge is pretty good. Started studying game development at a university after summer though where we began programming from scratch and as a task we have to make a simple game in a 2D engine we made together in class.
So the game I decided to make was a copy of bomberman and I've gotten as far as where I'm now making the bombs functional.
The problem I'm having is that I don't know how to propperly add in a timer that counts down the time to where the bomb exlpode so the player can avoid it.
I've tried SDL_Delay and _sleep which both just pause the entire program so that doesn't work and I've searched around for more options but not really understood how things work. If I could get some expamples and links to pages that explains how to properly make something like this work (something easy and small hopfully :P) then that would be highly appreciated!
Note that we are using SDL in the engine.
Thanks!
Typically, a game uses a loop, in which you read user input (you are probably using SDL_PollEvent for that), advance the game state for a short time period and draw the screen. This loop is typically called the game loop, render loop or main loop.
A simple, accurate and typical way to delay an event (such as a timed explosion), is to store the future time into a queue. Then, each time the game state advances, check the first and therefore the oldest timestamp in the queue and if the current time is higher than the stored one, then we know that the the thing should now happen and you can call the function that executes the event without delay. Then remove the timestamp from the queue and check the next one until only future events remain or the queue is empty.
If the event delay can vary, then you'll need to use a priority queue to always get the event that should fire next.
skypjack points out in the comments that this is a problematic approach if you need to implement pausing the game. That can be solved by not measuring wall clock, but instead use a separate simulation time that drifts from the wall clock when the game is paused. They also propose a simpler solution:
store a timeToEvent (to be elapsed) and decrement it, so that you detach the game time from the real one. Once it's <= 0, it's its time.
That approach is simpler, but has more overhead for checking the expiration of deadlines.

Implementing a game turn-timeout on the server side

At the moment I am writing a turn based game for the iOS platform. The client is written in Objective-C with CocoaTouch, and the server is written in C++ for the Ubuntu Server OS. The server is connected to a MySQL database, in which it stores user & game data.
Right now I wish to implement a time-per-turn restriction, and this has to be done on the server side. When a user takes a turn, the next user will have a maximum of 24 hours to answer, otherwise I want the game to skip this user's turn and move on to the next player. I have some ideas about how to do this, but I am not sure if they are any good. What I've been thinking of is storing the date&time of the last turn taken as an entity related to the Game table on my SQL database. Then I'm thinking of launching a thread on the server which runs until termination, and looks up current time minus every game's last turn, say every minute or so. If it's been more than 24hrs since the last turn was taken, this thread allows the next player in the queue to take their turn, and skips the lazy player.
Does it sound over-complicated? Is there another, more simple way to do this? I know it's been done in many games before, I just don't know how. Thanks in advance!
I don't think you need any threads or background processes at all in this case.
What I see here is a simple algorithm:
When a user logs in to the game/match - check up the last turn ending time in the database,
If the elapsed time from the last turn ending time is greater than 24h, get the current time, substract the time from the database (obviously you need to convert both times into hours) and divide it by 24,
If the division yelds an odd number, it's the turn of the other player (player A)
If the division yelds an even number, it's the turn of the player B.
Set the database time to databaseTime+division*24
This algorithm can skip multiple turns. When player A finishes his move, and 48h passed, it's players B turn.
You probably just want a background process that has a schedule of "next actions" to take, a sort of priority queue you can work through as the events should be triggered.
A single process can handle a lot of independent games if you design the server properly. The architecture would pick up an event, load any associated data, dispatch accordingly, and then go back to waiting for new events.
C++ does have frameworks for this, but you could prototype it in NodeJS or Python's Twisted really quickly.
Please look at the reactor pattern (boost.asio, ACE). These frameworks are asynchronous, use an event-driven model and require no threads. Below is pseudo code on how you can solve it:
reactor.addTCPListener(acceptSock(), Handler::AcceptSock) // calls AcceptSock when accepting a new TCP connection
rector.addTCPListener(clientSock, Handler::ClientData) // calls ClientData when user is sending the server game stats (its move, status etc)
.
.
.
later on somewhere
.
.
.
for(set<Game>::Iterator it = games.begin(); it != games.end(); ++it) {
(it*)->checkTurn() // this call can be responsible for checking the timestamps from the ClientData function
}
Summary:
With the reactor pattern you will be able to have a non-blocking server that can do cleanup tasks when it is not handling IO. That cleanup can be comparing timestamps to switch/pass turns.

Achieving game engine determinism with threading

I would like to achieve determinism in my game engine, in order to be able to save and replay input sequences and to make networking easier.
My engine currently uses a variable timestep: every frame I calculate the time it took to update/draw the last one and pass it to my entities' update method. This makes 1000FPS games seem as fast ad 30FPS games, but introduces undeterministic behavior.
A solution could be fixing the game to 60FPS, but it would make input more delayed and wouldn't get the benefits of higher framerates.
So I've tried using a thread (which constantly calls update(1) then sleeps for 16ms) and draw as fast as possible in the game loop. It kind of works, but it crashes often and my games become unplayable.
Is there a way to implement threading in my game loop to achieve determinism without having to rewrite all games that depend on the engine?
You should separate game frames from graphical frames. The graphical frames should only display the graphics, nothing else. For the replay it won't matter how many graphical frames your computer was able to execute, be it 30 per second or 1000 per second, the replaying computer will likely replay it with a different graphical frame rate.
But you should indeed fix the gameframes. E.g. to 100 gameframes per second. In the gameframe the game logic is executed: stuff that is relevant for your game (and the replay).
Your gameloop should execute graphical frames whenever there is no game frame necessary, so if you fix your game to 100 gameframes per second that's 0.01 seconds per gameframe. If your computer only needed 0.001 to execute that logic in the gameframe, the other 0.009 seconds are left for repeating graphical frames.
This is a small but incomplete and not 100% accurate example:
uint16_t const GAME_FRAMERATE = 100;
uint16_t const SKIP_TICKS = 1000 / GAME_FRAMERATE;
uint16_t next_game_tick;
Timer sinceLoopStarted = Timer(); // Millisecond timer starting at 0
unsigned long next_game_tick = sinceLoopStarted.getMilliseconds();
while (gameIsRunning)
{
//! Game Frames
while (sinceLoopStarted.getMilliseconds() > next_game_tick)
{
executeGamelogic();
next_game_tick += SKIP_TICKS;
}
//! Graphical Frames
render();
}
The following link contains very good and complete information about creating an accurate gameloop:
http://www.koonsolo.com/news/dewitters-gameloop/
To be deterministic across a network, you need a single point of truth, commonly called "the server". There is a saying in the game community that goes "the client is in the hands of the enemy". That's true. You cannot trust anything that is calculated on the client for a fair game.
If for example your game gets easier if for some reasons your thread only updates 59 times a second instead of 60, people will find out. Maybe at the start they won't even be malicious. They just had their machines under full load at the time and your process didn't get to 60 times a second.
Once you have a server (maybe even in-process as a thread in single player) that does not care for graphics or update cycles and runs at it's own speed, it's deterministic enough to at least get the same results for all players. It might still not be 100% deterministic based on the fact that the computer is not real time. Even if you tell it to update every $frequence, it might not, due to other processes on the computer taking too much load.
The server and clients need to communicate, so the server needs to send a copy of it's state (for performance maybe a delta from the last copy) to each client. The client can draw this copy at the best speed available.
If your game is crashing with the thread, maybe it's an option to actually put "the server" out of process and communicate via network, this way you will find out pretty fast, which variables would have needed locks because if you just move them to another project, your client will no longer compile.
Separate game logic and graphics into different threads . The game logic thread should run at a constant speed (say, it updates 60 times per second, or even higher if your logic isn't too complicated, to achieve smoother game play ). Then, your graphics thread should always draw the latest info provided by the logic thread as fast as possible to achieve high framerates.
In order to prevent partial data from being drawn, you should probably use some sort of double buffering, where the logic thread writes to one buffer, and the graphics thread reads from the other. Then switch the buffers every time the logic thread has done one update.
This should make sure you're always using the computer's graphics hardware to its fullest. Of course, this does mean you're putting constraints on the minimum cpu speed.
I don't know if this will help but, if I remember correctly, Doom stored your input sequences and used them to generate the AI behaviour and some other things. A demo lump in Doom would be a series of numbers representing not the state of the game, but your input. From that input the game would be able to reconstruct what happened and, thus, achieve some kind of determinism ... Though I remember it going out of sync sometimes.

Game main loop logic

I'm writing a game in c++ using allegro 5. Allegro 5 has events which are stacked in an event queue(like mouse clicked or timer ticked after 1/FSP time). So my question is how should be the logic of the main loop of my game, or since it's event based I can implement it without the main loop??
Any ideas how real games do it? Links will be good.
I have no experience with Allegro, but when using SFML and rendering a game with OpenGL, I myself poll the event queue as part of my main loop. Something like the below pseudo-code (but more abstracted):
while(game_on)
{
auto events = poll_occured_events();
for_each(events, do_somewithng_with_event);
render_game();
}
Seems to work fine so far... I'd guess something similar is possible in Allegro. Event driven games are tricky, since you need to continually update the game.
You could (possibly) have the main loop in another thread and then synchronize between event thread and game thread...
I don't have any experiences with Allegro too but logic would be the same.
(so called) Real games also have game loops but the diference is they use threads which are working parallel but within different time intervals. For instance there are different threads for physic calculations, AI, gameplay, sound, rendering... as user events are usually concers gameplay events are getting collected before it (as Max suggests) and consumed until the next frame (actually some collects it in for instance 5 frames).
As a frame might get too long, all the events coming from OS are getting collected by the game for that reason these inputs are called buffered input. There is also one another method which is called unbuffered input which doesn't work discrete but instead you test it during gameloop at the very instances it is queried.
If the user input is very important and you dont want to loose any inputs at all then you can use buffered otherwise unbuffered. However unbuffered might be tricky especially during debug.
here are some links
book excerpt game engine
Game Loops on IOS