I've been doing some reading about the various forms of multiplayer that exist today. In a nut shell, I believe the industry standard way involves the following:
Running the physics for each client on the client machine/device
Sending the input data of this physics to the server (could be another client running a 'server' session along with their own client data)
Server processes this data to determine if the client is making legitimate moves, and if not, forces the client to sync to it's instructions (Rubber banding).
Server forwards historic data from other clients to each client for simulation.
Effective result from each clients perspective, is playing themselves in the present, while seeing the other clients in the past.
Hit detection is performed on the server by 'rewinding' the game state to see if at the time stamp an event occurred, where the affected players were at that point in time.
Presently, I use a pure dead-reckoning system. Inputs are collected from each client and physics calculated on each client. This works, however units quikcly get out of sync and rubber band because the dependency on a players previous position/speed/orientation is not high enough. AKA: they are free to change directions and speed quickly and often.
With that being said, how do I solve this?
Is my client simulator effectively supposed to collect several data points for each player and interpolate the rendering between those nodes? (IE: each client has multiple data points about all the other clients historic positions).
As such, my client's simulator drawing player B, would have positions X0, X1, X2, X3 in a queue at time 0. Between the transition of Time 0 -> Time 1, I know the starting relevant values (location, speed, orientation, etc) and where he should be come Time 1.
Is the solution to interpolate these values between these known historic times and data points?
Thanks!
Ryan
Related
People! I thought to include it in original question but didn't.
WHILE VOTING, YOU ARE ALLOWED TO COMMENT WHY DID YOU VOTE?
Please use it to enable learners get theirs things done and convey their thoughts/issues to others better way. Not everyone knows what you think. Thanks
In Short:
I need to synchronize clocks of two Android Phones (placed close to each other OR not; both cases) with each other AND with up to an accuracy of a few milliseconds (10, 20 ms max).
Either sync the clocks
Or get an offset of one from the other
What I am Doing:
I have a developed app that I am using to measure different GSM network statistics. I am using telephony manager to get three states (OFF-HOOK, IDLE, RINGING). Phone A calls phone B. Both phones are running an app that is saving the time-stamps with regards to the states mentioned above. After making many calls I export the time-stamps in a data file and analyze them to get different network stats.
What is my Issue:
I have to cross-match the time-stamps to get stats. Now the problem is that if the phones' clocks are not synced then I will not be able to get exact stats (e.g. how much time it takes to get phone B in ringing state after phone A initiates a call?).
What I have Tried: So far I have tried to sync clocks with NTP, GPS or atomic clock. I have used ClockSync (Android app) to get offset of both phone clocks from atomic clock. The issue is that this offset depends on RTT of network packets from my phone to server. I gives my difference of up to 100 ms when I check offset two times (tap refresh two times consecutively). The offsets at both phones can lead to error of up to 200 ms which is unacceptable for me.
All other syncing apps/methods have same issue.
Possible way forward: (What I think). I may develop an app that
takes the time-stamp at phone A
transfers that to phone B via Bluetooth or WiFi (connected to same router),
B then compares that time-stamp with its own clock, calculates offset,
And I run my original app, run experiments and,
Use the offset to correct time-stamps before processing data
Your Comments/Suggestions: How to do it? And comments on the method described in last part..
I'm developing an Android application to control my quadcopter from the smartphone: I have a periodic process that sends the data acquired from the touchscreen.
The data in then received from a microcontroller, that generates a PWM command to 4 DC motors, obtaining the duty cycle values with a control loop that exploits the received commands.
Can someone suggest a precise criterion to choose the period of the process on the smartphone? Or it is possibile only a "trial and error" approach, checking the reactivity of the system?
EDIT: I have successfully implemented it just setting the frequency of the smartphone task as 2*control_loop_frequency
If you knew or could measure the impulse response of the system it would be possible to determine an appropriate control loop rate; however you do not have that data and it will be confounded in any case by external factors such as wind speed and direction. Determining the rate empirically will be faster than determining the precise characteristics.
If the control is open-loop, then probably you have to ask yourself how far off the desired course can you allow the vehicle to get before a correction is applied. That will depend on the vehicles maximum speed (in any direction).
In the end however Android is not a real-time operating system, so there are no guarantees that any particular periodic update will be performed precisely; its always going to be somewhat non deterministic. At a guess I would imagine that such a system might manage 10Hz update reasonably reliably and that would probably be sufficient for adequate control and responsiveness - if the only feedback is via the human controller's hand-eye coordination, that is perhaps the limiting factor in the system response.
I'm using Delphi XE7 for developing mobile application. And I'm using TIdtcpClient component to interact with the Server application. And I need to know for Android mobile & iOs mobile app, what is maximum size of data which I can send at a time to server. Or it depends on the speed of the internet. Please help me in this
TCP sockets are data streams, the length of the transmitted data is unlimited. For data with fixed length, client and server have to know when the stream ends, either by sending length information first before sending the actual data, or by using a end-of-data symbol / terminator sequence. You can also send an 'endless' stream, for example live audio / video data, which continues until one side disconnects.
There is no theoretical size limit to data that you can sent. Limitations are because of system resources/processing power, bandwidth availability and of course time that it takes to send.
System resources in the case of mobile devices will be memory, cpu power and data availability (cost per data) as it will most probably be for other platforms as well. Another resource that influences performance is the developer; the worst he writes the app the worst it will perform.
Bandwidth availability will determine how fast that chunk of data can be sent which directly influences the time it takes. Who wants to wait forever, right?
One more thing that is important, is the recipient. How patient the recipient is and how much resources he has also influences how much data you can send him.
So if you have plenty of time and resources then you will be able to send large amounts of data.
The Indy suite which TidTCPClient is part of, uses TidBytes as a memory data container into which an array of bytes is stored (the bytes that make up your data). Those TidBytes arrays are used to hold the data that you send or the data that you receive. They are handed to TidTCPClient when sending or receiving. The size of TidBytes arrays are once again limited by resources of the sender/receiver. If that causes an issue then you can break the data into smaller chunks then send them one-after-the-other. As long as you indicate to the recipient how big each chunk is, as mentioned by mjm and in the case of segmented sends you must also indicate which segment goes where in the complete data stream. A way of indicating to the recipient is to prefix the size of the data as either a byte, word or integer to the start of the entire package that you will send and as long as the server knows to either read the first byte, word or integer he will know how much data will follow that indicator and thus know how much data to expect as actual usable data.
Seeing that you might not know how much resources the recipient has it is wise to always break large amounts of data up into smaller chunks. This unfortunately is something that you will have to test to figure out how large. Also keep in mind the technology that will be used to send it across. For example Ethernet has certain packet sizes and if data is broken up into too small sizes it might cause too much overhead. The trick is to try and find the balance. Do not worry about that too much but do read up on it.
I have 2 android phones phones, both connected to the same wifi, both with bluetooth.
I want some method that syncs somehow the phones and starts a function on the same time on both phones.
For example playing a song at the same time.
I already tried with bluetooth but its with lag, sometimes 0.5 secs. I want something in +- 0.01sec if possible.
Someone suggesting playing it in the future with 2-3 seconds, sending the time-stamp, but how do you sync the internal clocks of the devices then ?
Before calling that particular method, try to measure the latency between the two devices:
1.First device says Hi(store the current time)
2.Second device receives the Hi.
3.Second device says back Hi !!
4.First device receives the Hi.((storedTime - currentTime) / 2 )
Now you have the latency, send your request to second device to start your particular method and start it on first one after the latency.
Try to measure the latency 5 to 10 times to be more accurate.
you have a way to transfer data between the devices right ?
if so you can send a time-stamp which is in the future,
ex: if the present time stamp is 1421242326 you send 1421242329 or something and start the function at that time on both devices.
Basically use #Dula's suggestion (device 1 sends command to device 2 and gives a "start time" which lies in the future). Both devices then start the action at the same time (in the future).
To make sure that the devices are synchronized, you can use a server-based time sync (assuming that both devices have Internet access). To do this, each device contacts the same server (using NTP, or HTTP-based NTP, or contacts a known HTTP server, like www.google.com and uses the value in the "Date" header of the HTTP response). The "server-date" is compared to the system clock on the device, and the difference is the "time-offset from server-time". The time-offsets can be used to synchronize on the "server-time", which is then used as the time base for the actual action (playing the media, etc.).
If your WiFi router allows clients to talk to each other (many public hotspots disable this), you could implement a simple socket listener on one (or each) device and have the initiating device broadcast a message.
For more complicated things and network flexibility, I've had good success with connected sessions using AllJoin. There is a bit of a learning curve to do interesting things, but the simple stuff is pretty easy once you understand the architecture.
Use a server to provide a synchronous event to just the two clients who have decclared their mutual affinity (random as a parm and pair serializer Partner-1 or Partner-2 which they share prior to their respectve calls for the sync event).
Assume both clients on same subnet (packets from 2 events serialized on the server , arrive across the network at the 2 clients simultaneously client-side) This provides synchronous PLays by 2 , bound clients.
The event delivered by server is either a confirm to play queued selected track OR a broadcast( decoupled, more formal)
The only tricky thing is the server side algorythm implementing this:
Queue a pair of requests or error
Part1, part2 with same Random value constitute valid pair if both received before either times out.
On a valid pair schedule both to the same future event in their respective , committed responses.
OnSchedule do the actual IO for 2 paired requests. Respective packets will arrive back at respective clients at same time, each response having been subject to equal network latency
Ng if two diff carrier 4G or lte networks involved. (Oops)
This thing is possible via socket, you will send a event via socket then the other device receive that event. For learn socket io chat
maybe it's not the answer you are looking for but i think that due to the high precision you are wanting , you should look for a push technology, i advice you to take look at SignalR. It's real time technology which gives you abstraction of sending methods , it have a built-in methods like Clients.All.Broadcast that fit your needs.
You can try to use some MQTT framework to send message between two device, or into a set with more number of devices.
TL;DR
android, board-like game.
latency unimportant.
client-server via LAN/Global, potential high score => no trust.
potential bluetooth layer in future => full trust.
mobile means expensive traffic, upstream more expensive than downstream.
PRNG used a lot, must be deterministic.
kryonet for serialization + transmission
Me & a couple of pals are building our "port"/"flavor" of a board-game (with a lot of different event-types and permutations of all sorts) to Android and adding a networked multi player aspect to it. We are no encryption or networking experts =)
The game:s default multi player layer will be client-server based (server is either dedicated host or run on an android device [in case you're out in the woods with your friends and you've no network] ). This might be a global server, or LAN - it doesn't matter much.
But there might be a potential high-score which needs some anti-cheating mechanisms
As it is a turn-based board-like game, latency is neither an issue.
In the future, if we've time - we might add a bluetooth based layer, but in this case cheating is not an issue as the assumption is that the people know each other well.
Since we're dealing with a (most likely) mobile network where upstream is more expensive than downstream, downloading from server is cheaper than sending the models from client.
We'll probably be using kryonet for the serialization and transmission of data.
The game will use PRNGs quite frequently, and as such it needs to have some good anti-cheat and verification logic, so after a lot of searching and reading at gamedev & stack overflow, I've devised the following logic. I need some input on how sound the plan is. All tips and recommendations are greatly appreciated.
Assumptions / Considerations:
PRNG behaves deterministically ( thinking of using Mersenne Twister ).
Normal game play shouldn't be penalized due to anti-cheat measures.
Scheme / Plan:
On "handshake" / first connection since "onResume()" - acquire PRNG seed from server and store it. Each player has its own seed in server.
Also send hash of game state to server in same request and if out of sync,
sync game state.
On action / user input, get next random number -> save to "bucket of randoms" (hence known as bucket - the bucket is a "trapped list" to which you may add but never remove). Also save input ID/Type/Enum to a list.
Accumulate changes until other players have to know (i.e next players turn) / PNR (Point of No Return)
PNR reached
Send change ID/Type/Enum ( ca. 64 bits ) + bucket + hash (post change) of model. Should bucket + hash be encrypted, maybe AES 256 (other encryption tech that's more suitable?).
Check bucket against N consecutive random numbers where N = size( bucket ). If no match, goto 6, then 7.
Make changes to model temporarily (without committing to full game model).
Compute hash and check against client provided hash. If invalid goto 6.
Valid: commit to game model on server.
Invalid: ask client to revert to state sent back by server.
Cheat: Ban ( not IP [dynamic IPs...], rather MAC addr or UID ) / Remove from game on several cheats.
EDIT: Also - another question regarding anti-cheat... Any good ideas for antimeasures for bot teams of 2 farming highscores for a board-like game?
EDIT2: Here's the links to the pre-question research I did:
https://gamedev.stackexchange.com/questions/4181/how-can-i-prevent-cheating-on-global-highscore-tables
Good link (for de-centralized, client-client protocol): https://gamedev.stackexchange.com/questions/47145/peer-to-peer-hostless-competitive-games-of-chance
http://en.wikipedia.org/wiki/Commitment_scheme
iphone puzzle game: Code examples for simple game servers
Look into:
5) Use some lightweight polymorphic encoding on your game connections.
6) Use some anti-debugging techniques to prevent debuggers from attaching to your processes. Google anti-debugging and you should be able to find lots of stuff.
7) Use a custom proprietary PE packer to prevent useful disassembly of your game.
8) Using hashes as a promise, and then reveal the meaning of the hashed promise once conditions on the behavior of other players are met.
It's complicated, and it has performance impact, but some of the ideas may be useful, particularly to peer to peer games.
9) I think a good way to make harder the problem to the crackers is to have the only authoritative copies of the game state in your servers,
only sending to and receiving updates from the clients,
that way you can embed in the communication protocol itself client validation (that it hasn't been cracked and thus the detection rules are still in place).
That, and actively monitoring for new weird behavior found might get you close to where you want to be.
Realtime FPS related, less relevance to us:
Client-Server: How to prevent cheating in our (multiplayer) games?
linked: How to secure client-side anti-cheat
Automation: Protection against automation
Trusting clients, Howto take latency differences into consideration when verifying location differences with timestamps (anti-cheating)?
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
Do good multiplayer/mmo client<>server games use latency within movement calculations?
Howto take latency differences into consideration when verifying location differences with timestamps (anti-cheating)?
That's about it, hope you've got some tips!