Meditations – April 8th 2019

In March 2018, I attended Train Jam and chatted there with Rami Ismail about a project he was starting up : contemplative, 5-minute games released day-by-day. I thought it was neat, but I didn’t commit to anything since my time for side-projects is super limited.

In late November 2018, I was asked by Jupiter Hadley whether I’d like to contribute to a super secret project she and others were working on… I asked about details, and realized it’s the same thing Rami pitched me months earlier : Meditations! Jupiter explained that I should spend no more than 6 hours on the project, and submit it before December 14th 2018. The timing worked out, so I decided to give it a go.

I picked April 9th as the date (it was moved back 1 day to April 8th after the fact), and started browsing my Google Photos to see what the heck happened on an April 9th in my life… 2013 jumped out as a memorable one. My then-girlfriend (now wife) MC and I went to Nara, Japan where we met bowing deer and strolled the city on a beautiful sunny day. The cherry trees were at the peak of their flowering time, and they shed pink petals everywhere.

Yours truly, making friends with the locals

So I figured I’d do a little vignette game with a tree, falling petals, and heavy emphasis on the soundscape. I wanted it to feel vaguely like Proteus, with a Boards of Canada kind of musical vibe. Other stylistic references I had in mind : Devine Lu Linvega‘s Kanikule, and @ktch0‘s Places.

I asked my friend and colleague Rodrigo Rubilar whether he’d like to do sound design and music. I originally planned to do it myself with my limited audio gear, but I was excited to work with him on a small project like this, and he’d produce quality results 10 times faster than I could! We jammed an afternoon on an ambient track with a few layers, and one-shot sounds for the leaves hitting the ground.

https://twitter.com/renaudbedard/status/1073678256304316416
Rodrigo’s home studio is a goldmine of analog audio gear

At the same time I started hacking at a fractal tree generator in Unity. It’s actually the first time I’d tried to write one, so it was interesting to see how the simplest algorithm could apply to 3D, with some randomness injected into it. I exposed a ton of parameters, and played with them until I was happy with the result.

Fractal tree generation in action

Then I started thinking about the petals, and how I wanted them to move in the air. I started with a basic Unity particle system and wind zones, but I suck at authoring those and I could never get the look I wanted. So I resorted to manually updating the petals with simple physics. But then I wanted a lot of petals… thousands of them. So I started toying around with Unity 2018’s job system.

Optimization ended up being the most interesting engineering aspect of the project for me, and the biggest time-sink. There is no way I respected the development time limit of 6 hours (probably spent more than 40 hours on it), but it was hard to let go. So I’d like to at least document what I ended up doing and why.

If you just want to look at the code, it’s all here.

Jobified update

I ended up with a single job that does most petal-related work :

  • Update physics based on wind parameters
  • Detect ground collisions
  • Detect player interactions (you can rise petals from off the ground by walking near them)

I want to update all the active petals every frame, so I schedule the job in the earliest Update callback (you can tweak that using Script Execution Order), and complete it in LateUpdate.

I wanted petals hitting the ground to trigger sounds, so the naive way of making this happen in Unity (and my initial approach) is to have one GameObject per petal, with an AudioSource component. The AudioSources don’t have to be enabled all the time, only when they’re playing a sound, but that does mean that I have to update their Transform so that the sound plays at the right 3D position.

It’s possible to access and update Transforms from within a job by implementing IJobParallelForTransform, and pass the transforms to the job using a TransformAccessArray. A major gotcha with the current version of the job system is that only root Transforms will be assigned to different threads. I originally had petals as child of an empty game object just for grouping, but then my job was using a single worker thread. Reading this forum post explained it, but it’s still baffling to me, and makes for a pretty hideous Hierarchy tab.

I ended up not using Transforms for petals at all, but more on this later.

One thing that I found interesting is how one returns data from the job to the game code. For instance, I want to know which petals should trigger a sound by returning a list of petal indices that touched the ground. You can declare a field in the job as NativeQueue<int>.Concurrent (which is part of the Collections package) , and enqueue data as the job runs on multiple threads. From the calling site, you need a NativeQueue<int> to be created, but when it’s passed to the job instance, you need to use the .ToConcurrent() method to make it usable. Then, once the job is complete, you can use .TryDequeue() to extract elements from it. Works great!

I enabled Burst on my job very naively, and spent zero time optimizing the generated code. I did take care of the basics : make sure to mark job fields appropriately as [ReadOnly] and [WriteOnly], use the SIMD-capable Unity.Mathematics package whenever possible. In the end, the job runs way faster than I need, so I just moved on.

