Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!

Angus Hollands

Member Since 06 Apr 2012
Offline Last Active Jan 27 2015 09:27 AM

#5201776 Average user packets per second

Posted by Angus Hollands on 04 January 2015 - 12:21 PM

If you're trying to ensure that you don't flood clients with data, then it would be sensible to perform some dynamic throttling. Start with an estimate of what you might consider appropriate. When you start dropping packets, halve the estimated bandwidth, otherwise increase slowly by some constant value.

(Thanks to hplus0603 for this recommendation in a previous discussion)


I would also recommend only modifying this value (reduction or growth) after it can be confirmed that data has been received from the client since the last change was made (as there might be n packets dropped before the client receives data at a reduced rate from the server due to the packet loss, so you would actually reduce the bandwidth by 2^n if you did not take this into account).

#5159483 game's protocol between client/server

Posted by Angus Hollands on 10 June 2014 - 06:22 AM

Typically, it won't matter what the contents of the message are when you need to handle where it goes. Usually, you might prefix the message with an identifier (type) that can be used to select the appropriate recipient. The contents are then managed by the requesting handler.


If you're using JSON, everything is serialised/deserialised in one go, so this is less explicit in practice, but you can still simply define the message to include a type field, and the rest is up to the sender.


That way, you check the type field and dispatch to the recipient as needed. Creating a generic message that does everything every message might need is both a waste of bandwidth and development time.

#5155768 Variance Shadow Mapping Shadow Brightness Issue

Posted by Angus Hollands on 24 May 2014 - 07:49 PM

Whilst I have little immediate experience on the subject, we had VSM shadows implemented recently, and a similar effect was observed.
The developer who implemented speculated (in passing) that the intensity of the light source was influencing the shadow


#5155757 Timestamping & processing inputs

Posted by Angus Hollands on 24 May 2014 - 06:15 PM

As long as the buffer has reasonable bounds, dropping any extra inputs which exceed the maximum buffer length will prevent the client from feeling lagged, instead they will notice server correction. This case will only occur if you send an excessive number of inputs, so you have to tune your upper bound for your buffer to consider the tradeoff between command latency and connection quality. 


Best ensure that you start sending inputs at a consistent rate though, don't try and account for the time spend loading for the map - that time is "dead time", meaning that user-input wasn't useful or valid during this time.

#5155707 Packet combining

Posted by Angus Hollands on 24 May 2014 - 01:08 PM

There are many different ways of handling your packets. I tend to define a header as the size of the packet contents, then its protocol. That is it. This helps avoid errors within a single packet from causing off-by-n errors elsewhere. So an entity update packet might involve sending the number of repeated entities, then packing their data, and appending the header to that packet. 

#5153321 Perfectionism and Programmer's Block

Posted by Angus Hollands on 13 May 2014 - 09:12 AM

I think that there is merit in thinking very carefully about what you do before you do it, just to stress this point. However, it is true that you cannot foresee what you will eventually ask of your code, so the most important thing is to keep to good design principles. It becomes structurally much easier to later modify the flow of execution if everything is nicely encapsulated, and even change implementation details.


But best choose one or the other. Either spend an inordinate amount of time planning and thinking before writing anything, or do the basic ground work, and get started - and quickly identify what might need to be changed. That way you make the best use of your time :)

#5148946 Your most valuable debugging techniques for Networked games?

Posted by Angus Hollands on 23 April 2014 - 06:58 AM

Unit tests are a god send!


I've never been exposed to their necessity in a production environment, but now I don't think that I will need that experience to encourage me to use them. If you can't write a unit test for it, it probably needs refactoring!


