Jump to content

  • Log In with Google      Sign In   
  • Create Account

Angus Hollands

Member Since 06 Apr 2012
Offline Last Active Sep 25 2016 01:02 PM

Posts I've Made

In Topic: How to structure my pure client/server model properly?

05 September 2016 - 06:51 AM

Simple answer: 
Don't allow different simulation rates. Update the simulation at the same frequency on all players. Render at a different framerate to suit the player.
Complex answer:
Use timestamps instead of ticks, and introduce time into all input values.
The simple answer is both simpler, more predictable and a whole lot more reliable. It's also quicker as you're not introducing lerps and other tolerance based comparisons where timestamps don't match exactly.
The important point is that you need to decouple the rendering framerate, and the simulation tick rate. You can render the game at a different framerate to the update.
If you set a baseline minimum for the update frequency, clients who can render at a higher framerate than the simulation rate can interpolate between the most recent states. This does mean you're rendering in the past by one-two simulation ticks, but that is usually acceptable, as you would otherwise be rendering the old frame anyway, and the effect is to reduce jagged movement, which will improve the UX.
I tried doing things using timestamps and variable simulation rates. It doesn't make any sense. You gain nothing by doing it, but a whole host of problems. Something about your game needs to be predictable and constant. That is the simulation. The rendering can happen at any rate, and the client will still move predictably and have a predictable experience across hardware.

In Topic: Friends living abroad have really laggy connection to me, why?(using raknet,...

20 August 2016 - 08:49 PM

There are several issues at play here.


Firstly, you shouldn't really be running at 500FPS simulation framerate. That's absurd! Most games with any physics will ask for at most 60FPS. You should lock your simulation frequency to something like 60Hz, and render separately to that timestep.


Secondly, you can't hope to send data every tick. You'll flood the connection. Running at a reduced transmission rate, and keeping packets small reduces the liklihood of this happening.


Thirdly, the speed at which information can travel between two end points is finite and non-zero. At best, it's the speed of light distance, realistically though the path between two nodes is not a geometric minimum, and isn't entirely vacuum (instead copper + fibre). In short, there will be latency, and it's calculable for a ballpark figure.


The clients do not need "new" state for each sim tick. You can interpolate between recent states, or extrapolate the latest state to smooth the timestep between two simulation states from the server.

In Topic: "Weapon Fired" Event -- Reliable, Unreliable, or In-Between?

29 March 2016 - 05:55 PM

Whatever solution you use will depend on a few things, including whether your client simulation runs in the past or not. If you're already interpolating entities, that will give you some additional time to receive information about projectiles.


When it comes to entity replication, I will send a reliable un-ordered packet that contains the information required to instantiate the entity client-side. From there, I would send state updates as unreliable, discarding out-of-date packets. You could even reduce bandwidth for predictable projectiles and just send the initial state, with the network tick and velocity, and allow the client to simulate it.


I'm generally uncomfortable with the notion of reliable ordered. The reason most use UDP for fast-paced games is to avoid the latency that is fundamental to the operation of a reliable stream over unreliable network conditions. At least with reliable unordered you can proceed other state whilst the packet is redelivered when dropped.

In Topic: Car transmission model

16 September 2015 - 06:38 PM

Indeed, the torque curve is defined as follows (see the BoxsterS2004 class)

maxTorqueArray = [220, 220, 310, 220]
rpmAtMaxTorque = [0, 1000, 4500, 6600]

Where maxTorqueArray are the Y values for the rpmAtMaxTorque X values.


I can see that the descending gear ratios will shift the engine back into the max torque region, but the applied force is reduced because the transmission factor (gear * differential * loss factor) is reduced by the gear reduction. 

From this, I am led to believe that the model is fine, but good data is required.

In Topic: Glitches in Navigating my NavMesh

28 June 2015 - 06:56 AM

Hi Angus, thanks for addressing those points for me; with your help I was able to get my basic system up and running and it seems pretty robust (so far.) Do you do any kind of agent-agent collision avoidance ? I was thinking about how best to handle that and some pointers will be helpful.


Waterlimon, thanks man, I wasn't sure how to undershoot, that info will come in very handy.

My experience with a range of techniques in this field is limited at the moment. I'm actually revisiting some pathfinding-systems I wrote in the past, which is why it's topical :)

NB, Mikko Mononen, the author or Recast & Detour, wrote some articles on his blog about general pathfinding & following concepts.

At the moment, I've left this in my own works, because I'm trying to get more performance out of the general navigation code (it seems that the funnel algorithm is running slowly for me, time to dig out the profiler!). However, local steering behaviours are the basis for collision avoidance, and there are a few great articles on digestingduck (the aforementioned blog) that describe how he does this. There are certainly other methods, though I will note that I like his approach to problem solving, which doesn't settle for cornercases.