Dev Blog

Dev-Blog 215: Build O Matic Part 2



Welcome back followers of the fearsome!

In a small development team of three, you often end up having to take care of many different things. In the last week I spent time trying to optimize my rendering, reducing temporary memory allocations in the game-play code, fixing continuity bugs in the network code, as well as updating our build machine to include Mac OSX builds. So many different things that it’s hard to chose one to write a blog about! Well, I’ll just pick the build machine one.

I’ve written a blog about our build-machine before, but today I’ll focus a bit more on getting the OSX build working, and uploaded at the same time as our windows build.

To get Viking Squad working on OSX, I’ve been working on converting the engine code to SDL 2.0 in my ‘spare’ hours over the last few months. Since my engine already supports multiple platforms (Windows, PS4, XBox, iOS, Android, etc), I’ve been able to concentrate platform specific code in a few small areas. Adding another target for SDL2 in those spots was fairly straightforward. Luckily I’d been keeping the OpenGL renderer up to date, so once I was able to create a window in SDL2, getting it to render to the window was easy. We’re using FMod for audio and besides linking the proper libraries there’s nothing I had to do to get it running. Great!

The next hurdle was to get game-pads working on OSX. At first I tried plugging in my wired XBox 360 controller, but I quickly found out that it’s actually not straightforward at all to get that working on a Mac. Third party drivers need to be downloaded and installed, which I don’t like, so I quickly grabbed my PS4 controller, and that worked straight away. I guess I will have to try installing the third party driver to make sure XBox 360 controller work properly at some point. The process of converting to SDL2 was so smooth, that I actually converted my windows build (running D3D11) to SDL2 as well.

Now the build was working properly, the next task was to get it building on a build machine. I had an older 13″ Macbook laying around, which I re-purposed to be our brand new MacOS build drone. I upgraded it to El Capitan, and since all my build tools are written in C#, I installed Mono to see if I would be able to run my console-applications. I was a bit startled that I could simply run windows EXE’s by typing ‘mono SomeProgram.exe’ in a terminal window. It just works. Just like that, I had a working OSX based build drone!

The current build process to upload a new build to Steam is as follows:

1. Build Windows RTM game, and copy to the network drive on completion.

2. Build OSX RTM game (in parallel as step 1), and copy to the network drive on completion.

3. Run a custom Steam uploader tool after both 1 and 2 are complete.

The steam uploader tool is another C# console app that checks if the latest Windows and OSX builds present on the network drive are exactly the same build number, and copies them into the proper place to upload to steam. In this step, the windows data files are copied to the OSX build path. Once everything is in place, and verified, an external tool is called to upload the build to Steam. That’s it!

All in all this took a fair amount of time to get set up, with lots of snags and issues along the way, but it’s all working now. Putting a new build on steam for both Windows and OSX is now only three mouse clicks (one for each step mentioned above). I wanted it to be 1 click, but I guess I can can live with three.

That’s it for this week. Keep those build machines build machining!


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




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




Posted by: Under: Tech,Vikingsquad Comments: Comments Off on Dev-Blog 215: Build O Matic Part 2

Dev-Blog 212: GDC!



Welcome back, followers of the fearsome!

Last week we didn’t do much developing, but lots of networking. (That is, meeting people, socializing, going to parties, etc. Not actual network programming). Maybe we should have, but we didn’t plan any press meeting for our game this year. We’ve been working so hard getting the game done that it has become a bit of a marathon, so it was nice to take a break and see what everybody else is up to.

On Monday and Tuesday we attended the fantastic Independent Games Summit, which is pretty much the reason we go to GDC every year. It’s a lot of fun seeing talks by people who are in the same boat as you. The main GDC often has talks that don’t really apply to small indies.

On Wednesday I met up with a few new friends who are all into networking, which in this case IS about network programming. It was good to meet them face to face rather than as an icon on our Slack page! Good conversation was had, and I am hopeful that many more good conversations will follow. It’s good to have friends when you’re small.

On Thursday we visited the Twitch headquarters in San Francisco. Our good friend Mos toured us around the office and treated us for lunch. It was great to see the inner workings of Twitch, and man I’m kinda super jealous of their offices. So modern and so much room for activities!!


Coming back from GDC I always have a bit of a weird feeling. Meeting so many friendly peers is super awesome, and going to the parties is always a ton of fun. Seeing all the games people are working on is super neat as well.

