If you know anything about our project, you’d know that it started out as a single-player, story-based platforming game. And if you’ve been watching it evolve on Twitch over the past 6 months, you probably know that we changed direction, focusing instead on a smaller game that is a multiplayer team-based ball & goal game.
How did this happen?
We decided to go this route after a couple of marathon whole-day meetings, the core of which was agreeing on our definition of success or “DEF-o-SUCK” as I like to call it. We agreed that a single player “Last of the Dashkin” style game with all my crazy ideas will be at least 2 years of hard work, with no assurance that it’ll ever be successful. Sure we could commit to finishing it. Brackenwood fans would probably buy it, play it and maybe even like it, but would anyone else? Would it have any replay value? Would it be talked about for years to come? Because all of these are in our DEF-o-SUCK.
The final decision was to start small. A more modest first project would allow us to set up the pipeline, the character, the world, the aesthetic and importantly, ship a product before the end of the year. Along the way we’d be watching and gauging the reaction from fans and gamers. A success would be our green light to proceed with the larger single player project, which would have all of its systems, aesthetic and movement in place. With a success under our belt, we plan to recruit a few more people and make a bigger, more ambitious multiplayer racing game. Only after those successes do we think we’re ready to commit to a single player.
So we had our 2D Bitey running around in the level, jumping on platforms and over obstacles. Planning a possible fatsack mini-game, we gave Bitey punches and kicks. In testing the movement and responsiveness of the controls, we gave Bitey the goal of getting fatsack up onto a ledge, or into a hollow log. You can see where this was headed. In order to test our movement and controls, things were beginning to point to multiplayer. That worried me. Lots of dashkin playing against each other? argh, that is NOT the story of Brackenwood.
Or is it?
Bitey of Brackenwood grew up alone in the world with only vague memories of his people. But they did once exist in Brackenwood along with the flying people – that is canon. So why can’t we have many dashkin in a Brackenwood game? Why can’t this be a prelude, a prequel, even a dream or memory?
In coming up with a name for our first Dashkin game, I decided to recycle the name of the very first BrackenSack made in Flash in about 2004. It was a solo mini ball game with click-to-move controls.
Anyone who knows Brackenwood knows that lighting is very important to me. In the Brackenwood movies, almost every colour has at least one tone variant. Grass for example generally has 2-3 colours – a base green, with a darker green for shadow tone and/or a lighter green for highlight. Of course this also goes for characters; in “Prowlies at the River”, Bitey’s main colours (hair, skin, horn) each have base and tone. Lighting got a little crazy in “Waterlollies” and “The Last of the Dashkin“, where characters had 3-5 colour variations for each base (light, dark, reflect, highlight, line).
The past couple of weeks have seen me working on lighting for Dashkin characters. Painting colour directly onto the character would mean the same lighting direction in every environment. But what if I want Bitey to be lit from the front as he runs toward a sunrise? How about a cavern level where he’s underlit from glowing mushrooms? Would I create a separate hand-painted set of Bitey animation states for each of those situations? Well no, that’s out of the question for pretty obvious reasons.
Unlike the movies, lighting in Dashkin is dynamic, which means that the character is lit by whatever lights are in the level. In the open grasslands this would probably be sunlight or moonlight, but in forests and caverns, there are more varied and movable light sources such as low light (sunset, sunrise), back-lighting, dappled shadows, light beams, glowing creatures and under-lighting.
I’m creating character light maps using Toon Boom Harmony’s light shading, then hooking them up in Unreal. It is a pretty tedious, sometimes painful process but the results speak for themselves. As you can see below, we have variable lighting on the character. In this test scene I’m using a particularly strong, white spotlight to accentuate the effect of the light map.
Last tech update covered how we move along sloped surfaces and dealt with tricky issues such as mantling up and into tunnels equal to our height. But a platform isn’t about just running along the ground.. its about.. platforming. That means jumping.
Step 1 : Leaving the ground
With our vector movement based approach it was relatively simple to get our character to jump. We merely used the existing horizontal velocity along the movement direction perpendicular to the normal of our ground surface and added a positive jump velocity. We do a quick sweep up to determine if our character has at least a minimum height ceiling above them and switch from ‘ground-mode’ to ‘air-mode’ for our movement.
Step 2 : Air Control
There are many key points for successfully creating jump logic in a platformer. Our character can influence their horizontal movement each frame in the direction the player holds the d-pad. This coupled with a jump height ‘kill’ (apply extra gravity when the user releases the jump button) allows the player to precisely control their motion in the air in a way that makes sense. If the player presses and holds the button they jump farther. If the player holds in a direction they attempt to move in that direction. If the player releases all controls the character attempts to stop moving and fall in the current location. While experimenting with motion it became very clear that stopping the character when no input is received is just as important as moving when a direction is pressed.
Step 3 : Landing
With our analog approach to movement using sweeps landing is accomplished by sweeping in the direction of motion, discovering the normal to the surface, and comparing that normal to what slopes are ‘landable.’ We preserve the horizontal motion of the character, switch to ground mode, and apply any extra time after hitting the ground to smooth out motion when we finally land on something solid.
Step 4 : Wall Hugging, Hitting our Head
Real physics aren’t always fun, that’s why we make fake game physics. When our character hits their head on a platform above them, we apply vertical and horizontal friction, but do not zero out their velocity. We then move our character along the ceiling in the direction perpendicular to the normal of impact. This allows the player to jump against curved ceiling, nudge around platform edges to get on top of them, and keeps motion fluid. These rules also apply to vertical slopes, so if a player is attempting to move into a wall their descent is slowed while they slide down it.
Step 5 : Playing with Friends
All the rules up until now have applied only to a moving character vrs a static world. Thankfully the same sweep tests, overlaps, and collisions also work great against other dynamic characters. By applying our same rules as before and preventing objects from penetrating each other, we merely perform the same logic as with our platforms and our characters can move freely around and over each other.
Step 6 : Rigging all the Things
Finally we’ve completed solving moving our object around our terrain. The final step is the incredibly tedious process of defining the bounding boxes of all our characters across all of their various animation states and frames. In order to do this we draw bounding boxes in ToonBoom Harmony and expert them per-frame into Unreal 4.
For a lone developer, there’s no need to spend time on graphics and animation for the game prototype. In Jonathan Blow’s 2007 IGF talk about his game Braid, he said that the prototype “didn’t need production values for people to play it and enjoy it.” In other words, Braid was playable and fun long before it had pretty graphics, indicating to him that he was on the right track and maybe even had a potential success on his hands.
For a solo developer it’s efficient to quickly prototype using placeholder assets. But we’re two people working full time; the tech guy and the art guy working concurrently, albeit on opposite sides of the world. So while Kirk is laying the code foundations, it makes sense for me to lay the animation foundations.
For this reason the Dashkin prototype doesn’t have your typical placeholder sprites. Even though they look like rough pencil sketches as you can see in this throw state, there’s lots of drawings and smooth movement. As an experienced frame-by-frame animator familiar with my own characters, I can nail this rough movement pretty quickly, and when it comes time to clean up all of this rough animation I’ll have a head start on it.
With so much animation complete, my current tasks are all about backgrounds. Backgrounds aren’t entirely necessary for a playable prototype, but these are in preparation for the latest phase; the “beautiful corner”.
The term is new to me. According to Kirk it is the stage of a project where you begin to define the visuals of the game in their final state. The beautiful corner itself is a short section of a playable level, arranged like a diorama of elements in their finished style. In this game, I’ve started working on our beautiful corner with some fully rendered skies, mountains, forests, terrain, the player character, some creatures and even an animated waterfall. This past weekend I’ve begun arranging these final assets in the prototype level.
The process is very similar to how I’d be doing it in one of my Brackenwood movies. Sky at the back, mountains, then forests, all the way forward to the character and foreground foliage elements.
From the beginning I’ve been anticipating this stage of the project where art and code come together to form what looks and feels like an actual game. Up until now there’s been a pile of code over here and a stack of art assets over there, but last week we saw things become an actual playable experience. Even though there are still a ton of rough assets, and lots of tweaks and polish to come, we can now build levels and run through them, overcoming obstacles, platforming and dashing. AND, thanks to the way Kirk has set things up, we can do that as any character, so it’s totally within the realm of possibility that we can play as fatsack, a prowlie or even the Yuyu cloud. Fatsack Exploration Adventure anyone?
Dashkin is all about platforming. Anyone who has ever played any platformer knows that movement is basically.. the entire game. This past week I’ve been exploring solutions on twitch to figure out how we’ll be doing this for dashkin.
Step 1 : Build Fatsack a test level
The first thing I did was create a simple level in Unreal 4 in order to test edge cases with collision. We made stairs, vertical walls, walls with tunnels, and a few giant ramps into space that we can run along and make sure our fatsack can into space. The idea being that if fatsack can traverse all the test objects properly in a horribly constructed danger zone, that he’ll be able to do so in a real level that we put together later.
Step 2 : Think a lot
Next I started drawing out all the cases I could think of and figuring out how we’d move our fatsack through the world. We went through an entire day of vector math drawings, hypothetical teleporting fatsack wormholes, and random tangents complaining about floating point to settle on our basic plan. We’ll be using sweep & overlap tests in unreal in order to move our object in an analog fashion (so not tile-based collision) through the world. Basically we sweep fatsack perpendicular to the normal of the surface he’s standing on, check for collisions, then resolve those collisions based on the situation.
Step 3 : Moving along the ground
In the simple case fatsack moves by nudging out of the ground by a tiny amount and sweeping forward in constant time along a vector perpendicular to the normal. If we run into an object we move to the point of impact and nudge out from that object by a small amount normal to the surface of impact. After we do this, we attempt to snap our fatsack to the ground. This allows us to run up and down slopes even if there are seams in the ground, as long as we don’t stub our toe into the ground.
Step 4 : Stubbing our Toe
The first issue with the motion is if we run into a piece of geometry which sticks out from the floor. A person in real life would just step a little higher and traverse over something like this (or they’d trip and fall on their face). In this game we want our characters to nicely glide over small seams in the geometry without any issue.
In order to do this we :
— Sweep in the direction of motion
— Move to the collision point with the sweep
— Raycast to discover a ‘mantle’ destination
— Sweep perpendicular to the impact normal
— Sweep along the perpendicular to the normal of the discovered mantling destination
Step 5 : Tunneling
One issue with mantle destination discovery is that we need to ensure that we can ‘step up’ into a hole that’s the same height of our character. In order to accomplish this we iterate in steps by our character’s height up the wall we’re climbing, move in the inverse of the impact normal, and again trace inverse in the perpendicular to the impact normal to discover the mantling point.
Conclusion Part 1 :
So far this method of movement has allowed fatsack to successfully navigate the ground in the test level!
Good Job Fatsack.
One of the biggest challenges associated with development is figuring out how you actually get work done. This becomes much, much more complex when you have people not only in different time zones but also halfway around the world.
Version control systems store your game assets and code securely so that everyone can work on the project at the same time. We’ve gone through quite a saga with zeroing in on the correct solution. First we started out with git hosted on github. This worked just fine until we needed to store large assets (like uassets in unreal 4). We tried throwing git-lfs (git large file storage) at this problem, but found that none of the toolsets supported it. This became a gigantic headache as I had to debug git commandline issues with Adam over voice chat. If you can imagine fighting a tiger with a blindfold on while googling how to compile ubuntu.. it was something like that. We then switched to the tried-and-true perforce. We were using hosted perforce on assembla, but when they raised their prices to over $200 a month for our services, we needed to pull the plug. We are now hosting perforce on our own t2.micro on aws and its been working out fantastically. We pay <$5 a month for this and it works great even though I’m in the US and Adam is in Aus.
All told we’ve migrated source control systems 4 times!
I don’t know how many indie studios have nightly builds, but we sure do. We’ve got a build machine setup under my other desk running Jenkins which builds all versions of the game nightly. It’s hooked up with its own gmail account and wakes me up at midnight if the build is busted (its always my fault). Having a build system which automatically builds our systems has caught so many boneheaded errors that I *HIGHLY* recommend any dev setup a build system even if you don’t think you really need it. All the software for Jenkins is free, so if you’ve got a spare machine sitting around you can set it all up for free in a snap.
Version control is good at storing source code and big assets, but what about temporary work or files that don’t work well with source control (I’m looking at you ToonBoom Harmony!)? We tried various solutions such as dropbox, share drives over VPN, and others.. but nothing has come close to the speed and just plain ‘works’ as Resilio Sync. Its a torrent-based file transfer system which syncs file systems asychronously. We just leave the build machine always on as a peer with automated nightly archives onto our NAS and we’ve got versioned backups as well as always-available secure peers for fast file transfers.
Tools and Scripts
Creating easy-to-use development tools can be very tricky even as a small team. Telling someone to go run ‘GenerateProjectFiles.bat’, sync down the latest on p4, run the sync tools for unreal dependencies, build the editor in ‘development’ mode, run the code generator, and run the newly built editor is a huge pain. In order to simplify our workflow we’ve created a master helper batch file which we both use. If one of us creates a new tool we just add it as an option and check it in. No more ‘oh yeah.. sorry Adam.. I totally broke all your stuff.. so.. here’s a 12 step process … Adam? Are you there? …..
Debugging crashdumps from C++ applications can be a gigantic headache. To solve this we host a symbol server on our shared NAS which our build server updates. We use srcsrv & symstore so when we get a crashdump all we have to do is double-click the files and it syncs down the files from p4, grabs the symbols from the Z: and we’re fixing bugs before we realize it.
*a quick hint for those troubled by p4 srcsrv requiring identical hostnames and not playing well with proxies, just edit p4.pm so it doesn’t include the host.. then tell developers to make sure p4v is open on the right server and it’ll automatically grab your correct files
Tools and scripts : Java / Python / Batch scripts
Version control : Perforce self-hosted on AWS (free for <5 users)
File share : Resilio Sync Pro (secure folders ftw!)
Debugging : Srcsrv & Symstore
Total cost per month : $25
If you’ve got any questions you can hit me up on twitter @ambientenergy_0
The past few weeks have seen steady progress in both technical and art sides of the project.
In preparation for the prototype, I’ve been making rough assets, including fatsack and Bitey animation. Not only is a lot of animation layer/node organisation required, but designing that organisation – that is, deciding how best to lay things out so it’s readable/usable – took half a day and still evolves with use. In the image below, there are two main sections. Left: states that happen on the spot. Right: states that happen at speed. The red areas below those contain finished states, the states in progress are in the centre.
Except for the top two, each red block contains several individual animation states. Each state consists of a 5 main nodes. At the top of each is the animation itself – a grouped hierarchy of embedded layers, including separate head, eyes, arms, deformer curves and collision rigging. Underneath that main group are two composite nodes and two display nodes. These are for working and exporting, respectively. In this screenshot, there are almost 50 states. I would estimate there’s at least another 50 to do. It’s also worth noting that this is only Bitey’s animation. This will need do be done for every creature and character in the game.
As anyone who watched my Twitch streams would know, I initially found it frustrating to rig fatsack and Bitey, struggling along slowly adding collision shapes to each state. Additionally, due to the frame-by-frame nature of this game, many animated states require splitting into various sub-states.
For example, the jump animation consists of 5 sub-states: spring, rise, hang, fall, land (see below). Having these all separate on their own layers (instead of all together in one sequence) makes it difficult for me to see the animation working as a whole action. It’s something I can get used to over time and I’ve developed a workflow but it hasn’t come easily. That said, this is the first character (the main player character no less) and once these initial teething problems iron themselves out and things will move more smoothly for the other creatures.
Rough animation is a very fast process for me and most of what you see above was animated in a couple of days. There’s plenty more to come yet so if you’re interested in seeing it take shape, you can find me working live most weekends on my Twitch channel. Once Bitey is done, I’ll be creating some very rough collision and terrain assets and looking further ahead, more creature animation.
Here we are! A few weeks ago on 12th March I announced live on my Twitch channel that Dashkin, a new game from the ground up, is in full time development. This neatly coincided with me landing a partnership with Twitch so they gave me some front-page time for the announcement which was a huge boost for us. Dashkin developer Kirk Sexton (ambientenergy101) was in the chat answering questions while I demonstrated our tools and process. He’s also the guy who set up all the sites here so he’s behind the scenes making everything work. You’ll see him around the place answering technical questions but we’re also compiling a FAQ on the Wiki.
The week after announcement, I continued my work on story, which I’ve split into five acts. By the time you read this I hope to be finalising Act 4. It has certainly been a challenge; telling story through game play is very limiting and games often use cut scenes to help drive the story forward. I need to avoid too many story-based cut scenes though, partly because it slows the game down (not good when our game has a “high speed” theme) but also because animation is a lot of work and I doubt I’ll have time to animate more than a minute or two of cinematics for this project.
I’ve also been working on rigging up sprites with collision geometry and exporting sprite normals from Harmony. This makes all my 2D animation ready to import into Unreal as flipbooks. So in this weekend’s streams I’ll be doing more animation and testing some stuff in Unreal. Drop in and say hi!
This past week was our websites week, with this blog and community sites. Kirk set everything up, I’m still working on customisations. So come check it all out! Join the forum, customise your profile, click around, explore, find broken things, ask questions, request features and tell your friends. We’ll be posting weekly updates from here on in and making any big announcements here first.