logo80lv
Articlesclick_arrow
Research
Talentsclick_arrow
Events
Workshops
Aboutclick_arrow
profile_loginLogIn

How Pixel Art Lighting Was Set Up in Seamless World of Nectarmancer

Don Bellenger remembered how life simulators influenced Nectarmancer's "Gardenvania" vision, told us about the challenges of the game's seamless world, and showed how pixel art lighting was achieved.

Introduction

Hello! My name is Don Bellenger, I'm a co-founder and a fellow worker-owner at The Beauty Cult. Previously I was the sole proprietor of SuperScarySnakes and we made a game called Black Future '88 for PC and Switch, but after some post-launch reflection, we realized that we needed a different business structure and process to make the games we wanted to make. I've been a game developer for the last 15 years, I've worked on Rimworld, Draw&Guess, a MOBA, a tank game, some Osmo stuff, and even a few of what I now recognize as "evil games", which cynically over-monetize players.

The Beauty Cult

A worker-owner co-op is just a regular business (typically an LLC in the USA) that has an extra set of bylaws to manage actual ownership of the business. Now that there are multiple owners, the bylaws should also specify how decisions get made and how resources get shared.

Co-Op stands for Co-Operative, and they rose to prominence during the Industrial Revolution as part of the labor movement. For us, we're centered around the radical idea that Labor Is Value. This may not seem all that radical at first blush, but in the context of games, I'd ask you to consider what the labor value is of a "failed game" or what the labor value is after a publisher recoups all their investment from royalties. It's not actually easy to pin down what constitutes Labor or even Value, and we don't necessarily try to define these things – instead, we orient our business at a high level around this concept.

So how does that work? We're currently 4 people, 1 programmer, 1 artist, 1 artist intern, 1 PR/comms. We lease out our labor to other teams as much as possible, the money they earn comes back into The Beauty Cult, and the money all gets split up evenly. A co-op is a great structure for something like this since it already has a lot of plumbing for equity and financial disbursement.

Everybody works on Nectarmancer. We still have a CEO, that's me, but we also have a tiny board of directors that the CEO is accountable to. We have a weekly meeting to talk about things at the co-op level. It's actually really nice to zoom out every week and see how we're tracking toward our highest-level goals. The number one reason we choose to consult for other teams is it lets us circumvent the dominant funding model in games, which we feel is so risk-averse, capitalistic, and genre-entrenched that it genuinely holds back the advancement of games as a medium. A lot of developers have watched Mick Gordon's talk about the DOOM OST, and the one thing that resonated with me the most was that changing the process changes the outcome. I really feel that a co-op business that consults for other teams is about the furthest thing you can get from the publisher model, and it really forces us to live Labor Is Value every single day. It’s a vastly slower way to make a game, however, but we’re far enough in that we can see that what we’re making is really unique.

Viewed through any ethical lens, the player wasn't really any different from the bad guys of the world and they lacked any kind of narrative agency. I still love the idea of a mobile city in a game like this, but the barrier between the tiny city and the rest of our nascent world eventually became too much, and we ditched this idea.

Over time, we started to isolate the best themes from our inspirations, namely centering on a moral-rationalist character who hacks the shit out of the world's magic system, making it do things it was never meant to do in order to solve impossible problems of huge scale. This led us to the concept of our character's real role in the world, casting her as an employee of her shitty/evil employer at first, but giving her a curiosity that lets her utilize her unique situation as part of her redemption arc. This started to feel much more in line with how I at least personally feel about the world: it's full of mostly good people who are yoked to an evil engine and do its bidding because they have no other realistic choice.

Giving our player, Aisa, agency over this exact situation at the same time that we were transitioning to a co-op structure just felt very right. It’s important for Aisa to reject cynicism wherever she sees it, and it’s important for us to do the same.

It's both liberating and intimidating to be working in such a novel design space. We've been really excited to dig into deeper simulation-based gameplay. It took us a while, but we're finally at a point where the plants in the world are really interesting.

