Dev Blog

Dev-Blog 225: Frame timing problems

06/22/2016

devblog_header03

Welcome back, followers of the fearsome!

This week I fixed a problem that has been popping up in our game every once in a while. Our game normally runs at smooth 60 frames per second, but every once in a while the game would start to stutter and just generally become very un-smooth, man. The stuttering would last a few seconds and then the game picked up again and was buttery smooth once more. I’ve got some profiling routines in our game to measure what is going on, but every time I started profiling when this effect would show up, it would magically disappear, and the profile data would show that we’re perfectly within the desired frame times. So what is going on?

Our main game loop waits for the video buffers to swap, and then it checks how much time has passed to determine how many times to step the game. A time-accumulator float value is used to keep track of the time elapsed since the game was stepped, which is a pretty basic practice in most games. It guarantees that the game is stepped at 60hz on average, over multiple frames. The general code looks something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
static const float GameTimeStep = 1.0f/60.0f;

void Game::Update(float dt)
{
	m_timeAccumulator += Util::Clamp(dt, 0.0f, 0.1f);	// Clamp the value to prevent spiral of doom
		
	while (m_timeAccumulator >= GameTimeStep)
	{
		Step();
		m_timeAccumulator -= GameTimeStep;			
	}
}

 
So in this code, m_timeAccumulator is the float value in the Game class that is increased by the delta time every frame, and then the game is stepped however many times to make sure the game gets simulated 60 times per second. This piece of code handles variable frame rates quite well, if the delta time dt is 1/30th of a second, the game will just step twice in a row, to maintain the 60x per second simulation rate.

(Oh, a small note about the spiral of doom. This happens when the game takes longer to step than ‘real time’. By capping the incoming delta time, we potentially slow down the in-game time, but at least the game doesn’t grind to a halt.)

Ok, we’re all good then, right? The code above should fix all our problems, no? Well, not exactly. The code above has one problem that is a bit hidden, and it only really shows up if the render rate is the same as the game step rate AND your time accumulator is very close to a multiple of your game step time. For example, in our game the problem only occasionally shows up when running in a mode that is 60Hz.

Hopefully the graph below will make it more clear:

frametimingbefore600_2

 

Lots of info in the graph above, so here’s some explanation. The black line at the top shows the perfect 60x per second game update time we want to have. The green dots are measured frame times. We measure our elapsed frame time directly after a the swap-buffers call, using the highest resolution timers available. I have found that despite using the most precise measuring routines, there will still be a bit of variation. In the graph you can see that the green dot are somewhat randomly offset from the perfect rate we’d like to have, this is the variation. And this variation is what is causing the problem I’m talking about. Sometimes the measured frame time is a bit before, sometimes it’s a bit after the actual time.

The perfect amount of game steps to take every frame in this case (60Hz render, 60fps game step) is of course 1. In fact on the console games I’ve shipped, I sometimes just hard-coded one game step per render frame, but on PC’s with wildly varying video modes and video cards, this isn’t viable. The preferred game steps are represented by the blue outlined boxes for each rendered frame. However, using the code above, the actual game steps done per frame is shown by the magenta boxes. This shows that in the first render frame, the game isn’t stepped at all, and the next render frame steps the game twice to make up for it. Then there’s another frame of zero game steps, etc. In other words, very un-smooth behaviour.

Now, how did I fix this? Well, in our game it doesn’t really matter too much if the game step is running at exactly 60 fps, or if it’s running at a slightly higher rate. So, I introduced a fuzz factor:

frametimingafter600_2

The fuzz area is basically a time difference that is ‘acceptable’ when determining how many times to step the simulation. It’s only really used ‘downwards’, so for example if your game step is 10ms, and you get a frame time of 9ms, you might still deem that acceptable, and step the game. If your frame time was 12ms, then the fuzz factor isn’t technically needed, and the game is stepped.

Note that the frame steps are exactly where we want them! Buttery smooth. The game update code now looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
static const float GameTimeStep = 1.0f/60.0f;
static const float FuzzFactor = 0.96f;	

