Muddledash is couch-competitive octopus racing. You are a wriggly little octopus, trying to get to the most bopping party of the year with a gift in hand before all your friends. Just one catch - there's only one gift. Fashionably late is now out of season. Myself and SafetySnail are making it.

Hey guys! Other developer tuning in here.I'll generally be working on level/game design and overall game feel, but I also like to try to contribute to the art and programming side of things too! Expect to see a bunch of posts about all of that stuff from me.Niall and I met on an animation forum years ago and have been working on games either together or independently since. We both have a love for the creative, problem solving and imaginative process used to make games. This year we got the opportunity to meet in person for the first time, Niall staying with me in Australia for around 2 months. We thought, "What better time to make a game together than now!", so that's what we're doing!Muddledash is a culmination of everything we find fun in games, It's an edge of your seat style, cutesy racing game with a lot of character and charm!

@7box and Lo-Phi, thank you both! as SafetySnail mentioned we're both living together in the same house currently (essentially the same room when we're both home), so expect frequent updates.we've also now got a twitter where we'll be postin more stuff too.

--

I wanted to talk a bit about LEGS. this was the first thing I tackled before really knowing what sort of form the game would eventually take. the first incarnation had been fixed-screen and tile based in my head, and initial tests were essentially a semicircle of raycasts out from the base of the player collider to see what it could hit in a certain range. it worked, but with the side-effect of being far too beetle-like:

my initial plan was just to use the predicted foot positions as waypoints to anchor bouncy bézier curves around, but the circle-casting approach just gave far too limited results. aiming to up the ¡Wow! factor a bit I experimented with giving the 'pus a little springy knee jiggle:

needless to say this is absolutely terrifying so I switched back to focusing on the base leg shapes. I added a couple more waypoints and instead switched the springs to the 'toes', i.e. the tips of the tentacles beyond the raycasted foot positions. in order to get more immediate control over the curves I progressively generate vertices along a cubic hermite spline. sidenote: if you dig splines, this presentation by squirrel eiserloh is a good read. I then added some extra rules to ensure all raycasts couldn't cluster to a single point, adding some randomization to their steps.the results were as follows:

this felt a lot closer but clearly some fine tuning was in order - going down steps allowed the legs to become spaghetti far too easily, and they would generally look far too separate from the body during actual motion. this is in part due to the absurd movement speed, but I tackled that later. the next iteration involved the introduction of an amped up face, secondary motion of the hat, and the ability for legs to hang off the edges (colour coded red):

a key factor in getting hanging leg rules working was just a matter of fine-tuning the threshold between 'the ground is close enough, snap down to it' and 'the ground is too far, just hang out in midair'. to support this there's an asymmetry in the x and y distances required before flagging a leg for repositioning, whereas before it was just a euclidean distance check. the added bonus of this is that when jumping there's a nice amount of squash & stretch going on.I tried revisiting the knee thing but ended up accidentally creating feral scurrying octodogs:

this essentially brings the legs system up to date with what it currently is - except for rendering, which I'll tackle in another post. the main difference between this prototype and now, motion-wise, is that before the foot positions would just have their x positions randomly jittered a bit with each step. this became insufficient on curved surfaces, as feet would get pushed through into the level geometry, and they don't have colliders to push them out. the modification I made just involved projecting the new jittered feet position out along the normal of the collided surface - whether it's flat ground, curves or another player's head - and now it works a treat!

--

hoping to do occasional tech posts like this, let me know if you enjoy them!

I don't even know where to start with this, it looks epic. The thought of cooperatively stabbing each other in the back to win sounds awesome.

I thought I'd reach out and introduce my company Greenlight Games, we're creating a small portfolio of published games and I'd love to help publish yours. We don't just message every game going, we pick ones that stand out.

We've only published one title so far and that was DEUL, it came out in January as a soft release and will be hitting 1 million players this weekend.http://www.deulgame.co.uk

If you're interested we would advertise PuddleDash via social media, exhibitions & help you get through Steam Greenlight. It would be great to chat more, please message me or fire me an email:[email protected]

