What's the approach to use when developing API with a callback? - rest

What's the approach that should I use to develop an API that receives two moves and return a result (win/lose/draw)?
Scattegories game
Example:
Animal that starts with letter L
Player 1 - move: Lion
Player 2 - move: Lyon
thegame.com/api/v1/game/1/player/1/move/1
thegame.com/api/v1/game/1/player/2/move/1
How return the result to the players?
Should object player wait for the response or ask result?
What's the best way to develop an API with a callback?
Any other way to resolve this kind of problem?
Thanks.

Plurals are a bit more common, ie:
thegame.com/api/v1/games/1/players/1/moves/1
I think it's probably more logical for moves to be directly under the game, independent of players:
thegame.com/api/v1/games/1/moves/1
where each move has an associated player who made the move. This would make it easy to re-run all moves and understand the game history.
For players, their canonical URL would be independent of games
thegame.com/api/v1/players/1
You can still have a way to access all games for a player and all players for a game, if you like
thegame.com/api/v1/players/1/games
thegame.com/api/v1/games/1/players
Assuming this is a 2 (or more) player game with humans waiting on each other, you could probably make each client poll the game every few seconds. e.g. if a client has made the latest move, it starts polling the URL thegame.com/api/v1/games/1?moves_since=123456. This returns a list of all moves since the timestamp 123456. The timestamp could be the time the last move was made by this user. Once it returns a valid move, the client shows that to the user and waits for them to make their own move. If there are several players, the "game" resource could include a field like "nextMover" to indicate which player is next to make a move.
A more modern way would be to use something like Websockets so the client gets an immediate push from the server when changes occur. It's mostly a similar design but server immediately notifies all clients of updates instead of clients polling.

Related

Sending game state only for entities that are "visible"?

Let's say I have an open world game that supports multiple players.
The game stores their positioning by X and Y in this world.
Also, whoever is playing the game can see a canvas of 11x11, where his player-self is represented on this screen, always centered.
The game world has 1000x1000 squares to walk using keys.
What I know is that:
I could emit events whenever a player walks,
check this event data at the server-side (to see if it is possible and the speed is correct/anti-cheating measures),
update the game state which contains all players and positioning,
re-emit this state from the server so every client would be able to render properly this new player.
The problem is, should I really update someone who isn't even being seen?
When everyone is walking around, moving items, earning levels, etc - those events are being emitted from the client, and that's okay, but thinking about the server-side, it will re-emit that for each update state, and, maybe that will be overloaded?
Also, sending the whole game state, even if it isn't being rendered, opens so many breaches to cheating that this made me think that there is another option.
I'm a beginner at Networking and Game Development, and that is being hard to get into my mind - so I decided to try and put it into a question. This way, maybe with someone reading what I'm thinking about, I might get some clarification. Perhaps I'm just thinking about it the wrong way.
Q: should I really update someone who isn't even being seen?
There is no need.
The normal way MMORPG games do in the server side is to cyclely process network packages and some other calculations like the connection of players like skill cast or something else.
The central of a server may look like below
void run()
{
while (true)
{
processNetwork();
processSkills();
processMoves();
...
}
}
The loop will run several times a second, like 20 frames a second is enough cause players can not feel the little frame, they think they move/play smoothly but the trueth is not.
For your question, player only need to see some little area, when he moves, the server will braodcast his postion to others in the area and the players in his area in the next frame.
And that is just the simpliest model, actual model will be more complicated and we will detach different functions of the game to different server, sucn as chat server, battle server, auction server and others.

How to synchronize a 1v1 realtime action online mini game?

What I'm trying to make
Hi, game development newbie here. The game I am trying to make is fairly simple. It's almost exactly like the old FC game "Ballon Fight" except that I'm trying to make it online where players can go through a match making to find opponents.
BalloonFight:
What I Read
I have read some articles, and found most of them lead to two approaches:
Put all game logic on the client, and the client sends player inputs to server on every frame update. The server acts like a dispatcher which only makes sure player A's input is received by both client A and B. My understanding is that if we see the client in this case as a pure function, and if the two players' inputs are received by each other, the game should produce same results on both clients. Thus synchronization is achieved.
Put all game logic on the server, and let the server do the calculations and send back results to both clients. In this case, clients only worry about displaying.
My Fears
Solution 1 sounded like a simpler one to me, but immediately I realized when network problem is put into account, it becomes incredibly complicated. Losing player A's connection for a few seconds means all the input is lost in that period. What I can guess is, to counter that, the server has to detect whether player A is lagged out and accumulate input from player B until player A is back then feed all the accumulated input to player A's client. Player A's client then need to do a fast forward to catch up. This sounds like there's huge amount of infra work on both client side and server side.
Solution 2 on the other hand looks very daunting to me, since for now I have only written some games on the client side.
My questions
in order to make a simple online game like this, what is the most beginner friendly way to synchronize game state?
if I were to use solution 1 stated above, is there any framework that provides such infra so that I don't have to handle network issues all by myself?
In advance, thank you game dev gurus.

Game Center Simultaneous Turns