void Game::Update(float dt)
{
	m_timeAccumulator += Util::Clamp(dt, 0.0f, 0.1f);

	while (m_timeAccumulator >= (GameTimeStep * FuzzFactor));
	{
		Step();
		m_timeAccumulator = Util::Max(m_timeAccumulator - GameTimeStep, 0.0f);
	}
}

 
The fuzz factor is set to 0.96, which basically allows the game to speed up from 60Hz to about 62.5Hz.

Since I put in the code above, the occasional stuttering when running in a video mode of 60Hz seems to have disappeared from our game. When running at different frame rates such as 50Hz the game will still ‘catch up’ every once in a while causing a one-frame jitter. This is distracting and not preferable, but I don’t currently know of a way to fix this other than running the simulation at a much higher rate to get more granularity (not really feasible in our case), or by interpolating everything in the renderer (which might introduce frame lag, which is also undesirable).

Anyway, I am happy this problem is no longer an issue, and thought I’d share the idea if you’ve seen problems similar to this. Yay, one step closer to shipping! :)

Alright, that’s it for this week, keep those frames buttery smooth!


As usual, today at 4pm there will be another Dev Stream with Jouste the Drawbarian. Don’t miss it!

VS_DevstreamBanner

 

-Nick

Twitter: Nick: @nickwaanders Jesse: @jouste Caley: @caleycharchuk SlickEntertainment: @SlickEntInc

Facebook: https://www.facebook.com/SlickEntertainmentInc

Twitch: http://www.twitch.tv/slickentertainmentinc

Posted by: Under: Slick Entertainment,Tech Comments: Comments Off on Dev-Blog 225: Frame timing problems

Dev-Blog 224: Polishing up the Pictures!

06/15/2016

devblog_header08

Welcome back followers of the fearsome!

Hope you’ve been having an excellent week! This dev-blog we’ll be taking a quick look at our cinematic section and some of the polishing we have been getting done. It took a while to get the process right. Initially the original cinematic images were drawn much too big, to many details and way to much work was involved to end up with a pretty lack luster final product.

Now we draw everything at double 1080p and then crunch it down to the actual screen res with a bit more bleed so we have some wiggle room in the editing process.

VS_silhouette173

Above you can see a rough image and the final pass. Drawing the Jarl’s crazy transformation has been loads of fun. Handling bigger key moments like this allows us to get more expression and cooler camera placement.


VS_silhouette174

Here we also see that boosting the saturation really helps make the images pop and brings a lot more life into the images. With a little movement, some camera shake, chromatic aberration, and some sound, these sections are really starting to come together!

Recently we added a big, furry cape to the Jarl. It really helped him look oppressed. In the shot above we can see just how sad he is going over the books, I’m sure we’ve all been there! Hopefully with our Vikings bringing home the bounty we can change that around!


And as always, remember to hit up our Dev-Stream today at 4pm-6pm PST! We’ve been having a lot of fun creating characters, weapons and enemies alongside our great group of Oar Boys! So come on by and hang with a bunch of great people!

VS_DevstreamBanner


And that’s it for this week! We hope you’ve all been well, the last few sections are getting polished up by Caley, and Nick is getting that online beast wrangled! So until next time, keep those cinematic sections polished up!

Jesse_avatar64-Jesse

Twitter: Nick: @nickwaanders Jesse: @jouste Caley: @caleycharchuk SlickEntertainment: @SlickEntInc

Facebook: https://www.facebook.com/SlickEntertainmentInc

Twitch: http://www.twitch.tv/slickentertainmentinc

 

Posted by: Under: Art Work,Vikingsquad Comments: Comments Off on Dev-Blog 224: Polishing up the Pictures!

Dev-Blog 223: Networking: Pack those bits!

06/08/2016

devblog_header03

Welcome back, followers of the fearsome!

This week is a follow up to Dev Blog 197, which was the first dev-blog on networking. I’ve been working on getting the networking system up and running for Viking Squad, and there are a ton of little peculiarities I could talk about, but I’ll start with a bit more of the basics, in particular about how to squeeze all the unused bits out of your precious network bandwidth.