Burst had a dramatic effect on the job’s performance. Here’s a profile of the same code running on the same system, with Burst compilation toggled off and on. The biggest noticeable difference is that LateUpdate does not need to wait on jobs at all when they are Burst-enabled, which means it runs fully in parallel!

Longest job without Burst enabled : 1.70ms
Longest job with Burst enabled : 0.05ms

Rendering

Note : even though I’m using Unity 2018.3, I did not use the Scriptable Render Pipeline in this project, so the following probably only applies for the legacy rendering pipeline.

I initially had every petal GameObject with a MeshRenderer, a simple quad mesh, and the Unity Standard Shader with instancing turned on. It definitely worked, but Unity spent a lot of time in culling and batching, and I thought I could do better… by short-circuiting it completely.

It might sound like rendering everything all the time is a bad call, but in this game, the worst-case scenario of all petals being visible at once is the very first thing you see. Might as well make it a fast general case!

One way to draw objects manually is to use Command Buffers. By specifying a mesh, a material and a bunch of transformation matrices, you can use the DrawMeshInstanced() method to draw up to 1022 (that number I got empirically, but it appears to be undocumented) instances at once, in a single call. There is no renderer on the game objects themselves, so Unity acts as if they don’t exist, apart from issuing draw commands.

My petal update job’s final step is then to bake the petal’s current position, rotation and scale into a 4×4 transformation matrix, so that I can use them in my command buffers later. But there it gets annoying :

  • DrawMeshInstanced() takes a Matrix4x4[], nothing else, so we’ll have to copy our NativeArray to a managed array.
  • We have to respect the batch size of 1022, so we have to use NativeSlice to take 1022-element slices of our NativeArray.
  • NativeSlice.CopyTo() copies element by element, and it’s very slow.

I found a faster CopyTo implementation on the Unity forums which I slightly modified, and it does perform much better, but it’s a lot of moving data around for no reason. I wish that NativeSlices were directly usable with command buffers.

I end up with two very similar command buffers : one for depth rendering inside shadow-maps and for the camera’s depth pass, and one for regular opaque rendering.
The depth rendering command buffer uses the ShadowCaster pass from the Standard shader, and hooks to the AfterShadowMapPass event on lights as well as the AfterDepthTexture event on the camera. I needed the camera depth pass for SSAO using Keijiro Takahashi’s MiniEngineAO Unity implementation.

Triggering audio

As I hinted to earlier, I ended up ditching GameObjects for petals entirely. The only reason I originally kept them around (and updated at all times) was for audio, but it’s a lot of data shuffling just for sporadic sound triggers, so I opted for a simple audio trigger object pool instead.

I pre-initialize 1500 (again, empirical) dummy GameObjects with a disabled AudioSource component that lay dormant in the pool until an audio event happens. At that point, I take one from the pool, enable audio, position it at where the impact happens, and play the audio clip. There is no update cost to having them around otherwise, and they are disabled & returned to the pool when the sound playback is complete.

Petals are then strictly represented by a data structure that lives in a NativeArray, not by a GameObject. And the update job becomes a IJobParallelFor, mutating elements of that array. Neat!

You may wonder how dramatic a performance difference this makes. So here’s a comparison, taken from the same Macbook, of the CPU time spent only scheduling jobs between the version using Transforms and the version without. Something about how Unity handles transform access to a job definitely incurs sizeable overhead.

Using Transforms (1.79ms spent scheduling jobs)
Without Transforms (0.03ms spent scheduling jobs)

Bending the tree

When I had the petals mostly working well, it still felt strange that the tree didn’t animate at all. I wanted branches to sway in the wind, and I figured I could make that happen easily in its vertex shader.
It turned out to be a lot trickier than I expected, for a few reasons :

  • The tree is generated as a single baked mesh, there is (ironically) no tree structure to it. No great reason for this apart from lack of foresight.
  • The petals aren’t really attached to branches, their position is just set to the endpoint of branches when generating the tree.

To make the smaller branches bend but not the trunk, I set a bendability parameter during generation (how far away from the trunk that vertex is) in the texture coordinates.

A visualization of the bendability parameter for a generation

I then define the a bend axis perpendicular to wind direction, a bend angle dependent on wind force, and a shake factor which is just a bunch of low-frequency and high-frequency sine functions multiplied together, to make it feel a bit more noisy & organic.
These variables are mapped to shader globals, and I used keijiro’s angle-axis to float3x3 HLSL function to apply this in the vertex shader of my tree. So far so good!

Where it got tricky is for petals. I need to differentiate when they’re attached or detached, so I can apply the wind bending selectively. I ended up using a MaterialPropertyBlock to have per-instance data (a single float) encoding this state.