Now I feel completely social-ed out though. I feel like I could work alone in an attic for half a year just to recover. Also, every year I come back wishing I was more prolific. Seeing all these cool games people are working on makes me want to make a few small games, instead of working on this giant multi year project we’re working on now. Viking Squad is taking up all of our energy, and I feel guilty when I spend time on anything else. Time to get this baby out the door and start working on toy projects again… soon. Soon. SOON!


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




Posted by: Under: Slick Entertainment Comments: Comments Off on Dev-Blog 212: GDC!

Dev-Blog 211: Resizing those textures



Welcome back, followers of the fearsome!

Earlier this week I sent out a few vines showing my system to resize textures to their proper size. I thought I’d talk a bit about that in our dev-blog.

When Jesse draws his amazing art, he usually draws it at a resolution that is somewhere in the right ballpark, usually slightly higher res than actual screen pixels. Sometimes we decide to shrink or grow an entity for game-play reasons, and having higher res source art helps in this case. However, when we actually ship the game with the final sizes of entities, it saves quite a bit of texture memory to resize the textures to the actual size they are being used at (on average). Saving texture memory also makes the rendering more efficient, as more textures can fit in one atlas, making batching draw-calls easier. Doing less draw calls is good!

To do this, we added a new icon to our already quite extensive toolbar in the editor, and this tab does all the re-scaling work.


First, it shows every single UI screen we have, including all animations. Then it goes through every level, and pans from the far left to the far right, making sure every part of it is rendered. After this is done, every entity is rendered at the size they appear in the game, including every single skin option, and every animation, which in turn spawns the visual effects that are used. In general the idea is to render everything at least once at the size it appears in game. Here are come vines I posted to twitter earlier this week:
The levels:

The entities:


So that’s all fine and dandy, but how does this translate into the texture sizes being used? Well, at the lowest level of rendering, I have a little (editor only) debug routine that calculates how big each triangle is on screen. Everything is rendered to a 1080p target (1920 x 1080 pixels), and for each triangle edge, I calculate the length in pixels being rendered. I also calculate the distance between the UV coordinates in texture pixels. Simply dividing one by the other gives you a scaling factor that you can use to resize the texture! The scaling factor is capped to 1 though, so a texture is never scaled to a bigger size than the original input texture.

For example, say you have a 512 x 512 texture that is rendered to the screen and appears as a 32×32 texture on screen. The screen distance of the top edge would be 32 pixels, but the distance in UV coordinates (in texture pixels) would be 512 pixels. This means you can re-scale the texture by 32/512 = 6.25%, without noticeably degrading the final image. Of course this is a hypothetical example, but hopefully you can see how this would be a huge savings.

One special note is that the blurred background and foreground layers are using a lower resolution render target, which has to be taken into account when calculating the resize factor for textures used only in these layers.

In our game, without texture scaling, we require 36 atlas textures (4096×4096) for all the used textures, totaling about 576mb of compressed textures. With texture scaling this number is currently 21 atlasses with total 336mb of compressed textures, and you can’t tell the difference! HUGE savings!

Alright, that’s it for this week, I have to get back to network programming. :)

Next week we’re at GDC, so there won’t be a dev-blog, but this Saturday at 1:30 EST (10:30 PST), we’re doing an interview and showing our game on the Geeks World Wide. Come check it out!

GWW Presents Indie Dev Day!!

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




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




Posted by: Under: Slick Entertainment,Tech Comments: Comments Off on Dev-Blog 211: Resizing those textures

Dev-Blog 208: Cinematic effects!



Welcome back, followers of the fearsome!

I have been plugging away on the networking code, while at the same time doing the administration of the company (as an indie, you get to do it ALL! yay!). To have a bit of fun (and partly putting the ‘pro’ in procrastination), I implemented some cinematic effects for our game.

First of all, I improved the vignette shader to give it more tunable values. We used to have only the ‘radius’ to tune how much the vignette was affecting the sides. Now, there’s a radius, a softness and an opacity value.

This next slider box shows the effect of different parameter settings. The hard line is the radius of the vignette, and the opacity is how much darker the outside of the vignette gets. The softness determines how soft the gradient will be between no vignette and full vignette. Slide over the box to see the difference between a softness of 0.0 and 0.2. Click on the image to go to a full screen slider box.

The shader used is pretty straightforward (glsl shader):

uniform float VignetteRadius;
uniform float VignetteSoftness;
uniform float VignetteOpacity;

// inputColor is the color of the final image for the pixel
// texCoord is the coordinate of the pixel on screen, in the range [0,1]. 
vec4 CalculateVignette(vec4 inputColor, vec2 texCoord)
    vec2 dist = (texCoord - 0.5);
    float len = length(dist);
    float vignette = smoothstep(VignetteRadius, VignetteRadius-VignetteSoftness, len);

    vec4 result; = mix(, * vignette, VignetteOpacity);
    result.w = inputColor.w;
    return result;

Of course these settings are a bit intense, so here’s the vignette effect in a more real in-game setting:

Next, I added a bit of film grain. Currently I’m calculating a random pixel value using a weird pseudo random generator I bashed together from some code I found online, which results in a super fine grained noise. I might actually change this to a 2d perlin based noise at some point so we can control the size of the film grains.

uniform float FilmGrainAmount;
uniform float FilmGrainSeed;

vec3 Random3D(vec2 uv)
    float noiseX = fract(sin(dot(uv, vec2(12.9898,78.233) + FilmGrainSeed)) * 43758.5453);
    float noiseY = fract(sin(dot(uv, vec2(12.9898,78.233) * 1.2345 + FilmGrainSeed)) * 43758.5453);
    float noiseZ = fract(sin(dot(uv, vec2(12.9898,78.233) * 2.1314 + FilmGrainSeed)) * 43758.5453);
    return vec3(noiseX, noiseY, noiseZ);

// inputColor is the color of the final image for the pixel the vignette is calculated for
// texCoord is the coordinate of the pixel on screen, in the range [0,1] for both x and y. 
vec4 CalculateFilmGrain(vec4 inputColor, vec2 texCoord)
	float luminance = dot(inputColor, vec4(0.299,0.587,0.114,0.0));
	float lum = luminance + smoothstep(0.2,0.0,luminance);
	vec4 noise = vec4(mix((Random3D(texCoord) - 0.5),vec3(0.0), pow(lum,4.0)), 0.0);
	return inputColor + (noise * FilmGrainAmount);

The Film Grain effect is hard to see in this small slider box, so click on it to go to full screen image!

Next up, Chromatic Aberration! This effect pulls apart the Red, Green and Blue layers of the screen to create the effect of an old tube TV. I added some settings to tune the amount of chromatic aberration depending on where the pixel is on screen, in much the same way as the vignette. There is a aberration value for the middle (innerAmount), the outer corners (outerAmount), and a curve power value to change how the amount of aberration interpolates between the middle and the corners. Here’s the code. Note that this requires a texturemap as the input. This would be the rendertarget you’re applying the post effects to.

uniform float ChromaticAberrationInnerAmount = 0.0;
uniform float ChromaticAberrationOuterAmount = 0.0;
uniform float ChromaticAberrationCurvePower = 1.0;

vec4 CalculateChromaticAberration(sampler2D textureSampler, vec2 texCoord)
    vec2 dist = (texCoord - 0.5);
    float len = length(dist);

    float power = pow(smoothstep(0.707, 0.0, len), ChromaticAberrationCurvePower);  // [0-1]
    float aberrationAmount = mix(ChromaticAberrationOuterAmount, ChromaticAberrationInnerAmount, power) * 0.001;

    vec4 r = tex2D(textureSampler, texCoord + vec2(aberrationAmount, 0.0));
    vec4 g = tex2D(textureSampler, texCoord + vec2(0.0, 0.0));
    vec4 b = tex2D(textureSampler, texCoord + vec2(-aberrationAmount, 0.0));

    return vec4(r.x, g.y, b.z, 1.0);

And the effect is shown below (with somewhat extreme values to show what the effect does). Again, it might be hard to notice in this small slider box, so make sure to click it so it opens up a full screen version!

Alright, now that all the components are there, we combine all of it using the following shader code:

vec4 rawColor = CalculateChromaticAberration(TextureMap, f_texCoord);
fragColor = CalculateFilmGrain(CalculateVignette(rawColor, f_texCoord), f_texCoord);

And the final result looks something like this: (Keep in mind, we’re still tuning these values, so it will look different in the final game!)

That’s it for this week, I hope you liked my little distraction from network coding. I think the post effects need a bit of work still, but they are starting too look pretty neat.

And of course, make sure to tune in later today at 4pm PST to see Jesse make a fool of himself in our weekly Twitch Dev-stream:


Thanks, and see you next week!


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



Posted by: Under: Tech,Vikingsquad Comments: Comments Off on Dev-Blog 208: Cinematic effects!