After setting up the low level networking system described in Dev Blog 197, we are now able to send and receive messages from remote clients. These messages get bundled up into a network packet and sent, only to be broken into individual messages again when they reach the other side. Now, bandwidth is always a concern, so we want to try and minimize the packet sizes, which means minimizing the size of the message that get sent.

If you’re familiar with C#, you’re probably aware of the BinaryReader and BinaryWriter classes to save and load binary data. These are constructed with a stream, and then you can read and write different data types to these streams.

For example, say we have this hypothetical entity that we need to save to the network. (Note: this isn’t what our internal entity class looks like, this is just an example to illustrate what I am talking about). This is what the code would look like:

class Entity
{
	private UInt16 m_entityID;  // Unique ID to identify the entity by
	private Vector3 m_position; // 3D Position of the entity in the world
	private Vector3 m_velocity; // Velocity of the entity in the world
	private bool m_onGround;    // Boolean saving if this entity is on the ground or not.

	// .. More data here

	public void SaveToNetwork(BinaryWriter writer)
	{
		writer.Write(m_entityID);		// 16

		writer.Write(m_position.X);		// 32
		writer.Write(m_position.Y);		// 32
		writer.Write(m_position.Z);		// 32

		writer.Write(m_velocity.X);		// 32
		writer.Write(m_velocity.Y);		// 32
		writer.Write(m_velocity.Z);		// 32

		writer.Write(m_onGround);		// 8
							// 216 bits total = 27 bytes 
	}

	public void LoadFromNetwork(BinaryReader reader)
	{
		m_entityID = reader.ReadUInt16();
	
		m_position.X = reader.ReadSingle();
		m_position.Y = reader.ReadSingle();
		m_position.Z = reader.ReadSingle();

		m_velocity.X = reader.ReadSingle();
		m_velocity.Y = reader.ReadSingle();
		m_velocity.Z = reader.ReadSingle();

		m_onGround = reader.ReadBoolean();
	}
}

As you can see it needs 27 bytes to save the state to the network. The smallest unit of data that can be written using BinaryReader and BinaryWriter is a byte, which is actually quite large if you think about it. For example, when the SaveToNetwork function writes the m_onGround boolean value, it will write an entire byte (8 bits) to save the state of the boolean. That’s 7 wasted bits to write 1 bit of actual data!

Now, how about we take this one step further? How about saving all values using exactly the amount of bits we think it needs? And in our loading code, we use the same number of bits to read the value and store it in our variable. To make this easy to do, I implemented my own BitStreamReader and BitStreamWriter classes. These have the same functions to read and write data types, except they also require a number of bits, and in some cases a minimum and maximum value. Internally they pack data in bit by bit, making it possible to waste no bits when saving the entity state. If you’re interested in the internals of these streams, just click here to see what the C# code looks like.

To be able to save the maximum amount of space, we need to know what the limits are for each of our variables. The m_entityID is a 16 bit value, but we don’t see it ever going over 1024. In this example, we’ll assume that the X Coordinate is always between -150.0f and 150.0f, and the Y and Z coordinates are always between -6.0f and 6.0f. The velocity is always between -10.0 and 10.0.

Now how do we save this efficiently? Well, lets go through them one by one:

m_entityID: This value will never go over 1024, so we can save this unsigned integer by using only 10 bits.

For m_position, we’ll need to be able to save the floating point values using a specific amount of bits, while retaining a minimum precision. Say we determine we want a precision of about 0.02 units. To be able to save the X coordinate we would need to divide up (150.0 – (-150.0)) = 300.0 into 300.0 / 0.02 = 15000 parts. The nearest larger power of two would be 2^14 = 16384. So we’d need 14 bits to save the float and get a precision of 0.01831. For the Y and Z coordinates we do a similar calculation, and come to the conclusion that we can save using 9 bits, giving us a precision of 0.02343.

For the m_velocity we decide we don’t need as much precision, and we can handle 0.1 unit of precision. This allows us to save the X, Y and Z component using just 8 bits each.

