Where Does the Time Go?
Part One: Obsessing Over 2D Lighting
My first mistake was picking up Sea of Stars. As a Game Pass game with strong callbacks to the Chrono Trigger era, I was certain I'd enjoy it.
As I relaxed into the game I realized trouble was brewing. The game is SO PRETTY. The way the lighting and shader magic combines with the very subtle glow and bloom paints a picture that still feels pixel perfect and retro. This was a problem because lighting is one of my favorite dev rabbit holes. Nerdery to follow, you've been warned.
Base State: Built-in Pipeline, No Lighting
Alexa play "Sleeper Island — Sea Of Stars Original Soundtrack"
When I spun up the project 2 years ago, I chose 2D and the built-in render pipeline. For those in the know with Unity, render pipelines have fractured and evolved recently. It's confusing to follow. At the time I chose built-in — the "new" Lightweight Render Pipeline (although it had been renamed to Universal Render Pipeline, much of the internet still referred to it by the old name). I wanted to reduce the surface area of things that could go wrong (it was still "experimental").
The built-in pipeline doesn't support 2D lighting. I was wary of upgrading the project's render pipeline — it seemed like a good way to bork the project completely. Off to the asset store!
Variant 1: Built-in Pipeline, Asset Store "Fast" Lighting Plugin
Alexa play "Crucible of Confirmation — Sea Of Stars Original Soundtrack"
Okay — fast lighting, built by a random internet person! What could go wrong. $20 and compatible with the built-in render pipeline. Turns out this worked pretty well for what it was — a complete lighting solution, implemented with familiar Unity primitives (sprites, colliders, physics shapes, etc).
QUICK DEFINITION BREAK!
Blend modes: A Photoshop wiz could define this better, but additive vs multiplicative blend modes are a core component for every 2D light. My take on this is that additive continues to layer light towards bright white, capping very quickly at 100% white (or, whatever your light color is). Multiplicative allows the full spectrum — layering at a slower rate by default, and crucially — allowing darker hues (multiply by .5 for example).
My implementation with this plugin resulted in some additive lights that I thought looked okay, but had this blurry quality reminiscent of glamour shots in old movies where Vasoline was smeared over the lens.
A few drawbacks —
There wasn't an obvious way to globally darken the scene (multiplicative) in order to get the lights to correct back to a more normal level
Since it wasn't a built-in tool, there was some jank
Didn't interact very well with tilemaps
Shadows weren't based on height OR on the sprite shape
SHADOW BREAK! 2D SHADOWS — CASTING SHADE
Alexa play "Cursed Woods — Sea Of Stars Original Soundtrack"
Shadows... I'm as flummoxed as Peter Pan. In hindsight, it all makes a ton of sense.
In order to cast an accurate shadow the engine needs to know the height of the light and the relative rotation of the sprites in order to cast a believable shadow. In the 2D Unity game engine, there is no such thing as height. Therefore we get out of the box shadows such as... drumroll...
Well that certainly doesn't look right! The shadow should start at his feet and extend out in a way that looks like his shape, distorted a bit geometrically given the distance from the light and the relative light positioning. Ahh, this got really complicated really quickly. In a nutshell, in order for lighting and shadows to look realistic, clearly the 2D engine needs a bunch of 3D info.
Variant 2: Universal Render Pipeline, Built-in 2D Lighting
Now we're getting somewhere. With a lot of futzing I came up with something that I think looks decent. While not perfect, the character shadows seem accurate and dynamically cast away from the 2D light sources, and when the static assets need a little bit of fudging I can handle it manually.
This screen includes:
A slight vignette effect
A slight bloom effect
VERY soft shadows (barely perceptible, meaning that your brain doesn't get stuck on the fact they're not precisely pixel perfect, or that they're not based in what should be 3D reality)
A multiplicative global light to turn off the lights a tad everywhere there isn't lamppost light
Lamppost light that adds a nice hue to an otherwise very purple palette
The shadows are based on the best approximation of the anchor point of the sprite and do not reflect the shape of the pixel, but it does direct the flow of the light enough that I think it's worth the addition. More experimentation to come.
Addendum: Other Shadow Ideas We May Try
Alexa play "Monuments to the Ancients — Sea Of Stars Original Soundtrack"
Hand drawn half transparent pixel art (for the props that don't move)
A shader that automatically creates "shadow" by replicating the sprite shape with a black color/some transparency and transposing at an angle (looks really two-dimensional)
Becoming a cave hermit, exchanging my keyboard for sticks I can rub together to make fire, thereby casting my own realistic shadows
Part Two: Hospital Visits!
(Doug notes: This section was written with Lisa's consent, encouragement, and input!) This month is more of a Game Non-update on my end, and I'm going to focus on a dev-adjacent topic: taking care of yourself, as best as you can! If you've been following Advent on social media or saw our last newsletter, you know that my wife Lisa is our amazing character designer! Lisa's always had it tough when it comes to health issues, having been hospitalized four times in last four years (three emergency visits and one planned major surgery). This month proved no exception with a nearly week-long surprise trip to the hospital. What started as a trip to an Urgent Care clinic turned into an ER trip and hospital admittance that lasted five days.
As anyone who has spent time with a hospitalized loved one will probably tell you, you enter a sort-of time portal as all other priorities shrink in comparison to ensuring they are comfortable, cared for, and in good company as often as possible. You pop out on the other end of it and wonder where exactly your last several hours, days, or even weeks went. Fortunately, Lisa's the toughest lady I know, and always leaves these miserable, stressful experiences stronger than before. Nonetheless, we both want to take the time to stress to everyone the importance of listening to your body when it's giving you signs that something is wrong. Nobody loves going to the doctor, and especially not via the Emergency Room — but if something is causing you concern, pain, or even just nagging at the back of your mind — you need to get it checked out!
It's been a rough year for our family outside of just Lisa's health issues (possible discussion for future blog posts), and we can both assure you that one of the greatest gifts you can give your loved ones this holiday season is simply the knowledge that you're happy, healthy, or at least taking steps to end up in that direction. Lisa has a couple weeks of bedrest ahead of her, won't be able to produce much (if any) Advent artwork until after the holidays, and we may not be able to make an appearance at all of our usual holiday gatherings — but that's a small price to pay for healing and peace of mind. We thank you all for your continued support as Lisa heals and we get back in the saddle for an amazing 2024!
See You Next Year!
We are so excited to have you along with us on this game development journey, whether you just discovered us or have followed the project since its early days. 2023 started out as a slow burn, but our progress really ramped up in the last half of the year. We have so much planned for next year and we hope you share in our excitement! From the entire Advent of the Reaper team, we wish you and yours a wonderful holiday season and we'll see you in 2024!