In the vertex shader (which is part of a simple Surface Shader), it took me a minute to understand how to do world-space transformations on vertex data. The simplest way I found was to transform the vertex to world-space, and take it back in object-space when I’m done. Not super efficient… ¯\_(ツ)_/¯

The full vertex shader for petals, color-coded by the lovely Rider

On the application-side, I did use a NativeArray<float> for instance data, but I’m not sure it’s the easiest way to go about it. I don’t actually read from or write to it from within my update job, it’s all happening in the regular Update(). It allowed me, however, to re-use Slice() and CopyToFast() to make 1022-sized chunks for rendering.
One thing to note : unlike with the draw arrays, MaterialPropertyBlocks cannot be reused for multiple batches, so I create all the ones I need up-front and iterate through them.

Another thing I realized, is that I need to apply the exact same function I used in the vertex shader to my petals the moment they are detached from the tree. This effectively bakes the tree’s bend at that moment in time into their transform, and avoids them visually warping around as they are detached.

In the end it still looks kinda stiff, but it’s better than the cement tree I started with.

Closing thoughts

I’m super happy with the final result. It’s relaxing, soft, yet sometimes surprisingly intense. It ended up feeling a lot more mournful than I expected, but I’m fine with that. I really enjoy the visual transition from a mess of pink sheets of paper to a menacing, pointy web.
But since everything was done in a rush, there’s some things I wish I’d done differently.

In Feburary 2019 I stumbled upon this rather excellent tree by Joe Russ, developer on Jenny LeClue :

https://twitter.com/Mografi_Joe/status/1100507496572223489

It made me realize that my tree shape and animation could be so much better. Having the branch splits be less even, more jagged and well, tree-like, would add a lot. And by having the branches hierarchically laid out, I could have bent the sub-trees and produce a much more convincing wind swaying effect.

Spending so much time on performance optimization made me wonder if doing a whole forest of trees, instead of a single one, would be possible at all. Wouldn’t that be neat? But it brought additional headaches that I didn’t want to deal with.

But there’s something to be said about making a small thing, with a tiny scope, a reasonable amount of polish, and putting it out there. Just the fact that I was excited enough about making this that I convinced Rodrigo to tag along made it worthwhile.
So big thanks to Rami, Jupiter and everyone involved in the Meditations project for making this happen. And thanks as always to my wife MC for humoring me while I spent precious evenings & weekends time endlessly debugging my stupid tree. ♡

Addendum : So what about ECS?

You might be wondering why I went straight with the Job System but didn’t use Entities, since they were showcased in the Megacity demo and Unity is really selling it as The Way to do massive amounts of objects with acceptable performance.
I don’t really have a good answer to this, except that I was short on time and was familiar with the idea of data parallelism, but not so much with ECS… and didn’t want to spend time learning how to use ECS properly. And I’m stubborn and will go down a path I’ve set for myself even if it’s a bad idea.

There’s good chances that using ECS is the best way to do what I was trying to achieve, but I didn’t go down that path yet. It would be interesting to revisit the project and do it that way; maybe I will!
I’m also curious to hear from people who have tried Unity’s ECS. Would it really make this easier to design? Would the rendering portion be simplified? Let me know!

I Know This (Global Game Jam 2015)

“I Know This” is a game I made for the Global Game Jam 2015 along with Gavin McCarthy (art, design), Adam Axbey (sound effects) and Matthew Simmonds (4mat) (music); I did programming and design. The name we chose for the team was Two’s Complement.

As seen on Kill Screen (who posted the first article on the game, thanks a million!), Polygon, Popular Mechanics, Rock Paper Shotgun and many more! We’re flabbergasted, and very grateful for how popular our silly jam game has gotten.

Downloads

Windows x86 (version 1.1) : iknowthis_win_v1.1.zip
Mac Universal (version 1.1) : iknowthis_mac_v1.1.zip
Linux Universal (version 1.1) : iknowthis_linux_v1.1.tar.gz

Soundtrack

4mat released the OST he made for I Know This on his Bandcamp, pay what you want!

Update Notes

v1.1 (2015-02-20)

  • Linux : Build now works! The Unity 5.0 beta version it was originally built with had issues with Linux, now built with RC2
  • Mac/Linux : Builds should be executable out of the zip or tarball without the need for chmod
  • Mac/Linux : File icons and names now display correctly, though they are not sniffed from the machine, it’s a pre-built list coming from mine
  • Mac : Hacking now affects percentages (yeah… I should’ve tested this a bit more thoroughly)
  • Fixed “magenta rectangle” overlay on Shader Model 2.0 or lower GPUs
  • Delete key works as well as backspace key to clear red characters
  • Tweaked Clicky interactions (6 honeypots instead of 5, the wrong text was triggered when finishing your first hack, mentions more clearly that red text needs to be removed)
  • Admin scan bar flashes and turns red when you’re running out of hacking time
  • Hacking timer now starts at 35 seconds (originally 30), and will get shorter or longer depending if you fail or succeed hacks (cheap adaptive difficulty!)
  • Added license file with credits and acknowledgements (released under a Creative Commons Attribution-Non-Commercial-ShareAlike license)

