ProcJam 2018

The annual event where we get together to make things that make things!

http://www.procjam.com/







Roguelike Celebration 2018

Last weekend I was at the 2018 Roguelike celebration in San Fransisco. There were talks from developers and fans, including a close look at Ultimate ADOM, a preview of plans for Dwarf Fortress, and a dive into the Nethack source code.

There was also an arcade set up with a bunch of different roguelikes, including original-hardware VT100 terminals connected to a remote server running Rogue and Hack.

The talks were streamed live, and the recorded videos will be posted on YouTube in the near future. (Until then, you can watch some of the talks on Twitch.)




Preliminary Poetics of Procedural Generation

I recently gave a talk about my theories about how we can express meaning through the processes of procedural generation. I called it “Poetics of Procedural Generation” in the Aristotelian sense of a poetics being a theory of literary forms. 

We need, as Mike Cook has said, better ways to talk about procedural generation. For starters, I object to the mutually-exclusive order-versus-chaos framing of procedural generation that I sometimes see thrown around. I think the reality is closer to the Apollonian and Dionysian balance I discuss in the talk: dice and patterned tiles can and do co-exist.

The talk also covers my views on how we can discuss the different forms of  Complexity, Form, Locus, and Variation in procedural generators. Each of those probably deserves its own post, so watch the video (or wait for me to write it).

If you’d rather just read the paper, I’ve posted it online too: https://isaackarth.com/cv/DiGRA_ProcgenPoetics_20180722_conference.pdf




Expressive Temperature

This post by Robin Sloan is interesting for three reasons.

First, it explains sampling temperature. This is a common term in machine learning: low temperature produces the most typical, cohesive results, and a high temperature produces the most novel but least likely to be cohesive results.

One of the points I’ve tried to make over the past year or so is that the distributions we use to generate things is a frequently overlooked way to give more interesting results. The same generator, with different temperature settings, can produce very different results. You can expand the expressive range of a generator by viewing the generator properties as variables that can change over time and space.

Second, the post is about varying the temperature within a single generated artifact. We don’t have to use the same distribution for the entire thing! Consider a map generator for a fantasy RPG: maybe we set the temperature low in the middle of the map so the player starts out in familiar terrain, and then increase it at the edges, so the really wild results are encountered the further the player gets from the start.

Third, Robin uses the generated samples as part of a collaborative composition process, where both the computer and the human composer have a say. This kind of centaur workflow is often more interesting to me than fully-automated generators, because:

  • This is a more practical use of procgen: humans have plenty of tasks that they could use a little assistance with, and relatively few that AI can handle on its own.
  • It sidesteps the hard problems that we already have good human solutions for and lets us work on the problems that machines are better at. Humans are great aesthetic pattern matchers but bad at serendipity. Computers are the opposite.
  • Constructing the interface language between the human user and the machine helps think through what the generation problem actually is.
  • And if we do want to fully automate it in the future, we have obvious places to start work.

https://www.robinsloan.com/expressive-temperature/




Kozinarium - Procedural Creature Generator

Denis Kozlov’s recent Procedural generator is a nicely expressive generator that makes creatures, rigs them, and then animates them.

I’ve posted about Denis’s previous work on generating aircraft, but while detailed hard surface modeling can be time-consuming, creatures have an additional set of constraints that leave me quite impressed with this new project.

As Denis describes it, the development process involved the distillation of an artist’s previous knowledge into a form that can be explained to the computer. Of course, the first step is that the developer has to understand the process themself.

There are two key points that I struck me in his writeup. The first is “recognize the patterns” or what I’ve been calling the underlying structure of the thing you’re generating. Figuring out what order to generate things in, what part is the steel frame and what part is the windows will guide the creation of the generator.

Second, creating “something seriously new” takes a level of understanding that goes beyond what tools are immediately available. In my opinion, this is particularly important when creating a tool that lets you do something new. Copying the existing ways of doing things tends to lead to getting stuck in the local maxima that has already been explored.

It’s one reason why I still use pencils and paper for designing generators: using a medium for design with completely different constraints than the medium for implementation helps you create a vision that isn’t limited by the easy affordances of the tools you are using to implement it.

Denis has a vision of a universal high-level content creation system, one that lets the user work in natural concepts that the machine understand the semantics of. (I’m reminded of the design ideas behind Ivan Sutherland’s Sketchpad.)

