Reasons

Chimera was meant to be an homage to Knight Lore. I had two motives to make Chimera back in December 1984.

  1. I was 18 when Knight Lore came out having recently released my C64 version of Jet Set Willy. I was young so I thought my budding “career” was already over. It was another video game for me, or bust. And when I say bust, I mean bust for life.
  2. Knight Lore was a glimpse into the seemingly impossible. The naïve young me saw it as a challenge. I had to know how it was done – and I had to do it myself. Only a handful of games have had the same effect on me. They include Star Raiders, Ultima Underworld and No Man's Sky. I really cant think of any more right now and if I'm ruthless, it's really only Knight Lore and No Man's Sky. I was inspired. Deeply, indelibly inspired. How often do games come out that not only take their place in the pantheon of greats, not only do they inspire a generation, but they divide time into “before” and “after”.

After I made Chimera on the first four 8-bit platforms, I think I lost my way a bit. I had so many options. I just didn't make the right decisions. I was young. I didn't know what I had until it was gone.

This is perhaps recklessly honest, but I don't want to do “this” the easy way. I want to write the follow-up to Chimera the best way I can. That means C++. Everything from scratch. As close to the metal as I can get these days.

A lot of people, quite rightly and logically have suggested that a man with a day job as demanding as mine should use all the help he can, perhaps using a tool like Unity or GameMaker. I like both of these tools, they're incredibly empowering, I would recommend them to most people, and I will use them for other projects — just not for Chimera.

I want to go as hardcore as I dare. I want to drink deeply from the pool of OpenGL and seek wisdom from the gurus of GLSL. I want to make this game look fantastic and play in a way that affects people. Only then do I want them to say “not only was this game made by one man, but he did it with ridiculous constraints”. If I'm shameless, I want a young, aspiring developer to look at what I've done, and without knowing anything about me at all be inspired to make a game like it, or better.

There is no better way to live and yes, it's the only way I know.

 

Taking a Step

Screenshot 2013 10 28 20 05 19

The version of Chimera I wrote last year was a C++ rewrite. It had a few minor changes, like Knight-Lore style collision with room exits, and a map, but it was essentially the same game. 

As I lay the groundwork for the sequel, some of the assumptions of almost three-decade old game have to be discarded. There was no saving or loading, so I didn’t have to worry about intermediate state. I wrote the remaster with that assumption in mind. So now I’m stripping the guts of the game out to allow saving and loading of arbitrary rooms. For this I’m using XML. I will probably switch to JSON at some point, but XML suits me just fine for now. I’m also redoing the Entity class to allow it to be regenerated from “DNA”. This means I don’t have to save the entire state for the object, much of which is unnecessary anyway.

I previously had the concept of a “RoomObject”, which differed from “Entity” in that it had some redundant extra information and pointed to an Entity object. Its only purpose was to allow non-background block objects to be manipulated more easily. There was no reason this couldn’t be an Entity, so that’s the first big change. No more RoomObject structs, everything is now an Entity. Even a Room is derived from the Entity object. The change has been made, but now no objects are being displayed at all, so that needs to be fixed.

A minor problem that I’m sure will be fixed soon is that the Cinder library I’m using is not displaying text under OS X Mavericks.

I’m smoking Ashton’s Smooth Sailing in a Parker pipe I bought from eBay. I was planning on listening to Led Zeppelin, but I’m going silent this evening.

 

Particles on the GPU and Winning

These last couple of days I’ve decided to dive into what might be the most important technique in games of the future, computing on the GPU. 

Now like you, I like particles. I remember doing a simple 2D particle system back in the Amiga days. It was basically a star field on the Amiga. Not really 3D other than it looked it. (I always preferred faking). I couldn’t draw a lot of particles (stars) before it started chugging. Then years later, in the mid 1990s in fact, I worked on a particle system again on the PC. This came on the back of numerous PC related tasks, one of which was to convert an undocumented, unportable video decoder written in assembler that only worked on a 320×200 screen to one that ran in C on a 640×400 screen. In a weekend. Which I did. Should have seen the look on the assembler programmer’s face when I turned up on Monday (I was the Producer) and demonstrated that. He’d previously said it couldn’t be done. (Seeing a pattern here?)

