Ambienome Brain Dump

Lately, I’ve been focusing so much on Common Lisp itself, that I have barely spent any time on Ambienome, the whole reason I’ve been learning it. It has been so long that I can barely remember what I was working on. (Physics engine integration, I think?)

That’s no good, so I wanted to take some time to set my thoughts and ideas for Ambienome onto paper (so to speak). This will help me slide back into that mode of thinking, hone my ideas by putting them into words, leave a journal of how the game evolves, and maybe spark some interest in anyone reading this.

Caveat: you should not interpret any part of this as a promise or firm description of how the actual game will be. I’m just unloading my thoughts and ideas as they exist now. Everything is still subject to change, etc. Continue reading Ambienome Brain Dump

Physics Engine and Object Selection

This is the second part of my post about what I’ve been working on lately. In the first part, I talked about data structures and serialization. In this post, I talk about the physics engine and object selection via mouse picking.

For Ambienome’s physics engine, I’m using SquirL, a Common Lisp port of the popular Chipmunk 2D game physics engine. I’m not far enough along yet to know how well it performs in my own game, but from running the demos, it certainly seems performant enough for my purposes. If it turns out to be somewhat sluggish, many Common Lisp implementations can perform some pretty aggressive optimization, given the right type declarations. As a last resort, I could create an FFI binding to the actual Chipmunk library, although that might not be any faster than a well-optimized Common Lisp port. One benefit of a binding to Chipmunk would be using its new features that have not been ported to SquirL (which hasn’t been updated in 2 years).

Continue reading Physics Engine and Object Selection

Data Structures and Serialization

Lately, I’ve been tackling several separate, but interconnected, systems in Ambienome: data structures, serialization, object selection, and the physics engine. These are complex topics, so I’ve written this in two parts. In this first part, I talk about data structures and serialization, and in the second part I talk about the physics engine and object selection.

Data structure simply means the way some data is structured or organized, either in memory while the program is running, or when the data is saved to a file or sent over a network. Is it stored in a hash table? An array? An instance of a class? What slots/members does the class have? How are different pieces of data related to each other? And so on.

Serialization is a topic very closely related to data structure. Serialization involves converting from one data structure to a simpler data structure, usually some human-redable text or a raw binary sequence with some specific order or pattern. The reverse process, deserialization, involves converting the simpler data structure back into the original structure (or a similar one). Serialization is most often used when saving data to a file or sending it over a network.

Personally, I consider binary serialization to be a measure of last resort, to be used only when performance is absolutely critical. Binary formats are notoriously fragile and difficult to extend, especially if they are poorly designed.

Continue reading Data Structures and Serialization

Complicated Code and Creative Blocks

The past several weeks have been a struggle, productivity-wise.

First, I spent quite a lot of time working on proto-slots. That may seem productive, but the amount of effort I put into polishing and documenting it was way out of proportion to the benefit I would get from it. I think I did a pretty good job on that project, but I also recognize now that I was using it as a way to avoid actually working on Ambienome.

It was about three weeks ago that I realized what was happening, so I tried to force myself to focus on Ambienome. That didn’t really work, and I just ended up with a serious creative block. I spent about two weeks making almost no progress. My code had been accruing unnecessary complexity, mostly due to exploring a lot of unfamiliar territory (Lisp, and OpenGL), which made it difficult to work on when my motivation was not very high. Each time I would try to focus on Ambienome, I’d run into some obstacle, grimace, and reflexively go find some way to distract myself. (In hindsight, it was probably not wise to start a challenging new project at the beginning of winter, since my energy levels and motivation always dip during the winter.)

(Those two weeks weren’t a complete loss, though; I did beat a lot of games! :P If you’re curious: Dungeons of Dredmor, The Binding of Isaac, Limbo, Glowfish, Blocks That Matter, and a couple others that I can’t recall at the moment.)

Continue reading Complicated Code and Creative Blocks

Colored Shapes

I got a bit sidetracked while working on creature components, but still ended up making important progress for the overall system.

First, I created a new transform class by abstracting and cleaning up the shape class’s position, angle, and size attributes and methods. I also created a transformable “mixin” class, which can be used by any class that has a transform. (Lisp doesn’t have mixins in the same sense that Ruby does, but since Lisp supports multiple inheritance, you can get more or less the same effect by designing a class in a mixin-ish style.) The transformable class provides accessors for the transform’s position, angle, and size, so that you can treat them as if they were direct slots of the object holding the transform.

