Limited time Hopeye and Socks plushies!

💜💜 Two years of Exocolonist

🚀I Was a Teenage Exocolonist🚀 is two years old this week! We’re celebrating our second Exoversary with a Steam daily deal (let’s make that a week) and two new Makeship plushie campaigns. The first 200 sales of each doll includes a free Steam key!

✨ Get yours before September 25 2024 ✨

🐸🐀 The Hopeye

Xenofelis monopodus

Hopeyes leap around on a single foot and live in colonies with up to 100 others. They can be fierce little creatures when their friends are threatened, so don’t underestimate them!

They love cuddles.

🐲🐛 The Dillypillar (Socks)⁠⁠

Xenosaurus polyped

Dillypillars can sometimes be seen in the western Wresting Ridges. They’re generally solitary, and can grow up to 100 pairs of feet!⁠ This particular dillypillar is just a wee four-legged juvenile, named Socks for her white-colored feet.

She loves cuddles too.

🍄🚀 Crowdfunding-style campaigns

Makeship is giving us one month to reach a minimum of 200 orders. On September 25 the campaign ends, and if we’ve met our goal then every plushie will be made-to-order for our backers. After that, no more will be made!

The estimated shipping date is December 14th so you miiiight get yours in time for the holidays, but if you’re planning to gift one to somebody, maybe have a nice card ready just in case your xenofauna is a little late. (Steam keys will be given out to the first 200 backers as soon as the campaign ends.)

🕘🕚 Limited time only

We did Nomi, Sol and vriki campaigns earlier this year, but Socks and the hopeye are the final Exocolonist plushies we have plans to make. I may change my mind later because you know I love making merch, but you’ve been warned: these might be the last!

So ✨ visit Makeship ✨ to preorder one (or both for 10% off) before the campaign ends on September 25th 2024!

Nomi-Nomi plush for Pride month!

Nomi-Nomi plush with rainbows

Another Exocolonist plush is on the way! This time it’s a limited-run Nomi-Nomi doll, only available in a Makeship campaign ending on July 2nd 2024.

The first 200 will include a free Steam key, and since it’s a special Pride month event 10% of all sales go to the Trevor Project, and include a cute pride flag cape.

Nomi-Nomi plush reading a mini zine

I do wish we could keep selling these dolls after the campaign ends, but storing and shipping plushies is a humongous pain. Interestingly, we’ve spotted some bootleg vriki dolls on Chinese cosplay stores since our last campaign ended. Is that a sign Exo has made it?

Get your limited-run Nomi-Nomi doll 🏳️‍🌈 here 🏳️‍🌈 during the month of June! Happy Pride!

Exocolonist Plushies Are Here!

Sol and Vriki plushies
Preorder your Sol and Vriki plushies now!

This is such a dream come true for me – I love merch and plushies are kind of the ultimate, aren’t they? We’re creating them through Makeship, which runs limited time campaigns sort of like Kickstarter. We need to reach our minimum goal of 200 sales before January 5th 2024 to get them made. So if you’ve been waiting for an Exo plush, lemme say it again:

🍄🍄🍄 Go get those Exocolonist plushies!! 🍄🍄🍄

The first 200 sales of each doll comes with a free Steam key for I Was a Teenage Exocolonist, which I’m told make excellent gifts (as do plushies!) if you’re in the holiday gift-giving spirit. Makeship hasn’t made them yet, except for these product samples I get to play around and take silly pictures with, but they should be shipping out by the end of March.

Once again: these are a one-time run available only for a limited time until January 5th!

Sol riding the Vriki
Save 10% if you buy both plushies together!

There are so many neat details, like the Vriki’s tentacle suckers and Sol’s removable jacket. They use a combination of printing and embroidery, and the material is so, so soft. They even fit together so Sol can ride the Vriki? Which is not exactly canon, but Vrikis can technically grow big enough, so I’m allowing it.

We’re doing these as a limited run not to torture people who are reading this after Jan 5th 2024 and missed out (I am SO sorry), but because we can’t handle fulfillment ourselves, so this is the only way they could get made. Imagine how much space 2,000 plushies would take up if I had to order that many!

Although that would be a pretty cool looking apartment, hmm…

Vriki beans and double Sol

Optimizing Glow Season in I Was a Teenage Exocolonist

Originally posted to GameDeveloper.com in August 2022:

How a Unity scene with 1600 lights was optimized for consoles.

Final product: Glow Season in I Was a Teenage Exocolonist