Since our game has so much in common with games in the life-simulator genre, there are complex systems that our plants can feed into, whether it's the economy, combat, NPC/quest goals, or part of the larger meta objectives we give the player around the world and the biological computer. Every time a plant spawns a seed in the game, it gets a volatile copy of its parent's genetics. We wanted to make sure that the player isn't just watching "bars go up", though, and that they need to make careful decisions on how they're going to use each seed. A seed might get a few positive mutations but a lot of negative ones to compensate or maybe one “hero stat” but with a lot of consequences, and the player will need to think about trying to merge its genetic line with something they already have, or maybe they just want to hock it at enemies as a ranged attack.

Similar to our previous game, things that may appear bad or useless at first are really just more complex, requiring more mastery from the player to utilize. This plays really well into our plant's genetics, as plants don't necessarily get "worse" mutations, just more complex ones.

Having plants as the crux for pretty much every player action and having them be breedable and mutable is what makes our game unique.

Pixel Art Lighting

The first thing we do is build an edge map of a sprite in the editor. We used to detect edges in the shader, but even though texture reads are cheap to do on the GPU, doing 8 times extra reads per pixel really starts to add up and is a good candidate for pre-baking! Unity has a pretty nice feature of Secondary Textures for atlases, it takes away the headache of managing different UV coordinates for maps related to the same sprite, and working in pixel art instead of high-res 2D means that we're really unlikely to run into performance ceilings around memory.

Detecting edges is also really easy to do in an editor script. Our edge maps also need some amount of directional information, a simple 1-bit mask wouldn't be that useful for us since if the light is above a character, we don't want their bottom edges lit- so when we detect edges we encode some directional information using the 4 color channels of our edge texture. From there, it's just a matter of reading out the encoded texture in the shader to spit out some normalized edge information. Passing light information into the lighting system is also relatively straightforward. We have our own type of lights that just get collected and passed into the GPU as a structured buffer. It's utterly simple, as we only currently support "point" and "directional" types of lighting, but it wouldn't be too challenging to put together something that's closer to spot lighting.

Here is how to create edge maps on the CPU and consume them on the GPU.

Seamless World

The open world is actually really difficult for various reasons, and the tech itself isn’t the biggest challenge. Luckily, the systems tech was one of the first things we tackled when building the prototype and it wound up being one of the easier components. The actual technical challenges aren't that bad once you break them all down.

We have a difference between local space and world space. All our various parts of the world are discrete unity scenes. Each scene has various "visibility points" with a few rules attached, like "when this point is in view, always do X", where X usually just means "load this scene", but can sometimes be "hide this scene", or "load/hide this scene if player is above/beneath me".

When we save a scene, all this data is saved into some global metadata that our scenes controller can read at runtime. From there, it's mostly about polling the player’s world position and telling the engine to load the scene as asynchronously as possible. We have a lot of workflow tooling to support this as well – when we work in individual scenes, we have some post-save hooks that take a screenshot of the scene with a camera prefab and also add that to our metadata, from there we manage all our individual world "rooms" in our world map, which lets us move the saved screenshots around and move giant portions of our world. It's tedious to line up all the level geometry so there aren't any seams, but once it works it's magic. 

The biggest challenges with an open world like this, in my opinion, are on the design side. While our Nectarmancer, Aisa, is highly acrobatic and has an easy time moving large vertical distances, we've found that a world layout that has a lot of verticality just isn't very pleasant to play. No matter how tight or convenient we could ever make traversal, moving up/down will always be more mechanical than moving left/right. We've seen this to be true in other games with a similar emphasis on verticality, as well, like Ori, Hollow Knight, and Dead Cells. In Ori, despite the player having a ton of vertical movement options, the world map is still 2-3 times wider than it is tall, and even then a lot of the verticality is achieved through switchbacks and not sheer surfaces. A game like Ori also has a higher emphasis on forward exploration and less on re-traversal, so we need our movement to be at least as good as Ori’s in order to facilitate our own world traversal, and that itself is a huge undertaking.

We've also seen that a lot of things that provide good scene depth for us become problems when we try to bring them into the world map. Especially for things that are very far in the background, they can become visible from very far to the left/right of them just due to the wider aspect ratio of the screen resolutions we're developing for, so we find ourselves using caves and other transition areas that bring the background in closer.