I'm new to iOS (although I do have a lot of C++ experience) and I am working on a turn-based card game using gamecenter. Here's the catch - The player who's turn it is is the judge and waits for all OTHER players to play a card before the turn is over. Is there a way to do this in Game Center, so all players chose what to do simultaneously and once all have done so, the judge is notified, makes a decision, and then passes priority to the next player? For example, say we start turn 1. I ask the question, #"What is your favorite color?" to all players passing them a gamestate which has that as the question and them not having answered it. Then you respond, #"Green", and our friend Steve responds #"Blue". I then decide which is better, give one of you a point, and then whoever I gave the point becomes the new judge. My question is, how do I allow all players to respond simultaneously, rather than sequentially. I know that, worst case, I could sequentially loop around through players until it comes back to me, then judge it, but this would slow down my game and make it less fun. Is there a way to do this simultaneously?
I agree with NSSplendid about the API for turnbased games requiring sequential turns. The only truly simultaneous method would be using the real-time matches from GKMatch, and that isn't really an option for games with more than a few players.
However, the sequential version could be improved slightly by using a programmatic approach to game center instead of the default view controller.
Ending a turn fires off a push notification through Game Center, and by using GKTurnBasedEventHandler's method handleTurnEventForMatch:didBecomeActive:, you can receive that in your app. When the judge asks the question, have the users display that as part of the game, and have their responses stored locally until their turn. Once it becomes a given player's turn, they receive the notification, even with the app in the background.
In the method, it can check the locally stored answer and end the turn immediately, if they've answered. If they haven't, send the turn once the answer is complete. It's not truly simultaneous, but the judge gets the answers as soon as everyone has responded, without the players having to wait for one player to finish before they can enter their own answers.
The players won't get the notification that the judge has ended their turn until they open the app, but they can't see the question anyways without doing that. Another approach to this, though slightly wasteful, is after the judge ends their turn with their question, is to do a runthrough of all the players ending their turn as soon as they get the "Your turn" notification, so everyone knows a question has been asked, then doing the steps from the previous two paragraphs.
The iOS API is built around the model of sequential turns. While the workaround you mentioned will work, there is no way to get GC to do real concurrent turns. Sorry ):

Game Kit Peer to Peer

I coded a bomberman application that uses a gamekit peer to peer connection. The problem is that after a while the game isn't in sync anymore.
I looked at the sample code for GKTanks and used their model. There is no client/server relation between peers so I didn't use one in my game. Both peers maintain a gamestate which they update based on received data.
I have a NSTimer that's used for running the gameloop at each frame. The NSTimers aren't in sync so sometimes the gamestates become different ex: players pick up a powerup at approximately the same time and they both get the powerup because it takes a while to send data.
I would appreciate any idea on making the app work. I'm thinking of rewriting the code to use client-server but I'm not sure if it's a good idea... yet
Thank you!
EDIT: I changed the code such that a random player is picked to be the host.
Every time a player places a bomb he asks the server where to place it. The server returns the players position(as seen on the server) and then tells the player where to place the bomb.
For powerups the server checks if a player picked up a powerup and if he did it sends a packet informing him.
Another problem has appeared now. The latency between devices is high(I'm using a bluetooth connection). It takes around 0.2 seconds to place a bomb after the client tapped the button to place it.
I'm sending all data reliably. Am I doing this right?
Well preferbly you want a host-client relationship where only the host can manipulate the game state, so in your case it would be:
Both players rush to the powerup.
Host picks it up first.
It gets registered and the host recieves the power-up.
Meanwhile player#2 also picks up the power-up, sends the action to the host.
The host informs player#2 that the power-up is already disappeared.
The thing with your situation you are bound to get desynchs from packet loss.
With host-client relationship that cannot happen, the only problem is the host always has an advantage that becomes greater when the latency increases between devices especially on smartphones.
In a game like bomberman it's perfectly plausible to send the entire gamestate each time something changes instead of the action that was performed, this is to ensure both devices are in sync.
To sum it up: both users have their gamestate but only the host can manipulate both.
what you should do:
one of the devices is host, another one is client
host process all the game states and makes decisions, then it sends whole gamestate to the client
client gets the gamestate and just draws everything based on it - it doesnt make any decisions (who picked bomb, did bomb exploded etc)
client just sends input to the host (pressed left,right, pause etc)
that's it. if you try to make decisions on both machines, you will run into big troubles trying to keep them in sync.

How to avoid create one thread per room (group of players)

I have made a game (is still in Beta, need improvements, and other things), and I would like to know if exists a better approach of what I have done in my game servers. (Programmed on C#)
The process to play a game is something like this:
Client application (player) → connect to lobby server → check for an available room with the game he likes to play → the lobby answer the request and point the player to right game server (all using "raw" TCP/sockets).
Each game server automatically start the game when exists at least 4 players in the room (multiple rooms are possible) and a maximum of 12. Each room is launched in a different thread, I mean, I create one thread per room (4-12 players), so if I have 1.200 (many more can be expected by game server) then will be at least 100 threads (even more depending of how many players are really in each room).
The main thread (and is work) plus all the threads created will be consuming all resources in my server... so, I was wondering if anybody can suggest a better idea or approach?
Keep in mine that all the connections are asynchronous, except in the room, I mean, in the room the server must wait for the move of one player (like a Ludo game or a bet) to let the next player (in the room) do the same. In fact, the buttons to make a move are enabled only to the player that is turn to move on. For that reason the transmission in place is synchronous and when somebody move the rest receive their respective notifications.
If you can wait on multiple sockets in the same thread (that I don't know and it's probably OS-specific) and you can unambiguously associate incoming data with a particular socket (this you should be able to, I think), then you can service all rooms (or just a few) sequentially in the same thread and thus save on per-thread data structures in the OS and the per-thread stack. You will likely need to implement some kind of a state machine to achieve that and rearchitect your data structures.
Coming from a MUD development background, the usual process for this kind of thing is to work on a "heartbeat" model:
You have a timer thread, which fires a heartbeat event/message at regular intervals.
With each heartbeat, a subscribed reader-thread checks all the connected sockets to see if they have any data to read. If so, the commands (button presses, etc) can be put in a queue (along with an indicator of which user, room, etc) to be read by the main game processor.
Game processor simply processes messages from the incoming queue, and produces responses (which can be put on an outgoing queue for delivery, if you fancy it).
This is how I've always done it when writing chat servers, talkers, and MUDs, and sounds like it could be a good fit for your requirements too.
HTH