The m_onGround just needs one bit to save, since it’s just a true or false value.

The code would look something like this:

class Entity
{
	private UInt16 m_entityID;  // Unique ID to identify the entity by
	private Vector3 m_position; // 3D Position of the entity in the world
	private Vector3 m_velocity; // Velocity of the entity in the world
	private bool m_onGround;    // Boolean saving if this entity is on the ground or not.

	// .. More data here

	public void SaveToNetwork(BitStreamWriter writer)
	{
		writer.Write(m_entityID, 10);                     // 10

		writer.Write(m_position.X, -150.0f, 150.0f, 14);  // 14
		writer.Write(m_position.Y, -6.0f, 6.0f, 9);       // 9
		writer.Write(m_position.Z, -6.0f, 6.0f, 9);       // 9

		writer.Write(m_velocity.X, -10.0f, 10.0f, 8);     // 8
		writer.Write(m_velocity.Y, -10.0f, 10.0f, 8);     // 8
		writer.Write(m_velocity.Z, -10.0f, 10.0f, 8);     // 8

		writer.Write(m_onGround);                         // 1
		                                                  // 67 bits total = 8.375 = 9 bytes 
	}

	public void LoadFromNetwork(BitStreamReader reader)
	{
		m_entityID = reader.ReadUInt16(10);
	
		m_position.X = reader.ReadSingle(-150.0f, 150.0f, 14);
		m_position.Y = reader.ReadSingle(-6.0f, 6.0f, 9);
		m_position.Z = reader.ReadSingle(-6.0f, 6.0f, 9);

		m_velocity.X = reader.ReadSingle(-10.0f, 10.0f, 8);
		m_velocity.Y = reader.ReadSingle(-10.0f, 10.0f, 8);
		m_velocity.Z = reader.ReadSingle(-10.0f, 10.0f, 8);

		m_onGround = reader.ReadBoolean();
	}
}

Now, what we ended up with is a routine that can save the entity data with the precision we needed, in just 9 bytes. That’s 1/3rd of the original implementation! Of course this is a hypothetical entity, but you can see here that there are huge space savings to be had if we know the constraints of our variables.

Alright, that’s it for this week, I need to get back to more network implementation. Writing this blog post made me realize how many little interesting things I did to make the networked game work better. It’s probably worth another future blog post or two!


As usual, today at 4pm there will be another Dev Stream with Jouste the Drawbarian. Don’t miss it!

VS_DevstreamBanner

 

-Nick

Twitter: Nick: @nickwaanders Jesse: @jouste Caley: @caleycharchuk SlickEntertainment: @SlickEntInc

Facebook: https://www.facebook.com/SlickEntertainmentInc

Twitch: http://www.twitch.tv/slickentertainmentinc

Posted by: Under: Slick Entertainment,Tech Comments: Comments Off on Dev-Blog 223: Networking: Pack those bits!

Dev-Blog 222: Roughing in Those Cinematics!

06/01/2016

devblog_header08

Welcome back followers of the fearsome!

We hope your week has been full of pillage and plunder as Slick Entertainment sails another Dev-Blog to you! This week we’ll be going over some of the ways we are approaching the last bits of polish in viking squad. The Cinematic areas! Now there isn’t too much of a story going on in Viking Squad and that’s on purpose. We found that players (and us included) didn’t really need too much justification for going around with cool weapons and beating up things. This was good news for use because that means that we only need to make a couple moments in our game have some exposition and hopefully the goofy actions in the rest of the game fill in the blanks.

VS_silhouette171

Above is some of our rough cinematic storyboard ideas. these are nice and loose and mixed around a bunch. Ones that feel right  are slammed with some quick colors. and chopped up and thrown right into the editor and can be controlled just like one of our puppets! This means we can add awesome stuff like chromatic aberration, screen-shake, and lighting.

I’ll be the first to admit that being atmospheric and cinematic is NOT one of my stronger skills. I can pump out a lot of content but not all the buckshot hits the target, luckily between the 3 of us here at Slick along with the support of the  skilled folks at Power Up Audio, we can get something pretty cool happening.

