Tuesday, September 7, 2010

construct

Ever watch The Matrix? Remember that part where Neo is on the Nebuchadnezzar and Morpheus loads him into the first white area? Morpheus calls it "The Construct Program".

I've been a real computer programmer for about 8 years. My background is different than your usual software engineer, though. I graduated from DigiPen Institute of Technology in Redmond, WA in 2007 - a Bachelor in Real-Time Interactive Simulation.
Real-Time - lighting fast
Interactive - you can change it as its happening
Simulation - computer worlds.

I'm a video game programmer.

Your usual software engineer is good at creating data processing applications. I'm good at creating computer simulations. It's a distinction I deal with every day at the office, every office I've ever worked at. Most other engineers don't understand this distinction and think that I have less education than them. Turns out, my mind works "per-frame" and theirs looks at a different big picture that allows for less interaction and less simulation ability.

This distinction isn't important for the rest of the post, but it is important to point out for someone that doesn't know too much about programming video games. Games are a very special piece of software - they must operate a subset of commands very quickly 30 times a second as well as produce 1-2 million colored boxes in that same time so the user can see the progress of it.

When I first was tasked to create one of these simulations, I was completely naive. I had a barebones program that could display computer-generated fireworks in real-time. It did not allow any user input to change the fireworks. Today, I'm running 4 cores trying to synchronize how the physics and artificial intelligence systems work with drawing them in a breathtaking real-time world. Oh, how times have surely changed.

Ignorance is truly bliss. Back then, things were so simple. If i wanted to "press A to continue", i sat on something called a block that "listened" for the user to press the A button. If i wanted to navigate a menu, each box of the menu was some specific call to draw a rectangle at a location, and as the mouse's cursor's math was between some decidedly tweaked numbers (if the cursor's location is greater than 128 and less than 228 and the Y is between 50 and 100 and the left mouse button is down this frame but wasn't last frame, then tell the program that some button was pressed!!!)... today, things are a lot more "smart" where a menu button has it's own structure and coordination with the input system (oh yea, it's a system now) to check to see if a callback needs to be called because the button was hovered over and actually clicked.

I had lost my job this February. I was really excited to be home again - i could work on a brand new engine! I had programmed a physics simulation a few months before and had thought long and hard about programming a Deferred Lighting engine. That is a special way to visualize a computer world with a large number of lights - i only light things that you see from your perspective. Before this, I could only have a few lights in the world because every single object, no matter if you could see it or not, would deal with all of the lights in the world. I had a very fundamental naive knowledge of how to program this. Before this engine, I had really just got something called a Render Target working the way I wanted it to, and the entire engine could look at all of the render targets at any time.

But today, which is why I'm tying today, I want to lay everything about the construct down somewhere so my brain can thouroughly process this information properly. Talking to my wife is great, but until she responds back with actual answers, it will be easier to just tell the vast interwebs what I'm feeling and everything will be ok in the end.

I had drawn a few ideas on paper for a new threaded construct program. I'm only calling it "construct" because that was the concept from The Matrix that my wife actually understood. I wanted the user to be able to drag and drop any asset from his desktop into the program at any time, and have it show up as a usable asset. This was a huge difference from previous engines, these were ones that had big bulky asset management schemes that required everything to be plotted in some XML document and linked up to objects individually. lame. A better system exists.

After working at two different companies do I realize that a threaded program is the only way to go. Now that everything has more than one processor (xbox = 2, ps3 = 6, my home pc = 4) I should be writing simulations that can take advantage of all of these processors. I was so naive about that, too. I just sat down and banged out a system where different threads would run different processes, one for rendering, one for input, one for simulation, one for...... and magically it would all work! And it didn't. I had issues where I just simply couldn't deal with the entity format without memory problems. When you thread, two processes can't read the same memory at the same time. So much for that.

Last week, I sat down and designed a system that would work. 4 threads; Simulation, Render, Loading, and Synchronization. It is a beauty. Render would be one frame behind Simulation. Synchronization would be in lock with those two threads. Came up with an object format that would work. Came up with enough data to transmit between the two easily and with a small data format. Everything may work this time around.

So why am I still so anxious? I just suck at this or something. Honestly, I don't know where to start. I wanted to write this post to talk about it. Now I've talked about 200 other things to set it all up for you. Such is my life.

To start, I had to create a system to lock the sync thread between the render and sim threads. That was not as hard as it sounds, but it took 5 minutes to come up with a decent algorithm. I am essentially creating 4 gates. Sim and Render wait for their own gate to be opened, walk through it, and lock it behind them. When it's done, it unlocks one of two gates that the Sync thread is sitting behind. When Sync goes through its 2 gates, it locks those gates behind it, syncs everything, and then unlocks the sim gate and the render gate. Sweetness.

To load things, messages are generated in the sim thread and sent during a Post Message step to the loading thread. When the object is done loading, it sends a message back to the Sim thread that the asset is ready.

Today, I was starting to write the render thread. I was really stressing out about this. Render needs to order and cull things to render before it starts to draw. It needs to order them in a special way. What is all an asset? What is the least amount of information needed to draw things? God this is a crazy world.

If I have time to work on it tonight, I'll post how it went. I feel good about this. I just want to make the first level of Zelda64 from tools in the construct. God i have so fucking far to go.


No comments:

Post a Comment