Taking a game from Unity prototype to Switch and PlayStation can involve compromises, but what you need most are some good tricks and custom shaders. Our narrative deckbuilding RPG I Was a Teenage Exocolonist is set on the alien jungle planet Vertumna, which you run around and explore as you grow up. I was still getting to know Unity when I created these outdoor scenes, and mistakes were made. But over five years I learned how to make our complex outdoor scenes fast and efficient.

I’m Sarah Northway, co-founder of Northway Games and creator (/designer/coder/co-writer/art director) of I Was a Teenage Exocolonist, as well as the narrative city-building series Rebuild and other games. I work with different artists for every game, from Flash browser games, to mobile, PC, VR, and now consoles.

I might be best known for traveling the world with my husband for five years when we first went indie. It was the jungles of Central America and the coral reefs of Southeast Asia that inspired Exocolonist’s lush landscapes and focus on the natural world.

Glow Season Concept Art
Exocolonist Glow Season Concept Art by Sarah Webb

To bring this world to life, I worked with concept artist Sarah Webb, illustrators Meilee Chao and Eduardo Vargas, and 3d modeler Sarah Roland on our beautiful outdoor scenes.

Quiet, Pollen, Dust, Wet, Glow

In the main colony region, all the plants, terrain textures, and weather effects change with the season. Some plants have yearly lifecycles, growing taller or flowering then returning to buds. 3d elements like rocks and colony walls are tinted to match the weather, which includes rain, snow, heat shimmer and clouds of pink pollen.

Our seasons have cute names (Quiet, Pollen, Dust, Wet) but are roughly equivalent to winter, spring, summer, fall. There is no night cycle, but during the fifth season, Glow, Vertumna’s two suns are below the horizon for several weeks. During that time, nature comes alive with firefly-like particles and light-emitting plants.

The five seasons of the planet Vertumna
The five seasons of the planet Vertumna

Exocolonist’s lighting is flat with only painted-in shadows, no normal maps or specular sheens. I used the built-in render pipeline and forward rendering to layer hundreds of semi-transparent Sprite-based plants. The Terrain uses a tri-planar shader and swaps its TerrainLayer textures when the season changes. 3d rocks have soft gradients applied based on their orientation, and plants and other 2d objects are billboarded to face the camera. The overall effect is of a painting come to life.

During Glow season, the colony gates close, characters hide indoors and the lights come out, all toggled by Components that enable or disable child objects based on the season.

There. Are. 1600. Lights

Here’s where things got complicated. Some plants emit light in Glow season: the bobblesprouts, mushtrees, and gnarlwood. Naively thinking “Unity will handle this for me”, I initially just embedded point lights into every plant prefab, which I toggled on or off based on the season.

The result was 1600 lights in one scene, up to a thousand at a time in the camera’s field of view, all affecting each other, the ground and the player. It was glorious.

Original glow with a thousand lights
Original Glow prototype with over a thousand lights

Glorious and slow. I cranked the concurrent pixel light count to 20 for screenshots (default for “Fantastic” quality is 4). The scene above was performing 6000 draw calls per frame, most with multiple lights, and ran at roughly 1 fps on my target low-end PC.

Batching Plants Blanches Pats

Let the optimization begin! I considered Unity’s tool for adding grass sprites to Terrain, but I couldn’t get the control I needed. Instead I dove in to custom shaders and prepared to batch the plant draw calls by tossing their art into an Atlas together.

I wrote editor tools to place a variety of plants in an area at once, clumping based on species parameters, avoiding duplicate art too close, and randomizing their angles and sizes. Then I tweaked them by hand to compose little vignettes.

Some plants wave, others bounce
Some plants wave, others breathe or bounce

Every plant is an individual object in the scene, rippling, bobbing, and bending when the player walks through it. Some species swell up and seem to breathe, showing the thin distinction between flora and fauna on the planet Vertumna. But they all use a single material, and up to a thousand can be rendered with a single forward-pass draw call.

To do this I used a custom vertex shader based on Unity’s default Sprite shader. Unity threw a wrench in by not supporting custom material property blocks on SpriteRenderers, so I passed the values I needed to calculate plant movement through the unused RGBA channels of SpriteRenderer.color. I was simultaneously horrified at my terrible hack, and pleased with how efficient it was.

Shader programming in a nutshell.

Batching took scenes down from 6000 draw calls to about 6. Next, I removed the Light components from the plant prefabs, and removed Unity’s lighting from the vertex shader. I wouldn’t need these where I was going.

Bloom

I stopped tinting the plants black via scene lighting, and instead I baked the tint in using Photoshop. Only the light-emitting parts of the plants are fully colored, and a murky fog tints distant ones. Then I started adding Post-process effects.

Everything looks better with Bloom and HDR, it’s a fact. I pushed it too far, then brought it back one notch. This gave the bobblesprouts and mushtrees the impression of emitting light into the world around them. And the geodesic greenhouses look fab.

Bloooom
Bloooom!

HDR porting gotcha: We had an issue on the Nintendo Switch with our post-process highlighting effect, which draws a glowing outline around interactive objects when you’re near them. We were using the alpha channel to store hidden info about the edges of objects, but with HDR enabled, the Switch ignores alpha during post-processing to save bits for the R, G, and B channels. To fix this we had to disable HDR on Switch, then adjust for the lower-bit alpha (even with HDR disabled, alpha is capped to 1). Luckily this was our only tricky rendering issue during porting.

Bake it Till You Make It

For the greenhouses and spaceships, I used an emissive texture map to layer additive light over a regular texture. Exocolonist’s 3D objects all use the same custom surface shader which includes Unity lighting, with soft Lambert shading and few shadows. But rather than render most lights on the fly, I switched to Unity’s baked lighting system.

After taking all 1600 lights out of the plants, I still wanted key areas of the ground and buildings to be lit by glowing flora. So I added back in baked lights here and there, matching the plants’ glowing colors. I did the same for the artificial lights on the colony walls and beside doors while I was at it. Only a few watchtower spotlights are still realtime, so they can illuminate the player and other characters moving under them.

Prototype (left) versus Baked lights (right)
Prototype (left) versus Baked lights (right)

The Baked Lightmaps system creates textures based on light positions that can later be additively applied to 3d objects while the game is running. As usual with optimization, I was trading increased ram (3-5 extra textures in memory per scene) for faster processing time. What made this possible was using Addressables to store most of our art in the filesystem when it wasn’t being used.

One catch: lightmaps had to be disabled when the seasons changed. I added a component to 3d objects which remembers their Renderer.lightmapIndex and sets it to -1 when not in use.

The Lightbearer

The floating particle effects just worked, they’re mad efficient out of the box. My only optimization was to make their world-space emitter a limited size volume that follows the player around.

But the player character still needed one final touch: a dynamic light they “hold” which illuminates everything they walk near – ground, plants, structures, and characters.

Glow season
The ParticleSystem using a texture sheet and noise turbulence

I played around to find an efficient way to do this. Since the plants already knew the player position to be able to bend out of their way, I used it to calculate the light in my vertex function:

o.playerLightColor = fixed4(1, 1, 1, 1);
if (_IsGlowSeason) {
	float3 playerWorldPos = _PlayerPos.xyz;
	float3 vertexWorldPos = mul(unity_ObjectToWorld, v.vertex);
	float distToPlayer = distance(vertexWorldPos, playerWorldPos);
	float lightRadius = 3;
	float lightPower = (lightRadius - min(lightRadius, distToPlayer)) / (lightRadius + 0.001);
	o.playerLightColor = fixed4(0.82, 0.80, 0.73, 1);
	o.playerLightColor.a = lightPower * 10;
}

The playerLightColor is then added in per-pixel during the fragment or surface method. I update _PlayerPos via Shader.SetGlobalVector as the player moves, and _IsGlowSeason when the season changes.

The Result?

Well, it’s a whole hecka-lot faster now! Glow season is a smooth 60fps on most systems.

I was ready to have to rewrite the reflective water shaders or downres our textures to 2k for Switch, but it didn’t come to that. Once Glow was settled, most of our porting woes involved controller support, ugui menus, and save timing. Oh, and being forced to upgrade Unity at the 11th hour (you’ve been warned!).

Enjoying Glow Season with Dys
Enjoying Glow Season with your buddy Dys

If we ever port to mobile I’m sure I’ll revisit some of these decisions and find more ways to reduce gpu cycles and lighten the load in ram. But I’m proud that Exocolonist has come so far, from “let’s throw a bunch of lights together hey that looks cool” to scenes that are attractive, consistent, stable and fast.

I Was a Teenage Exocolonist launches on Switch, PS4, PS5, and PC/Mac/Linux on August 25th.

The Narrative Octopus of I Was a Teenage Exocolonist

