Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 03 Jun 2003
Online Last Active Today, 01:37 PM

#5256026 Using a physics engine on the server

Posted by hplus0603 on 07 October 2015 - 10:14 AM

@sheep19: It sounds like you're not using a fixed simulation step rate. I believe you will, in the end, have real trouble with this. I suggest you decide on a fixed number of simulation steps per second (30? 60? 182? whatever.) Then, run the input-and-simulation at that rate on all clients and on the server. However, rendering will be run at whatever rate the client computer can keep up with. You should also send the user inputs in a given group size -- say, 60 Hz simulation, two inputs per packet, means 30 packets per second. This way, there is no difference in "how many inputs are there in a second" or "how does a player move for a particular network packet."

For more on this, check out this article: http://www.mindcontrol.org/~hplus/graphics/game_loop.html

#5255941 Using a physics engine on the server

Posted by hplus0603 on 06 October 2015 - 09:45 PM

Be permissive in what you accept, but strict in what you send.

I have read that too, but I think it is actually wrong.

Because of that approach ("permissive in what you accept,") the HTML language, to this day, 25 years later, has a "tag soup" mode to stay compatible with all kinds of terrible things that "happened to work" on Mosaic version 0.6 or whatever.

"Be strict in what you accept, and stricter in what you send" would be better. And if you're going to go ahead and accept something that's outside of spec, make the user (and developer!) aware that this is going on with something angry and red that can be clicked on to see what's actually wrong, so it can be fixed.

Another anti-pattern: Taking out assertions in release.

The problem is that, if you assert in debug/development/test, then the code doesn't get any further than that.
If you then, in release, suddenly accept that code path, then who knows what will happen? You're executing code in situations it's never seen before.
So, either make it so that assertions don't actually stop the program, just collect all kinds of useful information and report it (somewhere where it will actually be cared about,) or make it so that assertions stop the in release mode, too (typically with a crash dump and program restart.)

Now, if you're running some debug asserts that cut your frame rate in half even when all optimizations are on, that debug code should probably be ifdeffed out for release. Or, more reasonably, only turned on with some kind of runtime flag that defaults to off, even in development, but is turned on in some automated qualification build/test environment.

Maybe I should blog about this...

#5255889 Using a physics engine on the server

Posted by hplus0603 on 06 October 2015 - 02:06 PM

@braindigitalis: While 3D physics have a constant factor higher cost in simulation than 2D, the main scalability limitation in simulation is that N actors may potentially interact with N other actors, leading to N-squared scalability. Thus, the end-term scalability is not primarily drive by 2D vs 3D math costs, but by how many object pairs need to interact, and what your broad-phase pair determination algorithm looks like. 3D actually gives more opportunities for culling pairs than 2D, because there are three dimensions instead of two to separate pairs among.
The "constant cost" of simulation in 2D is likely smaller, and thus in absolute numbers on a single, constrained, CPU, you may get more 2D entities than 3D entities, as long as they all have room to spread out reasonably in the world. That's kind-of a special case, though -- not the determining factor of how something "scales."

@sheep19: You probably want to number each game simulation tick. Make sure you use the same, fixed, tick rate on all nodes! The player would then enqueue commands "for the future" for the server. This would include both "spawn bullet" as well as "move" or whatnot. The server applies the appropriate input at the appropriate simulation tick.
You'll then end up with latency, which means that the local client may be displaying tick 100, but the server is currently simulating tick 105, and the data won't get there until tick 110, which in turn won't get back to you until tick 115. (Assuming a 5 tick one-way delay.) This causes a 15 tick delay between "command" and "effect." You can then display the local player in an "accelerated" time frame -- display local player as if the tick was 115, which means all the commands have been applied. The problem then is that you'll see others at a 15 tick delay, which leads to "being shot around a corner" type lag in the experience. That's often better than "taking a long time for controls to affect the player character" kind of lag.

#5255451 Real-Time WebSockets and REST

Posted by hplus0603 on 03 October 2015 - 08:43 PM

REST-ful-ness and real-time do not mix well. REST is almost purposefully not a real-time design approach, as it trades overhead for long-term evolution robustness. Games can almost always update client and server in parallel, and thus don't often benefit from this (but still have to pay the cost.)

I think your approach sounds like it can work. Some caveats:
Web sockets are TCP -- there will be occasional lag. However, if you've played agar.io, or Realm of the Mad God, you would know how good/bad this is.
Use HTTPS or TLS for all requests if possible. While HTTP and TCP is easier for debugging, there are so many weaknesses with plaintext these days that HTTPS and TLS is pretty much a must.
Amazon may suffer the "noisy neighbors" syndrome, where suddenly you suffer a lot of performance degradation, jitter, packet loss, etc. Beware, monitor, and be prepared to move to another availability zone if it gets bad.

