September 11
Day 08: Camera Edge, Scene Culling, and Optimization
Finally wrote the transform that’d stop the camera from “keeping center” when it’d show beyond the level bounds. It’s amazing how much this small feature changed the feel of the game. It feels much more claustrophobic now, but in a good way. Like the character actually exists in a world, instead of space with some abstract shapes around him. I started the code that’d let me actually do scene culling. Right now, I’m drawing and texturing the entire level, even though the simplicity of working in a 2D projection allows me to clip the map very aggressively and avoid a lot of iterations. I optimized the hell out of texture sharing and binding (even for these boring black geometry shapes). It was originally written with no thought to performance, and, unlike the optimization work with Ruby Inline, I got 3x speedups with a few really sharp, small changes(thanks ruby-prof).
+
Day 08: Configurable Poly Simplification
I got un-nerved seeing how over-and-under simplified certain shapes were getting. On the left of the platform is a solid circle that has been simplified and tessellated with a pretty aggressive setting.
+
Day 08: More Geometry Fixes
I got a really weird feeling about the validity of the geometry simplifier/tessellator, so I spent the time to make debug-mode more visual. Showed a few errors that were only going un-noticed because the character was to large to fit into the cracks. Now I’ve got the geometry engine totally visual, and I can get a wireframe of the exact polys the physics engine is getting..
September 10
Day 07: Bug Fixes and Ruby Inline
No major new functionality, just spent quite a while bug fixing. All were weird edge cases. My poly simplifier was simplifying way too much with certain inputs, causing straight slopes (e.g., perfect right triangles) to get no useful geometry. The tile merging algorithm had a special case that was not applying a range in certain cases. Didn’t bother even tracking that down, just rewrote that hack-of-a-module from scratch and it worked out. Doing all this tracing in Ruby at startup was starting to get REALLY slow. Tracing consists of two tight pixel loops: A) scanning the bitmap’s alpha channel and determining which pixels are “on enough” to consider them geometry, and feeding that as input to B) The Marching Squares tracer. With a 10x32 physics tileset, with each tile 64x64px, I ended up with more than 5 million pixel operations on level load. It was taking 9 seconds to load a level even at the bare state I’m at. Writing Ruby-Inline versions of just these two tight loops brought the load time down to 2 seconds, and, of course, some of that is compiler overhead.
September 9
Day 06: Irregular Geometry Works
Lost a good amount of time when refactoring left me with various stages of black screens for a day. In the end, though, I got all of my geometry code connected to the game, and it’s working awesome. I’ll probably have to rewrite my marching squares in C/Ruby Inline, doing all this stuff on level load is taking too long. It’s time to start actually applying “plaform physics” to the character instead of just having a textured circle. Lost debug/geometry view in the shake-up, gonna get that back working. Up soon: Parallax backgrounds, and some foreground tiles.
September 8
Day 05: Giving the Last Two Days a Purpose
Irregular, deformed geometry tiles. I actually did most of these yesterday. I think the extra “touch” of production will make the game feel more real. No more walking across perfectly flat floors, hills, etc. The level and placement of deformity is a total design-time/map editing decision now. Thanks to Tiled being so fast to use, I don’t feel bad having a level’s geometry totally separated from its visuals. As of now, I like the flexibility, but if it gets tedious having to tap on each tile twice to give it look, then feel, I’ll wire up a way for visual tiles to reference static geometry tiles. There are a few kinks and missing features in Tiled I’d like to dive into if I had more time, I’ll get into that later.
+
Day 05: Triangulation, or, Solving The Concave Poly Problem
Punted and used the Glu tesselator. Was trying to avoid functionality that doesn’t exist in OpenGL ES, but as this Ruby prototype would never run on mobile targets anyway, for now I’ll just plan on ripping out the reference Glu code when I port to C down the line. Should be the last code-nerd screenshot for a while! This was the last piece of really letting me crank up the tile engine. The ability to load static geometry automatically cost me a day, but in the end, I think it’ll save countless hours of hand-writing poly coordinates for tiles later.
+
Day 04: More Interesting Static Geometry
I’ve created a tileset which has no other purpose than to define a level’s static geometry. I’m starting with the simple shapes, and adding things I think would be useful as I go along. I’m currently looking for a SIMPLE vectorization algorithm which can trace these gray-scale tiles and generate ~3-8 faced polys. Most algorithms I’m finding are huge (e.g., look at potrace) but must handle much more demanding requirements than I have.
September 7
Day 04: Marching Squares and Path Reduction
As a followup, I implemented Marching Squares to trace static geometry tiles into polys. Marching Squares generates a lot of redundant points for anything but straight lines, so I put together a simplification pass that removes vertices which are “damn-near” (sub-1 pixel) on the line created by the points before and after it. Now I don’t have to worry about ever hand-specifying tile polys.
+
Day 04: Designing Geometry Tiles/Polys
Even though Chipmunk does not support concave polys, I’m designing around them anyway. Elements (Python library) has a pretty straight-forward convex polygon decomposition algorithm I plan on looking at. Inkscape is absolutely invaluable. It’s one of my favorite pieces of software in any genre, on any platform.