Originally posted to GameDeveloper.com in August 2022:

How the home-rolled scripting language Exoscript helped us design a flexible open world narrative of nearly 600K words.

Solving a Mystery with the Gang
Solving a mystery in I Was a Teenage Exocolonist

My favorite narratives are ones where the reader – or player – is a participant, taking the author’s text and telling their own stories with it. For our narrative RPG I Was a Teenage Exocolonist, I wanted this: organic worldbuilding, characters with their own lives, replayability, and major events as signposts in a larger narrative space the player can explore. Not a linear visual novel, but a loose and vast narrative intertwined with deckbuilding and stats raising, dynamic yet deterministic.

I’m Sarah Northway, co-founder of Northway Games and creator of I Was a Teenage Exocolonist, as well as the narrative city-building series Rebuild and other games. I grew up an avid reader and writer before games became my life. I even considered writing a young-adult sci-fi novel instead of this game, but I know my strengths lie in programming and game design, and it would be a waste not to combine them with the story I wanted to tell.

With Rebuild 3, the similarly large 200K word narrative was delivered as an assortment of procedurally generated events involving a post-apocalyptic settlement. But for I Was a Teenage Exocolonist, I had a new challenge: to tell a coherent narrative along a 10-year timeline, involving characters who grow up, change dramatically, and may (or may not) even die mid-game.

I worked with co-writer and narrative designer Lindsay Ishihiro to produce Exocolonist’s huge and complicated narrative, with approximately 6 novels’ worth of text and 800 triggered events.

Collecting Roots in the Prosaic Plains
Clicking a question mark while exploring will start a story event

The Octopus

With our focus on replayability, I wanted players to only see a small amount of the narrative during each life, but without forcing them into one track at a time. For a dynamic open world, we’d need events to occur with or without you there to witness them, and you could pop in on a plotline in the middle of some crisis which might be too late to solve.

I wanted you to see the world from different points of view as you grow up in the game: as a child or an adult, as a farmer or a soldier, as a romantic or a rebel.

A branching narrative wasn’t going to cut it, or at least not just one. We needed many different plotlines overlapping and affecting one another, and hundreds of one-off triggered events to build a narrative world you could explore at will. And we couldn’t always control what order events would fire in, or what state the world would be in when they did.

Our narrative wasn’t a branching tree, but a juggling octopus. Flexible and interconnected, with a core narrative and many wriggling limbs.

Closest thing we have to an Octopus: the Vriki
What passes for an octopus in Exocolonist: the vriki

Event Categories

Our 800 narrative events break down into these types and trigger methods:

1) Main plot

These occur in every playthrough, and tie the game together with the consistency of changing seasons. Every year there is an event for your birthday, then the Vertumnalia harvest festival in midyear, then an event during glow season as the planet begins to reject the colonists’ presence. Unique challenges happen during specific years, always on the same date in every life, but the outcomes can be changed by your decisions and skills.

The predictability of main plot events provides an anchor as the months tick by, and reinforce the current mood of the game as it grows darker over time.

2) Sequential threads

Spend time in geoponics, and you’ll discover a friend’s secret pet, which over ten events grows up to be a huge problem. Work in the command wing, and you’ll get embroiled with a secret club with plans to free the colony from tyranny. There’s a series of world-building events as you improve in each of the twenty-five school, hobby or career paths, which often give the player a choice between two or three cards to build their deck, representing how the player is growing as they increase particular skills.

Sequential events always happen in order, but might be skipped if you’re too old. They’re triggered with the main plot events after you do an activity for the month. If two or more happen at once, I try to pick the highest priority one and delay the others.

3) Friendship events

Characters have love meters which trigger sequential events as you get to know them. These tend to be less connected to larger colony plotlines, and they’re optional, requiring you to walk up and talk to the character when they have a speech bubble over their heads.

Relationship Events
Some of the most emotional moments are in friendship events

4) Exploration

These appear as signposts, creatures or floating question marks out in the wild, and feel like miniature RPG encounters. Many involve a card battle or a skill challenge, and they’re scattered around semi-randomly depending on the region, season, and year.

5) Barks

In addition to our 800 triggered events, there are 1800 barks: short single paragraphs with no choices that play when there’s nothing else to say. They’re highly conditional, based on anything from the weather or your combat skill to obscure choices you made as a kid.

Enter Exoscript

Exoscript with N++ Syntax Highlighting
Exoscript with syntax highlighting in Notepad++