https://www.the-working-man.org/2018/04/procedural-bestiary-and-next-generation.html




2008 SG Interactive Procedural Street Modeling 

The tensor field street generation I talked about previously originally is from this research by Guoning Chen, Gregory Esch, Peter Wonka, Pascal Müller, and Eugene Zhang.

It uses tensor fields, as I discussed last time. You can see how the tensor fields let the generator generalize its knowledge of what direction roads should follow in each region: instead of the user having to hand-draw each route, the tensor field derived from the major roads can smoothly interpolate across the space.

This interpolation in space is one of the things that I find fascinating about generativity being applied to design problems: when we open up the ability to smoothly travel from point to point rather than moving in big, discrete steps, we gain flexibility and expressiveness.

They also use it to build an interactive tool that gives the user instant interactive feedback as the road network is edited. Smart interactive tools are one of the other big things I’m interested in about procedural generation. Tools that help artists by taking care of the minor details while still giving the users control over the direction and goals of the overall project–and feedback when something might go wrong with the current design.




Space-filling tangent field

Sometimes, someone comes up with a technique that seems so obvious in retrospect that you wonder why you haven’t seen it before.

It’s not new (this ACM 2008 paper describes the technique) but if I’ve seen it before I didn’t remember it. Or maybe I just connected to the context in the right way this time.

So, what the heck is a tangent field and how can you use it to generate a city? A vector field is a field of vectors–that is, for each point in the space there is an arrow pointing in a direction, which can be shorter or longer. This should be fairly easy to understand if you’re already familiar with vectors: it’s just a bunch of vectors that each have a position in space. They can be useful for a lot of things, such as wind simulation, pathfinding, and crowd simulation.

A tangent field is a vector field on a surface, where the vectors are in tangent space–for a flat plane they’re lying flat on the ground. The city generator Stijn Raaijmakers made works by taking the weighted average angle (with the weight as 1/(r*r) where r is the distance to each tangent attractor) and generating a building there either along the tangent angle or perpendicular to it. This creates a densely packed space to sample from to give a degree of order to the placed buildings.

Packing problems come up quite a bit in procedural generation, especially where you’re trying to fill a space with content and don’t want any unsightly gaps. (There’s non-spatial applications of packing problems too, but we’ll leave that for another day.) Stijn’s generator reminded me that there’s a lot of useful research to draw on out there.

https://twitter.com/bugshake/status/996509163302866945




Summer ProcJam

Want to participate in ProcJam but you’re too busy in the fall? Or maybe you just want to make stuff that makes stuff twice a year?

You’re in luck! This summer there’s going to be another ProcJam a month from now. The ProcJam website has more details (plus a nice redesign).

ProcJam is, as you might expect, one of my favorite events, so I’m really looking forward to seeing what the summer crowd makes.

http://www.procjam.com/




Nethack 3.6.1

I wasn’t really expecting to see this today: The NetHack dev team have gone and released an update. Mostly bugfixes, but this is NetHack so there also new features.

Sadly, they’re dropping support for some older platforms because they don’t have a current maintainer to manage the port. By older I mean things like “Atari” and “OS/2″. They’re also moving to ANSI C. Which is maybe the most significant change, since there’s source code in there that literally dates back to the early 80s, long before the C standard.



Yeah, at this point it’s identical to what Loren described here on twitter.

This is in javascript because I wanted to test some es6 features I haven’t used before.

A rule is a 2d array containing values of 0, 1, 2, or 3:

Here’s the JS that applies the rule to each cell:

Every step, for each cell, we loop through the neighboring cells in its Moore Neighborhood (the 8 cells around it, not counting itself).

We count the number of neighbors that have 1s and 2s.

We use the 1s value to pick a row in the rule array, and the 2s value to pick an element from that array. (That values is stored as ‘outcome.’)

The outcome of 3 is “stay the same,” so we just return the cell’s same value.

Otherwise, we return whatever value was in the rule table at rule[ones][twos].

For the non-programmers reading this, just read it as “each cell gets a new value determined by counting how many of each type of neighbor it has.”

Future areas for expansion I might tackle: random chance in rules, randomly setting a few cells to random values each step, adding history as a rule input, adding more possible states (represented by a larger color palette), having cells’ colors determined by combinations of their neighbors colors.

Thanks for the question :)