Version 1.1 should clear all known bugs except for the seemingly rare “return does nothing” and the “redtext has HTML code in it” bugs which I can’t reproduce accurately at the moment. Let me know if there are new/other issues! And thanks for your patience.

Straight outta Isla Nublar

Remember that one scene in Jurassic Park? The one where Lex hacks the computer system in order to lock a door and protect everyone from the raptors, and exclaims…

unix-jurassic-park

That was basically the whole premise for our game.

When I saw the movie as a kid, that scene (and the file system UI that Lex “hacks”) always stuck with me as a quintessential faux-futuristic Hollywood representation of how computers work. I learned a bit later that this GUI was not made for the movie, but actually existed on SGI workstations and was ported to Linux as well, so it’s more legit than it looks! But in the end, it’s still a really great artifact of 90’s VR hopes and dreams, in which everything is better in 3D, even file browsers. (and Web browsers, too)

fsn1

The Game

It starts with the same basic premise as the scene in the movie : you have to find a file. To make it more interesting than your average hidden object game, you need to hack specific Search Nodes (purple files) which, upon successful hacking, will help you narrow down which potential Golden Folder contains what you’re looking for. Don’t pick the wrong one though, all the other ones are full of viruses and bad stuff!
Fun fact : the filenames you’ll see in the game are lifted from your hard drive, and 8.3ified for formatting and retro-chic reasons!

hacking

Hacking involves mashing your keyboard until code appears, and hitting the return key where the line endings are, just like in real life. The hacking minigame was heavily inspired by hackertyper.net, a fantastic way to feel like you’re real good at making up C code on the fly. However, we gamified it (oh, the horror) by not letting you go further than line endings, and adding a timer.

As you hack (or fail to hack) search nodes, sentinels will spawn and start looking for you. If they catch you, they warp you back at the root folder. Not a huge punishment, but enough to make you at least a little careful.

clicky

And then there’s Clicky, your favourite Office Assistant ripoff. He means well, but he sometimes gets in the way… and hides a dark secret. :o

Closing Thoughts

I don’t know that the game really qualifies as a jam game, because I worked for many evenings after the jam to smooth out the rough edges, make better Clicky interactions, fix the endings and other various bugs. The party version of the game was without music, I asked 4mat to produce something for us after the fact, and we were so so so lucky to have him contribute the lovely tunes you can hear in the game.

This was also my first experience with Unity 5, but I barely touched what it can accomplish. I’d say that the Audio engine is really nice, ducking was painless to implement… and the new UI stuff (even if it’s 4.6 and not 5) was a joy to use compared to the old GUI system.

And Gavin is the best! First time jamming with him, and it was a great match of design sensibilities, work-mindedness and just plain fun. <3

Malisse

Malisse Logo

Malisse is a game I made at TOJam “Party like it’s 19TOJam9” in 2014 with Devine Lu Linvega, Rekka B., Dom2D and technobeanie as Les Collégiennes, with sound effects by dualryan.

The game is playable in the web player at its itch.io home : http://renaudbedard.itch.io/malisse

It uses Unity and the whole source code and assets are hosted in a public repository on GitHub, and released under a Creative Commons Attribution license.

Malisse screenshot

The gameplay is a two-player cooperative physics sandbox and puzzle game. The objective for both players is to clear a path for Malisse as she walks on a sinuous path in the world through the looking glass…

A bunch of rabbits trail behind her, but they get scared easily! Everytime Malisse bumps into an object she cannot climb, a rabbit will run away, but you recover one rabbit for every level cleared. If all the rabbits are gone, Malisse ends up alone and … cries herself to death? That’s the end of that play session, anyway!
Otherwise, the levels are chosen randomly from a pool of 11 hastily-authored levels which vary in difficulty. If you get stuck early on your first attempt, definitely give it another shot since you might find more palatable challenges.

It was an interesting game jamming experience for me in many respects : first time with a 5-person team, first time implementing sprite animations in Unity (using 2D Toolkit), and first time writing a tool for use inside the Unity editor — a spline tool for drawing roads quickly. We also had interesting last-minute collision issues, since we wanted Malisse to be able to climb slopes but didn’t want to resort to rigid bodies to have that done automagically. Spherecasting to the rescue, and lots of debugging! ^_^