So anyway, I worked on a particle system on a PC that chugged at a thousand particles, but was OK with 400 or so at a decent clip. I was not happy.

And so today a few thousand particles on a CPU on top of  everything else is good, but it’s not good enough for me. I’m thinking of hundreds of thousands of particles. The only way to achieve that is to do them on the GPU and exploit the enormous parallel compute power. Particles lend themselves to parallelisation of course. 

So I’ve been looking, learning, rewriting, testing, writing shaders, understanding shaders, and I’m getting somewhere.

Computing on the GPU is achieved through a technique called FBO ping-ponging. It sounds tough. It’s not all that tough. The reason you do this is because you cannot read from and write to a texture map at the same time. Why texture maps? We’ll come to that, but suffice to say they’re no longer acting as texture maps.

You use a texture map to store other data, in our case, particle data; like velocity, position, time to live and so on. You then read this data, perform your computations and then write out the modified data to the write-only texture map. You then flip the FBOs and carry on. With my test program, I am initialising from the CPU, but there is no reason why you can’t initialise from the GPU and that’s what I’ll be doing at some point. Ping-ponging textures like this is the only way you can maintain state in what would otherwise be a stateless architecture. Exploiting the heavily parallel nature of modern GPUs is what gives these techniques such extraordinary performance over doing them on the CPU.

I have a lot to learn. Ray-marching, distance fields, ray-tracing, ambient occlusion in real time and other forms of optimised global illumination. It sounds heavy, but it’s just process and like anything else, if someone else has done it, you probably can too.

In the meantime, I am going to spend some more time studying ShaderToy and seeing just how they achieve such incredible effects. I’m planning on having Chimera looking amazing. At the beginning of the week, it was a crazy, foolish dream. Tonight, it is within sight.

One Step Beyond

Never, ever, ever give in. Sometimes, I accept that the day is done. And that the battle continues the next day. It hasn’t been lost, it’s just going to go on another day. Then I carry on. And on. And on. 

I’d made little visible progress tonight and I was about to call it a night. Then I pushed past and had the breakthrough. I now have the original Chimera drawing in 3D. The blocks are placeholder and all the same, the camera needs adjusting, but it’s there. Lighting, shaders, perspective, 3D, C++, 3 days.

Never give up. 

Push through.

Win.

Screen Shot 2013 05 29 at 22 28 27

Screen Shot 2013 05 29 at 22 28 37

Screen Shot 2013 05 29 at 22 28 39

48 Hours

Screen Shot 2013 05 28 at 23 25 05

From a former programmer who never thought he could get past 2D, to a family man doing 3D OpenGL graphics in C++, using vertex and fragment shaders, lighting, texturing, mesh export and import and a lot more, in 48 hours, I have to be very, very happy with that.

Tomorrow I think I will have the Chimera map being drawn using placeholder objects in 3D. What’s blown my mind is that if I want to go for straight up isometric, I can just use an isometric transform instead of a full perspective transform. And as for fragment shaders, well, I’m only using those for lighting yet, but I could go to town there.

I’ve not been this excited about something in a very long time.

Want to know how to keep young? Keep learning. Never be afraid to set stupidly high targets. And don’t be surprised when you hit them.

Screen Shot 2013 05 28 at 23 32 00

It’s Never Too Late

May 28, 2013

12:22 PM

It’s Never Too Late

This is the last fig leaf.

Yesterday, I went from never having really done any 3D programming to getting a cube up on a display with a simple geometry and fragment shader. That was a great start.

Today my ambition is to entertain some friends, whilst ignoring Twitter as much as I can and importing a textured mesh and displaing that. If things go really well, I’d like to get some kind of ambient occlusion going.