Dev Blog 200 (!): Playstation Experience 2015



Welcome back followers of the fearsome!

Today is a very special day, as this is dev-blog number 200, which means almost 4 years of weekly dev-blogs! I am quite proud that we’ve kept up a weekly dev-blog for this long, and rest assured we’re planning to keep it up for a long time to come.


Last weekend we were showing our game at the incredible Playstation Experience show in San Francisco. We arrived on Thursday afternoon, and met up with a lot of indies that very night. My favourite part of game-cons is meeting up with all the cool indie developers, and sharing stories and experiences. Our hotel room somehow turned into one of the meeting places for indies. Just look at the amount of awesome in this picture:


From left to right: Julie Miller, Adam Saltsman , Nicholas McDonnell, Mike Ducarme, Chris Lavina, Nels Anderson, Gordon McGladdery, Ryan Clark, Dan Nichols, Andy Moore

The next day we went to the show and collected our exhibitor badges, and set up our booth. Normally at these kind of shows you arrive at 10am, and then you end up waiting around until 6pm or later for the TV’s to arrive, but this show was very well organized by Sony and Anna Marie Rembold, and we had two TV’s and two PS4’s waiting for us at our booth space, ready to be set up! We unrolled our banners, and put up our horizontal banner, installed the builds on the PS4’s and we were done! We helped a few of our neighbours with their horizontal banners, and we were all ready to rock.


The organizers put a lot of the Canadian indie developers together, so we quickly nicknamed our area. At first we named it the Vancouver Corner, but after finding out that the guys from Life Goes On are from Edmonton, and the developer from Celsius was from Newfoundland, we renamed it the Canada Corner, or the Canadalley. I prefer the last one. This was one kick-ass corner to be in!

IMG_2507 Resized

Here’s a list of games on display from left to right:

Darkest Dungeon – Red Hook Games

Skytorn – Skytorn Team

Drifter – Celsius Game Studios


Life Goes On – Infinite Monkeys Entertainment

Shakedown Hawaii – VBlank Entertainment

Viking Squad – Slick Entertainment

Crypt of the Necrodancer – Brace Yourself Games

Quite a few of these games have audio by Power Up Audio, and they were there helping us all out with showing the game.

The first day of the show was a very long one, the floor opened at 11:30, and closed at 10pm (!). It was very tiring, but very satisfying to see to many people come by our booth and playing our game. The next day was thankfully a bit shorter, from 10am to 6pm. After a somewhat slower start it picked up and became a steady stream of people coming through our booth. Unfortunately I only have a blurry iPhone photo of people playing at our booth.


Sony installed scanning stations where people could scan their badge to collect cool prizes. Because of the carpets and the big metal pole they were mounted it, the phones got confused a lot with all the static electricity going around, and they would stop scanning badges. After a few hours we figured out how to get them working again, so we kept an eye on them to make sure people could scan their badges. I think this system actually brought a lot of people by our booth, and we showed a bunch of them our game. In total 2240 people scanned their pass at our booth. That’s a pretty good number, I think!


We were instructed to close down the booth and cut the power at 6pm sharp. We rolled up our banners, removed the builds from the PS4’s, and collected some crash data from the PS4’s. The game crashed a few times during the show, all at the same spot in the game, so with the crash-logs we should be able to find and fix the issue. Free playtesting! :)

When it was all done, we took a quick group picture of the Canadian devs at PSX:


After the show was all done, it was time to hang out one last time with all the cool indies. After a great recommendation by Anna Rembold, we went to the House of Shields, where bartender Keith took care of our sizable group of indies all by himself. Great times were had, and all I have to show for it is this super blurry group selfie:


From left to right: Me, Jesse, Julie, and Kevin from the amazing Power Up Audio

The next day we all flew back to Vancouver, and here we are! Re-energized to get the game DONE!


Until next week, and don’t forget the art stream later today!




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



Posted by: Under: Slick Entertainment,Vikingsquad Comments: Comments Off on Dev Blog 200 (!): Playstation Experience 2015

Follow us!

titlebutton_twitter titlebutton_facebook titlebutton_youtube titlebutton_twitch

Join our mailing list!

/ /

Dev Blog

April 27 2016

Welcome back followers of the fearsome! We hope your week has been awesome as you check out what’s been happening on this side of the Squad! Today we’ll be checking out some of the visual updates we’ve been giving to our beginning area. I’ve always had a problem when creating spaces that I focus too […]