Next, I decided to enhance the shape class so that shapes can have a color. This turned out to be somewhat challenging, because of how I had designed the OpenGL wrapper classes.

Continue reading Colored Shapes

Shape Mesh Progress

Yesterday, I completed the code to generate triangle and circle meshes:

Screenshot of a rectangle mesh, a triangle mesh, and a circle mesh.

The triangle looks like it’s too small, but it fits perfectly in the circle, and the circle fits perfectly in the square. Yay, geometry! Of course, when building a creature, they can be scaled to whatever size you like, and the algorithms can produce meshes at any level of detail. Eventually, I’ll make it so the game automatically adjusts the level of detail based on the shape’s size on the screen.

As I mentioned in the previous post, these aren’t the only shapes that will be available, but they are enough to let me move on to other things. One of the core concepts of Ambienome is that I can program new shapes later, even after the game has been released. If I’m feeling really clever, I could probably leverage Lisp’s power to allow users to program new kinds of shapes, too. That’s not a high priority, though.

Today I’ll start code-sketching the concept of components and creatures. A creature is built from one or more components, which are basically shapes with some associated behavior. Components can be grouped to move together, and groups can contain other groups, so it’s essentially a “tree” (hierarchy) of transformation nodes, with each “leaf” being a shape. This is the same concept as grouping in SVG or Flash, or parenting in 3D software like Blender or Maya.

After weeks of just studying and debugging OpenGL, it sure is nice to be making visible progress again!

Adventures with the OpenGL shader pipeline

For the past several weeks, I’ve been learning “modern” OpenGL programming practices, by which I mean using a GLSL shader pipeline with vertex and fragment shaders.

Even before starting Ambienome, I was already somewhat familiar with the old OpenGL “fixed function pipeline”, using glBegin/glEnd, glColor, glVertex, etc. Ambienome is going to be visually simple enough that I probably could have used the fixed function pipeline, but I decided to learn the shader pipeline to improve my knowledge and skills, to allow nicer visual effects, and to leverage the GPU’s number-crunching power as much as I can.

Grokking the shader pipeline was a challenge. There are many separate concepts to learn, and then you must understand how they fit together. Also, there are fewer learning resources for the shader pipeline than there are for the older fixed function pipeline. I relied mostly on Joe Groff’s “An intro to modern OpenGL” article series, but if I were doing it over again, I might try to find a good book. Unfortunately, the selection is somewhat thin. I’m considering OpenGL Shading Language (the so-called “Orange Book”) or the OpenGL ES 2.0 Programming Guide. (OpenGL ES 2.0 is conceptually very similar to the OpenGL shader pipeline, and also very similar to WebGL.) Unfortunately, the reviews suggest those two are not very well written, organized, or proofread. Real-Time Rendering looks like it might provide a good high-level understanding of shaders and rendering, but it’s not specific to OpenGL or GLSL, and I’m not really interested in advanced photorealistic shader effects. Maybe if there are any book stores still open in this town, I’ll see if any of these books are on the shelf so I can assess them before I buy.

Anyway, even after I had scraped together a modest understanding of the concepts behind the shader pipeline, applying that knowledge in practice took longer than I anticipated. It was fairly frustrating at times, partly due to some (minor) shortcomings of cl-opengl and lispbuilder-sdl, and partly due to me misinterpreting some vague parts of the OpenGL documentation. There were many times when I felt like putting the shader pipeline aside, and just using the fixed function pipeline for a while, so I could keep my momentum up. But I stubbornly stuck with it, and now I’ve got a working, reusable rendering framework built atop the shader pipeline. Huzzah!

My next task is to write code to algorithmically generate mesh data for several geometric primitives. Yesterday, I finished the code for a rectangle mesh built from triangle strips (well, actually one long strip with degenerate triangles connecting each row). Here’s a screenshot of a 10×10 rectangle mesh rendered in wireframe mode:

Screenshot of a rectangle mesh

