Category Coding

The Poor Man's Dialogue Tree

As some of you may know, Lemma has an interactive dialogue system that lets you exchange text messages with an AI character.

I implemented every conversation manually in code (well, scripts) until this week, when I got fed up and decided to automate the process!

Like the last article in this series, my system has all the hallmarks of a Poor Man's solution: developed in-house, tailor-made, simple, and based on free and open source software.

The Poor Man's Gameplay Analytics

You don't want to take time away from your awesome game to write boring analytics code. So you either call up some friends, hire playtesters, integrate some 3rd party SDK (ugh), or just do without.

WRONG. You roll your own solution. Here's why.

Why you don't do without

The OODA loop models the way human individuals and groups operate. It goes like this:

  • Observe the situation
  • Orient your observations in the context of goals, past experience, etc.
  • Decide what to do
  • Act on your decision
  • Repeat!

After the initial act of creation, game developers operate under the same principle. You play the game and observe it, orient that data in the context of your goals, decide what to do, open your IDE, and put your plan in action. Rinse and repeat.

Auto-generating JSON serialization code in Objective C

I wrote this article for the Sidebolt company blog. Reposting it here for your reading pleasure!

Our latest game Skyward Slots makes extensive use of JSON. We send Gigabytes of it flying back and forth haphazardly between client and server over a WebSocket connection. At first, we wrote code by hand to pack and unpack each message. Later on we decided that life is too short for that.

In the beginning, we just dove into the JSON right where we needed it.

Simulating UIScrollView in Cocos2D

I wrote this article for the Sidebolt company blog. Reposting it here for your reading pleasure!

We publish our games on both Mac and iOS. Since UIKit is not available on Mac, we have to build all of our UI by hand in Cocos2D. One of the hardest parts to get right was emulating the UIScrollView bouncy scroll formula. Here it is in action:

There are tons of implementations available in nearly every language and framework, but few of them nail all the important properties of the UIKit scroll:

My Biggest Fear for the Future of Human-Computer Interfaces

I recently had to install and configure an 18-node OpenStack cluster, a process which involved a lot of SSHing and text-editing in terminals. I thought about learning Vim, but I was afraid of the incredibly steep learning curve, so I made do with GNU nano. It's not at all powerful, but it's easy.

Eventually I realized, "This is my job. This is what I do every day. Why am I holding off on learning something now, thinking it will slow me down, and that I'll have time to learn it later? It's not like I'm anticipating a major career shift any time soon."

Mac and Linux Support

How's everyone doing? I'm doing okay. It's a Monday. Hope you're doing okay too. Surviving Sandy aftermath, school, work, and whatever other forms of oppression you may be under.

I don't have anything pretty to show for the past... wow, it's been three weeks. I've been working on a very lofty addition to Lemma's feature bullet list. And that is Mac and Linux support, via the awesome MonoGame project.

Don't get too excited. There is a ton of work left to do before this becomes a reality. But after a few weeks' work, I do know a few things:

Allocating large arrays in .NET

I experienced a strange memory issue with Lemma this week. Memory usage skyrocketed each time I loaded a level; it never dropped back down.

Now granted, I am definitely the garbage collector's worst nightmare. (I'll just say this: closures. Closures everywhere.) But at this point I am setting fields to null all over the place and manually calling GC.Collect() after unloading a level, all to no avail.

Enter the .NET Large Object Heap. See, the .NET garbage collector actually compacts the regular .NET heap by relocating small objects to fill the fragments. For exceptionally large objects, it's simply too expensive to relocate them, so the runtime allocates them on the Large Object Heap, which is not compacted.

Scary Monsters and Nice Clouds

Nice Clouds

I got sick of my old pixelated skybox powered by Google Images and decided to make a real one. I used Spacescape to generate a sufficiently trippy outer space skybox, chopped up some cloud photos in Gimp, fought with my code for a couple hours, and wha-la:

Scary Monsters

What's that glowy green thing you say? It's the new monster I just added, creatively named "the vine". See that string of dark blocks coming out of it? It snakes its way to you and basically tries to constrict you to death. Here's another screenshot of its handiwork after running for a minute or two.

Finals week

Sorry, no news to report on Lemma this week. School is keeping me busy. But I thought I'd share some of the projects I'm working on for school, since they're kind of cool and actually somewhat related to Lemma. First up: a 3D rapid prototype of the original toon-style Parkour Ninja!

Here's the model rendered in Cinema 4D:

And here it is printed out in 3D:

Quick update - Alpha inbound soon!

This week was a lot of under the hood improvements. The voxel engine got a TON of performance optimizations, which allow my Nvidia GTX 260 to render my test scene at 100-200 FPS.

Screenshots:

New features:

  • Rough-draft tutorial level with instructions and whatnot.
  • Fullscreen toggling on-the-fly by hitting F11
  • Rudimentary fog effect

Performance optimizations:

  • Voxels are now rendered as surfaces, rather than complete cubes. This lets me cull a lot of unnecessary geometry.
  • Voxels are now split into chunks. This lets me easily implement frustum culling and view distance, which helps tremendously with shadow map rendering as well.
  • I fixed some bugs in the voxel modification code, making voxel modifications of up to 100-150 cells practically instantaneous.
  • Shadow maps and reflections are now rendered every other frame. It's a hack, but the important thing is that the gameplay is responsive.

My biggest development challenge was my battle with fullscreen toggling and graphics resource management. Switching from fullscreen to windowed mode, the entire XNA GraphicsDevice is invalidated, along with every vertex buffer, texture, shader, everything. So that was interesting.