Week 3, oblique

This is an edi­tion of Robin Sloan’s video game devel­op­ment diary.

Welcome: to returning readers as well as everyone newly subscribed. If you missed it, week 1 sets up the moti­va­tion behind this project. All the pre­vious edi­tions are avail­able over on my blog.

The wonky k in the hea­dine at the top of the page doesn’t seem so wonky anymore. Maybe we’re get­ting a little wonky, too.


Wot I got

This week’s work pro­duced


Oblique strategy, part 1

Here’s one of my key ref­er­ences for the look of the map in Perils of the Overworld — and the game’s whole visual approach, really:

Oblique Drawing by Mas­simo Sco­lari

That’s Oblique Drawing: A His­tory of Anti-Perspective (!) by Mas­simo Sco­lari, which I picked up many years ago because, no kidding, I thought I might someday do a project like this! And here we are. I’m glad I kept it around.

It’s an odd book — academic verging on abstruse — and, in truth, I can’t follow all of it, but I love Sco­lari’s intro­duc­tion to the his­tory of oblique “anti”-per­spec­tive and its uses in archi­tec­ture and war — a way of drawing that does not dis­tort scale, and can there­fore serve as a prac­tical reference, a source of truth, a tool—and I love the illus­tra­tions he has assembled, pages upon pages of them:

Oblique Drawing illus­tra­tion

Oblique Drawing, Mas­simo Sco­lari

This one, in par­tic­ular, jus­ti­fied the book’s whole pur­chase price:

Oblique Drawing illus­tra­tion

Louis Ange, Plan d'une cam­paigne avec une per­spec­tive cavaliére, France, 18th century

Is it just me, or are Louis Ange’s forests … a tiny bit Super Mario Brothers?

Note the ter­mi­nology in the title of the illus­tra­tion above: per­spec­tive cavaliére, cavalier’s per­spec­tive. Sco­lari quotes France’s sixteenth-century Super­in­ten­dent of Fortresses (!):

No one should expect to see the method or rules of per­spec­tive in these works; mainly, because it is not part of a soldier’s pro­fes­sion to pro­duce them, and secondly, because the fore­short­ening involved would remove too much from the plans, whereas the entirety of these works lies in such plans and out­lines as shall be called “sol­dierly per­spec­tive.”


Oblique strategy, part 2

That’s all to estab­lish that oblique per­spec­tive has been part of this project from the start. One of my first lines of code sum­mons not a PerspectiveCamera() but an OrthographicCamera().

This week, I saw a link posted by John Oram, a.k.a. Bur­rito Justice, who is, among many other things, a great curator and cel­e­brator of maps. This link led me to a USGS pub­li­ca­tion called The Atlas of Oblique Maps, pub­lished in 1988, avail­able in its entirety online. (Be careful with that link: it points to a 250 megabyte PDF!)

This work is just unbe­liev­ably beautiful:

Atlas of Oblique Maps illus­tra­tion

The Atlas of Oblique Maps

For me, the appeal of oblique per­spec­tive is that it makes even an epic assembly like Cape Blanco look as though it could fit in the palm of your hand; like a model, even a toy.

The work in The Atlas of Oblique Maps isn’t just beautiful, but deeply human: there is simply no ignoring the fact that a par­tic­ular person drew these maps. I swear I can almost hear the scratch of the pen. The lines are sketchy, the ren­der­ings playful; they wouldn’t be out of place in a comic book:

Atlas of Oblique Maps illus­tra­tion

The Atlas of Oblique Maps

Isn’t this just the absolute best?

Atlas of Oblique Maps illus­tra­tion

The Atlas of Oblique Maps

This book sent me rushing to my computer, to the POTO code, to the map.

More about that in a moment. First, here is your weekly:


Sound snack

Sev­eral writing ses­sions this week began with me playing one of Jesse Solomon Clark’s draft com­po­si­tions and sort of “synchronizing” with the scene it suggested, so I asked Jesse if he would write a few notes about it. Press play, then read on:

Cre­ating music for a project early in its devel­op­ment is really a treat; there’s a rare freedom there to imagine tex­tures and scenes that don’t yet, and might not ever, exist. This phase is truly research and devel­op­ment for me, but these music sketches are often just as useful to my col­lab­o­ra­tors as they develop the work.

For this piece, I cre­ated a little film sequence in my head gleaned from the few details Robin pro­vided about this location:

Suddenly! We are in the middle of PORT FABRI, a bustling city of commerce. Things feel huge and new, full of pos­si­bility and danger, so: hard-edged per­cus­sive and plucked sounds, brash horn rips — all with an under­cur­rent of activity. Next, we encounter narrow streets and for­eign tongues, so: short and hectic musical phrases using dis­parate instru­ments from dif­ferent cul­tures that clash and argue. We pop out of an alley and arrive at the docks to wit­ness a fleet of ghost ships as they dis­ap­pear into the mist: cue the soaring and dreamy orches­tral strings that will take us to other lands to fur­ther our quest!

Jesse is right about these sketches being useful to his col­lab­o­ra­tors, i.e., me, because, in a very real sense, this theme has been co-creating Port Fabri with me all week. Pretty cool.


