shade, light and glorious heightoverlay, slippery surfaces, and much more a lot of work has been done over the past couple of days!
I've still been getting disproportionately distracted by the visual aspect of things particularly with GameFest getting ever-nearer, but it was just too interesting to put down - SafetySnail has been doing draw-overs for various rooms and I didn't want to face him having to redraw everything if I found out our approach wasn't going to work later on down the line.
to follow up on the previous mention of SVG assets, I've since decided to switch back to standard unity native sprites. our terrain layering just doesn't play well with SVG properties as to get nice inner glow filters (that 'softness') would have to be approximated with some post-processing RenderTexture solution. basically a lot of performance / visual gain from the SVG assets would be counteracted by the added postprocessing cost in the long run anyway. plus, sprites work just fine, and since we only need to use 1 with some clever dynamic tinting (will go into this later), the texture memory load is pretty negligible.
I finally got one of the main racing mechanic components out of the way: detecting who’s in the lead! we could decide only to care about the order in which people make it to the finish line, however by tracking who’s in the lead we can design the camera to stay with the faster runners:
dynamic leader camera prioritisation this begs the question of what to do in the case of people being left behind. it’s not feasible to assume the camera could just keep zooming out ad infinitum as it’d get hard to track where everyone is, and it lends itself to pretty slow gameplay.
the solution we came up with is this: when a player has ‘died’ by being left behind, little trigger pads will pop up in front of the leader of the octopus pack. by triggering it, either intentionally or accidentally, the dead player will respawn just behind them, crawling up out of the earth. the nice part of this is that it adds the tension of either attempting to avoid the respawn pads when you’re alive so your friend can’t rejoin, or deciding whether to risk getting them back in for the sake of a fun match. I’ve yet to implement the actual respawning part right now, and I feel like it’ll take a lot of testing to make sure it still feels fair, but in principle it should be pretty fun. I’m envisioning the “dude wtf why didn’t you let me back in” conversations with your partner, or alternatively “I should never have let you back in, I was so close to coming first”.
here are some very rudimentary hand-drawn overlays for rooms that I took while we were testing out svg / sprite formats:
of course rooms boundaries will never be this clearly defined, I’ll combine linked islands’ colours to make it seamless – but it’s a fun little proof of concept from before the gif at the top was created.
one thing you may have noticed from the above few images is another little addition: shadows!
right now the system is a bit hacky and rudimentary but for our purposes, particularly under the time constraints of GameFest in a few days, it works quite well. essentially the way it works is using a two-phase raycasting check. initially, I shoot a ray straight down from the player’s centre. if it’s within a certain distance of the ground, I position a simple alpha-blended shadow sprite at the raycast’s point of collision. it’s rotated to align with the normal of the plane – to prevent jittery shadows I smoothly interpolate the shadow’s orientation over a few frames. it’s very subtle, and not enough to make the shadow ‘lag’, just enough so that you don’t see pixel flickering when going down curves, for example.
the scale and alpha of the sprite are also slightly modulated based on the distance between the player and the raycast’s hit point. the further away, the wider and more transparent it is.
this has its limitations though – when it comes to things like sharp corners, overhangs and steep slopes, shadows end up bleeding out over the level geometry and making it obvious that they’re just decals. ideally I’d have some kind of sprite-warping projection routine here but I am too poor for these high quality Solutions.
so for a second stage of refinement, I move on to raycasting down at the either side of the player’s extents:
if it detects that the vertical gap between each ray’s hit point exceeds a certain threshold, it flags that the shadow should be rescaled so that there aren’t any overlaps. it also interpolates this width over a few frames, you can see it in action in the very top gif as each player reaches either side of the half pipe. I’ve done this very naively and just fixed it to be around 20% of its usual width and it looks
okay, but again, a better way of doing this would be to do a few more raycasts and stretch the shadow between the last two ‘valid’ rays that touch the ground. in any case, the system I have so far already makes the podes feel a lot more rooted in the world.
--
more things related to level layouts! I’ve added a little bit of sproing to the slam-switches and it instantly feels a lot more lively. one thing I’m not quite sure what to do with right now is that moving kinematic rigid bodies can cause players to pop right through if they’re standing on ‘em while a switch is triggered. perhaps that’s okay? physics glitches can be fun, but if during gameplay it’s too common, starts to feel unfair or just plum doesn’t fit I’ll revisit this for real.
loosey goosey slam-switches I also added some probabilistic tuning variables to all the traps for some more varying rooms, and finally added proper support for frictionless and slippery surfaces. best showcased again in that top gif. players can slam right down on them and build momentum, so hopefully we’ll have a few more momentum driven situations coming up.
over the next couple of days I’ll start working on getting a proper character selection screen and other parts of the UI functioning. with RJ! on the beats we’ll get an actual gameplay vid out soon!