Feel free to come back and ask for more specific questions if you need to, or just keep us all up to date on how the project goes!

#5254653 Should i run the client logic in separated thread or in update () ?

Posted by hplus0603 on 29 September 2015 - 12:45 PM

The kernel buffers incoming messages. You don't have to "be there" right when the packet comes in to listen for it. You will not lose messages if you poll for messages from the main thread.

Also, polling from the main thread will not increase latency, because the time when that message affects the physics and game logic on the client is determined by the main thread anyway.

Thus, it's simpler, and just as robust, to poll for messages in the main thread; a separate thread for receicing network messages from the Lidgren library is not necessary or particularly helpful.

#5254652 How to deal with inconsitent game state in entity interpolation

Posted by hplus0603 on 29 September 2015 - 12:43 PM

If the server is authoritative, then the message didn't get there "late" -- the client was overly optimistic.

The delay time you show on the client needs to include client->server time as well as server->client time, so the "0.1 seconds" you have in your interpolation probably needs to be more like 0.3 seconds for the 150 ms delay case.

#5253738 How to go about a lobby based game.

Posted by hplus0603 on 23 September 2015 - 06:20 PM

Btw: If you like writing Python code, a good way to get started on web services in Python is Flask: http://www.fullstackpython.com/flask.html

#5252962 Interpolation & Extrapolation Help

Posted by hplus0603 on 18 September 2015 - 05:42 PM

One thing you need to do is that, each time you receive a new position, you should set the 'start interpolation position' to *the calculated interpolated position* you last saw, and set the 'target future position' to the received position. That way, you won't "jump" to the previously received update position when you receive a new packet.

#5252955 Interpolation & Extrapolation Help

Posted by hplus0603 on 18 September 2015 - 04:27 PM

The first obvious question is: Are you properly receiving all packets, or are you having TCP packet-merge issues?

The second obvious question is: If you're using UDP, do you re-send data every tick, or would a packet drop right when I stop just end up with me in the wrong position until I start moving again (and thus send another packet)?

Instead of "InterpToPosition()" updating the state, you probably want a function called "PositionAtTime()" and "RotationAtTime()."
Those functions will then look at the given time, and the time stamped data it has, and output an appropriately interpolated value.
That ends up being easier to prove correct than something which attempts to incrementally update the values.

#5252795 ENET peer list?

Posted by hplus0603 on 17 September 2015 - 07:42 PM

Ha! I think I'm the mellowest of our mods here :-) I never down-vote a question, unless it's an obvious troll. I don't down-vote answers unless they are outright dangerous to follow, or go beyond the line of acceptable criticism.
That being said, I will close this thread, because I'm not interested in discussing ratings. Open a new thread if you have a particular new question you'd like to ask.

#5252751 ENET peer list?

Posted by hplus0603 on 17 September 2015 - 03:01 PM

enet_host_broadcast(server, 1, packet);

Yes, this works if you want every client to get the same packet.
If you want to be careful about which client gets what packet, and you have more than one client, then this will not do that.

then i got -10 rep from the mod

I don't see anyone voting you up or down in this thread, so that's probably from somewhere else.
That being said: Don't worry about reputation in the short run. Everybody has up-ticks and down-ticks; good participation will lead to good reputation over time.
There is actually a slight negative correlation between worrying about reputation and actual reputation gain. I guess people don't like people who worry too much about it :-)

#5252717 ENET peer list?

Posted by hplus0603 on 17 September 2015 - 12:35 PM

enet_host_broadcast will send a packet to the local network for everyone to receive if they're listening to it. I don't think that's what the OP wants.

The ENetPeer is the main connection object representing the "other end," so I imagine this is valid until such time that the connection goes away. I don't know what kind of notification you get when it becomes invalid, though.

#5252715 Prepared statements and SQL injection.

Posted by hplus0603 on 17 September 2015 - 12:33 PM

@frob, @deflinek: The poster (@menyo) already mentioned that they're using Client -> Server -> Database as the topology, so I think they're fine there.

#5252377 Prepared statements and SQL injection.

Posted by hplus0603 on 15 September 2015 - 10:50 AM

Yes, assuming your prepared statement library doesn't have bugs, you can now assume that you don't have SQL injection vulnerabilities in that code.

One down! Only 9999 other kinds of vulnerabilities to go :-)

#5251975 Testing my Database pooling?

Posted by hplus0603 on 12 September 2015 - 10:37 PM

The client library may be caching the connection and pooling it across threads.
Thus, you may need multiple processes, rather than multiple threads, to create more of them.
If you're on Linux, you can easily run a shell for loop to create however many copies you want.
On Windows, I'd probably create a text (.BAT) file that just calls "start java ... MyClass.class ..." and copy-paste that line many times.
"start" is a Windows shell command that runs the given command asynchronously.