A story- and atmosphere-heavy spellcasting RPG, heavily based on Ural mountain folklore.
The protagonist (we never came up with a name for her) moves along a 2D plane in a 3D environment, with generally realistic platforming movement inspired by Flashback: The Quest For Identity. The system uses the Unity physics engine, manually controlling the character’s momentum to create grabbing and climbing, and adds quadratic drag for “crunchier” falling per Bennet Foddy’s 2015 GDC lecture. I started by modifying an existing character control script, the final system ended up a complete rewrite.
Character interaction is controlled with Layers. If an object has a Collider and is in Layer “Walkable,” the protagonist can traverse it, including ledge grabbing when appropriate. Rope climbing is the same, only with Layer “ClimbableRope.” (Wall climbing was also implemented, but cut for time.)
Want to play with it? You can download the Unity package here. Feel free to use the controller scripts & prefab setup for whatever you’d like (but not Anastasia Jacobsen’s cute character model please!)
Footprints are based on the method used in Röki. At the animation frames of the walking and running cycles where the foot first makes contact with the ground, an animation event is called with a boolean indicating left or right foot. A Projector Prefab with a Normal Map Texture is then instantiated at the location of the foot’s Bone. The Prefab has its own script, which fades the Normal Map out over 10 seconds, and then self-deletes.
The Solus demo is available on to download and play on Itch.io (Mac & Windows).
Anastasia Jacobsen’s concept for Solus is an attempt at a semi-hard-sci-fi take on Alex McDowell’s “Planet JUNK” collaboration. The Earth has somehow stopped rotating, creating a 6 month summer/winter cycle and migrating the oceans away from the equator.
In the demo, the player journeys down into the sand-buried remains of a skyscraper looking for water. For visual interest (and irony) I suggested the Futurist city of Brasilia which went over well with the team: Niek Meffert, Anastasia Jacobsen, Rosa Friholm, Ida Lilja, and myself. I was Technical Artist and Lighting Designer. (Solus was the first of two Planet JUNK collaborations. Many lessons learned were later applied to Shrooms.)
Solus uses Unity’s High Definition Rendering Pipeline (HDRI), allowing a wide variety of realistic volumetric effects—the simulation of light’s interaction with microscopic particles suspended in air, like smoke, water droplets and dust.
Topside, the lighting is very simple. There’s a Directional Light (sun) and not much else. Fill lighting is created by Global Illumination from the skybox. Blowing sand is created with the Unity VFX Graph. A number of post-processing effects are added, including Bloom, Tonemapping, Color Curve adjustments (for a more cinematic “desert” look) and a custom sparkle shader in the brightest areas. A faint volumetric Fog pervades the scene, to create a dusty atmosphere. Slightly behind the main plane of action, a second “thicker” Fog Volume is added, faded from bottom to top, to make the background distances appear greater and create a Bryce-like height fog effect.
The underground lighting is primarily driven by a Point Light attached to the character’s lantern. The Volumetric Fog is thicker, increasing with depth into the buried skyscraper. An extremely bright Spot Light shines in through the entrance, volumetric and colored bright blue to contrast with the warmer lantern light. A similar, very narrow bright blue Spot Light shines down from the top of the first elevator shaft, as if a tiny stab of sunlight were blazing in through a chink in the roof. Farther down, mushrooms glow with an eerie green Emissive Material, casting light onto their surroundings via covert green Area Lights.
The theatrical darkness demanded that a final Light be added, to only be activated while editing the scene—literally named “Work Light.”
The Solus demo is available on to download and play on Itch.io (Mac & Windows).
“Tiny Convoy” is as a demo-length convoy simulator–a moving base builder–developed in Unity 2019 by Niek Meffert, Lucas Oliveira and myself. Playable betas for Mac and Windows can be downloaded here. The goal is to survive as a group of tiny robots in a big dangerous world: find power, upgrade your bots, and avoid dangers.
Remember the annoying escort missions in “Warcraft III,” where your soldiers kept hauling off to attack anything that moved, instead of protecting the things they were supposed to? It’s like that. Except your bots can’t attack anything. You are essentially robot herbivores. Looked at another way, “Tiny Convoy” is a herd simulator.
As a small team in our first year Masters, the work was loosly siloed. Oliveira took the lead on modelling and texturing, Meffert was point on UI and the first version of the A* pathfinder, and the C# code base is about 90% mine. (I also designed the Touch-Me-Not exploding plant.)
1. Emergent visual storytelling–Design Pilars
no dialogue, no scripted beats
2. Keep moving & exploring
3. No weapons
4. Cooperation is essential to survive & thrive
Our goal was to marry emergence and progression in an interesting and satisfying way. We wanted to build a game in which the player could create in their own mind an emergent storyline around an algorithmically-generated world. If the content one encountered became too boring and undifferentiated, there would be no sense of progression, and little incentive to keep exploring. On the other hand, if too many things were deliberately laid in the player’s path at defined points, it would take on the feeling of an “on rails” story game, to the detriment of replayability.
Every “Civilization” player remembers when the Mongols took their capital, and they rallied back to win. What happened was only the randomized game content interacting with the rules and the player’s choices, but it took on the quality of a narrative moment because it was different and valued by the player. Likewise, we wished to create moments like “When Little Blue got stepped on,” and “When we found the field of Touch-Me-Nots on the other side of the desert”—moments created entirely by the game systems interacting with the player’s choices, but which would feel personally meaningful.
To do this, we needed to construct a series of game loops, with systems of player feedback. We would gradually challenge the player by introducing limits on stock (not enough power available) and new sinks (dangers that damage parts). The game engine would introduce new content and changes to the starting conditions in a measured manner as the player moved farther and farther across the game world.
An html5 auto-conversation game about the different versions of ourselves that have been, are, and will be, meeting an ex from many years prior. Graphics designed/performed with iOS Messages animojis. Created for the October 2020- game jam at KADK. (Plus fixes, cleanup, and the addition of a third character.)
Introducing beta 7 of Forest, with better graphics, a more dynamic game world, and many behind the scenes tweaks. This project is released under an MIT License.
Forest Gods. Nearly all aspects of the board can now be influenced by randomly-generated, free-floating roamers. Some are dramatic (like lightning gods) others practically invisible (like soil porosity gods). They’re intended to make the forest more varied, and perhaps even less lonely and more mysterious.
Improved Fire. Fire has been an aspect of the game world for several versions, but is completely rewritten in beta 7 to be much more graphical, dramatic, realistic in its effect on the forest, and unpredictable.
Better Graphics. The band of the sun now moves throughout the year more accurately, and the stars now properly blur into rings as well. Fog is a custom shader, the minimum of height fog and linear distance fog. Lighting for the ground and water now comes from an array of lights aligned with the sun ring. (Trees are still sprites, however, and don’t yet respond to lighting.) The randomly generated forest’s average temperature is used as a stand-in for latitude.
Smaller Board. Moved from a 200×200 tile grid down to 128×128. This seems to tax the CPU a little less without noticeably changing the scale of the game.
Erosion. Soil is now washed along by water. Stream system formation is still rare, but it does happen.
Introducing beta 6 of Forest. This release should bring a much higher framerate in all browsers, and a number of small fixes.
Architecture – A Quick Outline
- Control Objects
- World: Manages weather, climate cycles & fps
- Ground: Manages ground conditions, GridTiles, RenderGroups
- Roamers: Everything that needs to be updated each frame, including the camera, the camera’s (invisible) target, lightning bolts, etc.
- Mats: Materials and texture maps, including the ground’s dynamic texture
- Sprites: Lifecycle and behavior management of trees, energy balls, etc.
- PostProcessing: Manages GPU special effects for the scene, like bloom
- Shaders: Overwrites some of Babylon.js‘s shaders with custom versions
- Actors: Container for the Actor classes
- GridTile: Manages one point on the map grid, and holds the Actors currently active on it
- TileAlias: GridTiles in the first row and column use these to keep track of the geometry they must also update to smoothly wrap the map
- RenderGroup: A block of GridTiles, which can be prioritized for drawing depending on the camera’s current position
- Fire: An Actor which consumes other actors, then temporarily blackens the GridTile
- Tree: A large, slow-growing Actor
- FallenTree: An Actor which slowly loses mass, producing new soil
- Grass: A small, fast-growing Actor, which greens the GridTile
- DeadGrass: An Actor which slowly loses mass, producing new soil, while it browns the GridTile
- ProtoRoamer: Class containing data fields and actions for things that roam around on the board
- Camera: Subclass of ProtoRoamer, which moves the camera
- Target: Subclass of ProtoRoamer, at which the camera is aimed
- Energy: Subclass of ProtoRoamer, short-lived, produced where you click, which feeds energy to the Actors there
- LightningBolt: Subclass of ProtoRoamer, very short-lived, obliterates all Actors on its GridTile and starts Fires on surrounding tiles
Better performance in all browsers. Beta 6 moves the process of updating water flow and ground conditions into a WebWorker, a second processor thread. Beta 5 was a major rewrite to accomodate this, moving most of the data of each GridTile object into a single, large Float32Array, and adding Getters/Setters to the GridTile class to make the array data behave like normal properties. Parts of the array can then be rapidly copied, to update the vertex data or to be sent to the worker thread, via the .subarray() function. Data returned from the worker thread can then be copied back into the main array via a .set() operation. Currently, any changes made to the board by Actors or Roamers during thread execution will be overwritten
Better performance in Firefox and Chrome. The GridTile prototype uses Getters/Setters to manipulate the data in the master Float32Array. This was originally done in Beta 5 to allow moving some updating to a WebWorker, but for whatever reason the major speedup of moving the data into the Float32Array alone ended up being worth the change. The index lookups in the Getters/Setters (e.g.
ground.data[ground.indices.watertable+this.index]) bring virtually no overhead in Safari, but Chrome and Firefox struggled with them. Beta 6 caches the lookup indices in each object, which speeds up Firefox and Chrome considerably even absent the WebWorker thread.
Thanks to some great playtesting with my nephews, please find an improved version 2 of the game here.
Forest Fire is a simple Pandemic-like (or Pandemic-lite) game for 4-6 kids, age 6 and up. The players work together to put out the fires in a forest. Encourage them to talk over their moves, and strategize as a team.
Make a 6×6 grid. Number the columns 1-6 and the rows A-F. These are the Forest Squares. Place a player piece for each kid around the outer edge of the grid, next to any square they choose.
To add Fires (counters) to the board, you will roll two dice. Announce the roll to the players as: The number from the first die, and the letter corresponding to the second die: A=1, B=2, C=3, etc. Have the players add a Fire counter to the square you call out. Now explain that when there’s a non-burning (empty) square between a new Fire and an existing Fire, the Fire spreads to the square inbetween–horizontally, vertically, or diagonally. (This is like Go, only Fire can only “flip” a single square.) Repeat once for each player, then have the players begin the round.
If at the end of a round anyone is still on a square with a Fire, they’re out of the game. Disaster! If all forest squares are burning, it’s game over. When the kids put out all the Fires, they win!
Difficulty: A Firebreak is a clearing (natural or artificial) in the forest that fire can’t easily cross. With a second type of counter, you may at the beginning of the game roll to add Firebreaks to the board. Players can move onto Firebreak squares, but if a Fire is rolled on a Firebreak square, nothing happens. For an easier game, roll one Firebreak per player. Roll fewer or none for a challenge game. (Remember, the players still lose if every non-Firebreak square is ablaze at the same time!)
Introduce the types of player characters one game at a time:
Have the kids mime holding a firehose. Explain that a Hotshot Team are the firefighters on the ground with hoses and shovels who work to put out forest fires. (This is where the term comes from!)
A Hotshot gets 2 moves per round. Each move can be either: 1) Putting out a Fire (removing a counter) from their own or an adjacent square (N, S, E, W or diagonally), or 2) Moving one square N, S, E or W. Moving one square off the board, like at the beginning, is allowed. No square can have more than one player on it at a time.
To begin the game, explain that it takes time to get Hotshot Teams to a forest fire. Because of this, the fire has time to spread. Add 2 rounds’ worth of fires to the board (one roll for each player) then have the players begin.
Have the kids mime holding onto the straps of their parachute. Explain that a Fire Jumper parachutes into the forest near a fire. Because of this, they can’t carry as much, but once they hike out they can jump in again anywhere they’re needed.
A Smoke Jumper gets 2 moves per round. Like the Hotshot, each move can be either: 1) Putting out a fire (removing a counter) from their own or an adjacent square (N, S, E, W or diagonally), or 2) Moving one square N, S, E or W. Because they have less gear, however, Fire Jumpers can only put out 1 fire per square. They also have a special ability: Upon moving off the board, they can “jump” to any square on the board. (Moving off the board and jumping count as one action.)
Add 2 rounds’ worth of Fires to the board, then have the players begin.
Have the kids make an airplane with they hand (palm flat, index and ring finger together under the middle finger, pinky and thumb out to the sides). (If this is too hard, just pretend to be holding the flying yoke.) Explain that Pilots fly modified seaplanes which land on a body of water, fill a large tank, and then dump the water directly onto a fire.
Movement-wise, the pilot works a little differently. Every other turn, they must leave the board to refill their water tanks. (The players each pick their piece up and hold it in their hand.) The next turn, however, they can put out all the fire on any 3 squares in a row (N, S, E, W or diagonally).
Add 2 rounds’ worth of fires to the board. When the kids begin, remind them that they must first leave the board to fill up–so there’s actually three rounds of Fires added before they can begin putting them out!
Now we put the pieces together. Let the kids decide (and encourage them to discuss strategically) what each would like to be: a Hotshot, a Smoke Jumper, or a Pilot. Explain how fighting forest fires is a team effort, with people in different specialties doing different jobs. (Now we understand the pantomiming; it’s to keep everyone’s role straight!)
Add 2 rounds’ worth of fires to the board, and have the kids begin!