I haven’t posted on here in too long, and it’s mostly because I have been very busy working on Darkwind again. The big news is that the game was greenlit in May, for release on Steam around the end of August.
Some of the main things I have been working on are:
- making the game ‘free to play’ with an in-game premium currency (‘Chromes’)
- overhaul of the lobby graphics
- integration of significant amount of functionality in the game client that was previously only available on the web site.
The last point is quite important, as we’ll hopefully get a big influx of new players from Steam, and the new player experience needs to be as good as it can. The split between 3D gameplay and web-based management has always been a bit awkward, so now you’ll be able to do core management of gang and vehicular assets from within the client, and complete management of squads – including set-up, travel, scouting, and multiplayer arrangement.
I have also been working again with Taskmasterpeace, one of the two guys who recorded all the excellent ‘sport commentator’ style vocals in the game. Task has been doing voice-overs for a series of tutorials I’m making about Darkwind.
Here’s some footage of a car driving around in the Shiva game engine, using the ‘raycast wheels’ approach. I have found that this gives much nicer results than the demo car that comes with Shiva, which treats wheels as constrained spheres. The problem with modelling wheels as spheres rotating on one axis is that this assumes rigid bodies for the wheels; actually, wheels are not rigid.
The basic idea with raycast cars is that you cast a ray from each wheel hub, and calculate the distance at which a surface is met (if at all). This defines the suspension’s extension, and then you simulate spring behaviour by applying increasingly strong forces as the suspension gets more compressed. There’s also some subtleties such as anti-roll and varying spring strength depending on whether its compressing or extending; but these are mostly tweaks applied to the core idea.
I also found that at high speed the default Shiva ‘spherical wheels’ car would suffer from occasional glitches and speed wobbles, rendering it fairly useless for most games. Sometimes it seemed to stagger sideways at high speed, presumably due to errors on the axis constraints allowing the spheres to role sideways. I assume these problems are caused by over-relying on the accuracy of the underlying physical simulation in order to obtain the required behaviour.
In the video clips shown here, the behaviour of the car in all ways other than spring response has been results-driven, i.e. the desired behaviour (skidding, drifting, tendency to roll, etc.) has been considered and this is used as a starting point for programming the calculations – rather than starting from an accurate physical simulation and expecting realistic/fun results as an emergent behaviour.
This represents very good progress towards what I’d like to have for a major new Darkwind project (Darkwind 2?) that I have started thinking about. Really the ineffective default Shiva car is what had stopped me considering this before now.
Last year I also wrote Musclecar Online. In this the car was entirely results-based, having no accurate underlying physical simulation from which the behaviour emerged. Musclecar Online is actually a 2D driving simulation with 3D models (hence, no hills or bridges) – and it was therefore entirely possible to define the behaviour I wanted first and then to write code to directly produce that behaviour.
Through my efforts to set up a game developers group in Galway in 2012 and 2013, I came into contact with two energetic and enthusiastic game devs, Liam Krewer and Alanna Kelly. Alanna had already run a successful Game Jam earlier in 2012, and it seemed like a natural collaboration to merge the fledgling Galway Games Group (GGG) with her Galway Game Jam (GGJ). So in June and October we joined forces and ran Galway Game Jam #2 and #3.
I hadn’t really been sure of the value of a Game Jam prior to this – it just seemed a bit insane to try to produce something in a single extended session. But the value is now clear to me – by creating very tight deadlines, you immediately make every team member useful.. so those with less experience are in a position where their work is relevant and important, which it would not be if the project had a month or two to complete. Apart from that the GJ is an excellent and fun networking opportunity. It gives a focus and theme to a networking session, which is something that we had already been struggling to manage in our earlier GGG meetings.
The first event, in June, ran for 12 hours. I took on the role of photographer and on-the-day organiser (making runs to the shop and Pizzeria etc.).. I didn’t really want to take part in the competition since I knew I’d only get too engrossed in coding, to the detriment of the other stuff that needed doing.
“We had fun! There were games made! .. mostly with only a tenuous link to the under-the-moon alternative-reality wonderland I envisioned. Apologies for my smart-ass comments and constantly sniffing nose. Also my camera battery died a couple of mins from the end so we didn’t get the wrap-up presentation from all teams.”
The second event, in October, ran for 24 hours (I, like the other more ahem.. mature.. attendees disappeared in the middle for some sleep!).
“Footage of our 24 hour game jam, 12th-13th October 2013, attended by about 25 coders, designers, artists and musicians. The quality of work going on was very impressive, and it was great to see visitors from Dublin and Tipperary this time, in addition to the locals! Thanks once again to the organising team Liam Krewer, Alanna Kelly, and me! I kept my cheeky comments to a minimum this time.. and the music being produced was so good that I didn’t want to muck it up by overlaying any backing track.”
Here’s some footage from an endless driving/shooting game I have been working on, for iOS/Android.
There will be 3 game modes:
(1) endless driving (how far and fast can you get without crashing),
(2) endless driving with guns (and armed enemies),
(3) story mode – you’re trying to catch spies in supercars while being attacked by armed cops – complete with end of level bosses in armed trucks, and radio-style narration by Robert ‘Task’ Smith.
Just today I caught up with Task and got him on board. I think the voiceover will be a really cool feature of the game: it will warn you of approaching enemies, let you know when you’re catching up with (or losing) the end-of-level boss that is your main target to complete each level. Task was one of the two voice talents in Darkwind, providing really slick and stylish TV-commentary-style comments during deathraces and arena combats.
Doodle Bomber is a little game I made with graphics by my 10 yr old son, Andrew. It’s based on the old game Blitz that I used to play on the Apple II, where your plane flies across the landscape dropping bombs and levelling buildings.
I’m very pleased with the visual style (kudos to Andrew!) and especially like the little stickmen. As usual I have focused on sound effects and once again the endless bounty that is freesound.org turned up some rather brilliant yells and screams which the little guys emit as you blow them 40 feet in the air
I did a little pitch shifting on them, which turns it from “slightly disconcerting bloodcurdling yell” to “comedy effect yell”.
The stickmen run towards the nearest building, and build it from the ground up to 4 floors. At this point a gun appears on the top and starts shooting at you. Tanks also appear if you’re taking too long on a level.
Here’s a quick look at the Doodle Bomber game’s use of 2D sprites in a 3D world; it’s a nice way to get parallax effects. In actual gameplay, the camera scrolls along beside the airplane, and as the various pieces of scenery disappear off the left of the screen they are transported forwards to the right, to give the impression on an endless (looping) game world:
So yeah, it’s a ninja swiping game, along the lines of a few thousand other games you might have seen before. There’s a nice combo/power-up system to give it a bit of a twist. And of course the sound effects destroy the opposition with their awesomeness! The theme tune by Art Munson of Shockwave Sound is really nice also
For the moment the big test is maybe the Android appstore, where downloads have been solid if not astounding. After a few days it’s now just breaking into the top 100 ‘new free racing games’ list – so maybe this will bring some increased traction. While the ‘new’ list on Google Play is a great concept, it’s always inundated with massively varied quality items, ranging from poorly designed wallpaper image apps (masquerading as games just long enough to spam you with adverts), to 200 clones of whatever lightweight crap is popular this month, right thru to high budget 3D racers. So getting some visibility even there isn’t always easy. The top ranking apps in the ‘new free’ lists are getting tens of thousands of downloads in a week or two, while getting to the top of the ‘paid’ list requires maybe 10 sales. Tells you something huh…
The Musclecar Online player-base is growing steadily; we’re currently getting a couple of hundred new downloads a day and by day-end we’re seeing upwards of 100 users posting laps in the more popular cars. The next couple of weeks will be interesting, and maybe we’ll see whether there’s any viral potential in the social features I worked so hard on!
The game is launching on Desura soon, and if you get a chance to upvote it on Steam Greenlight that would be most cool
Here’s a couple of screenshots from the new 3D camera viewpoint, added in version 1.3:
and here’s the most recent teaser movie made for the Android store:
I have been making good progress with my “social versus-ghost racer” Musclecar Online. A bunch of friends and Darkwind players have been testing it and having a bit of fun in the process.
The game is functionally almost complete at this stage, and we have been listed on indedb.com as well as being approved for distribution by Desura.com. I have pretty much decided it will be free-to-play on every possible platform, with monetization* via in-game purchases and (where appropriate) adverts.
*monetization: somehow that word only looks right with an American spelling. Lol.
Last year, when one of my games went a bit viral, I discovered first-hand about the alarming inefficiency of Apache (webserver), especially when running PHP which forces you to accept a process-per-request approach. It became pretty clear that something much more lightweight would be required if I wanted to build gameservers with large player-bases in mind.
After some research I have settled on node.js as a good solution. It’s very well regarded, largely due to its non-blocking, asynchronous model. This essentially means that anytime a resource is required (such as a database recordset) the request goes into a queue, to be called back when the resource is retrieved. In Apache, the model is blocking – the process sits and waits for the resource, thereby stopping any other activity.. this is why Apache needs all those independent processes, so that it can serve multiple clients simultaneously.
The game I have been working on is ‘Musclecar Online’ – a top-down racer in which players build their own tracks, vote on them, and then everyone in the world races on the same track-of-the-day. Rather than being real-time, you race against the ‘ghost lap’ recordings of other players; kinda like Speed Racer
Cache stuff in RAM
a 5-day pack of track layouts, allowing the players to see what’s coming up over the next few days;
per-cartype, per-second frequency bins, succinctly providing the data needed by the client to display a histogram of worldwide laptimes and point out where the player stands versus these;
a temporary array of ghost lap recordings, hashed by user ID for easy over-writing when they improve. This is only used up until 40 players have recorded laps for that car type on that day’s track, and allows random ‘unclassified’ packs of ghost laps to be delivered to players without the need to bother MySql about it;
more long-term packs of ghost lap recordings, separated into 6 divisions (F thru A) – the idea is that the player starts off racing against poor ghosts, labelled as division F, and if they beat these they are allowed to progress to division E, and so on. These longer-term packs are re-generated periodically, but not for the first time until 40 recordings are available for the car type.
Don’t fall into the ORDER BY RAND() trap
I have done some pretty naive stuff in MySql in the past, but running Darkwind for the past 7 years has helped me understand efficient database design and querying. With the characters, vehicles and weapons tables running into the millions, I was forced to. One of the newbie gotchas in MySql is to avoid doing a massive SELECT statement with ORDER BY RAND() LIMIT 1 in order to get a random record. If you do this, you’re basically asking the database server to load an entire table into memory, apply a random number to each record, sort the whole damn thing, and return one row. There’s a few obvious solutions, depending on how well distributed the data in your index fields is. One simple way is just to find your data range (e.g. laptimes min and max), generate a random number in this range, and then SELECT the first row greater than or equal to this laptime, LIMIT 1. Assuming laptimes is an index field, and also assuming there are enough records to make a reasonably even distribution across the data range, this works nicely.
Interesting asynchronous design solutions
Now, I love callbacks as much as the next man, but it can be an old-fashioned PITA sometimes trying to work with asynchronous coding. In a nutshell, anytime you want a resource that may be delayed (database query, file read etc.) you can’t use a traditional flow of control, can’t use loops for multiple accesses, etc. One of the things I have to do in the ‘Musclecar Online’ server is build packs of typical ghost lap recordings, in order to pack them into strings ready for dispatch to the clients. This means querying for each row with a separate SELECT statement, and therefore means 11 car types x 6 divisions x 5 different packs x 4 ghosts per pack = 1320 queries. Embedding each query inside the callback of the previous one certainly isn’t an option, but with a little thought I settled on recursion; a perfect way to unravel the asynchronous tangle. This works nice and efficiently, while still operating in serial (and therefore not choking up any server resources) and allowing nice tidy code. It’s kind of strange I didn’t see recursion mentioned as a solution anywhere on the web while researching node.js. Well, maybe I didn’t look for too long.
Let’s Break Stuff! was shortlisted for 2 awards at the Engineers Ireland Game Developer Awards at the recent Games Fleadh 2013 in Thurles. I have been aware of this festival (now in its 10th year) but hadn’t travelled to it before. There’s a lot of impressive work going on there – kudos to Phil Bourke and his team at LIT-Tipperary.
Anyhow, LBS ended up winning the ‘best casual game’ award