If you’re wondering, the music was made during the jam by Devine (aka Aliceffekt), based on “When Johnny Comes Marching Home”, because it just fits marching so damn well.

Other than the web player, you can download the OS X and Windows standalone builds.

Enjoy! Had lots of fun building it. Closing with an outstanding band shot of us by Myriame Pilgrim!

LES COLLÉGIENNES

Pyramidwarf

Pyramidwarf is a game I made in collaboration with Samuel Boucher (alias Monsieur Eurêka) with music by Stefan Boucher at the Global Game Jam 2014 in the TAG Lab of the Concordia University, in Montréal. The version you can download here is a tweaked, split-screen version of the “party build” you can find on the GGJ website.

Windows : pyramidwarf-final-1.01-windows.zip [12 Mb]
Mac : pyramidwarf-final-1.01-mac.zip [12 Mb]

Pyramidwarf's glorious title screen

This was my first experience with Samuel in a jam, he’s a kickass vector artist currently working with Ko-Op on GNOG, which you should totally check out.

(the game was demoed at the Montréal Joue Arcade 11, too!)

We worked with Unity, as is the usual for me in game jams, and the initial idea was to make a stacking game where you’d either race the other player with a really unstable stack of little guys, or throw parts of your pyramid to the other player’s to break it up. And of course, this being a game jam, we didn’t do half of the stuff we planned for, and ended up with a super janky physics-based stacking game that happens to be silly enough to be fun!

Pyramidwarf Gameplay

On my side, it was my first time really exploiting Unity physics in a game. I’d done some basic rigid-body stuff and used character controllers (Volkenessen was physics based as well), but never hinges or physics-based multi-body animation. One of the fun/interesting parts to do under pressure was the walk animation using torque and impulses : the leg pushes itself up, angles up, the body gets a magical shove and the legs readjust themselves to stay upright. It’s definitely not physically correct, but it looks like a bunch of cardboard puppets and that’s exactly what we were going for!

To build the pyramid, dwarves need to go up somehow, and the way we solved that is just… teleportation. These little guys have magic on their side, and they can teleport to the first free spot of the pyramid to keep stacking up. This caused rigidbody overlapping problems that I sorta resolved by just testing a whole lot if something’s there before teleporting, and denying the move otherwise.

The “final 1.01” build I posted here is not bug-free, but it’s shippable, so here goes. I might come back to it and fix rendering issues, and maybe implement dwarf-throwing, because it still sounds so great in my head.

Enjoy!

Pico Battle

Updated 04/07/2012 : Version 1.1 — see below for patch notes & downloads.

At long last!

Pico Battle is a game I initially made with Aliceffekt for the Prince Of Arcade event of early November 2011, which more than half a year ago. But between FEZ, Volkenessen, Diluvium and Waiting for Horus, we never took the time to actually finish it properly, until now!

In its PoA demo form, it used the same crude networking code as The Cloud Is A Lie, which requires two computers plugged in the same LAN or ideally directly by a cross-wired ethernet cable. Releasing that particular version publicly made little sense, so we decided to make a much more extensive multiplayer version.

Above, Pico Battle 2011 (albeit a terribly compressed and cropped screenshot).
And below, the version we’re releasing! :)

This game’s name might remind you of another Prince of Arcade game, this one in 2010 — Pico³. It’s the same basic idea of playing with colors, mixing and matching them, but this time in a competitive versus environment.

How To Play

Upon launching the game, you will find yourself in the Lobby, a temporary haven. You should look for an hexagon floating about the edges of your screen (right click drag to rotate around the planet) and click on it to practice against the AI. You might see circles too, they are other players and could challenge you as soon as you raise your shield.

To protect yourself against incoming attacks, find the patch of dirt marked by a black & white circle, and connect a node to it. The shield will light up, eating away at the incoming bullets with a similar hue. In the lobby, you are invisible to potential attackers as long as your shield is unpowered.

To win against your opponent, locate a patch of mushrooms and connect nodes to it — this is your cannon. It needs a minimum amount of power to be able to fire, and based on the incoming nodes, will fire bullets of various sizes and colours; easier or harder to defend against. The idea being to match the colour of incoming bullets with your shield, and to differ as much as possible from the opponent’s shield colour (which is indicated by the contour of his circular icon) with your cannon’s bullets.

Pico Battle is an entirely wordless game, and might seem offputting or hard to grasp at first. In the lobby, a robotic voice will explain the basics of the game, and take your time there to experiment with the controls and the scarce UI elements. As you get familiar with the game and its interface, you will discover strategies and enjoy it even more.

Updates