It’s not much to look at in itself. I could have achieved that in an afternoon using the fixed function pipeline! But that humble mesh, rendered here using the simplest possible vertex and fragment shaders, represents weeks of learning. Now that I have the basics working, I can write more interesting shaders to morph the shape and create cool visual effects. For example, Ambienome takes place underwater, so I’ll probably write a shader to make things sway and ripple as if they were being affected by a water current.

Next, I’ll be writing the code for a triangle mesh, and then a circle mesh. I have plans for more shapes, like teardrop, leaf, ring (circle with a hole in the middle), and tentacle (a Bézier curve with thickness controlled by another Bézier curve). But, I’m going to save those for later. Once I’ve got rectangle, triangle, and circle, I’m going to take a step back from the low-level foundation for a while, and start fleshing out higher-level concepts like components, creatures, and scenes.

Ambienome – Technology

In my previous post, I described the concept and roadmap for my new project, Ambienome. In this post, I’ll be describing the technology (programming language and libraries) I’m using, and why I chose them.

Even though I have seven years of experience with Ruby, and my own game library, Rubygame, already available and ready to use, I’ve decided not to write Ambienome in Ruby. Instead, I’m writing it in Common Lisp, using OpenGL and OpenAL for graphics and audio. Continue reading Ambienome – Technology

New Project: Ambienome

I’ve started a new project: Ambienome. This is a game (or, rather, a toy) I’ve wanted to create for years — I blogged about it in May 2007 and November 2009 — and now I’m finally making a serious attempt.

I’ll be blogging about my development progress, both to solidify my ideas by putting them into words, and to keep myself “accountable” for maintaining progress. I’m starting off with a two-part announcement and introduction to the project. In this part, I’ll describe Ambienome’s concept and a tentative list of progress milestones. In the second part, I’ll write about the tools (programming language and library) I’m using, and why I chose them.

Concept

Ambienome will be a freeform creative toy/playground, where players design and interact with colorful, musical, AI-driven aquatic creatures. The concept is heavily inspired by Toshio Iwai’s Electroplankton, and by Will Wright’s Spore.

I loved Electroplankton, but wished there was a way to create new types of creatures, to have multiple types of creatures in the same scene, and to save and share scenes with my friends. Spore’s easy-to-use method for creating new creatures out of parts, and integrated system for saving, uploading, and downloading creations online, suggested a workable model for creating and sharing Ambienome creatures and scenes.

Roadmap

This is a very novel kind of project for me, and it will have many challenges to overcome and problems to solve. I can’t even guess how long it might take to finish, so I’m not going to bother speculating about a project timeline. But, I have plotted out some of the major milestones for the project, in terms of functionality to be implemented:

  1. Players can interact with a variety of built-in creatures, and watch/hear them interact with each other.
  2. Players can assemble new types of creatures from a variety of built-in parts.
  3. Players can import and export creations (creatures and scenes), to share with other players.
  4. Players can upload and download creations from a central site (a la Sporepedia), and rate and comment on other players’ creations.
  5. Players can design custom parts, and share them with other players.
  6. Multiple players can build and interact with the same scene simultaneously, over the network.

I consider 1-3 to be essential, and the rest to be icing on the cake. I’ll do at least one release per milestone. I haven’t decided yet whether this will be an open source project or not. If it seems to be turning out well, I might try to make some money off it.

Currently, I’m still laying the foundation, implementing low-level functionality. For reasons I’ll discuss in the next post, I’ve chosen not to use Ruby or Rubygame for this project. So, in many ways I’m starting from square one, reimplementing the basics: opening a window, handling input events, drawing to the screen, managing the game loop, etc. Well, not exactly square one — I’m building atop other libraries, and I can borrow the basic concepts from Rubygame, so I don’t have to solve those problems all over again.

In the next post, I’ll be writing about the programming language and libraries I’ll be using, and why I chose them.

Dreaming of Ambienome

Lately, I’ve been having visions of a game I’ve been wanting to make for years, which I call Ambienome, a pseudo-portmanteau of Ambient (as in ambient music) and Anemone (the tendrilled sea creature). Both the concept and the name are inspired by Toshio Iwai’s Electroplankton. Like Electroplankton, Ambienome would be more of a musical toy than a game; the purpose of it is to have fun and express your creativity, not to “win”.

Continue reading Dreaming of Ambienome