In this blog post I’ll talk a bit about prototyping games or apps and moving quickly when stuck in a tricky programming problem.

I’m currently prototyping a circular puzzle game. Part of the game is about matching colors to their neighbors. I wanted a way to start the level by randomizing the blocks while having no neighboring tiles that were the same color.

random tiles example

However, I didn’t want to spend the time to figure out if there was an existing algorithm to do this. I wanted to keep coding and figuring out more important mechanics to the game, so I just made a quick while loop that would keep randomly shuffling until it found something.

The loop took a long time to run… Sometimes several seconds or more.

I realized that the while loop was sometimes going through hundreds or thousands of iterations. Now, I didn’t know how to visualize how complex of a problem I was trying to solve. It could have been simple or it could have been vastly complex. My goal wasn’t to visualize this problem. Instead of getting distracted on a problem whose complexity I didn’t know how to guage, I decided to cobble together a quick hack.

So instead, I wrote a Lua script that ran iterations of the while loop until it found some. Then, whenever it found a true result, I simply stored those combinations in a table. I ended up only finding 13 combinations. Then when I run the game, it just chooses one out of the table randomly. (Each number represents a color.)

shuffleTiles = {
{4, 1, 4, 1, 3, 2, 1, 3, 2, 3, 4, 2},
{2, 1, 4, 1, 4, 2, 3, 2, 3, 1, 4, 3}, 
{4, 3, 4, 3, 2, 1, 3, 2, 4, 1, 2, 1}, 
{4, 1, 3, 2, 3, 1, 2, 4, 3, 4, 1, 2},
{3, 2, 1, 4, 1, 2, 3, 4, 2, 3, 4, 1},
{2, 4, 3, 4, 2, 1, 4, 1, 3, 2, 3, 1},
{4, 2, 3, 4, 2, 1, 3, 4, 2, 1, 3, 1},
{3, 4, 1, 3, 1, 4, 2, 3, 2, 1, 4, 2},
{3, 1, 4, 3, 2, 4, 3, 4, 1, 2, 3, 2},
{4, 1, 2, 3, 1, 2, 3, 4, 1, 2, 4, 3},
{4, 1, 2, 4, 3, 1, 2, 3, 4, 3, 2, 1},
{4, 3, 1, 2, 3, 1, 3, 2, 4, 2, 4, 1},
{1, 2, 4, 3, 1, 2, 3, 4, 1, 2, 3, 4}
}

Since I can also rotate the board, this results in 12 x 13 = 156 starting configurations. This is much faster than running a slow algorithm at run-time (which would last for an unpredictable amount of time) and gets me back to coding the important bits. 156 combinations is enough for me to test the game on.

I call this “random enough”.

Later on, as development continues, I can come back to solving a fast algorithm or researching if there is an existing sorting algorithm that would suit me. But if it is good enough, then I might not even need to. At this stage, my most important goal is to find a fun set of rules that results in a fun game.

This is one of the principles in “How to Prototype a Game in Under 7 Days”. “Nobody knows how you made it, and nobody cares.”

The board-sorting is an important detail, but how it is sorted is a trivial one and it could potentially have cost me days of tinkering and research. It is fun to solve problems, and easy to get distracted in ways like this. When prototyping something new, my goal is to continue moving as fast as possible. You don’t want to get stuck on one little problem when you have a whole bunch more work to do.

There are two lessons here:

  1. If you have heavy calculations to make that result in a relatively small output, it may be better to front-load the calculations and store it as data.
  2. Don’t get stuck on side problems. Focus on the core problems. (Which for me is finding a fun game mechanic and designing the interactions.)

A Manual Progress Bar in Scrivener

by Chris Lesage on November 18, 2013

In this blog post I want to show you a cool trick for making semi-graphical Status labels in the writing program Scrivener, and then explain some of the reasons you might want to do this. I used it to make a manual progress bar.
scrivener_status_screenshot

I use Scrivener and Markdown to write my blog, as well as writing documentation and training material. If you don’t know, It is a structured writing program – usually used for novels, scripts, screenplays and academic writing – which can output to PDF, HTML, Markdown, LaTeX, ebook, Final Draft, Word formats and more.

So it is also a great tool for blogging, research, course notes or technical documentation for software.

I’m currently transitioning the help docs for a Maya plugin I’m working on from Google Docs into Scrivener. The revisions/snapshots and structured nature of Scrivener make it ideal for documents which need frequent updates.