04/07/2012 — Version 1.1

  • Fixed bug where the AI wouldn’t defend itself if it is challenged too quickly
  • AI now raises a random shield before you attack with any colour
  • Fixed graphical issue on arc-link shadows
  • Escape key now quits the game if pressed in the lobby

Downloads

Windows Version – picobattle_pc.zip
Mac OS X Version – picobattle_mac.zip

The soundtrack is available on Aliceffekt’s blog entry for the game.

Diluvium – TOJam 7

Updated 15/06/2012!
See bottom of the post for updated download links.

Diluvium is a game I made with Aliceffekt, Henk Boom and Dom2D as Les Collégiennes over the course of TOJam The Sevening, a 48h game jam (though we had a ~8h headstart on that) which took place between May 11th and 13th 2012.

Gameplay

Diluvium is a versus typing tactics game.
There are two summoners on the battlefield, and you are one of them. Type animal names to summon them, and they will attack the enemy’s spawns and ultimately the enemy summoner himself. The first to kill the other one wins, as these things usually are.

You can type up to three animal names in a row, which spawns a totem of these three animals. Each animal has its own stats : speed, attack power, health and intelligence. The totem is as intelligent as its most intelligent member, and health is summed up, but movement speed is averaged.

If someone spawns a dog on the playfield, nobody can spawn another dog until it dies. No duplicate animal! Thankfully you have 284 animal names to choose from, 100 of which are illustrated differently.

The game has a half-assed single-player mode that you can access by typing “LOCAL” in the connection screen. Otherwise, the game should work fine in LAN and over the Internet, as long as you open up the server’s port 10000 (I’m not sure whether Unity networking uses TCP or UDP, so go for both). The connection screen lets you know your LAN and WAN IPs as you host the game.

Things you can also enter at the connection prompt : “MUTE” to kill the music, “IDDQD” for degreelessness mode, and one other secret code which will be revealed elsewhere on the interwebs!

For more information about the commands you can enter on the splash screen, see Aliceffekt’s wiki page on Diluvium.

Development

This was the second network multiplayer game I’ve worked on that uses actual Unity networking instead of a hacked up UDP sender/receiver pair. It’s SO MUCH EASIER TO SET UP! And it works consistently, no threading bugs and random Unity crashes. Knowing this makes me much more comfortable in attempting more network-multiplayer games in jams. The Cloud Is A Lie was a nightmare to keep synchronized, it would’ve been so much easier with the built-in stuff.

We had sort of an Montréal Indie Superstar version of Les Collégiennes this time at TOJam, with FRACT‘s Henk with me on code and Dom2D as an animal portraits factory for the whole weekend. Aliceffekt and Dom’s visual styles merged really well, and having all this extra super talented manpower allowed us to create a much more ambitious game. Henk happened to have working pathfinding classes just lying around, and his deeper knowledge of Unity intricacies meant less time spent fighting bugs and oddities. It was such a great jam! ^_^

Updates

Version 1.1 – 15/06/2012

  • Server Naming : You can now name your games and tell your friend to connect to it by name instead of IP! (IP still works, though)
  • Anonymatching : Create a server and wait for a user, or join an anonymous server randomly!
  • NAT Punchthrough : Server no longer needs to forward port 10000
  • Adaptative AI : In local mode, AI opponent spawns more/less units per second depending on wins/losses
  • Splash Redesign : Options better presented, no more accidental enter key press
  • Balancing, a handful of new animal names supported
  • Escape key quits to splash at any time during gameplay

Downloads

Diluvium v1.1 – Windows version
Diluvium v1.1 – Mac version

Enjoy!

A Replacement for Coroutines in Unity + C#

Coroutines are a great idea and super useful, but they’re kind of unwieldy to use in C# and sometimes they just don’t plain work. Or I don’t know how to use them properly. All I know is that they’re more complicated than they need to be, and I remember having problems using them from an Update method.

So I made my own version of Coroutines inspired by the XNA WaitUntil stuff I posted about a long time ago. Here it is!

using System;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;

class ConditionalBehaviour : MonoBehaviour
{
    public float SinceAlive;

    public Action Action;
    public Condition Condition;

    void Update()
    {
        SinceAlive += Time.deltaTime;
        if (Condition(SinceAlive))
        {
            if (Action != null) Action();
            Destroy(gameObject);
            Action = null;
            Condition = null;
        }
    }
}

public delegate bool Condition(float elapsedSeconds);

public static class Wait
{
    public static void Until(Condition condition, Action action)
    {
        var go = new GameObject("Waiter");
        var w = go.AddComponent<ConditionalBehaviour>();
        w.Condition = condition;
        w.Action = action;
    }
    public static void Until(Condition condition)
    {
        var go = new GameObject("Waiter");
        var w = go.AddComponent<ConditionalBehaviour>();
        w.Condition = condition;
    }
}