Most network errors are caused by misreading data from the byte stream (off by-n errors).I always check the data coming in. However, recently I had an error in some reading code which caused an off by one error. The best thing to do in those circumstances (my error only arose after data was already sent) is to break the simulation into three different states and compare the transition between them (whenever my variable was set to None, it remained considered as a None value (Which isn't included in the byte stream) hence we forgot to read an extra byte from later packets! I had to break it down to fix it.


Having an inspector in game is really useful, (assuming you're a runtime interpreted language) even a GUI with a command input dialogue is all you'd need (as long as you can prevent the game state from progressing)

#5148211 Entity Interpolation

Posted by Angus Hollands on 19 April 2014 - 01:31 PM

You might want to split it into more functions, so it can be easier maintained and checked for errors:

function interpolateClientState(stateA, stateB, interpolationFactor)
	// Interpolate between the two states
	var interpolatedPosition = previousSnapshot.position.lerp(nextSnapshot.position, interpolationFactor);

	// Create interpolated state
	State interpolatedState;

	// Set the position from the state
	interpolatedState.position = interpolatedPosition;
	return interpolatedState;

function applyState(state, actor)
	// ...

function updateRemoteClients() {
	var currentTime = new Date().getTime();
	var renderLatency = 400;
	var delayedTime = currentTime - renderLatency;

	// loop over all our remote clients and find the interpolated position to draw them at
	for (var c in remoteClients) {
		var actor = remoteClients[c];
		for (var i = 0; i < actor.snapshots.length; i++) {
			// make sure we don't go out of bounds with our checks
			if (!(i + 1 < actor.snapshots.length))
			// Get snapshots
			previousSnapshot = actor.snapshots[i];
			nextSnapshot = actor.snapshots[i + 1];
			// Get timestamps
			var previousTimestamp = previousSnapshot.timestamp;
			var nextTimestamp = nextSnapshot.timestamp;

			//  Determine if we straddle the delayed timestamp
			if (!(previousTimestamp < delayedTime) or !(nextTimestamp > delayedTime))
			// Calculate the factor (0.0 <= factor <= 1.0) to interpolate by
			var interpolationFactor = (delayedTime - previousTimestamp) / (nextTimestamp - previousTimestamp);
			// Get new state
			var interpolatedState = interpolateClientState(previousSnapshot, nextSnapshot, interpolationFactor);
			// Apply new state
			applyState(interpolatedState, actor);

Be aware this is psuedocode (I can't remember all the Javascript object creation information).

#5136654 Switch or Not?

Posted by Angus Hollands on 05 March 2014 - 06:39 PM

All programming languages become boring eventually, because the user confuses their own lack of direction with a fault in the language (not that I'm accusing you of that in these circumstances). Except Brainfuck. I can't see how you'd ever get bored, because you'll never understand what is going on :)


If you're trying to produce a game, using an existing framework / engine will help you get there quicker. But if you're truly passionate then it's inevitable you'll one day take a step back and implement the same things for yourself, so it's where you start.

#5136605 Cannot connect two computers

Posted by Angus Hollands on 05 March 2014 - 03:37 PM

If you're using UDP, are you binding the server to the external ip? In Python, that entails leaving the address field blank, instead of "localhost" or

#5119496 Have you made a game engine

Posted by Angus Hollands on 27 December 2013 - 09:34 AM



Just fyi, if any part of a codebase uses GPL, the entire codebase must be licensed under GPL or equivalent. This means, if you use GPL code in a library, game, or engine, you don't have a choice of whether it's opensource or not: It is legally required to be opensource by the license.

And that is why MIT license is the King of all licensees smile.png

The CC BY 3.0 is also very useful.

That's why the blender game engine is having problems.


The Blender Game Engine isn't having problems in that regard. The issue is that most people are users and not developers, license notwithstanding

#5022313 Losing interest in game development...

Posted by Angus Hollands on 16 January 2013 - 03:41 PM

We have all experienced feelings such as yours before. At this very moment, I am angered with the level of obfuscation that seems to have arisen in my networking codebase. So, I am removing it. From the ground up. A good point was raised earlier that one should try and refactor wherever possible. Yet, coming at this from the other direction, sometimes it is best to start again. I just purchased a book on software design. Normally, I would not have considered such a step, yet what limits my creativity the most is my constant fear of implementing something the "wrong" way. But, in many cases there isn't a wrong way. Get something working, learn from it, and if needs be redesign it with the newer functionality in mind. The point about a "buddy". I think it is one of, if not the MOST important point.

#5017314 can python be used to create professional games

Posted by Angus Hollands on 03 January 2013 - 06:26 PM

I don't know of many games that are truly Python based. Because the drawing libraries are usually C++ it often makes sense to use Python as a scripting layer on top of an engine framework. And, this has been done regularly.

#5009151 Network input handling

Posted by Angus Hollands on 10 December 2012 - 01:03 PM

Are you polling the input at the same tick rate as the server, or applying it for the same duration as a poll tick interval?

#5008481 Network input handling

Posted by Angus Hollands on 08 December 2012 - 07:06 AM

Let's assume that the client and server time are sycnhronised, thus at the same time in the real world they equate to each other.

If the inputs are sampled at t=100, and the server receives them at t=200 then assuming they were sent at sample time, upstream_latency = recv_time - sample_time.
We can then predict that these inputs will be received by the server at sample_time + upstream_latency
On the client, we will rarely be told this by the server, so instead we can use the RTT time (time after sending an ACK that we receive a reply) to get the total trip time and halve it for a rough approximation of upstream latency. We can use the same method to determine when the inputs will be received.

What has been said is that if the client runs its local simulation at server_time + (rtt / 2) then the inputs will be received in time for intended processing on the server.