I considered various commercial scripting systems, including Inkle’s ink and the Unity asset store Dialog System, but none were quite right. I was planning to hire a co-writer, so I wanted something that would be easy for a non-programmer to learn and use. I wanted script that would look like plain English and feel simple and natural to write in, lightweight with a limited set of powerful features that we could use in complex ways. I wanted to be free to easily extend it, integrate it into the Unity project, and change events while running the game.

Ink came closest, and I would recommend it to someone in the same situation. But I was bitten by the desire for full control, and writing my own parser sounded like fun!

In the end creating Exoscript was indeed fun, and didn’t take as long as I’d expected. About a week to get the base features in, then another few weeks of optimization and upgrades gradually as we needed them. Co-writer / narrative designer Lindsay (who turned out to have a background in code) quickly got the hang of complex conditionals and started asking for more.

Example of Exoscript
Exoscript with choices, skill gates, and method calls

In this example, choosing “Try to distract it” sets an event-level variable (“~set var_distract”), then returns to the previous list of choices while removing itself (“>>>”). This will reveal a new choice to “Attack the monster!” now that you’ve distracted it (“~if var_distract”), which triggers a card battle (“~call battle(combat_10)”). But it has an additional bravery requirement (“~ifd skill_bravery >= 10”) which must also be met. If you win the battle, a new illustration will show (“~set bg = nearby_close”) and a permanent variable will be set (“~set mem_savedTonin = true”) to remember this for future events.

A Terrifying Encounter
Screenshot of the above Exoscript in action

Calls and Conditionals

Call statements like “~call battle()” use reflection to jump into a C# library of about a hundred methods that gradually grew through development. If they have parameters, those are automatically validated when the scripts are parsed, along with parameters used in any “~set” or “~if” commands. I wanted to be sure we’d catch typos in the IDs of skills, backgrounds, characters, or cards as early as possible.

The validation step also checks that referenced variables have been set at some point, and for unlikely cases like jumps causing infinite loops. This made my job as an editor much easier, and will be handy if players mod the game to add their own events.

Closely connecting Exoscript with the Unity project made it easy to trigger visual effects, for example “~set left = marz” slides the character Marz in to the left side of the scene, and changes the color of text in double-quotes to her color, blue.

Anemone's Barks
Anemone’s Barks

Our in-line conditionals (eg “[if skill_bravery >= 50] How brave you are! [else] Scaredy cat! [end]”) work like “~if” to determine which block of text to show. We use them all over the place, but prefer to put them around full paragraphs. This is both easier to read, and if we ever decide to localize one day it will make translators’ jobs easier.

Groundhog Day and Our Process

A key narrative feature in I Was a Teenage Exocolonist is a mysterious wormhole that lets you remember bits of past lives. On your second playthrough onward, new choices appear in events you’ve previously encountered. These can be used to shortcut difficult challenges, like curing a disease without spending years researching it, so you could eventually combine many lives of knowledge into one “perfect” life.

In honor of the classic Bill Murray movie Groundhog Day, these are called “groundhogs” or just “hogs” in the code.

Double Vriki
Wrangling our multidimensional octopus was no easy feat

The simplicity of Exoscript was a relief given how much we had to keep track of. Generally our system was: I blocked events out, Lindsay wrote them, then I edited and tested them in the game. Lindsay pulled in the direction of romance and longer prose, and I pulled towards blunt gameplay-oriented choices, and together we found a great balance. We hashed out the trickiest parts of the narrative together on Discord.

We had notes and spreadsheets of facts and jargon, and Exoscript was easy to skim for references, but writing Exocolonist really only worked because both of us were able to hold the entirety of the narrative in our heads for a few years.

The Future of Exoscript

The Stratospheric in Space
Launch is only the beginning

I mentioned modding above, which I hear Exocolonist fans are already doing before the game is even out! They’re adding their own events, and have even ported the syntax highlighting to other text editors. I tried to make modding easier by storing the story files in the filesystem in plain text, and if there’s enough demand I might implement Steam workshop support after launch.

Localization is something else we’ve wanted to do but have been unable to so far due to the enormous nature of Exocolonist’s narrative. But fan translations may also be possible some day via a modding system. And I’ll be using Exoscript again for my next (unannounced) game.

I’m looking forward to seeing what players think of the game, what stories they tell inside it, and how it inspires them creatively in their own writing and art.

I Was a Teenage Exocolonist launches on Switch, PS4, PS5, and PC/Mac/Linux on August 25th.