Here’s an example of use, straight out of the Volkenessen code (with special guest appearance from my ported easing functions) :

var initialOffset = new Vector3(hitDirection.x * -1, 0, 0);
var origin = armToUse.transform.localPosition;
armToUse.renderer.enabled = true;

Wait.Until(elapsed =>
{
    var step = Easing.EaseOut(1 - Mathf.Clamp01(elapsed / Cooldown), EasingType.Cubic);
    armToUse.transform.localPosition = origin + initialOffset * step;
    return step == 0;
},
() => { armToUse.renderer.enabled = false; });

What’s going on here :

  • You call Wait.Until as a static method and pass it one or two methods (be it lambdas or method references) : The first one is the Condition which gets evaluated every Update until it returns true, and the second gets evaluated when the condition is true (it’s a shorthand, basically)
  • The Wait static class instantiates a “Waiter” game object and hooks a custom script component to it that does the updating and checking stuff
  • The condition gets passed the number of seconds elapsed since the component was created, so you don’t have to keep track of it separately.

I use it for waiting for amounts of time (Wait.Until(elapsed => elapsed > 2, () => { /* Something */ })), interpolate values and do smooth transitions (like the code example above, I animate the player’s arm with it), etc.

I’ll probably keep updating my component as I need more things out of it, but up to now it’s served me well. Hope it helps you too!

Volkenssen – Global Game Jam 2012

Volkenessen is a game I made with Aliceffekt as Les Collégiennes on January 27-29 2012 as part of the 48h Global Game Jam. We actually slept and took the time to eat away from our computer, so based on my estimate we spent at most 30 hours making it!

It’s a two-player, physics-based 2D fighting game. Each player starts with 9 random attached items on his back, and the goal is to strip the other player of his items by beating the crap out of him. When items are removed, they clutter up the playing area, making it even more cahotic and hilarious. The washing machine and sink in the background can also fall and bounce around!

Controls

You need two gamepads (so far the Xbox wired, wireless and a Logitech generic gamepad have been tested and work [you can use the Tattiebogle driver to hook up an Xbox controller to a mac]) to play, there are no keyboard control fallback (yet). The controls are pretty exotic. To move around you can press either the D-Pad (or left analog stick) or the face buttons (A/B/X/Y), and the direction of the button does the same input as if you pressed that D-Pad direction. As you move, your player will throw a punch, kick or flail his ears to make you move as a result.

To hit the other player, you need to get close to him by hitting away from him, then hit him by moving away from him. Ramming into the opponent just doesn’t do it, you need to throw punches, and depending on the impact velocity, even that might not be enough. You can throw double-punches to make sure you land a solid hit and take off an item.

Development

It was made in Unity, with me on C# script and Aliceffekt on every asset including music and sound effects. I see it as one of our most successful jam games; it even won the judge award at our local GGJ space, and it was just so much fun to make, test and play.

I was surprised how well the rigid body physics worked out in the game. I had to use continuous physics on the players and tweak the gravity/mass to get the quick & reactive feel we wanted, but the game was basically playable 6 hours in! After that it was all tweaking the controls, adding visual feedback, determining the endgame condition and coerce the GGJ theme around the game.

I’ll be porting the game to the Arcade Royale in the coming days/weeks, and it should be a blast to play on a real arcade machine :)

Downloads

Windows (32-bit)
Windows (64-bit)
Mac OS X (Universal) 

Enjoy!

Pico³

Pico³ is a game I made with Aliceffekt (as Les Collégiennes) over the course of a month, and that we presented at the Prince of Arcade party on November 9th.

Download

Pico³ – Windows Version [6.3 Mb]
Pico³ – Mac OS X Version [11.6 Mb] (Nov. 15th Edit : Fixed the mac build, it runs now!)

Aliceffekt designed the game mechanics, levels and visuals, while I took care of all programming and procedural animations.

How to play

The game is fairly simple on the surface :

  • Emitters emit cells of a primary color (red, green or blue).
  • Receptors expect cells of a certain color, or color (ordered) sequence.
  • You can place Projectors that redirect cells or combine them, if different cells hit the projector simultaneously.

The challenge is to combine colors at the right time, with the given resources and world layout. It becomes an intricate resource management/puzzle game, and even the simplest-looking puzzle can prove almost impossible!

There is only 13 levels in this version, which was made for a party setting. The difficulty curve proved to be very harsh for new players, and even seasoned players (like me) can’t reach the end. It’s a hard game — Aliceffekt’s trademark game design. ^_^

