Procedurally Generating a Universe

How about we become monsters together?

… all the universe conspires …

When a person really desires something, all the universe conspires to help that person to realize his dream. — Paulo Cuelho

This is the first entry in what is planned to be a series of posts inspired by my recent participation in a Diaspora FATE-based sci-fi tabletop campaign. This particular article is a very simplistic, high-level, mapping of a programming construct allowing for the generation of story elements.

The premise of science fiction has really spurred my inspiration forward to begin to create vast subsets of a universe for the purposes of telling a story that transcends the stars.

I have started a small programming project in my free time that uses the principles found in the Diaspora cluster generation process  and my love for Python in order to build upon the idea of generating an entire set of these networks of concepts, settings, and locations at various levels of existence, where nodes of a network relate to another network. This is in order to encompass the topology of all concepts and relationships from a high-level down to a low-level, from the geography of the universe down to the configuration of a social encounter.

This started as simple an exercise of object orientation, as in Object Oriented Programming (OOP). I started with what I decided to call a network, a base graph by which to call a single unit. This leads us to question how this fits together in the grand scheme of things.

Very simply, how do we describe a “node” in a universe? What we have is a very large topological space of individual topologies which themselves can be considered the very same thing.

In order for this to become analogous to the graph structure I called a network, the graph would itself be a set of vertices where each vertex is another network. Here is some simple pseudocode to start with.

class network {
  network parent;
  graph topology;
}

This code defining a network very succinctly defines what we want to be a base unit in our universe. Implementation in a language is straightforward, using any appropriate graph library.

This has been designed and can be considered as a recursive problem. But how do we stop this recursion: at which point do we consider having reached an atomic state of no longer being able to get a smaller topologies to describe a single item’s substructure?  We need a condition upon which to terminate recursion.

A naive method to satisfy this would be to generate a random number of nodes less than the current network’s number for successive networks: this would ensure an eventual termination. But let’s be clever. Why even terminate in the first place? There exists a concept in computer science known as lazy evaluation. This is the idea of only ever evaluating the exact composition of a variable or collection of things when it is needed and never before. What does this entail? This grants the ability to construct infinite structures: this grand construct of topologies does not need to end. It can end whenever the user deems it satisfactory enough a descent of concept maps.

Randomization is always nice, though, and even necessary. What use would a universe be if it was just a collection of static, unchanging graphs? What can we randomize here, exactly? The number of nodes in a topology can still be randomized, if the programmer wishes. The generation of the topology of a network, the definition of connections between nodes, can also be done in a stochastic manner.

For example, here is a very effective and length-independent manner of stochastically generating connections in a manner that is self-destructive so as to avoid the construction of a fully connected graph. First, define a seed object, a probability construct that is merely an encapsulation of an integer that can never go above 100 or go below 0. Initialize it to some number, say 50. Also define n as the number of items in a given network and that n subitems or nodes have already been created. As a sub-procedure of this network:

s = new seed object;
for i = 0 to n {
  for j = i to n {
    r = generate a random number between 1 and 100;
    if (r < value of s) {
      reduce the value of s by a large quantity (say, 25);
      add an edge between nodes i and j of the graph;
    }
    else increase the value of s by a small quantity (say, 2);
  }
}

Visualization of this space is a more ambitious project than what has been outlined in this post; this is merely a setup for the construction of the topologies themselves.

What do one of these topologies look like? Here is an example created by an implementation of these ideas in Python.

A network graph.

If a programmer wants to take this further, attributes can introduced to the nodes at any given time. Diaspora makes use of a collection of three Fudge values:

  1. Technology
  2. Environment
  3. Resources

A value of +4 in technology would mean a technologically-mastered society, whereas something like T-1 (technology at -1) would be modern day Earth.

Taking all of these ideas further, let’s generate the inner topology of a system in a Diaspora cluster, assign a unique two-letter ID to each node, and randomize the three attributes above for each node, as well as their size and colour. Furthermore, we can control the flow of connections such that centralized nodes in the graph are the most technological, resourceful, and environmentally sound entities.

So that about covers everything I wanted to cover in this little article. Just a source of inspiration for those roleplaying-loving programmers out there.

This entry was posted in Programming Articles and tagged , , , , , , , , . Bookmark the permalink.