Scrivener already has a progress bar which is based on target word-count. That’s fine if you are aiming for a particular length in a long novel or an essay with a word target. However, you don’t always know what your target is before-hand. Especially when you are writing a lot of shorter documents such a blog posts, course notes, technical documentation or training tutorials.

I prefer having manual control. So to simulate a percentage progress bar in Scrivener I created 6 “Status:” options using the following Unicode characters:

Note: If you are setting this up, you don’t have to enter the number codes. Just copy/paste the characters in “Project -> “Meta-Data Settings” and then click on the “Status” tab. You can paste the character there to make these statuses. The numbers are there only for reference in case they aren’t displaying properly in your browser.

▢ - White square with rounded corners
Unicode number: U+25A2

█ - Full block
Unicode number: U+2588

░ - Light shade
Unicode number: U+2591

▒ - Medium shade
Unicode number: U+2592

▢▢▢▢▢ 0%
█▢▢▢▢ 20%
██▢▢▢ 40%
███▢▢ 60%
████▢ 80%
█████ 100%

Or if you prefer increments of 25%:

▢▢▢▢ 0%
█▢▢▢ 25%
██▢▢ 50%
███▢ 75%
████ 100%

And some extras:

░░░░░░░ done (published)
▒▒✘✘✘▒▒ scrapped

Click here to see the image if your browser isn’t displaying the unicode characters properly.

Here’s how this looks in Outline mode: scrivener_unicode_screenshot

So Why Do This?

Sometimes your progress depends on elements that are not related to the word-count, such as data, graphs, multimedia elements that another designer is creating, or any other amount of tasks that may need doing.

There is also a big difference between “finished writing”, “finished editing” and “ready to publish”.

Also, you may have a lot of words or notes that need a LOT of editing. Your rough notes shouldn’t necessarily count towards your progress. Maybe you will write 5000 words just to edit it down to 2500. Some days you will end up with less words, but you are still technically making forward progress.

So using “Status” graphically is a way to manually set your progress, in a sort of eye-catching way.

You can also sort by status with this. The black bars go in the correct order, and the “done” and “scrapped” shaded bars go to the bottom, but above 0%.

If you want to search for other unicode characters that you can use, check out this unicode website. You can also copy/paste a character into this website to find out the unicode value.

I bet you can think of some other ideas to make some graphical reminders or just make your status labels more meaningful to you. Give it a try and let me know what you think in the comments.

Maya Python: Reset Selected Controls

by Chris Lesage on October 1, 2013

Reset Selected Script

I have a script snippet to share with you today. This is how I quickly reset all selected objects to 0,0,0,0,0,0,1,1,1 in translate, rotate and scale with the stroke of a hotkey command.

This is fantastically useful when you are animating! But it’s also for riggers, modellers or anyone working in Maya. Softimage XSI has this feature built in (Ctrl-Shift-R), so I made a little snippet to do the same in Maya.

First I’ll show the simple code, explicitly written for each attribute. And then for the Python fans, I’ll show how to shorten it using List Comprehension because why not? After the scripts, I’ll explain a bit more how it works. If you just want the script, just copy/paste this and use it. If you want to geek out about List Comprehension and PyMEL, read on…

Reset Selected: The simple version

import pymel.core as pm

def reset_selected(oColl):
    for oNode in oColl:
        try: oNode.tx.set(0)
        except: pass
        try: oNode.ty.set(0)
        except: pass
        try: oNode.tz.set(0)
        except: pass

        try: oNode.rx.set(0)
        except: pass
        try: oNode.ry.set(0)
        except: pass
        try: oNode.rz.set(0)
        except: pass

        try: oNode.sx.set(1)
        except: pass
        try: oNode.sy.set(1)
        except: pass
        try: oNode.sz.set(1)
        except: pass

runthescipt = pm.Callback(reset_selected, pm.selected() )
runthescipt()

Reset Selected: The Fancy List Comprehension Version

import pymel.core as pm

def reset_selected(oColl):
    trList = ['.tx','.ty','.tz','.rx','.ry','.rz']
    sList = ['.sx','.sy','.sz']

    # o is each object, x is each attribute
    for attr in [(o, x) for o in oColl for x in trList]:
        try: pm.Attribute(attr[0] + attr[1]).set(0)
        except: pass
    for attr in [(o, x) for o in oColl for x in sList]:
        try: pm.Attribute(attr[0] + attr[1]).set(1)
        except: pass