Science! (shot by Aliceffekt at the Prince of Arcade)

 
It is played with mouse+keyboard on all platforms, but also supports the Xbox 360 gamepad (either wired or wireless with an USB receiver) on Windows by using Rémi Gillig’s XInput.NET for Unity. I made my own wrapper over it to detect press/hold/down, actually the code was ripped out of my XNA code. That’s the fun part of using C# scripting, I can just share code between projects even if it’s not the same technology!

Controls

If you’re too lazy to read the tutorials :

  • Right click and drag to rotate the camera round the world, scrollwheel to zoom in/out
  • Left click to create a Projector, and left click on a face to select its direction
  • Z to undo the last Projector (or hover any Projector and hit Z to undo that one)
  • R to restart the level
  • Escape to return to the first Level
  • ALT+F4 or Command+Q to quit

Hope you like it, it was a a lot of fun to make and I’m already looking forward to my next Unity creation… It’s a great work environment.

The Cloud is a Lie

The Cloud is a Lie is a game that me and Aliceffekt (our team name was “Les Collégiennes”) made at a 36-hour gamejam/competition in Québec City called Bivouac Urbain. (Last year I also attended the event, and made Stimergy with Heather Kelley).

Download

The game is available for Windows or Mac OS X. [10 and 15Mb respectively]

Controls

WASD or Arrows keys move. (you need to hold them)
Spacebar shoots.
M toggles the music.
Escape quits. (there may be a 2-5 seconds pause when quitting the game on Windows)

Gameplay

The Cloud is a Lie is a LAN multiplayer game for any number of players, but best suited for 2 to 4 players. It can be played alone too, it’s just less fun.

Otherwise, it’s like Tower Defense meets Tron.

  • There is a constant flow of enemies (the spinning cyan cylinders) coming in from the end of the map, and their goal is to reach your home base.
  • By moving around, the players create walls that eventually fade out, but that can slow down the enemies’ movement.
  • You can shoot lasers using your headpiece/weapon, and one shot kills an enemy (but there’s a cooldown time).
  • You gain experience points by killing enemies, and experience points levels up your weapon (faster kills, up to 3 attacks per shot).
  • The more experience you and other players gain, the more enemies are produced.
  • If an enemy makes it through your defenses to your base, every player loses a level.
  • The game never ends, but eventually there’s just too many enemies, everyone falls back to level 1 and the game falls back to its initial state.

Concept

The idea was to make a multiplayer game without a server, that happens “on the wire” and free for any one to drop in or out.
So it kinda goes against the idea of cloud computing, where the client is as thin as possible and the server (or server farm) does all the work and keeps all the state. In our game, the clients are as heavy as can be, and try to maintain the state of the whole game based on the messages that are passed around.

Also, the theme of this year’s Bivouac Urbain was the song Dan Dan by Misteur Valaire. The song that is played in-game is Aliceffekt’s remix of that song, and it complements the gameplay nicely.

Post-Mortem

This year’s jam was very different from last year’s. Aliceffekt is a super-productive multi-talented artist/designer/hacker and he was quite an asset at a gamejam.
The game’s design was already decided before the jam started, so that saved us a lot of time. And 12-hours in, most of the art was already done, and I was really lagging behind. :P

Concept art for the player model

It was a huge challenge to me for two main reasons :

  1. It was my first real game in Unity (I only skimmed through tutorials before, but I use C# daily)
  2. It also was my first network-multiplayer game, and a weird one at that.

Most of my time at the jam was spent debugging the network code, and just messing around trying not to crash Unity. Even at the end of the 36-hours, the game had pretty bad synchronization issues between clients, different enemies on-screen and lasers shooting in the void. People seemed to like it nonetheless. :D

I can’t say I regret decisions that we’ve made, or that I/we should have done things differently. It was a great learning experience, stressful but gratifying, and jumping into unknown territory like that is one of the best ways to kick yourself in the butt and learn a technology for good. I feel infinitely more confident in using Unity now than before the jam.

About the initial concept (a headless LAN multiplayer game), I’d say that it’s feasible, but keeping the clients in sync is a big challenge. I’d also say that my implementation is pretty poor and doesn’t play well with lost packets (and it uses UDP, so no guarantee) or an unstable connection. I didn’t do any kind of client-side prediction either, but I literally flood the network with packets (every client sending 10 packets a second) so interpolation isn’t really necessary if the network can stand it.

A couple of things annoyed me with Unity, but I was at such an early learning stage that I probably did things all wrong, so they’re not worth pointing out. The general thing that stood out is that Unity is fantastic when you use the built-in stuff, and less fantastic when you want to hack it your way… but everything’s possible if you have sufficient google-fu and patience. :)

Hope you like the game!