I have never and will never claim to know how to program anything. Recently, however, I found myself beginning a game project with several of my students, none of which are programmers themselves. The idea was to get their hands on a real game project, one where they could use their artistic talents to compile something more than the rendered scenes and concept art pieces they had been working on. Having done art for a few indie projects in the past and after downloading the latest free version of the Unity engine, I was in the mood to try something new, so I volunteered to handle the in-engine scripting…
If I kept everything simple, how hard could it be?
Kind of what I look like programming...
After having my player nudged to death a few times, I took to a forum and asked the programmers there how to get my enemy to ignore the player for a few seconds. This is where I learned my first important lesson about programming: how to talk to programmers. This is not to say that I have never chatted with a programmer in the past, most of my previous game art was handed to a programmer friend of mine to be added to his engine. Trying to explain your artistic vision to another artist is one thing, but doing so to the engineer that is going to make it happen is another.
Programmers; let me clarify that, REAL programmers; are magicians. They can get a game character to do just about anything you can envision. They can make anything happen in the world you’ve created, but you have to know how to talk to them. The first few times I contacted the scripting forum, I got code that did a great many cool things, but not quite the things I wanted. Therefore, I learned to clearly and concisely give specifications on what I wanted out of each script. Soon, I was getting great feedback that worked well in my game, even if it was mixed with a few backhanded comments on how my code was “redundant.”
The next thing I realized was that much of my code was REUSABLE! Holy cow! What a great way to work efficiently! At this point I know only a few basic things: instantiating objects, triggering things with collisions, using raycasting, creating AI that patrols with waypoints then follows the player when they are nearby, and some methods of activating/deactivating things with Booleans. I have used and reused the scripts that do these things for just about every enemy and player ability I have created. Every piece of enemy AI in our game was a combination of some or all of those functions. Looking through other codes, books, and forums became my method of hunting down functions to paste into my scripts, modifying them to fit the game. While I was limited in what I could do, I got a working set of enemy AI’s by understanding the modularity of the scripts I was using. This worked well with my background in 3D modeling, where you create one object then paste them all over your scene to cut down on time and the need for custom objects everywhere in a scene.
The next thing I learned was that there are a million ways to solve one problem when using code. Like I said before, talking in scripting forums yielded some helpful but slightly backhanded feedback. Likewise, talking with programmers I knew seemed to yield arguments that went something like:
“What do you mean you’re doing it that way…you should do it THIS way!”
“But it works fine…”
“Yeah, but my way will make it work better!”
“But it’s doing the exact same thing…”
Basically...the consensus seemed to be:
Talking with artists that have encountered similar experiences, they told me that since there are so many ways of doing something in a program, arguments often arise from the fact that everyone thinks that their solution is the best. As designers we’re familiar with this phenomenon: tell fifty artists to draw a unicorn, and you won’t get the same unicorn twice. Occasionally a fight breaks out over who has the best unicorn. Using the forums was an interesting experience akin to being in design school all over again and putting my code in front of a panel of critics. As I said before, clear communication became the key to getting my work done.
The last thing I learned, but possibly the most important of all, was to accept mistakes as “happy accidents.” These accidents ranged from amusing occurrences of not-quite-working code, as in the case of an enemy spawner that shot thousands of enemy creatures into the air like a fountain (which I now greatly regret not taking screenshots of), to things that actually are better solutions than you had planned. Yet again, this is something you learn as a designer: things don’t always come out how you plan but can make your work even better. In game design especially, when you are indirectly designing the experience someone has with your game, this knowledge is hugely important. This is why we playtest games. When I was coding a set of shark enemies, I planned on having them charge the player, who would sidestep the shark. I was trying to program the shark to go in a direction then forget about the player but continue to move in the direction it had originally charged, then turn back when it collided with an object. Playtesting with this enemy showed that I had not made it charge past the player at all, but had accidentally made it swim quickly towards the player, but get scared off whenever the player shot it with a harpoon. I thought this was a much better behavior for a shark, and having three of them in the scene, each set to charge the player at a different time interval, created a tense experience for players.
I will have dreams of being attacked by man-eating blocks
I clearly have a lot more to learn when it comes to the other half of game development. But as an artist to whom the engineering half was formerly a vague and mysterious place, I would recommend that all game designers and artists make a similar journey. Not only is it necessary in many standard engines, but it is an experience that will help your ability to design and communicate with your team.