The original cinematic sections we built for the trailer were a little hard to handle and not very organized (mostly due to my lack of experience). But now we have some super cool and helpful changes added to the Waanderful Engine!

VS_silhouette172

Above you can see that every different shot in the sequence is under a different bone, by hitting ctrl+shift and selecting that bone it’ll select everything in that shot. This makes it super handy to move shots around and play with their length in order to make them fit better in sections. Keeping the effects and animations properly named and organized is something that is important as well because it’s easy to lose track of what’s going on when the puppets get this out of control.


And don’t forget that we’ll be Dev-Streaming today at 4pm-6pm PST! Come on by as we slam some more art down with our great crew! Ask questions about everything from art and design, to coding! Hope to see you there!

VS_DevstreamBanner


So that’s it for this week! Caley has been getting the final boss experiences implemented and Nicks been working super hard on our Networked multiplayer so everyone can play with each other from around the world! Thanks for dropping by and checking out what we are working on, and until next time, keep those cinematic files organized!

Jesse_avatar64-Jesse

Twitter: Nick: @nickwaanders Jesse: @jouste Caley: @caleycharchuk SlickEntertainment: @SlickEntInc

Facebook: https://www.facebook.com/SlickEntertainmentInc

Twitch: http://www.twitch.tv/slickentertainmentinc

Posted by: Under: Art Work,Slick Entertainment,Vikingsquad Comments: Comments Off on Dev-Blog 222: Roughing in Those Cinematics!

Dev-Blog 221: Heaps of Riches!

05/25/2016

devblog_header08

Welcome back followers of the fearsome!

This week we’ll be taking a look at some areas in background art that we’ve been putting together as we polish up the last few levels in Viking Squad!

We’ve decided it’d be really great to show some of our Jarl’s crazy greed in the form of some massive piles of gold in the background. Trouble is, drawing massive piles of gold is pretty tricky if you don’t take some shortcuts and approach it a little smarter than usual!

VS_silhouette168

As you can see above, we start out with a big, slightly jagged pile, and then fill it in with a few smaller details and even some props to mix it up. It definitely took a few attempts to get it close to something I was happy with, it’s still a little rough but it definitely gets the point across! Drawing valuables in Viking Squad has always been a little tricky. They need to kind of “Stick out” and look shinier than  the metal bits on a lot of our characters. These piles have to perform double duty by being less obvious and hang out in the background to make scenes look more interesting.

VS_silhouette170

Another small thing that helps out these larger piles are smaller piles that are just simple enough to clot around our larger ones. It’s tricky for me to keep them simple because I tend to over design everything but I think they turned out alright! It’s always fun tackling these different challenges, this may not be the best way to handle the problem but it works out ok!


And today at 4pm – 6pm PST we’ll be dev-streaming again! Don’t forget to drop on by and hang out with the crew here as we sail closer to our ship date! We’ve been having a great time interacting with all of our squad mates and Oar-Boys so heft those hams and helmets today!

VS_DevstreamBanner


So that’s it for this week!

Testing our networking. polishing up our last couple bosses and levels, and building some marketing material is what we have on our table! Thanks for stopping by and checking out our progress! And until next time, keep those treasures piled high!

Jesse_avatar64-Jesse

Twitter: Nick: @nickwaanders Jesse: @jouste Caley: @caleycharchuk SlickEntertainment: @SlickEntInc

Facebook: https://www.facebook.com/SlickEntertainmentInc

Twitch: http://www.twitch.tv/slickentertainmentinc

 

Posted by: Under: Art Work,Vikingsquad Comments: Comments Off on Dev-Blog 221: Heaps of Riches!

Follow us!

titlebutton_twitter titlebutton_facebook titlebutton_youtube titlebutton_twitch

Join our mailing list!

/ /

Dev Blog

June 22 2016

Welcome back, followers of the fearsome! This week I fixed a problem that has been popping up in our game every once in a while. Our game normally runs at smooth 60 frames per second, but every once in a while the game would start to stutter and just generally become very un-smooth, man. The […]