This is the first Paint the Town Red dev log that is about something I just worked on. Over the weekend I added something I'd be thinking about for a while: an easy to use animated gif tool. The idea is that the game is always recording small screenshots as you play and when you pause the game, you can review the last X seconds of gameplay and choose a range to turn into a gif.
Here's what it looks like to use. Bear in mind that this footage is from an in-development version of the game with many little animation and physics bugs so ignore anything non-gif related:
Paint the Town Red has some very dynamic and often hilarious combat moments. Creating an animated gif is typically quite time consuming and complicated. You need to be capturing the screen somehow, need video editing software to cut out the section of the video you want for the gif and then you need some way of converting it to a gif. From my experience Adobe Premiere makes terrible animated gifs and there's not many good video-to-animated gif applications around. There are good web sites for video to gif conversion, but they have limitations on file size and duration that will probably send you back to the video editing software to get the resolution or length down. In my experience the process is very time consuming and often frustrating.
The number of people that can and are willing to make a gif no doubt pales in comparison to the number that would like to if it were easy.
This is easy.
The hope for us is that more people share their experiences playing the game through gifs which I think is one of the quickest and easiest ways for people to comprehend what the game is and get interested in seeing more.
Recording the Screenshots
This was the easiest and quickest part of the process. Within 30 minutes of deciding I was going to work on this I had a circular buffer of screenshots being saved at my desired resolution and framerate. This feature lives and dies on it being fast. Capturing screenshots conventionally is fairly slow if you're trying to do it in the background, even for relatively low resolution images. The method I went with was to create an array of Unity RenderTextures and as part of the post processing process, copy (blit) the render buffer to one of these render textures every frame. The array length is the number of seconds I want to record (currently 14 seconds) multiplied by the frame rate. I treat this as a circular buffer and always have the last 14 seconds of gameplay available.
This wasn't made with the gif tool... I just wanted to throw another image in here and this one's fun.
Displaying the Screenshots
When the game is paused, the pause menu has an area dedicated to displaying the replay along with sliders that allow you to set the start and end points of the loop you'd like to save to a gif. At the moment for simplicity I always record the screenshots at the same resolution regardless of the aspect ratio, but here I scale the image UI to make it appear to match the aspect ratio of the window. The images cycle along at the recorded framerate and loop correctly using the current start and end positions of the circular buffer of render textures and the user set start and end loop points. The GUI for all this took a few hours to setup all together.
Creating the GIF
One thing I didn't want to have to do was write my own GIF encoding. Typically I prefer to write my own implementations of things like this rather than use a third party library, but I wanted to complete this task over a weekend. I looked at a few C# animated gif libraries hoping to find one that would be fairly simple. NGif was the best I found for my purposes. Besides a couple of files that handled some image analysis and encoding, there was really only one file I needed to deal with. I converted its implementation from using Windows based Image and Bitmap classes to Unity textures, made some optimisations and had it working pretty quickly. At gif creation time for each of the desired frames I create actual readable textures from the render textures and perform bilinear filtered scaling to get them to the correction aspect ratio if required. These textures are then processed one at a time and encoded as gif frames. Once complete, I save the result as a gif file on the users machine in their save game directory and then provide the option to upload the gif.
Ultimately the process of finding the gif library, getting it working in Unity and setting it up for my purpose of pumping out gif files from the replay recordings took 2-3 hours.
The process of creating a gif file now was infinitely simpler than it was before, but I also wanted to remove any barrier between that step and users sharing the gif with others. I looked at the APIs for Imgur and gfycat with the intention of supporting uploading to both. Imgur's API is more mature, but there are more hoops to jump through. It also appears as though commercial applications may need to pay a fee to use the API. gfycat on the other hand has a very simple API and less restrictions. Their documentation is pretty poor with spelling and even mistakes in their URLs, but I was able to figure out the correct steps to get something uploaded and transcoded and get the result gif URL back.
Uploading to the Amazon S3 servers gfycat uses was quite slow so I made sure you could resume playing the game while it was happening. Once the upload completes, the gfycat transcode URL is called to take the uploaded gif and turn it into whatever gfycats HTML5 video stuff is. When that process completes, the URL of the result can be grabbed and at that point I display a button to open the gfycat page in a browser (user's default browser if non-Steam and Steam browser in in Steam) so you can see the result and easily copy the URL to share it. gfycat also makes the original gif file available.
Here's the gfycat I uploaded in the video above:
Looking at Imgur's (and to a lesser extent gfycat's) APIs also re-affirmed my hate for how things are typically done on the web.
All together the recording, GUI and gif creation side of things took around 5-6 hours to get done. The gfycat upload process including handling the various error cases probably took another 5 hours or so. For a weekend where I had a lot of other things I had to do that kept me off the computer, I'm extremely happy with the result. Being a 2 man team with our heads down working to get the game done almost all the time, it's hard to focus on marketing. For a game to be successful (i.e. sell and make money), effective marketing is extremely important. We don't have money for advertising and PR companies, so instead we rely mostly on word of mouth and if we're lucky, gaming sites covering the game and Youtube channels playing it to get people's eyes on it.
You can only sell the game to people that see it, and I know that personally I will often ignore a game until I've been beat over the head with it several times. Hopefully this leads to more people sharing their cool moments on Twitter, Reddit, forums, etc so more people get beat over the head with Paint the Town Red when it's out in Early Access.
The next dev log will likely go back to covering one of the larger topics like our custom lighting. Keep an eye on this site, the Steam community, my Twitter or my TIGSource DevLog thread for the next update.
If you read this far and haven't added the game to your Steam wishlist yet, you probably should go here and do that.
One of the key features of Paint the Town Red that we’re adding to elevate the over-the-top gore from what we had in the 7DFPS game jam version is the that the main shapes of the enemies like the head, torso and upper and lower arms and legs are made up of "voxels". What that essentially means is instead of the head being one big cube-shaped mesh, it's a shape based on the combination of a series of smaller cubes. Being able to then dynamically change the cubes that make it up by changing or removing some and having the overall head shape reflect that means we can have chunks of the head or other body part be severed and destroyed when hit.
Creating the Mesh
The naive approach to rendering voxel objects would be to simply make each voxel a separate renderable cube mesh in the game. While that might work for certain types of games where there might only be a very limited number of voxels, it's not a viable approach for a game where you're concerned with hitting high framerates and not having tight restrictions on the number of voxels.
The approach that we've taken with creating the mesh to be rendered for each voxel-based object is to create a single mesh that contains the triangles of all the exposed faces of the voxels. So something like the head of an enemy may start as a 10x10x10 3d grid/matrix of voxels that are all intact. If we look at all these voxels and check what each of their 6 faces are touching, we can see when a face is touching nothing (i.e. not touching another voxel) and add that face as 2 triangles to our objects overall mesh. We also need to account for whether that voxel face requires a UV coordinates for a texture and pass that information to the new vertices along with other particular rendering information for that voxel stored in the vertices for our custom shader.
This approach involves looking over the state of all voxels at creation and every time they change and recreating the entire mesh. Fortunately our voxel mesh creation code is already very mature and efficient as it was brought across from another game we were working on prior to Paint the Town Red.
The function to define the mesh can easily be multi-threaded and the results applied upon completion for rendering. Currently however, the voxel mesh creation code is not a performance concern at all compared to things we have a little less control over like physics, animation and pathfinding.
We had some basic dismemberment in the game jam version where we'd separate the head or limbs depending on the weapon used and some degree of randomness. Now that we've switched to voxels, not only can we sever these body parts in their entirety, but they can be damaged and severed in any spot and way imaginable.
When a voxel object is modified we can look over all the voxels and separate them into groups with other voxels that they're directly or indirectly connected to. An intact object will have one group where you can find a path from one voxel to any other through the voxels they're touching. When there is more than one group, we need to disconnect separate chunks from the rest.
The process of sorting the voxels into these groups to check for dismemberment is the slowest part of the voxel system and there are a number of different cases to handle. For each group of voxels in a particular voxel object such as the head or the lower left arm, we need to determine if it's attached to anything else on the body and in what way. To answer these questions, certain voxels in an object are set as connection points along with information about the connection type and what they connect to. We can then determine how to handle the dismemberment of a group of voxels by seeing if there are any connection points in the group and if so, what they they are.
For example, in the image above you can see 2 small groups of voxels have been severed from the head. The head contains 4 connection points which are 4 central voxels at the bottom of the head where it connects to the neck/body. The small chunks of voxels in the image don't contain these so this is the most simple case where we simply need to break these groups off into new, separate objects with their own collision and physics. The head is essentially duplicated with only those voxels being set in the new objects, while also being removed from the original. Bruising and blood effects are also copied across for consistency.
Things get more complicated when a severed group contains connection points. Below you can see a debug view of a character with the connection points shown as yellow cubes. Imagine we cut clean through the center of the left foream with a sword. Our scan of the object after the sliced voxels have been removed will show that there are 2 groups of voxels and each contain connection points. The upper portion of the forearm contains a connection point which serves as the primary attachment point for the object. Whether this point is intact determines whether the forearm remains connected to the upper arm. In this case we don't need to do anything with the upper portion of the forearm. The lower portion however contains a connection point that says it's connected to the hand object. Severing this is much more complicated than the head chunks above as we need to first create a new object with these voxels in the same way as the head example, but then also need to take the hand and its child objects (fingers, the katana in the below image, other unseen collision objects) and have them all reparent to the new lower forearm object and enter what is essentially their ragdoll state.
When removing voxels and creating new objects with a subset of the voxels of the original, we also need to update the collision geometry to match the new shape of the object. Because of how collision intersection algorithms work in physics engines, the collision geometry needs to be convex. Fortunately Unity handles the convex hull generation for the most part, although it does have some issues with recalculating the center of mass which we need to solve ourselves.
The most extreme cases where you cut through both arms and the body and the hips all in one motion work now without issue, but the incremental steps through development to reach that point led to some pretty fantastic bugs. I have captured and continue to capture videos throughout development whenever something interesting is going on. The video below was from a pretty great stage in developing the dismemberment system where all sorts of odd things could and would happen.
One of my favourite aspects of our voxel characters is that not only can we have different visuals for the voxels in terms of colour and texture, but we can also give them different attributes. This doesn't just set whether they have a texture (like the outer most face of skin voxels) or their colour, but also things like whether they can be only damaged by certain objects or their resistance to damage from weapons. This primarily manifests in the bone voxels being more difficult to break through than skin, flesh and brain voxels (which each have different resistances also) and that gives some great gameplay opportunities. If you're using a weapon that does more voxel damage than "health" damage to enemies, trying to damage the brain (which will instantly kill the enemy) could be important. To reach the brain you might need to try attacking the same point on the head where the brain is exposed so there's more chance to break through.
Alternatively you might find that some weapons do little voxel damage and aren't actually capable of breaking through bone, only the surrounding flesh. Along with other weapon characteristics (health damage, break-ability, stick-into-person-ability, throw damage, etc), this adds to the complexity of the weapons and combat in subtle ways that don't affect the ability to get into the game, but add depth for those that play longer and want to do better.
Having the different voxel types in the internal structures of the enemies also opens opportunities for weapons and effects that target different voxel types differently. Already in the disco level we have the afros setup to only be able to take damage from (be cut by) bladed weapons, although they also reduce the damage taken from shots that pass through the hair. But one could image a sci-fi level where some effect leaves only bones behind for example.
There's a lot more involved in the voxel tech than discussed here such as how we handle the weapon collisions and in the future when I have a bit more time (perhaps after the game is out in Early Access) I'll be able to go into more detail on everything.
I'm very happy with how it's turned out so far and it should make watching other people play the game much more interesting. It makes everything much more dynamic and different every time you swing a weapon.
This first Dev Blog serves as more of a history and introduction. Future Dev Blogs will be much more in-depth on technical aspects of the game.
The Game Jam and Greenlight
I'm going to first give a brief history of Paint the Town Red up to this point. It might not be terribly interesting so skip to the next section below to see more more about what you'll see in Paint the Town Red.
In 2013 both Shane and Myself (Matt) had transitioned to working jobs part time so that we could dedicate most of our week to finally making South East Game's first big game. Despite this, things were moving along at a fairly slow pace as work commitments and a lot of up-front technical work for the game weren't allowing us to ever really get completely motivated. We decided we should quickly make something considerably smaller, probably for a game jam. It should be a game that has the potential to be popular enough to warrant a larger version that we could make some money from. We threw around ideas to see what stuck and before too long we came up with the idea for what would become Probably Archery. I remembered that the 7DFPS (Seven Day First Person Shooter) game jam was coming up within a couple of weeks and that seemed like a good fit. When the game jam came around, we ended up making the that version of Probably Archery in 6 days and were very happy to find people liked it and it was getting a lot of attention on YouTube and elsewhere. We went on to eventually make a Steam Greenlight campaign and then release a full version on Steam which did quite decently considering the time spent on it. Ultimately we spent about 2-3 months of part time work making the full version.
Developing Probably Archery was ultimately not the most enjoyable experience. We liked it as a game jam idea, but we weren't as enthusiastic about making a full game based on it and got it done pretty quickly. We still worked hard to make it polished and have enough content to make sure it was worth it to people, but there wasn't much more to do with the concept besides some novel inclusions like Oculus Rift and Razer Hydra support. Neither of us wanted to go through developing a game like that again. We would now only make something we wanted to play ourselves and could be passionate enough about to put a high level of time and effort into.
We began working on another of our larger game ideas in 2014 and this time while things were going a little better, financial obligations and the expected dev time were constantly in the back of our minds. Then I saw the announcement that the 2014 7DFPS jam was coming up and started thinking that maybe we could make lightning strike twice but this time do things a bit differently. There's no harm in seeing if we have another good small game idea up our sleeves. We both agreed that if we were going to do this we had to make something that would work well as a one-off game jam game like Probably Archery did, but if it proved popular it would be something we actually would want to make into a larger game.
Let's make a first person bar fight game.
It was the obvious right choice as soon as we came up with it and it wasn't hard to think up ridiculous gameplay and weapon ideas once we had. We settled on the art style quickly. It had to be simple enough to allow making the amount of content needed in a week and we wanted it to be cartoonish to offset the violence in the game. The large expressive faces of the enemies ended up being perfect targets for pool cues, baseball bats, broken bottles, etc. We were pushed much closer to the 7 day limit this time around but were very happy with the result. It certainly had issues, but it felt like a complete little standalone game that had gameplay that was pretty unique. First person melee combat has never really been done like this before in anything we'd seen or played.
The game was done and part 2 of our plan and the task for the second half of the 7th day of the game jam was making the Steam Greenlight campaign for the game. We knew from Probably Archery that the most important aspect of Greenlight is getting eyes on it so we wanted to have it up before the end of the game jam. That way we could include a Greenlight link in the game so anyone that enjoyed it could support us in making a bigger version.
It might have been that we were a little burnt out and weren't terribly interested in doing a big marketing effort at the end of the 7 days, but for the most part all we did was upload it to itch.io for the game jam, throw up the Greenlight page and walk away. Really though, this was mainly based on our attitude of "if it deserves to get greenlit then it will get there on its own". We pushed hard to get Probably Archery greenlit and this time we were well aware of the time commitment that would be involved in making the full version. We wanted to make sure people really wanted it first. We watched from the sidelines and didn't push for votes.
It only took 21 days for Paint the Town Red to be greenlit on its own merits. Now we just had to come up with what the full game would be contain. This time we were genuinely excited to make the full game, especially if we could come up with some cool new features to make it even more unique and fun than the game jam version.
Some New Tech
Most of our discussions on the full version of the game revolved around levels and story at first and we couldn't nail anything down. It wasn't until we had the idea for taking our box-y enemies and making them out of much smaller boxes that we had a direction. The story and levels didn't seem like an important concern compared to the excitement of voxel based enemies. Imagine if the heads of the enemies had an internal structure including a brain, skull and the flesh around it. Now when you hit someone with a baseball bat it wont just make blood or maybe knock their head off like in the game jam game, now it could knock chunks off their head exposing the flesh and bone beneath. Keep hitting and you could break through the skull and start bashing through brain. Or how about taking a sword and cutting through someone completely and having their body and limbs sever and separate exactly according to your cut.
Sounds pretty gross, and for a time we were a little concerned with whether it was too much. We decided it wasn't.
I'll be going into much greater detail on the technical aspects of the voxel characters and the possibilities in the next dev blog very soon.
The issues with lighting and shadows in games is a hard to describe even to other developers that have never really dealt with it.
In a static game environment you can utilise baked lightmaps to achieve high quality results that have little runtime cost, but they can't work well with dynamic objects. You can use Light Probes (in Unity, and similar in other engines) to bake the lighting information for points throughout the level so that you can then have this applied to dynamic objects, but this still doesn't allow for proper shadow casting and receiving for dynamic objects. You could have a mix of realtime shadows and baked lightmaps, but there will be a visual discrepancy and many issues with how shadows are cast and received as to do this in an efficient way, the realtime lights will only be rendering the dynamic objects to the shadow maps and not the static ones that use the lightmaps.
Alternatively you can use completely dynamic lighting and shadowing which has the benefit of essentially working in all cases, but the downside of being much slower, particularly when you have lots of lights.
Dynamic shadowing isn't especially important for Paint the Town Red in the traditional sense, but we do want lights in rooms to not cast light through walls into adjacent rooms, so that means we need a good shadow solution. We also want things like doors that are dynamic to cast shadows correctly as they rotate, so that means using baked lightmaps isn't really going to work out. Luckily with new features added to Unity 5, and particularly 5.2, I was finally able to make the lighting system I'd wanted to in Unity for a long time.
In Paint the Town Red we have custom lights and shadow mapping that can bake all static geometry into one map and render and composite dynamic objects as needed into a final shadow map used for rendering. Shadow maps can persist across frames without needing to be re-rendered when nothing has changed so for the most part we have the equivalent of dynamic shadows with very little performance cost. I'll go into much greater detail on all this this in a later dev blog.
Our persistent blood decals in Paint the Town Red are one of the most important features seeing as though it's essentially the name of the game. We had this working well in the game jam version using a 3rd party decal system for Unity and for that small environment and number of characters, it ran well enough. Larger environments, more enemies, more objects and a lot more blood flying about at once meant we needed something custom and much, much faster. We considered deferred decals and texture splatting approaches, but ultimately the standard mesh based decal approach was going to be best for the various cases we had. Writing our own decal system, being able to do lots of pre-caching of mesh data, breaking the level into decal system chunks and a lot of other optimisations meant we ended up with a system that ranges between 50x and 100x faster than the old game jam's decals.
There are a lot of (I think) interesting technical and design challenges we've been working through on Paint the Town Red and I'll be going into more detail about them in future blog posts.
When Paint the Town Red was greenlit, we expected we'd have the first Early Access version ready in Q1 2015. Ultimately it's going to be the start of Q4. Things were delayed quite a bit at first as I was moving into a newly built house and dealing with all that's involved in that. During that period we were mostly discussing the design of the game and its story while working on the new biker bar level and the voxel tech. At that time we were intending on having a linear progression of levels with a story tying them all together. Ultimately we had desires that didn't fit in that mold like having levels that took place in different time periods. So we changed our plans and removed all concept of an explicit story from the design in favour of just doing what would best serve the gameplay.
During development our Steam Greenlight page has continued to have a lot of people eagerly awaiting the game and at times getting agitated at the lack of a release or firm timeframe. We've wanted nothing more than to give definitive answers, but we haven't known when it would be ready for release for quite some time. Our goal has been to make the best Paint the Town Red we can and that has meant letting the game design itself somewhat as we work on these new features. We decided it best to wait until we had a date and had something worth showing before we said much else. Now we have those things and we don't intend on shutting up about them. There's so many cool things to show and talk about.
October 13 is the release date we've set for the first Early Access release. We might adjust it slightly earlier or later depending on factors we haven't accounted for, but that's a pretty safe window. We've been focused on 2 levels for the first release, the Biker Bar and the Disco. It's important to us to show the type of level variety we'll have in the final game so these seemed like good choices for the first release. Our goal is to have the gameplay close to final so that it is almost a vertical slice of the final game, but there will definitely be some changes to these levels over the course of development in Early Access. There'll be some more work on a larger enemy type for example for special characters and some of the boss characters. Primarily though our focus will be on adding new levels to the Early Access versions with the goal being a least 1 new level every month. At this time we're expecting to be in Early Access for around 6 months, but we're going to work with the community on the direction of the game so we don't know exactly where it will end up and how long that might take.
Steam Store page for Paint the Town Red. Follow and/or add to your Wishlist if you'd like to be notified of updates and release.
We're definitely going to strive to be active and involved with the community discussions and hope to hear from you on the Steam community, Reddit and Twitter (@SouthEastGames, @MCarr and @ShaneCarr).
We're currently hard at work on the full version of Paint the Town Red for release on Steam Early Access and we'll have a series of development blogs starting very soon showing all the cool features we're cooking up.
Keep your eye on southeastgames.com and our Steam Greenlight page for updates.