I'm not here to pretend we're a huge publisher but we've done very well so far and I'm sure we could both gain from working together.

Thank you all very much, we aim to make the gummiest, hattiest game of 2016!

Let's talk about level design!One of the major design points we had when coming into this game was the ability to slow down the leaders of the pack without anyone being frustrated. We wanted to approach it in a way that would make people feel bested but not beaten. Tight races feel really fun and being able to potentially take the lead at any point keeps the game exciting.

Originally the game was focused almost solely on getting ahead via the use of traps that slowed players in front of you and as a result I found myself coming up with a lot of unavoidable traps that just didn't feel fun. I wanted players to always have the opportunity to avoid dangerous situations if they played smart and looked ahead.

With this in mind we came up with 3 trap mechanics targeted at helping players at the back of the pack.-Flatgrass Grows in areas that are either unavoidable or give a significant speed boost to the player. Flat grass slows the first player that runs through it but then flattens to the ground allowing others to pass through with ease.This forces leading players to either take a hit to their speed or choose a less favourable route.-Seedshooters Dangerous in tight spaces, seedshooters are activated by the octopodes. Once enough have trampled on them they shoot a seed that bounces itself along the level, knocking down anything in its way. Fortunately the seeds are quite small and can be avoided with a well timed leap in the right direction.-Flip/timer switches Switches activate swinging/rotating platforms in the level, these tiles may offer faster routes for those who flip them or may force a player further ahead through a tougher area. Players still gotta be careful - if used to re-direct someone else they may also have to take the same route.

Some flatgrass in action

Along with these 3 traps we've also implemented a fun attack - slamming! The slam can be activated while in the air, it causes the player to shoot towards the ground at high speeds, potentially knocking out anyone underneath. It also has the added bonus of shooting you along curves if you time it just right.

With the traps and how they work clear it was much easier to come up with what I thought were some great levels. Unfortunately I later found out was not at all the case!

Not so great level design

Although the traps worked really well, kept the pack quite tight and the races exciting there were a lot of issues with the way the octopodes actually moved around the level. We quickly found that obstacles that changed direction or that required any sort of wall jump style movement were at best frustrating and at worst completely unfair.

The moveset we have is best designed for downward movement, but we ain't making Downwell!

Muddledown

We had to think a lot about the way to approach obstacles. It's pretty straightforward to design for a single player, but taking advantage of and exploiting multiplayer takes a lot of experimentation to strike the balance between playability and intrigue.

Hitting curves and getting a good flow going was great, and being able to break someone elses stride felt really rewarding. Because of this, levels with multiple high and lowground routes worked great. Fortunately we'd had some tiles made up from an old game we worked on that suited this need perfectly.

Nice curves gurlAlternate routesTiles!

Just missing a ramp or getting hit off your path is now all part of the fun and you know that you'll have every opportunity to hit someone with a revenge slam and get ahead again!

for the past few days straight I’ve been working solely on level generation. it turned out to be a lot harder than I expected, and I went in with the expectation of it being pretty hard already.

from the get-go I've wanted procedural levels. just naively placing fully random geometry would be guaranteed to create some very unpleasant or even impossible scenarios, depending on how carefully set the constraints are. due to this fact I decided to go for a technique of combining hand-made level ‘fragments’ or rooms together contiguously. this is similar to what Spelunky does – have a fundamentally tile-based layout divided into chunks, such that each chunk is a hand-made room. rooms are then combined with a few connective rules to ensure that you have a guaranteed solution path. a key connective rule for Puddledash we decided on was to never have two ‘up’-traveling rooms in a row, as vertical movement in multiplayer platformers gets slow and often too punishing if e.g. one player slips and falls off a platform. we want these races to be close!the big thing I aimed to exploit here was that we AREN’T making a tilebased game – I didn’t want rooms to have to be constrained to a grid.

initial test rooms we made

so my initial attempt was to have rooms built such that they contained ‘start’ and ‘end’ points. when a new room was added, it would just ensure its start point was aligned with the previous room’s end points. initial tests of this were super promising:

however, we ran into problems very quickly. there were 2 fundamental problems: 1) it's very hard to ensure rooms never overlap or spiral into each other 2) difficult to know whether we’d designed a ‘valid’ room with correct start and end points that would work in all casesafter battling with this for a while, I started to look at exactly how Spelunky does it, and what constraints are placed on each room. if anybody is interested in this and isn’t familiar with the article, darius kazemi made a great breakdown of how it’s done.

I battled for a day with implementing a spelunky-style algorithm to get a guaranteed solution path before realising it made no sense for Puddledash. the room-generation rules in the article hinge on downward movement – if you want to ensure that levels can twist around on themselves (as we would like) things get more complicated, particularly with variably sized rooms.

it was at this point that I realised I could instead create a path that loops in on itself while still guaranteeing a solution by building a MAZE

plausible level path in magenta

I settled on a fixed width and height standard for all rooms – my logic was that if we wanted rooms of different dimensions, they would only need to be integer multiples of the base width and height. then in cases where we had e.g. two rooms traveling left in a row, it would be a potential candidate for spawning a 2x-width room. I implemented the maze just using a basic depth first search graph traversal (for those inclined, this post is a nice conceptual breakdown of it, plus implementation!). the level path is then found by solving the maze with another depth-first search.

- ..but hold on a second, didn’t we agree we never wanted two ‘up’ tiles in a row?

oh yeah, ok. well we can’t just remove additional ‘up’ tiles since we could overlap ourselves. let’s just identify where we have multiple ups in a row and stair-step them along the last direction of movement, shifting the level as we go.

so basically screw the maze. I looked a little into modifying the directional heuristic such that it never goes up more than once in a row, but it was very difficult for me to make heads and tails of on a conceptual level and I’d been spending a lot of time in what felt like a hole. so I tried to shift perspective, searched around a bit, and came across the term ‘self-avoiding walk’, which is exactly what I’m after (given the upward movement constraint). the maze was essentially just a conduit for this all along.the random walk code I wrote is not very tough to grasp but took a while to get bulletproof. the theory is: - pick a random direction – if it’s not visited, add a room here - if all possible positions from the current room are taken and we still need to place more rooms, backtrack (delete rooms) and try a new path I also of course made sure it couldn’t pick ‘up’ more than once in a row. I actually ended up prototyping this in flash of all things for quick visualisations and so the recursion wouldn’t destroy my computer while I debugged it.

this gives a nice little path! the next hell-hole we collectively dived into was getting a consistent room ‘tileset’ to work with, but SafetySnail may put up a post about that later.

the last thing to do is bias our random direction sampling to favour horizontal motion over vertical, as our game is one of more scurrying than falling.

final horizontally biased level path

and that’s the level generation at present! always guaranteed to have a connected solution path, randomized and (hopefully) fun, particularly so once we get enough variation in each room’s tileset. I’ll also be adding probabilistic trap locations, so even rooms themselves will have a bit of randomised procedural cajun flavour sprinkled atop.SafetySnail is working hard at creating some fun tilesets. in the meantime I’m going to be fleshing out the level gen to ensure you can’t take unintended shortcuts by walling in appropriate path edges, and some other ZANY trap / traversal mechanics.

also, as ever, we greatly appreciate all the interest so far! nothing warms us more than your cheerful moods.

This looks like the kind of game that (if you pull it off right) I would have my friends over to play along with Nidhogg/Towerfall/Smash Bros. I like the depth of technical discussion you're doing in this log, too!

Are you planning on finishing it as a smaller project inside the time you two have living together?

@Natman that's high praise! knowing people are playing it alongside each other and slamming each other in the face with their tentacles is a dream. the social aspect of this is definitely one of the major driving motivations here. it was actually after seeing the highlights footage for ARENA GODS that I started focusing on creating scenarios that would allow people to start screaming at each other while they play (more on that soon). glad the tech is interesting, hearing that somebody reads it is good motivation to do more.