Knowing that no chunk of our world is ever really rendered in pure isolation means that when we’re building scenes and areas, we have to always jump back to the world map to see how it all looks in context. Another challenge in the open world system that we have is that working on one giant map with a lot of interdependencies is just universally more complex. In Hollow Knight, there very well may be rooms that are not "geographically consistent" and we'd never know because of the way that game does room transitions. Having to carve out space for new or emergent ideas always has impacts, sometimes on rooms that are rather far away. This generally makes iteration more difficult and time-expensive. We can always try to plan more on paper, but game development has so much sheer emergence that plans can only go so far or hold up for so long. There are significant upsides to having a continuous open world map, though. A lot of the problems we run into have us creating clever shortcuts and surprises and lots and lots of secrets to make spaces more meaningful; I think we have wound up with a richer world because of it.

Challenges

While we've had some meaty technical challenges, our biggest challenges are more around the design and business aspects of the project. It wasn't obvious to us when we started just how novel our gameplay was going to be. We knew it would be plant-based, but at this point, we're refining our fifth iteration of what a plant "is" in the world.

Our very first attempt put a ton of simulation and rendering parameters into these uniquely procedural plants. We went super deep into asynchronous mesh generation jobs and came up with some novel tech for all of it, but at the end of the day, it wasn't even close to fun. This included a very high-fidelity growing model where plants responded to light, nutrients, soil, crowding, and a growing spec with over 100 parameters for generating branching structure, leaves, and flowers. Each plant became way too big and important and could generate more plant matter than was reasonable for the player to be carting around- and while that had some interesting qualities, it just wasn't very fun and didn't satisfy our game's other pillars around combat and exploring an interesting world. 

While "Farming" is a well-explored design space, "Gardening" is very different and we haven't actually found a lot of examples of it in games, especially action games. While “Farming” has the player putting stuff into the ground and then ripping it out and selling it, “Gardening” often sees the player revisiting that plant to perform some tiny optimization to it. This is fun in the real world, and we think that eking out a tiny player advantage is fun in the game, too. To us, it has that Rogue Legacy or Dead Cells feel of constant incremental progress that I think is just such a good hook in a game. It also helps us address the tedious open world and Metroidvania problems of re-exploration: where sometimes the player has to go somewhere and it forces them to re-traverse an area that's no longer exciting or challenging to them. This is especially important in a 2D platformer, which tends to have the player moving primarily on the horizontal axis. Eking out tiny bonuses in service of all their other goals is a pretty good time. Even though our world is all hand-authored, it's never "fixed" because of our plant genetics. As soon as the player enters it, it starts reacting to them and every single thing they do gets reflected back at them in some way. 

The other biggest challenge is that we have a fundamental impedance mismatch with the dominant funding models in this space right now, e.g., publishers. While our overarching philosophy is that labor itself is valuable, the current style of game investment often attempts to get the actual development labor for free by including recoup clauses in contracts. A "recoup" means that the investor gets their money back before the developer starts to see shared revenue.

Some will argue that a publisher isn't buying your labor, they're just buying the “publishing rights”, but I disagree. Emphatically, I think this is messed up, and we've turned down publishing offers for Nectarmancer because of this, knowing that it puts us very out of step with the industry. I'm 42 years old, I've been programming professionally for 20 years, I've worked in every technical field imaginable, and absolutely nothing I've ever done is harder than making a video game. I do not think it is reasonable for an investor to get their money back if I cannot get my labor back. Part of “Labor Is Value” means that we can go do labor for somebody else and bring that back into our team. In a way, it’s a bigger bet on ourselves and it lets us do an end-run around the publishing model. If we can somehow get to launch and actually own our Steam release, then we’ll have won. 

Conclusion

Our plan now is to keep inching forward in development and making something we think is good, fun, and unique.

I'm nominally on Twitter but also on Mastodon. The best way to support us is to wishlist the game and join our email list, both of which can be found on our website.

Don Bellenger, Game Developer & Co-Founder of The Beauty Cult

Interview conducted by Arti Burton

Join discussion

Comments 0

    You might also like

    We need your consent

    We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more