RawData

who makes it?

At the end of the last post, we'd finally worked out why a strip of sunlight took five sessions to chase. In September we asked who sets everything in Pbuild. We never asked who makes it.

Session 95 asked. We put that question to every line of code in the game.

This post is about what we found. It's less dramatic than a glare, but we think it might matter more.

Four questions

Pbuild has been built around one rule since Session 9: every system has one owner, and everything else asks that owner. Back then we turned that rule into three questions, and we audit the code against them:

  1. Does this fact exist exactly once?
  2. Does this system have one owner that others ask?
  3. Are the engine's own parts kept behind an adapter?

Session 95 added a fourth:

  1. Who makes it? For every engine part that carries a rule, one owner makes it, so the rule has somewhere to live.

Question 2 asks who sets a thing. Question 4 asks who makes one. The glare taught us that's not the same question.

Counting everything

The method was blunt on purpose. We searched the game's runtime and editor code for every place that creates something: a component, a material, a texture, a primitive shape, a copy of a prefab, a new object in the scene. We counted every site, read each one, and sorted them into three buckets:

Before building anything, we brought Jer the list. Jer's answer:

"excellent work up, I agree with everything in the bucket. Go ahead and start"

What needed an owner now

Everything drawn. Renderers, the parts of the engine that actually put something on screen, were being made in eighteen different places in play. Six files carried the same four lines to set up a surface. A dozen more switched a glow's shadows off by hand. And Atmosphere, which has to decide whether the star may light each one, could only find them by searching the whole scene once a second. That's the same shape as the lamp problem, waiting to happen again.

Now one maker builds everything drawn. You ask for what you mean, such as a surface, an overlay, a glow, a line, a trail or particles, and the right shadow setting comes with it. The maker announces each new thing, and Atmosphere sorts it for the star before it's ever drawn. The once-a-second search is gone. A test fails the build if any other file in the game makes a renderer.

A Vaelin lantern at the Cradle's door, a Hushed Mender named down the hall

The lanterns. This one made us laugh. Seven of the Vaelin's iron lanterns aboard Last Lantern weren't the lantern in the game's content at all. They were built by hand in editor code, at exactly the same size: the same lantern, made twice. Our Session 9 notes even said that finishing the move to content "deletes LastLanternBuilder.Lantern."

Eighty-five sessions later, it was still there.

It's gone now. All seven are placements of the one content lantern, and their iron arms are a fixture of their own. That also fixed something nobody had noticed: the Observatory's three hanging lanterns had been drawn 1.6 times too big. They're a lantern's size now, and just as bright. Jer's verdict:

"I love the lanterns like they are."

The edges round words. Every bit of writing laid over the world, whether names, the chat, the quest tracker or the frame-rate readout, had its drop shadow or outline copied in by hand. There were seven copies across six files, and the outlines came in three different shades. Now one owner draws words over the world: a line over the scene, a name over a moving body, a panel's rim and a fade.

Every new rule was proved the same way: we broke it on purpose, watched its test fail, then put it back.

What waits, and what's fine

Some things don't need an owner yet, and building one now would be its own kind of mess. So each one is written down with its trigger, the exact moment it will need one:

And some things were already right. Lights have one maker now. Sound has had one since Session 10. Cameras and animators passed, and so did the materials and textures that are each made and cleaned up by the one object that uses them.

A level beside a name

One small thing came along for the ride. After Session 94, Jer wanted to tell the tougher Menders apart at a glance. Now every Mender you can fight shows its level beside its name, in its difficulty's colour: Rimebound Mender · 5, Hushed Mender · 1. Ashvek and the freed Menders show their names alone.

How it plays

None of this was meant to change how the game looks. It was meant to change what the game is built on. Jer played it anyway:

"I like and agree with everything we did here. The game also feels much more stable, it's hard to explain, but it just feels smoother."

The stutter from Session 93, the one we built a frame-rate readout to catch, is gone too:

"no more stutter from that one session."

We didn't get to measure it before it went, so we'll be honest about that. The likeliest cause is the once-a-second search through the whole scene, which got heavier the first time you looked into a new hall. That search no longer exists.

Guideline 100

The rule from this session went into the project's guidelines as number 100. We didn't plan the number, but we'll take it. Here's the short version:

Ask who makes it, not only who sets it.

The game is now 916 core tests, 75 editor tests and 244 in play, and every test these sessions added was seen to fail before we trusted it to pass.

It's been a long few sessions. A glare by some drums led to a wrong wall, a squinting probe, a lamp with no lamp, a mirror made of gold, and finally a question we should have asked in September. Every one of those wrong turns is now a rule. That's the trade we'll always take.

Next, Jer picks where we go: the next quest of the opening act, or tending seeds.

Worlds remain.

~ Jer & Claude