we're just going to work as hard as we can on it in the timeframe that we're together, focusing on the core gameplay. if people are interested in it by the time we're saying our in-person goodbyes and we've still got a lot we wanna do (and there are already plenty of great ideas floating around) the scope has a bit of elasticity to it. we both love working on it, and at the bare minimum we'll have an alpha of sorts within the next couple of months.

our next big milestone is that we'll be showcasing it in person at GameFest at the University of Wollongong to get some early feedback and testing with real life human beings. it's a 24-hour all nighter event and we hope to get some good notes + maybe footage out of it! expect more on that front soon!

on another note, I've made it a bit easier to visually tell when your octopus is capable of wallclimbing with this cheeky wee ledge-grab:

I spent yesterday working on getting things set up so that SafetySnail can get crackin on more room design, among other things. this involved doing some brief tests of the sprite integration. here's a basic test of parallax layers formed of many heads:

there were some issues along the way involving multi-camera depth buffers:

I call it 'judgment of the octogods'

another aim for puddledash is to have fully procedural colour palettes, so every level has a different feel. right now we're just working within one palette for the sake of fast prototyping but I'll hopefully be digging my paws into that soon and have a post about it. just know that the tones we're choosing aren't final!

Without thinking much about the process of actually implementing rooms into the game I naively assumed we could string any rooms together just by attaching start and end points. Although when we started to implement procedural level gen it didn't quite work that way. Levels were constantly overlapping each other and cohesive gameplay was impossible to guarantee. Looking at the time limit we've set ourselves to get a working build for Gamefest, we decided to stay away from trying to get this to work as it was just too messy with too many variables to factor in.

In order to create reliable and predictable levels within the system we'd already created we needed to specify a few rules for level generation.Firstly, we needed to have rooms with standardized sizes. These rooms can then be used as the grid for the self avoiding walk to navigate through.Secondly, rooms needed to have start and end points that could always stitch themselves together within jumping height of each other. This ensured that any room could spawn anywhere after any other room and still create playable areas.Lastly, we already knew that constantly changing directions was not fun and broke flow so we needed to work on rooms that made it as smooth as possible to change directions.

These new rules lead way to discovering a lot of problems with our level gen and how we were trying to approach room placement. Stitching rooms together through standardised start and end points was good, but placing up or down travelling paths cut off the next rooms.In order to counteract this we created the corner case tile. We placed these corner cases at the tops and bottoms of all up and down tiles. This gave us an extra transition tile to take us from horizontal movement into vertical movement.

The immediate problem with this solution was that it pushed our grid all over the place, again we were faced with gaps and overlaps.

To counter this we tried to approach transitional tiles in a different manner. We found that most of the problems were caused on the ins and outs of up tiles, so we implemented 2 solutions. If the upward slope was to continue in the same horizontal direction we create 2 up rooms, one to transition between the horizontal tile before it and one to transition into the horizontal tile after it.

If the upward slope changed horizontal directions afterwards, we implement a bounce pad that shot you onto the next horizontal tile.

I'm sure you can see the issue with this solution!

After a few hours and about 4 full pages of frustrated scribbling we finally came up with a solution. Instead of adding or shifting tiles to make the paths work we came up with tiles that worked completely within what was generated by the walker script. This seemed so obvious once implemented but for some reason it took us a long while to get there!

To make this work we changed the level generator to ensure we always spawn a minimum of two horizontal rooms between vertical rooms. After this we converted the horizontal rooms that were directly before and after the vertical rooms into transitional rooms. In the code they are still considered left or right facing rooms but when you play on them they appear to be up or down travelling rooms.

Thinking of levels in terms of start and end points and not as individual rooms helped a lot in finding a tileset that worked for our moveset. Thinking this way removed the clutter of what was in the rooms and focused in on the actual path travelled and the critical points that made that work. This let us figure out the basic shapes needed to be able to actually traverse through these points and along the paths.

The next step is to expand on these basic shapes and room types and make some fun situations inbetween them!