I’m an optimist. And because it shouldn’t be possible, I’m going to do it. Most people confuse the “infeasible for most” with “impossible”. I like reaching for the stars, it’s less crowded up there too.

I understand I need to be able to load an OBJ file and that many 3D packages, like Blender for example, will export these files. I know that meshes have a winding order and that it’s better that a 3D package take care of that rather than do all of this manually. The winding order goes clockwise or counter-clockwise, and depending on that order, a face (triangle) either faces the camera, or doesn’t, in which case it can be culled. Byron assures me that hardware now takes care of that. Having done some preliminary reading on shadow maps, it might still make sense to draw back faces anyway, something to do with rounding errors, but we’ll cross that shadowed bridge when we come to it.

A 3D package will also take care of a normal map and the texture UVs. I’m always happy about a tool that takes away pain. There is no need to inflict pain on yourself. In fact, the first thing I did for Chimera in January 1985 was to write an isometric sprite editor for it, in Z80 assembler, as you do. I wasn’t going to use graph paper (though that had been my preferred method for creating bitmap fonts!)

The Cinder library includes an OBJ loader that allows me access to a TriMesh object directly for OpenGL draw calls. This is fantastic.

So my plan is to make some simple Chimera cubes and apply some simple texture to them, then spit them out of some draw package. Which draw package?

Well Blender is free, and free is good, but the interface is intimidating. It does however make it really easy to create voxel output, which is the kind of look I’ll need for Chimera, even though I don’t know if I’ll be using a voxel technique necessarily.

Then there’s Cheetah3D and there’s Milkshape. I’ve not really looked into Milkshape, but I have a problem with sloppy looking websites, and the Milkshape site looks like something from the ’90s. That doesn’t sound hopeful.

Cheetah3D looks very complete, is available for under £50 on the App Store (remember I’m on a Mac) and does OpenGL preview. Also, unlike Blender, the interface looks Mac native. That means a lot to me. It saves me time when I’m trying to pick something new up.

I might also be able to enlist the help of an architect friend in creating some Chimera objects.

To say I’m excited is an understatement.

I used to be afraid of water. I couldn’t swim most of my life. I’d do anything I could to avoid it. Then I made up my mind at 36 to fix it. Steven Shaw took away my fear of water and eventually, that fear turned into love. I’m not a strong swimmer, or even much of a swimmer, but I’d love to swim every day if it was more convenient. Becoming a swimmer changed my self-image completely. Before, I saw a limit. Suddenly, that limit was gone, along with potentially all other limits. I learned to juggle. Not very well, but I did it. I learned to sing. Not very well, but enough to record demos. Many other barriers have been smashed in my life.

And now I’m removing the last fig leaf. 3D graphics.

Feels good.

Not Bad for a Day

1:57 PM

Recap

Isometric allows me to make a lot of assumptions.

For each Chimera block, I need to draw 1024 voxels. Each voxel is always going to have the same shape, or geometry, but not scale or size necessarily.

3:54 PM

Lots of learning about how to do meshes and stuff in Cinder.

I have a cube being drawn as a VBO. Next up, I need to set the normals and rotate it isometrically before it gets drawn.

6:10 PM

Pretty lost in experimentation. I keep oscillating between a simple isometric approach (fast) and a full-blown camera approach (flexible, and possibly not much slower)

11:05 PM

A breakthrough.

After pontificating one way and another, I took half an hour of Byron’s time (thanks Byron!) and received some valuable insights into how the rendering pipeline works.

I spent a few more hours working and you can see the results for yourself. This morning I had never done any real 3D programming in my life. I’m a family man and a business development person with lots of distractions and of course, today my Twitter timeline saw an unusually high level of activity… And now, I have shaders running, drawing a cube from a given camera position. There are still some kinks to be worked out, but I’m really happy with how far I came in a single day.

Chimera2 image002