Procedural Names

I’m not quite ready to start talking about my current game project, but one thing I can say is that it requires the ability to generate names procedurally. Of the several methods I’ve researched, Markov Chains seem to be the most promising. Among other things they can be used to generate random music, text, and individual words. We’ll be concentrating on individual words.

A Markov Chain describes a state machine that can transition to the next state based only on the current state and probabilities. Stated simply, this method works by analyzing input data to build up a table of states and some probabilities. Given a current state, the next state is determined based on the probability of that state as found in the sample data.

Drilling in a little deeper, to use Markov Chains for generating random names we can use a large set of names as input data. Our system will analyze these names to determine the probability of a letter following another letter. We can then start with a random letter and pick the next letter based on those probabilities, and the next, and so on. Using a single letter like this is said to be first-order. We can also use two letters, or three or more for second-order and third-order systems. A higher order will produce random output that more closely resembles the input.

Let’s build a second-order probability table using the names “Domitrovich” and “Dombrowsky” as input.

Starting with domitrovich we grab the first two letters do and use that for a state. The next letter is m.  So far we know that when the state is do, there is a 100% chance that the next letter is an m.

The next two letters are om, and the letter following is i. So now we know that when the state is om there is a 100% chance that the next letter is an i.

Following this same process we end up with this table:

State Following Letter Probability
do m 1.0
om i 0.5
om b 0.5
mi t 1.0
it r 1.0
tr o 1.0
ro v 0.5
ro w 0.5
ov i 1.0
vi c 1.0
ic h 1.0
ch end_of_word 1.0
mb r 1.0
br o 1.0
ow s 1.0
ws k 1.0
sk y 1.0
ky end_of_word 1.0

 

Note that the om and ro states each have two instances with different following letters.

We can now use this table to build a random name. Our word starts with a random 2-letter state. We use that as a key into this table to grab a random following letter based on the probabilities. We add that letter to the end of our word and use the last 2 letters as our new state and repeat the process until we reach the end of the world. For example, starting with tr:

State Following Letters Word
tr o tro
ro v, w trow
ow s trows
ws k trowsk
sk y trowsky
ky end_of_word trowsky

 

With two names as input we won’t get much variety, but with a hundred or more we get some very good random output that strongly resembles the input.  Here is some example output using a list of 400 Ukrainian surnames as input.

Anovsky
Ragoniak
Stepkap
Stutkovich
Tulinovich
Vichuna
Buchalk
Rovichal
Pandamar
Popolek

 

We can expand this basic algorithm to improve the output quality:

  • Expand the probability table by including word beginnings and make sure the output words always start with one of the word beginnings from the input data
  • Identify consonant and vowel patterns in the input data and ensure the generated word follows one of those patterns.
  • Allow for minimum and maximum word lengths.

 

I’m not going to go through all of the code for implementing this, but it’s all included in the downloadable sample project.

Create a GameObject Image Using Render Textures

On occasion when making a video game there is a need to display a texture that contains an image of a 3D game object. For example, to display in a toolbar, or chat message or something similar. These images could be created statically by your artist, but sometimes the image needs to change based on something happening in the game, or there is some other compelling reason where runtime creation is required.

Render Textures are a straightforward method for creating an image like this at runtime. I’ll spend the rest of this post describing how I do this sort of thing. I’m not going to do a step by step tutorial. I’ll mostly just describe the actual rendering part, and you can look at the code for the rest.

First, we set up a camera that will be used to render the object. I usually make it orthographic and fill with a solid background color, but you can really do anything you want. I also set up a single light. The camera and the light all get their own layer to work on, and the main game camera has its culling mask set to ignore that layer.

Here are the settings I usually use. Note the layer and and culling mask. Also, you’ll need to remove the Audio Listener or you get complaints from Unity about having multiples.

ObjectImageCameraProperties

To render the object, we first want to clone it. This lets us change the object’s properties at will without messing with the original.

GameObject gameObject =
  GameObject.Instantiate(prefab, position, rotation) as GameObject;
gameObject.transform.localScale = scale;

We instantiate the object at the desired position and rotation, then set the scale. These values need to be set so the object is positioned in front of the rendering camera. You can really do whatever you want here, even add multiple objects and lights and set up a whole scene.

Now we need to make sure the cloned object, and any children, are in the layer that the camera renders. So we set the layer by calling this function, passing in the cloned object.

void SetLayerRecursively(GameObject o, int layer)
{
    foreach (Transform t in o.GetComponentsInChildren<Transform>(true))
        t.gameObject.layer = layer;
}

Now we get to the fun part. We could create a render texture in the editor and assign it to the camera, but Unity provides a nice way to acquire a temporary render texture with code. I believe it was designed to simplify post processing effects, but it works equally well for our needs.

camera.targetTexture = RenderTexture.GetTemporary(128, 128, 16);

RenderTexture.GetTemporary allows us to acquire a temporary render texture from a pool maintained by Unity. Here, we’re asking for a small texture with a 16-bit depth buffer. You can check out the documentation for additional parameters and other information about how it works. It’s worth mentioning that if you ask for a format that isn’t supported the texture will come back as null without raising any errors (at least it did for me). So it’s a good idea to check for a null return value and deal with it accordingly.

We assign the temporary render texture to our camera’s target texture. This means that when we tell the camera to render, the results will go to our render texture instead of the screen.

And the render comes next.

camera.Render();

This will render everything the camera sees into our render texture. To recap:

  • We’ve set up a camera on its own layer.
  • We cloned the object we want to take a picture of.
  • We positioned the object in front of our camera, and changed the object to the render camera layer.
  • We acquired a temporary render texture and assigned it as the camera’s target texture.
  • We told the camera to render.

So at this point we should have our object rendered to the render texture. Now we need to get that object into a texture.

RenderTexture saveActive = RenderTexture.active;
RenderTexture.active = camera.targetTexture;
float width = camera.targetTexture.width;
float height = camera.targetTexture.height;

Texture2D texture = new Texture2D(width, height);
texture.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);

texture.Apply();

This code saves the active render texture, makes our render texture active, creates a new Texture2D instance, then copies the pixels from the render texture to the Texture2D.

Finally, we call Texture2D.Apply to actually perforom the pixel copy.

All that’s left now is to clean up after ourselves by restoring the previously active render texture, releasing the temporary render texture we acquired earlier, and destroying the cloned game object.

RenderTexture.active = saveActive;
RenderTexture.ReleaseTemporary(objectImageCamera.targetTexture);
GameObject.DestroyImmediate(gameObject);

And that’s about it. The trickiest part is getting the object positioned and rotated properly in front of the camera so it looks good.

Here is a sample project that implements this. It includes a nice prefab for setting up the camera and everything.

So there you have it. Enjoy.