What I know about animation you could happily fit on the back of a postage stamp. I purposefully dodged it when making Lumo — through a cunning lack of in-game NPC characters — but I have vivid memories of swearing in 3DS Max for a couple of weeks, while trying to learn how to rig, then skin, what characters I did have. It was horrible, and the end result looks shite.
Fortunately, you don’t get particularly close to the characters in Lumo, otherwise you’d notice lots of silly little folds and polygon creases where the skinning isn’t quite right. There’s one very obvious issue that’s visible in the close-up cut-scene, when you collect the wand, and it still annoys the shit out of me to this day.
Anyway, that’s a long way of saying that, eek, I’m skinning / rigging the first character for Next Game. This time with Modo.
As I’d not bothered adding any animation controls before, I figure it was time to do things “properly”, especially as the characters in Next Game will be much more in your face. There are some really nice tutorials on Plural Sight, which got me over the hump with this, but it’s still a long, incredibly boring process, that I’m ashamed to admit took me the better part of a week. It’s stupidly easy to get distracted when you’re just fiddling about with vert weights…
But I have something that resembles an animation rig:
Once you get there, animating things is actually a lot of fun. I do really enjoy the process and I’ve got a new found respect for the people that do this well. Modo’s whole animation process — like the rest of the software — just fits my head, so it’s actually nice to sit there and tweak things, with the added bonus that the export process into UE4 is flawless, which is more than I can say for Max into Mecanim…
One thing I love about animating in Modo is the Actions. These are short animation clips that are tucked away behind a little drop down menu. With Max I ended up with a timeline full of different animations, or multiple copies of the character, each with a different animation on. Now I have everything at my finger tips, and I can cut-and-paste bits between different animations. It’s clean, and it’s tidy, and it works. And when I export a single FBX, UE4 takes each Action and makes a single Animation Clip out of it. Each of these can be re-imported singularly, meaning iteration times are nice and short. Big thumbs up.
After another week of fiddling, I ended up with this:
I’ve never done a “proper” walk (or run) cycle before, so I’m pretty happy with those. There’re not perfect, for a start there’s not enough follow-through, or looseness, in the hands and arms. Particularly in the run cycle. I think that’s a result of me using an IK chain on those limbs, which limited my ability to control the elbow angle at certain points. It was fiddly to make sure the swing stayed in a clean arc as the body moved up and down, as well, so with hindsight, I don’t think I’ll use IK on the arms in future. Everything else, though? Not baaaaaad, 7/10.
I’ve spent the rest of this week preparing to develop the character AI. I’ve created a new Game Mode for the co-op campaign, and I’m halfway through building an open space for the AI to run around in (see the screenshot at the top of this page).
So, some lucky person on the U.S. version of The Price is Right walked away with a copy of Lumo (plus Uncharted & Ghostbusters) and a shiny PS4. That was a surprise, to say the least.
I’ve not thought about the game in a while, but Lumo’s popped up three times this week: Once in the issue of Edge I was reading, once on the PC Gamer podcast, and now this. One year on — it was released on May 24th, so happy 1st birthday, little game! — and I’m still being surprised by it.
Last time I wrote I’d made the fairly drastic decision of binning most of my code and starting fresh, with a clean project, to build the networking from the ground up. I’ve continued down that path over the last couple of weeks, and bar a few exceptions — moving platforms, trigger spawns and a bit of front-end UI— I’m past where I was before “the great purge”.
Unreal’s RPC & replication system is actually pretty straight-forward, for the most part. And now I’ve got everything working I think I have a reasonably good understanding of it, but the documentation can definitely be improved. ShooterGame takes a fair old while to Grok.
I’ve ended up structuring things as follows:
This mainly handles players logging in-and-out of the game session, as well as tracking which team the players are assigned to and what spawn points are available at any given time. Initial spawning (and re-spawning) are also handled here, as well as “starting” the game and passing that fact on to the Game State to track. What I’ve not done atm, but will have to go back to, is handling a clean exit out of a game and back to the main menu.
Oh, and acceptance of invites to a running game, but that’s probably a problem for a different area…
I am handling the travel between maps as the game defaults to starting in an empty one before jumping everyone to my test level when the host presses a button. That should “just work” when it comes to detecting end game logic, but we’ll see.
This is doing very little right now apart from tracking if the game is running, and telling the HUD to switch between Lobby and In-Game presentations, if so. For the co-op games it’ll be tracking everything from number of pickups & secrets collected, to how and why players got their score. I’d already written this code before the purge.
This is the 3rd time I’ve tried to structure a player character in UE4 and this time, rather than split things like health and score between the Character and the Player State I’ve opted to put everything not related to movement, rendering and audio into the Player State. All changes to Player State values happen on the server and replicate out. All requests for information; “Can I change to this weapon?”, “Can I pick up this item”, etc. are all server authoritative, as well.
Because of this there’s a lag in the update of a client player’s HUD, say when taking damage, as the new value may take a while to propagate over, but interestingly, all control related stuff is instant. I’m guessing this is the way UE4 networking is optimised internally. I’ll need to look into the HUD issues, but at a guess I can mirror values locally, do non-authoritative updates to them, and overwrite with replicated values when they appear. I doubt the player will care or notice.
I not done any customisation to the default player controller at the moment.
Re-writing this has been the biggest win, by far. It’s significantly less code than previously, and what I am replicating is done in a much cleaner fashion.
Important control stuff, like firing/changing weapons is server authoritative and there are multicast functions for things like playing audio cues, or hit effects. Will this feel laggy in the real world? I’m not sure, but everything I’ve read points to this being the normal way to do things, and it’s absolutely fine in the test environment.
I still need to put things like the damage beans back in, but that’s a five minute job…
Because I’m networked I’ve been able to spend a few days with the weapons, armour and damage calculations. I’ve ended up creating custom Damage Types, which I’m passing through the normal UE4 damage system. These are dead handy, and it means I can detect what weapon has been used, who fired it, and even scale damage down for things like my own rocket jumps. Or, muhaha, scale up because the player is on a multiplier…
This obviously opens up the whole balancing can-of-worms, so for now I’ve side-stepped it by using a mixture of weapon damage values from Doom 2 and Quake 1. Just to get me started, like…
My double barrel shotgun is fucking lethal, though. You do not want to be meeting that in a dark corridor.
Armour has been interesting, not only how to scale the damage, but how to split the percentages between absorption and immediate health deductions. I can already tell that I’ll be moving this lever up and down until release…
It was a nervy few days, starting again, but it was the right choice. Doing networking with a bunch of existing code, that you need to break in many ways in the effort to rebuild, was absolutely the wrong way to go. So even though my current build doesn’t have the nice front end, and my test level is just a bunch of unused FBX files that haven’t even been imported, I have the basis for everything else going forward: a networked pvp environment that I can drop onto any level.
Next up, animating this fella, before exploring how to do some AI against co-op chums.
First week back on Next Game, for oooh, a few weeks, and time to tackle the networking side of things. I had an inkling that retro-fitting multiplayer into the work I’d already done would be a bit of a ball-ache, but I was wrong. It was a massive fucking pain in the hairy-tits.
The problem wasn’t so much that I didn’t understand the theory behind it all — although it does take a while to bed-in, and in all honesty Epic could really do with providing some better documentation on the C++ side of things — but that switching something simple, like the character responses to items being picked up, involves changing a lot of small bits of code in various classes. So where, sensibly, do you start?
I tried a couple of things, first the pickups, then the weapons, but half-way through each it was clear that I’d basically have to refactor a whole bunch of supporting code. Admittedly, there’re some easy wins with the default replication that’s built into the engine; things move, things spawn and you can feel good about your progress quite quickly. But the devil’s in the detail. Do things destroy themselves correctly for client and server, when either side triggers the event? Are modifications happening on the server instance and replicating correctly? Should this multi-cast or is there a better way?
And obviously, debugging this stuff isn’t fun when you have multiple copies of the same instance running, and try to breakpoint something.
I spent four days poking about at this, and although I’d made pretty reasonable progress there were bugs, little fiddly fucks that I really didn’t want to carry along with me. So yesterday I started a clean project and wrote a very simple Team Deathmatch game. Even re-built the characters from the ground up, this time using the Animation Starter Kit from the UE4 Marketplace.
That’s not a particularly exciting screenshot, but it’s 8 players in a TDM game mode, with a dedicated server. Players automatically join and leave teams and you can run around and kill each other.
If you’d told me a week ago that I’d effectively be starting from scratch to get this working I’d have given you the sad panda eyes, but now I’m on the other-side I’m happy. It was a good thing to do. I’m pretty confident I’m entering and exiting the game mode properly, I’m going through the login process and I’m cleaning transferring Player States and Controllers about. None of that was working 100% properly in the previous branch. And, I still have all the “old” code lying about. The HUDs, menus etc will “just work” when I drop them back in, and under the hood it’s going to be easier to migrate things over, piece-by-piece, test, and then move forward.
So, lesson of the week — and worse, something I knew anyway — if you’re making a networked game, do it from the beginning, don’t try and bolt it on afterwards.
Quite pleased I managed to get through all that without making the obvious “built to last” Bladerunner/Replicant joke.
Easter and consultancy work have got in the way a bit, but the side project’s taken a big step forward…
When I last wrote Neutrino was rendering directly to the screen, which wasn’t exactly the look I was after for low resolution, pixel-based games. So last week I took a day to sit down and finish off the rendering path, with the aim being to have some control over the process and get closer to a CRT “glow”.
I’ve ended up with a fairly standard process that you’ve probably read about before.
Stage 1: The background tile-map and all the sprites collected in the VBO during the current tick are rendered to a 480x270 pixel texture. I picked this size because it’s a quarter of a 1080p screen, so scales nicely to my 4k monitor, but isn’t too chunky as to leave pixels the size of my face on-screen.
Stage2: The texture generated in Stage 1 is then rendered to a second 480x270 texture, via a high-pass “filter”. Atm this filter checks for pixel luminance, rendering any pixel above a certain brightness as normal, and any below that level at some, definable, smaller multiple of itself. I could discard these failing pixels completely, but I found the effect looks nicer when there’s a ramp.
Stage3: The texture from stage 2 is blurred in two passes, once horizontally, and once vertically. The resolution of this can be defined at run-time, but I’ve found that I get good results by blurring the low resolution texture from stage 2, and then getting the benefits of bi-linear filtering as I draw the blurred result, enlarged, as part of the final composite
Stage4: I draw a single full-screen quad to the screen, using the low resolution texture from stage 1. This is rendered with a trivially simple “scanline” shader, that checks the output position of the pixel: Every other line is rendered “dark”, for the scanlines. For “normal” lines, the shader checks the pixel, rendering the 1st biased to red, the 2nd biased to green, the 3rd biased to blue and the 4th “dark”. After this, the same quad is re-drawn, but using the blurred textured from pass 4, and again, I have controls for how much this bloomed texture contributes…
This is probably the simplest form of scanline effect. It’s not emulating PAL, or NTSC screens. There’s no phosphor persistence — although I probably will add that in, to a degree, by using the blurred “bloom” texture as an accumulator — and there is no barrel shifter to simulate the curve of an old screen.
To be honest, I’m not going for either of these looks. All I actually care about is the feel of staring into an arcade, in a dark room, where those white pixels were too white, and where certain colours left a bit of a tint on your eyeball. The screenshot at the top of the page is a fairly toned down example of where I’ll end up, cos, If I crank some of the settings up, I can get to some pretty mad places.
All of this will be optional for the player. I know some people hate scanlines — why emulate broken technology? — but I’ll probably setup a few different presets to pick and choose from, so those of us of a certain vintage feel a bit more at home.
(I’d be tempted to leave all the settings available, but that’d probably mean that every time I saw a screenshot of the game online it’d be at some crazy-bastard setting, that I hate…)
Possible todo items: Adding some saturation controls to this may be handy. And maybe a colour look-up table, so I can set curves in Affinty Photo and have them baked into the final output?
I’m dead excited. Hoping to have more to show soon. ;)
Zelda has been pushed to the back-burner, I’ve been to the UK for a trade show, and started up a new consultancy gig. Even found some time to do some programming…
I’ve not been to Rezzed in four or five years, but I can safely say that it’s my favourite “trade” show. It’s far more chill than the Expo, and there are plenty of opportunities to
catch up with Developers, ask them techie questions, and get the shizz on who’s getting published by whom, and where the funding’s at. Eurogamer also do a good range of panel discussions,
which are great to watch, and what with it being in central London, getting ruinously drunk in the evening is entirely possible.
It’s hard to pick stand-outs at shows like these, but ExoOne and Tokyo 42 were the two that got me, and were by far the best looking Unity developed games at the show. I
know it doesn’t matter what engine a game is written in, but having spent 2 days walking around it was incredibly obvious - for the most part - who was using what. Unity on the
Nintendo Switch looking rough as balls (Overcooked was running at 15-20fps at points) and there were many many tales of people having the same problems as I had, while shipping Lumo. So I did leave the
show thinking that I’d made the right choice moving to UE4, and Epic having a large presence at the venue definitely didn’t hurt that.
And if Snake Pass really was ported to Switch in a week, well, I’m looking forward to begging Nintendo for some Devkits toward the end of the year… :D
I didn’t show anything, or talk to publishers this time around. It was just nice to go to a show with no pressure and mooch around. My Zub t-shirt had its first public airing. :D
I’ve picked up some consultancy work with a start-up in Helsinki. Can’t say much about it atm, but that’s one or two days a week helping them get going with their project. It’s time away from
doing my own stuff, but extra cash in the bank is never a bad thing, and I’m working in an area I’ve not really touched before, so a few things to learn.
You’d think with all the planes and trains I’ve been on this month, I’d have done more, but it turns out that in my excitement at getting exit row seats on the plane, I forgot that no bags are allowed to be stashed and the table barely
holds a cup, let alone my laptop. But I did manage to do a few things.
I’ve put in the various game states so Neutrino moves through the splash-screen, “main menu”, and into a test level, and finished off the saving of tilemaps to a binary file. I can load this, and I can create a static
VBO that holds the tile-data. But I’ve not quite got it all hooked up so the level is being displayed. That’s the next job.
Most games have several versions, Debug and Release being the most common. Normally these will do slightly different things: Debug will have more integrity checks, print out more logging information, and may even contain different modes
(none of Neurino’s editors, for example, are even compiled into the release build).
Release, as the name suggests, is normally what gets shipped to the players. To date I’ve only ever been working in Debug builds, so I thought it was about time
that I checked out how the release build was getting on… And the good news is, excellently! I’d made a couple of mistakes with some #ifdef wrapping, but once fixed, Release was up and running in a couple of minutes. I’m mildly
surprised about that.
Work’s been a bit stop/start, but quite a lot’s been done. The bulk of the effort has been working on the game-flow: at launch the game presents a little splash-screen with the company logo on, which nicely fades into the main
menu. From there, you can jump into the first level, or quit out to the desktop. In-game it’s now possible to pause (in single player) and the level’s exit teleporters will take control away from the player and
present an end of level stats screen, showing score, items collected, time taken and any bonuses earned, etc.
This was a good exercise and I uncovered a few things: for a start, I’m still not using the various game and player state classes correctly. Things like the inventory are currently in my Player Controller, and should
be in the Player State class. Level pick-ups and secrets aren’t being tracked in the Game State class, but by the player or individually. All of this comes back to UE4 being opinionated about how to structure the
game, and I’m still learning that stuff. What I have “works”, but will be completely broken in a networked game.
I’m at the point now - having basically got my head around how to do the single player stuff - that I’m going to refactor the bits I’ve got wrong, and then make a start on the network replication. I’ve no idea how to handle
the lobby system, or picking game-modes, but if I can get the players, weapons, projectiles and pick-ups replicating, that puts me in a good position to then start on the AI. I can work the rest out later.
I also discovered that it was possible to have a static library of C++ functions you could provide to Blueprints, but despite this working well for a few days it eventually started to give me
build errors, complaining that things were compiled with out-of-date outers (or something). I’ve no idea what this meant, and I’m starting to become more and more distrustful of Blueprints in general. They’re ok for little
throw-away things, but even doing the UI flow in them was tedious. Debugging them is an absolute nightmare…
51Daedalus is giving a serious of lighting lectures over on his You Tube channel. I can highly recommend these, as I’ve learned a lot from the
few hours he’s already done, including a lovely little trick for faking volumetric light areas (which I’ve nicked and slapped all over my test level). I think lit particles and these sorts of faked volumetric tricks
are going to be really important, in Next Game. Some of the best looking stuff at Rezzed was doing of a lot of this for atmosphere, so it’s something I’m really keen to try and learn.
Also, a shout out to the Unofficial Unreal Discord Community: Unreal Slackers I’ve been able to get a few questions answered, and people seem nice and friendly. It’s good to be able to bounce
stuff off other developers now and again.