Posts

  • Streaming containers

    This blog post is about an issue I’ve run into several times, but still unsure how to solve in a nice way. Consider this more of an “organize-my-thoughts” type post, rather than a solution to the problem.

  • My journey into game development

    I often get the question how I got into game development and if I have any tips for beginners. Here’s my story and thoughts about getting into game development.

  • The Spraycan

    Teardown uses an 8-bit color palette for voxel materials, so any voxel volume can have up to 255 different materials and the representation per voxel is then just a single byte to save memory. A material specifies not only the color, but also things such as roughness, emissiveness, reflectivity and physical material type (wood, metal, foliage, etc). Each object can have a unique palette, but a lot of them share the same one. When something breaks, all the pieces inherit the original object palette, so the number of palettes do not increase over time. I pack all palettes in a texture that is 256 in width and number of materials in height and keep that on the GPU for rendering. This way of handling materials conflicts with one particular feature that I really wanted in the game - the spraycan.

  • Teardown quicksave

    Saving the complete state of a game at any time and then restoring to that state is hard for any game, but in a fully dynamic voxel world that constantly changes, controlled by dozens of lua scripts, all with their own internal state, implementing this was quite a challenge.

  • Teardown design notes

    Teardown started as a technology experiment and it’s one of those games where gameplay was designed to fit the technology, rather than the other way around. It’s not the first time I’ve been involved in such projects (Sprinkle, Smash Hit), and probably not the last, but Teardown was by far the most frustrating experience yet.

  • The importance of good noise

    There are many articles to read about noise functions in computer graphics, especially now that a lot of people recently got interested in ray tracing, but it took me a long time to fully understood why noise characteristics are so important and I didn’t find a good resource on the Internet explaining it, so I’ll give it a shot.

  • From screen space to voxel space

    There has been quite a few changes to my rendering pipeline over the last couple of months. The biggest being that I now do full raytracing in voxel space instead of the screen space counterpart.

  • Undo for lazy programmers

    I often see people recommend the command pattern for implementing undo/redo in, say, a level editor. While it sure works, it’s a lot of code and a lot of work. Some ten years ago I came across an idea that I have used ever since, that is super easy to implement and has worked like a charm for all my projects so far.

  • Bokeh depth of field in a single pass

    When I implemented bokeh depth of field I stumbled upon a neat blending trick almost by accident. In my opinion, the quality of depth of field is more related to how objects of different depths blend together, rather than the blur itself. Sure, bokeh is nicer than gaussian, but if the blending is off the whole thing falls flat. There seems to be many different approaches to this out there, most of them requiring multiple passes and sometimes separation of what’s behind and in front of the focal plane. I experimented a bit and stumbled upon a nice trick, almost by accident.

  • Stratified sampling

    After finishing my framework overhaul I’m now back on hybrid rendering and screen space raytracing. My first plan was to just port the old renderer to the new framework but I ended up rewriting all of it instead, finally trying out a few things that has been on my mind for a while.

  • GDC Rant

    It’s almost a tradition for me to get grumpy on the last day of GDC, and even though I had a great week this year there are some things that I would like to shine some light on.

  • Hot reloading hardcoded parameters

    Here is a trick that I cannot take any credit for, but that I finally implemented. I remember reading about it online several years ago, but I cannot find the reference again (it might have been on mollyrocket), so I’ll write up the idea:

  • Header file dependencies

    Ten years ago, I wrote my own C++ software framework and it was probably one of the best moves in my career as a software developer. It has been immensely useful for every little project I have done ever since, but adding bits and pieces and modifying it down the road has made the software quality slowly degrade.

  • Screen Space Path Tracing – Diffuse

    The last few posts has been about my new screen space renderer. Apart from a few details I haven’t really described how it works, so here we go. I split up the entire pipeline into diffuse and specular light. This post will focusing on diffuse light, which is the hard part.

  • A better depth buffer for raymarching

    When doing any type of raymarching over a depth buffer, it is very easy to determine if there is no occluder – the depth in the buffer is farther away than the current point on the ray. However, when the depth in the buffer is closer you might be occluded or you might not, depending on a) the thickness of the occluder and b) if there are any other occluders behind the first one and their thickness. It seems most people assume a) is either infinite or a constant value and b) is ignored alltogether.

  • Upscaling half resolution screen space effects

    When working with diffuse lighting and ambient occlusion in screen space it is often very tempting to do computations in lower resolution. Most of it is blurry anyway, and for any kind of GI/path tracing, diffuse lighting is undoubtedly the bottleneck. Here is a test scene with all colours set to white and no textures.

  • Depth of field in VR

    I have always been very fascinated by depth of field in computed graphics. For me, it often defines photo realism, mimicking the shortcomings of a real camera. Naturally it is a poor match for interactive applications because the computer doesn’t know what the user is looking at, but I’ve tried to squeeze in depth of field in as many of the Mediocre games as I could get away with. In Smash Hit I wanted to use it for everything, but Henrik though it looked too weird and made it harder to aim (he was probably right), so we ended up only enabling only it in the near field. In Does not Commute and PinOut, which both have fixed camera angles I’m doing a wonderful trick, enabling a slight depth of field by seamlessly blurring the upper and lower parts of the screen. This is super cheap and takes away depth artefacts completely.

  • Adventures in Screen Space

    Eight years ago, just when I first started writing this blog my second post was about screen space ambient occlusion. I used that renderer for all my physics experiments, leading up to the fluid simulation that became Sprinkle. At that point I left desktop computing in favor of mobile devices. Ten games later I’m now back to desktop machines and I’m completely blown away by all the computing power.

  • Pinball physics

    This might be the first time I reveal something about an upcoming title on this blog, but here it is – we are currently working on a pinball game. Not a classical pinball game, it has a pretty cool twist, but the basic mechanic is still very similar. As a physics programmer this sounded easy at first. Hey, it’s just a sphere. What could possibly be easier to simulate?

  • Stack allocated containers

    No matter what fancy allocator you come up with, memory allocation will always be expensive. In order to reduce memory allocations I have been using stack-allocated containers for the past four-five years and I think it has worked really well, so I thought I’d write a post about them here. These methods have been used in all our games (Sprinkle, Granny Smith, Smash Hit as well as our new project).

  • Physics tutorial at GDC 2015

    I will give a talk about the fracture algorithm in Smash Hit at GDC 2015. Come by room 304 on Tuesday at 1:45 PM. The session will cover the actual fracture algorithm as well as the physics engine to support it and how fracture affects other subsystems in the game. There will be be cool, shiny videos of stuff breaking!

  • Hail to the hall - Environmental Acoustics

    One of our early goals with Smash Hit was to combine audiovisual realism with highly abstract landscapes and environments. A lot of effort was put into making realistic shadows and visuals, and our sound designer spent long hours finding the perfect glass breaking sound. However, without proper acoustics to back up the different environments, the sense of presence simply would be there.

  • Cracking destruction

    Smash Hit is a game built entirely around destruction. We knew from the beginning that destruction had to be fully procedural and also 100% reliable. Prefabricated pieces broken the same way every time simply wouldn’t be enough for the type of game we wanted to make. The clean art style and consistent materials made breakage easier, since everything that breaks is made out of the same, solid glass material.

  • Smashing tech

    Our latest game Smash Hit has gone far beyond all expectations, being the #1 free game in over 100 countries during launch week and approaching 35 million downloads! I will write several blog posts about the technology here, starting with a tech summary of what is being used and then go deeper into each subject in future posts.

  • GDC Physics Tutorial

    I will give a talk on fluid simulation on GDC this year! Make sure to attend the physics tutorial.

  • Low level audio

    Audio has been a neglected area of our game engine for a long time. Except for a few tweaks, we have essentially used the exact same code for all our games. A pretty simple channel pool with pitch and volume per channel and an OpenAL back-end for iOS, Windows and OSX and an OpenSL back-end for Android.

  • Uniformly distributed points on sphere

    Sooner or later everybody will need uniformly distributed points on a sphere. There doesn’t seem to be a standard method for doing this, so I wrote a very simple iterative algorithm that pushes verts away from each other while continuously normalizing the point data. This will eventually find a stable state where the distance between any two neighboring points are very similar. Performance is terrible but it gets the job done, so only use this for offline stuff. There is also an option for distributing points on a hemisphere (y>0). Set the number of iterations to at least the number of input points for a good distribution.

  • Convex Hulls Revisited

    I have written about 3D convex hull generation here before. I find it a very appealing problem because it is so well defined and to my knowledge there is no de facto standard algorithm or implementation. I come back to this topic every now and then since I need a good implementation myself.

  • Mediocre properties

    I think most games use some kind of property system as a way to expose, edit and serialize parameters for game objects. There are of course very many ways to implement it, but here is how I’m currently doing.

  • Development environment

    A lot of people have asked about our development environment so I thought I’d write a post about it here. Both Sprinkle an Granny Smith as well as our two titles in development follow roughly the same pattern. I do all day-to-day development and testing on Mac and PC, compiling to native Win32/MacOS applications. Hence the code is cross-platform and mouse input is used to emulate touch input. My preference for actual coding is Visual Studio due to its superior debugging and Intellisense. On the Mac I use Textmate, shell scripts and makefiles. I only use XCode for iOS testing and deployment. I have used the XCode debugger on a few occasions, but it very rarely manages to do any meaningful on-target debugging. This might be due to my broken project files though.. I run Visual Studio through VMWare on the Mac as well, so it’s actually only one physical Machine. I used a separate development PC laptop before, but the VMWare solution is far superior in almost every aspect and removes a lot of clutter.

  • Small Object Allocator

    Prior to the latest update of Granny Smith, we ran into memory problems when loading levels. This was due to the unfortunate choice of using XML and TinyXML for level data. I’m generally very positive to both XML as a data format (as opposed to most game developers) and TinyXML as a library. However, since we don’t use instancing, a level can easily be 500 kb or more and TinyXML will parse the entire file into a DOM structure before it can be read. This results in a myriad of small allocations ranging from a few bytes up to about 100 bytes. I’m not sure exactly what the per-allocation overhead is on iOS and Android, but I suppose it’s at least 16 or 32 bytes. In addition the LUA library also makes a fair amount of small allocations.

  • Programmers are people

    Something that annoyed me for many years now is how the games industry (well, software development community in general) treat individual developers as “resources” in a project schedule. It doesn’t just sound awful and is a direct insult to the profession, it’s also plain wrong, stupid and counter-productive.

  • How Granny Got the Look


    In my last post I mentioned briefly how all graphical objects in Granny Smith are made out of 2D polygons which are transformed into 3D at load time. It was never initially designed for the sometimes complex environments in the game, but we decided to stick to this method instead of involving a separate 3D modelling software. I think, at times real 3D objects could have come in handy, but overall the current workflow is preferable since it's much more efficient. There is no need to track separate files or assets - every level is totally self-contained. Because the 2D data is so small, we don't even use instancing, so there is no risk of trashing another level when altering objects.
  • The Physics of an Old Lady


    It's been almost two months since we released our second title - Granny Smith (available on App Store and Google Play).
  • Jump start jumps


    I once heard that elegant code is in some respect contradictory to useful software, because it's often the sum of all exceptions that make a program useful, rather than it being strictly logical. Do you remember the frustration back when the javascript of slow-loading web pages was allowed to switch input focus to a login input box while you were typing a URL? The software was just following it's strict logic, switching input when it was told, while the better way of handling it would be a not-so-elegant check if the user have manually focused something else in between the start loading and finished loading, or a timer checking if the input focus change is still relevant.

  • Sprinkle behind the scenes

    This summer a friend and I released a physics puzzler for iOS and Android based on fluid simulation. It started as a really small project almost a year ago, but grew along the way and has been really well received on both platforms.
  • Impressions of the green robot

    I've been working on a mobile, physics-based game over the last five months (I'll post stuff about the project very soon) and today I started toying around with Android and porting the game. I'm not really sure what to think yet honestly. Some things are better than iOS development and other things are quite annoying. I really appreciate having command line tools for everything, and the ability to login to the device and do maintenance. Especially the ability to login and run a shell command on the device via a command line tool on the host. That way you can run scripts on your development machine that coordinate things both on the device and on the host at the same time. Awesome!

  • General wisdom

    I'm following quite a few game programming blogs, and whenever there is a post about a lifehack or general wisdom that can help me simplify my work I'm all ears. So, I thought I'd share some of my own experiences:
  • Schedulicious

    I've run into a pretty interesting/annoying problem while working on parallization of the physics pipeline.

  • Milkmans mistake

    After two posts full of boring text and graphs I feel like I have to give away a crowd pleaser. Again, not a realtime simulation. About 120.000 particles, running at almost one FPS.
  • The life of an impulse

    For a long time I've wondered how impulses develop inside a rigid body solver. Mainly for trying to come up with a prediction of where the final magnitude would be as early as possible. I dumped the data for all impulses out to a CSV file and graphed it for a couple of simple test scenarios. Let's start with a small test case, a box pyramid of two layers (three boxes). All dirty tricks are switched off, so this is a plain vanilla solver. The Y axis is impulse magnitude for the normal impulses and the X axis is iterations.
  • Explaining the rigid body solver

    Following my last post about scientific papers not being written for engineers I will do an attempt at explaining a rigid body solver without equations:

  • Academic frustration and running liquids

    I experimented with fluids about five years ago, at Meqon. Back then I didn't really have a clue about fluid dynamics. I guess it's fair to say I still don't have a clue about fluid dynamics, but I did read a few papers lately on SPH.
  • Practicing quadrupel windsor

    Starting to get soft body stacking and interaction in place. Especially the friction between two soft bodies is a little tricky. This is not a fake rigid body interpolation, but a true particle representation, which can compress to a single point and then return to it's original shape. It's quite expensive to be honest, since it takes more than just the regular verlet loop to get this kind of stability, but demo runs at 60 FPS.
  • Mesh collisions

    This is usually where physics gets messy. It's all fun and games until someone suggests that maybe all objects are not perfectly convex, such as... the game level? There is convex decomposition, yes, but I'm not totally convinced that's a silver bullet. Convex decomposition is awfully complicated, and requires heavy preprocessing. It's definitely a good idea in many cases, but there will always be raw triangles.
  • Movie time

    It was a long time since I posted a movie, so I thought I'd record a little snippet of what I'm working on at the moment - mesh collisions. Without the fancy SSAO renderer it runs in 60 FPS. Stay tunes for details!

  • STL

    I really like the idea of using standardized versions of simple data structures. Small snippets of code rewritten over and over again by thousands of people. I bet there are a handfull of programmers world-wide at this moment implementing a dynamic array or a hash table. As much as I like the idea, I hate the only standard out there - STL.
  • Visualizing complex algorithms

    I have had this idea for a long time about some tool to follow the steps of a complicated algorithm in some way other than stepping through it in the debugger, trying to mentally visualize what's going and frenetically scribbling unrecognizable geometrical figures on envelopes and old receipts.
  • Thoughts on shape casting

    I implemented a different type of shape casting yesterday. The most common way, to my knowledge at least, is to do it with conservative advancement:
  • Greetings from the inside!

    So after spending a few weeks outside the CSO, I got around to step inside and experiment with a number of different penetration distance algorithms this week. However, I failed to come up with an alteriative to EPA that can actually guarantee a global minimum separation. These are the ones I tried:
  • Trapped in configuration space

    I've spent the last couple of weeks tinkering with GJK and ended up rewriting it from scratch. Ever since I saw Casey's video about SAT-GJK a couple of years ago I've wanted to try it, so I finally did. Now Casey's video only deals with binary overlap status, not closest points, but it was relatively easily to extend his approach and even do a linear sweep operation. I especially like how his method does not include any divisions or square roots, which makes it very robust. I must add though that it's not straightforward to get a robust implementation that works on both polyhedra and quadric objects. Especially the termination criteria needed a lot of attention.
  • Oh how hard can it be

    Funny, I'm falling into my own how-hard-can-it-be convex hull trap I described just three posts ago! It turns out my idea for a support mapping-based convex hull generator isn't that great after all. It works perfectly in 2D, but in 3D it turns out the surface can get concave during the process, which of course will mess up the whole thing, so just forget everything I ever said about convex hull now would you (except perhaps the part about it always being harder than you think)? Thanks. Back to the drawing board. There must be some way to compute convex hulls using only the support direction..

  • More hull

    I realized I never wrote anything about the generic convex object visualization I mentioned earlier. It actually turned out really good, and the algorithm is very simple:

  • Big or beautiful

    Here is a capture from a couple of simple demos. I've made a number of improvements to the solver lately and also now gathering multiple contact points in the initial manifold. Incremental manifold is such a neat idea, but it does affect stacking stability, and objects tend to penetrate more, which in turn affects both performance and behavior. I'm now using relative rotations and reiterating GJK to find multiple points, but I'm experimenting with other methods that should be both cheaper and more stable.
  • Full hull

    Today I was scouting around for a decent convex hull generator. It's quite surprising to me that such a clearly defined task still doesn't have a de facto standard implementation that everybody uses. I just wanted one for computing the visualization meshes, so performance is not even critical.
  • Putting on the shades

    For rendering, I wanted to go one step (but not more than one step) beyond the flat-shaded polygons that are typical for physics demos. I wanted shadows, but I have never been a big fan of sharp edges, such as with shadow volumes or even shadow maps. Soft shadows is really what enables a whole new level of realism.
  • A new hope

    So I finally did what I should have done a long time ago - I started coding physics again. All those ideas that were lingering in the back of my head in the Meqon and Ageia days but I never had time to try will finally materialize, be implemented and posted on this very blog, along with pictures, videos, demos and general ideas around physics engines.

subscribe via RSS