runthescipt = pm.Callback(reset_selected, pm.selected() )
runthescipt()

Notes about this script:

  • Fully supports undo and redo.
  • There are 2 scripts below. Grab either one. They do the same thing.
  • Set it to Ctrl-Shift-R in your Maya hotkey editor. Don’t forget to set the hotkey to Python.
  • I personally use PyMEL instead of maya.cmds because it can generate a list of object pointers rather than strings, so it is a lot easier to use from an OOP point of view. Some studios do not use PyMEL, so be aware of this.
  • The pm.Callback() takes an argument, so instead of pm.selected() you could pass it a list of all your character rig controls, or all the locators in your scene, etc. etc.
  • Every iteration has a try/except on it, so that if your attribute is driven or locked the script will continue without failing.
  • You can also use makeIdentity() to quickly reset an object, but if some of your attributes are locked, this won’t work.

How list comprehension works:

  • List Comprehension lets you build up lists quickly by using [x for x in y]
  • But you can also loop over two lists at once with one line:
    [(x + y) for x in (1,2,3) y in (4,5,6)]
  • This acts like a nested iterator which will add each of (1,2,3) with each of (4,5,6) resulting in 9 combinations. (1+4, 1+5, 1+6, 2+4, 2+5, and so on…)
  • I then take those two combined elements to gather all the transform attributes for all of my objects.

How pm.Attribute works:

  • I’m iterating over two lists with my list comprehension so I need to combine it again, casting it as a pm.Attribute( object name + attribute ).
  • However, if you were explicitly setting an attribute it would be as simple as yourObject.tx.set(0)
  • You could also create your attribute in the list comprehension, but if you try and run the script on a shape node that has no attributes, then the script will fail.
  • You could get around this by including a try/except function inside the list comprehension or by filtering your objects for transform nodes only, but that is just becoming too complex for this little script.

In Summary

I use this hotkey all the time! I missed it from Softimage. Your animators are going to love using it too! Feel free to use it, and if you find bugs, improve it or rewrite it in MEL or maya.cmds let us know in the comments. Thanks!

The Fastest Way to Search API and Help Docs

September 24, 2013

You probably frequently visit at least one or two API documentation, help docs or reference websites when you are programming or learning a new language or software. Firefox and Chrome have a trick to use a custom search keyword in the location bar to quickly navigate API docs or any other frequently searched sites. If […]

Read the full article →

A New Demoreel & My Cartoony Face Rig Structure

September 9, 2013

(Update: I had to temporarily remove some unreleased face footage from my demoreel until the movie comes out. Whoops!) I just got back from an awesome summer vacation, travelling in South America! Now I’m back to work, developing some new Python animation tools and plugins (which I’ll blog about soon) and looking for new clients […]

Read the full article →

Manually Create a Single Maya Follicle in Python

February 22, 2013

Do you use Maya follicles to pin objects to your geometry? Are you still doing it the old way, by creating a Hair System and then deleting all the parts you don’t need? Below I’ll share my simple Maya Python script that creates and pins a single follicle onto a nurbs surface. (Jump straight to […]

Read the full article →

How To Stop Collapsing Vertices in Maya Post Normalization

May 14, 2012

So this is annoying. You are trying to paint weights in Maya using Post Normalization and a bunch of your vertices are collapsing to the origin! What’s going on!? Don’t fret. There is a simple explanation and an easy fix for this. But first, let’s look at what Post skinning is doing: “What is this […]

Read the full article →

Using a Unit Vector to Make a Cylindrical Foot Roll

April 3, 2012

Here is a tutorial that will demonstrate how to use a Unit Vector to animate the pivot point of a cylinder so that the cylinder will roll on its bottom edge in any direction. I’m using this technique for the feet of my Mini Mammoth rig, but it could also be useful for robot feet, […]

Read the full article →

Use K to Easily Navigate Your Maya Timeline

March 7, 2012

There are tons of features and hotkeys and hidden marking menus in Maya that are extremely useful but surprisingly seldom known. While everyone is talking about big new features, these underdogs can easily be forgotten. I just started a “tip of the day” with my animators at work because I realized that there are lot […]

Read the full article →