Oblique strategy, part 3

Okay, so I saw those sketchy lines in The Atlas of Oblique Maps, and I wanted them for myself. What next?

The graphics framework I’m using for the map connects, through a few inter­me­diate steps, to the GPU in your phone or laptop. The GPU (which stands for graphics pro­cessing unit, snooze) makes modern visual com­puting pos­sible using One Weird Trick: rather than work its way through the pixels in order, one at a time, it draws many at once — whole swaths of the screen, blorped into place.

This strategy is breath­tak­ingly efficient, but/and it raises a per­sis­tent question: how do you trans­late a qual­i­ta­tive aes­thetic goal like

into a pro­gram­matic “recipe” that each pixel can follow simultaneously?

My instinct — maybe yours, too — is to say, “Let’s draw some nice sketchy lines on the hills; some will be short, others will be long … ” but that’s the one thing we can’t do. There is no floating vir­tual pen. There are only indi­vidual pixels, and each one has to follow its own recipe, blind to its neighbors. It’s really very strange.

For a long time, I found the lan­guage of these recipes, which are called shaders, totally inscrutable; like, truly brick-wall difficult. This dialect of computer-ese just did not make sense to me. Then, last summer, in one of the more mem­o­rable learning break­throughs of my recent life, it just … cracked open.

So, here is a zoomed-in sec­tion of the new map, which now takes inspi­ra­tion from the sketchy lines in The Atlas of Oblique Maps:

Every pixel in the ani­ma­tion above is fol­lowing the same recipe, all in lockstep. There’s a pre­amble in which the pixel is col­ored pale yellow, or blue, or shad­owed by a mountain, but then, to deter­mine whether it should turn inky black to form part of a sketchy line, each pixel asks:

  1. Does my posi­tion on the ter­rain line up with the spacing Robin wants for these sketch lines? If so:

  2. Is the ter­rain beneath me steep — i.e., is it pointing more “out” than “up”? If so:

  3. Wait! Does a semi-randomized noise value indi­cate I should be skipped, rep­re­senting a broken part of the line? No? Phew. In that case:

  4. Turn inky black!

At each of those steps, there are many “knobs” you can twist to trans­form the appear­ance of the sketchy lines.

Maybe the lines should be longer, more continuous?

Maybe they shouldn’t be so orderly??

After get­ting the map to the point depicted above, I decided my excite­ment had sneakily mor­phed into procrastination. So, I’ll let it sit for a while now, and, in the next round of work, try to bring in some of the bold­ness of our lodestone, Eva­line Ness’s map from week 1:

Map of Pry­dain by Eva­line Ness

Map of Pry­dain by Eva­line Ness

If you’re curious about the shader code that draws these lines, you can click or tap to reveal it here:

// SKETCH LINES

// this determines line spacing
float zFactor = 1.0 - abs(vNormal.z);
float fractFactor = max(ceil(zFactor * 3.0) * 16.0, 8.0);
// translation: "when the normal's z-component is larger,
// the lines are spaced more widely"

float combinedCoord = (vWorldPosition.x - vWorldPosition.y);
float f  = fract(combinedCoord / fractFactor);
float df = fwidth(combinedCoord / fractFactor);
float fs = smoothstep(df * 0.5, df * 1.0, f);

vec3 noiseFeed = vec3( vWorldPosition.x / 13.0,
                       vWorldPosition.y / 11.0,
                       vWorldPosition.z / 17.0 );

// this calls a perlin noise function swiped from the internet
float dashNoise = noise(noiseFeed);

// step cutoff value of 1.0 means solid lines
// step cutoff value of 0.0 means no lines
float stepCutoff = 1.0 - abs(vNormal.z * 1.8);
// the multiplier there is important aesthetically
// 2.0 produced very sparse lines

float dashNoiseStep = step(stepCutoff, dashNoise);
fs += dashNoiseStep;
fs = smoothstep(0.9, 1.0, fs);

outColor *= vec4(fs, fs, fs, 1.0);

The map is still a long way away from where it needs to be … but even now, it’s fun to toggle back to week 1 and remember the rather dank artifact we started with 😝


Chasing a ghost

Ear­lier this week, I wrote a blog post about a par­tic­ular effect that I have often noticed, and admired, in film titles from the pre-digital era, which you can see here — the way the white logo­type “detours” through blue as it fades into darkness:

I’m including a link here because there’s a good chance that some of what I learned about the effect will find its way into POTO.


For as much progress as I made this week, I still feel very behind, writing-wise, so

Wot I’ll do

is keep writing. I have some thoughts on ~worldbuilding~ that I began com­posing for this edi­tion, but then sol­dierly per­spec­tive took over, so I’ll save it for next week.

From Oakland,

Robin

P.S. Most of The Atlas of Oblique Maps was drawn by a car­tog­ra­pher named Tau Rho Alpha, who turns out to be an inter­esting character. Clicking around, I found another USGS doc­u­ment he pro­duced, this one in 1991. The PDF appears to be — get ready — 

The Hyper­Card stack

What a beautiful, dizzying artifact.


This has been an edi­tion of my video game devel­op­ment diary, sent by email every few weeks. You can subscribe: