Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 03 Jun 2003
Online Last Active Today, 07:40 PM

Posts I've Made

In Topic: browser games - when to update server data?

Today, 09:10 AM

For building games, storing the "finish time" (or perhaps the "start time" and "build duration") is absolutely the right thing to do.
This also lets the client do all the animation and estimation of when the building is complete; once the progress bar on the client is complete, the client simply asks the server what the state of the building is, and updates it.
That way, you only need to query buildings by their object ID, not by time. If you need the full state of the world, query all objects that belong to the player in the game instance, and derive their done-ness at the current date.
The client might want to periodically ask for a dump of all state anyway, to make sure it stays in sync, but this can be pretty infrequent, depending on the pace of gameplay. Every 1, 2, 4, 8, 16, and 32 seconds after a command has been given seems alright, with the presumption that once a command has been accepted by the server, the chance of it somehow reverting is slim.

I don't see how you're going to implement a traditional Tick method with PHP

I've seen PHP code that uses a process that hits a URL on a schedule to implement something like that.
I can't say that I like the pattern, because it wastes hardware resources a lot, but it can be made to work.
The benefit of PHP is that it scales horizontally very well, as long as you keep state in databases and network attached memory.
The drawbacks of PHP are that it's a home-grown hodge-podge of a language, which is a real problem for large projects, and its hardware resource requirements (constant factor) are very large.

In Topic: Syncing issues (algorithm description inside)

18 September 2016 - 09:12 PM

I don´t think you can solve this without a position sync and smoothly moving the player to his real position.

It is possible to get 100% sync in lock-step by design, as long as everyone runs the same build of the game on the same CPU architecture.
This is the whole point of "lock-step architecture," used in a lot of RPGs and a small number of other games.
(See for example the "1,500 archers on a 28,800 modem" article, which is the classic text on this method.)

In Topic: Syncing issues (algorithm description inside)

15 September 2016 - 10:10 PM

I find that building the networking such that you record every packet that comes in, with the game step at which it comes in at, and the full payload, is super helpful.
Also record system state, such as the clock value each time through the main loop.
Then, and this is the real important bit, build the reverse -- a reader, that, instead of reading from a socket, and reading the system clock, read from the file and returns those values to the program.
Now, you suddenly have a fully debuggable system, where you can pause/stop and single step as much as you want, without losing state.
And you can re-play as often as you like with the same state.

The replay files also make for great QA tools -- run an automated test at top speed without any graphics or delays, and make sure that the events you expect should be happening, do happen.
And, the final tip of that ice berg, is making record/playback available to players. But that's really just icing on the cake. The amount of time you save in development is the real win!

In Topic: Syncing issues (algorithm description inside)

13 September 2016 - 09:39 AM

There are a number of reasons that simulations can diverge. Examples include:

- If there are multiple players, the position of player B on player A's computer when running simulation step X will be different than on the server (bacause of latency)
- If the server and client have different CPUs, slight implementation differences where the last bit of some math function is different, and the butterfly effect makes it diverge
- Random generators used for simulation outcomes may end up with different seeds or being called in different order
- If you use a software physics engine like ODE or Bullet, the order that the constraints go into the physics simulation may vary, leading to subtle math differences
- If you use a GPU physics engine like PhysX, you will additionally get math bit mis-matches across different GPUs

Options 2 .. 5 can be solved with a carefully constructed simulation engine.
Option 1 is a killer for FPS-type games, because the only real solution is to wait to simulate until all commands/positions of remote players are known, which means that you have a round-trip time of latency between command and action.
This is why RTS games have a "Yes, Sir!" acknowledgement animation when you give units commands -- it hides the round-trip latency.

In Topic: Hundreds of timers...

10 September 2016 - 12:38 PM

Yes -- std::map<> is sorted (it's a red-black tree, typically, as opposed to the heap used for priority_queue.) Thus, the next event to fire will be the begin/leftmost/lower_bound element of the map.
This also means that insertion/lookup in std::map<> is actually O(log N) not O(1) -- it's not a hash table! (You want std::unordered_map<> for that.)

The reason to use std::priority_queue<> over std::map<> is that the "remove the first item and keep the queue ordered" and the "add one item in the right spot in the queuue" operations are some small constant factor faster for heaps than red-black trees. Meanwhile, the general "keep a map ordered and allow random access" is faster for the red-black tree.