• entries
19
27
• views
21466

Python, video games, and universality. My quest to build multi-platform games/engines using Python!

## Android, Pyweek and Seperate Axis Theorem

[BLURB:] Sooooo... Perhaps I should work on smaller projects... hmmm. In any case, spent some time taking a look into python on Android, tried the pyweek challenge, and NAILED THE HELL out of SATs... not the school education kind.

[DEVELOPMENT: Hell]
Hmmm... Archetype needs to take a little break (not that I haven't already put it on the back burner). I've thought this many times, but still, I'll say it... I need to work on smaller projects. To that end, I tried my hand at the pyweek challenge that just occurred. For those that don't know, the challenge is to write a game, either alone or in a team, within one week, based off a theme that isn't revealed until the moment the challenge begins. This challenge was "Nine Times".

So... did I succeed...
Ummm, not exactly.

Turns out, having to help move family from one apartment to another takes a hell of a lot of time (8 hours of day 1... lost).
Nine hours a day due to my full time job doesn't help much either.
Then, of course, my father's computer fails two days before the end of the challenge and who's the only one in the family that can fix it? Yeeeah...

None-the-less I still spent most of my free hours working on something, and while I didn't have anything playable until 5 minutes AFTER the end of the challenge, I learned a lot!

One thing I learned was that Android's SL4A is not a viable platform for writing games. I'm thrilled that there's a method for writing applications for the Android outside of Java and C++, but as I looked into the SL4A project, I soon realized that the Android graphics library was not exposed to the scripting languages. This is a HUGE oversite of the project, I think, and, as such, I lost a few hours of the pyweek challenge because I didn't realize this issue until I was preparing to develop my pyweek game on Android. DRAT! With any luck, SL4A will get a graphics hook and then we'll REALLY be cooking! HA!

[TUTORIAL: SATs]
Pyweek wasn't a total loss, though, as I learned and nailed Separate Axis Theorem collisions!! There's a bit of documentation out on SATs and it's all pretty good, but I figured I'd share my discoveries with my wide blog audience for no other reason than to solidify my understanding of the system.

• Firstly, I'd like to point out that this is for calculating collisions on 2D objects. While SAT works on 3D, I only really worked with 2D, and that's what I'm working with.
• Secondly... I haven't worked with sphere (or rounded) objects. It wasn't what I was focusing on when I was developing my application, and so, for the time being, I'm skipping rounded objects.
• Thirdly, SAT ONLY WORKS WITH CONVEX OBJECTS! These are objects that if you drew a strait line through them, the line could NEVER intersect the object in more than 2 locations regardless of where you drew the line.What is Projection:
To begin let's talk about projection. What is projection? It's a shadow. For a 3D object projected onto a plane, the result is a 2D shape (or, if you think of the real world... a shadow). For a 2D object, the projection is a line with a length long enough to encompass the entire 2D object when viewed from the axis in which one is projecting.

Huh?
Well... let's think of a rectangle. The axises of a rectangle are the X and Y axis, and the projection of a rectangle upon the X axis would be the same as the length of the rectangle.

Projection in regards to SATs:
Let's stick with the rectangle for a little while and start talking about SATs...
With the Separate Axis Theorem we can determine if two objects are colliding with one another if ALL of the axises of projection between the two objects in question overlap each other. If even a single projection doesn't, then there is no collision.

Think of the two rectangles... I dare you to try drawing two rectangles in such a way that the shadows on the X axis AND the Y axis for BOTH rectangles touch but the rectangles AREN'T colliding. Go ahead. I'll sit here and wait for you...

...
...

No? Couldn't do it? And that's the point. If all shadows for both objects are all overlapping each other, then your objects are colliding. If even a single pair of shadows ARE NOT colliding, then the objects ARE NOT colliding. That's the Separate Axis Theorem. Take your objects, find all axies in which you need to project upon. If even a single axis has a pair of projections that DO NOT overlap, then there is no collision and you're done.

Finding Axises to Project Upon:
Great! Now you may be wondering... "If I'm suppose to project upon some axises, what axises do I need to use?"... As it turns out, the axises you need to project against are simply the normal vectors for each side of your 2D object. Lets look at a little python code that does this...

Code Example: 1.0
# This is a 10x10 rectangle centered at the origin.points = [[-5, 5], [-5, -5], [5, -5], [5, 5]]axises = [] # an empty list at the moment# We loop through the edges of the objects...# which just so happens to be the same as# the number of points.for p in range(0, len(points)): if p == len(points)-1: edge = [points[0] - points[0][0], points[1] - points[0][1]] else: edge = [points[0] - points[p+1][0], points

[1] - points[p+1][1]] # Now that we have the edge, we need to find it's normal... There're actually TWO # normals you can use, depending on if you use the left handed or right handed # normal. For the most part, it doesn't matter which you use, as long as you're # consistent. # I'm going to use Left Handed normals.... norm = [edge[1], -edge[0]] # Or... (y, -x)... it's that simple. # At this point we've found our normal, which is more or less our axis. I say # "more or less" only because, for simplicity, our axis should be a UNIT vector. nlength = math.sqrt((norm[0]**2)+(norm[1]**2)) axis = [norm[0]/nlength, norm[1]/nlength] # <--- That's our axis for this edge! axises.append(axis) # and we add it to our list of axises for this object.

HEY! HEY! You're example uses a rectangle and creates FOUR axises! When you were talking to us about projection, you said rectangles only have TWO!!!
Ummm... well, yeah, sort of. Because the rectangle has four sides, it technically has four axises in which to test... however, two of those axises parallel the other two. In essence, it's like we have the same axis twice (even though they may both be going in to different directions). To solve this problem, you can change the last line of code above to...

Code Example: 1.1
AddAxis = True# We need to loop through our existing axises.for a in axises: # Calculating the dot product of the two axises... dp = (axis[0]*a[0]) + (axis[1]*a[1]) # Now we get the arc-cosine of the dot product. If the two axises are parallel # then the value of acos will be either a 1.0 or a -1.0 ... so we check the # absolute value of the acos to see if we get a 1.0. If we do, we DON'T want # to add the axis to the list, since a similar one already exists. if abs(math.acos(dp)) == 1.0: AddAxis = False breakif AddAxis: axises.append(axis)

Yes, it's a bit more complicated and eats more CPU cycles, but, depending on the complexity of your shape, it shouldn't effect you too much and doing the above would cut down on the number of tests you need to do in the upcoming examples.

One important thing to keep in mind is, we need to calculate the projections of BOTH objects over BOTH objects' axises! We'll see this in Code Example 3.0

Calculating Projections:
So... now that we have our axises in which to test against, how do we calculate out the projection of the object over an axis?
Well... we take the dot product of each point in our object against our axis, storing the minimum and maximum values.

Code Example: 2.0
# These are our minimum and maximum projection values.# Initially, we don't have any.proj_min = Noneproj_max = None# We loop through each point in our objects.for p in points: # Calculating the dot product. # NOTE: While the axis should be normalized (as we did in Code example 1.0), # we don't need to, nor should we normalize the point. dp = (axis[0]*p[0])+(axis[1]*p[1]) if proj_min == None: proj_min = dp proj_max = dp else: if dp < proj_min: proj_min = dp if dp > proj_max: proj_max = dpprojection = [proj_min, proj_max]

Keep in mind, we would have to do with for ALL axises from BOTH objects ON BOTH objects.
Huh?
I'll explain next...

Putting it All Together... Simply:
So now you see how we get our axises to test upon and how to calculate out projections... let's put it together!

Code Example: 3.0
# obj1 and obj2 are assumed to be a list of points like used in Example Code 1.0def collides(obj1, obj2): # Assume the CalculateAxises function does the same as Example Code 1.0 # and returns the axises list. # Calculate the axises for the first object o1axises = CalculateAxises(obj1) for axis in o1axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # Assume the Overlaps function returns true if the two projections # overlap and false otherwise. if not Overlaps(o1proj, o2proj): # As soon as ONE pair of projections DON'T overlap # we KNOW there's no collision. Done. return False # NOPE! Not done yet. We now have to do the SAME THING for the axises of the # OTHER object. # Calculate the axises for the second object and repeat the same as we did above. o2axises = CalculateAxises(obj2) for axis in o2axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # Assume the Overlaps function returns true if the two projections overlap and false # otherwise. if not Overlaps(o1proj, o2proj): # As soon as ONE pair of projections DON'T overlap # we KNOW there's no collision. Done. return False # We've now looped over all axises for both objects. If we're still here, then # ALL PROJECTIONS OVERLAP! # We've COLLIDED! return True

And now you know, using the Separate Axis Theorem, whether or not the two objects collide.
Of course, you usually want to know a little more than that... like, if they've collided, how do you break OUT of the collision? Turns out, that's not too much harder than what we've already done.

Putting it All Together... MTV Style:
No... not the TV station. In this case, MTV stands for Minimum Transition Vector... or, more simply... What's the quickest way out of here!!!

What we want is a vector showing us the way to non-collision safety. All we need for that is axis in which the minimum overlap was found. Lets go to code, shall we?

Code Example: 4.0
def collides(obj1, obj2): # These will hold the information we need to find our MTV. # For now, they're None... meaning we didn't find anything yet. MTVOverlap = None MTVAxis = None # Calculate the axises for the first object o1axises = CalculateAxises(obj1) for axis in o1axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # We're getting rid of the Overlaps function from before, and using the # Overlap function (we dropped the 's'). Overlap will return a scalar # value equal to the amount of overlap between the two projections. # If there is no overlap, then Overlap will return a 0.0 ol = Overlap(o1proj, o2proj) if ol == 0.0: # We have no overlap... meaning we have no collision... meaning # we have NO MTV. We're done. return None # Here's where we do some new stuff... if MTVOverlap is None: MTVOverlap = ol MTVAxis = axis elif ol < MTVOverlap: MTVOverlap = ol MTVAxis = axis # Calculate the axises for the second object and repeat the same as we did above. o2axises = CalculateAxises(obj2) for axis in o2axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # We're getting rid of the Overlaps function from before, and using the # Overlap function (we dropped the 's'). Overlap will return a scalar # value equal to the amount of overlap between the two projections. # If there is no overlap, then Overlap will return a 0.0 ol = Overlap(o1proj, o2proj) if ol == 0.0: # We have no overlap... meaning we have no collision... meaning # we have NO MTV. We're done. return None # Here's where we do some new stuff... if MTVOverlap is None: MTVOverlap = ol MTVAxis = axis elif ol < MTVOverlap: MTVOverlap = ol MTVAxis = axis # Ok... we've gotten this far, which means all projections overlap between # the two objects, so we want to return the MTV. We've already captured # the MTV, so we return it as a single vector... return [MTVAxis[0]*MTVOverlap, MTVAxis[1]*MTVOverlap]

And we're done... Yeah.. ummm... for the most part...

MTV Directionality:
This little bit caught me for a while when I was figuring this out. I had done everything right, but, when I tested two objects as certain angles, instead of the MTV moving the objects out of collision, it'd send them further IN! It had occurred to me, after a couple hours of frustration, that... What is the MTV was pointing in the same direction as the colliding object.

First thing I had to realize is that the winding of my object's points were important. Meaning, where they clock-wise or counter-clock-wise. For instance, for Code Example 1.0, the points in the "points" variable are counter-clock-wise. There's probably ways to determine this programatically, but, for simplicity, just say all objects must be drawn in the same winding. In my case, I was drawing in a CCW direction as well, so...

I thought to myself... "self", I said, "during the collision, one object has to be moving and the other not" (simple situation). So, I decided that I would calculate the vector between the two objects...

vector = collideeObj.position - colliderObj.position

...and normalize it...

vector.normalize()

Then I would get a normal vector of my MTV...
MTVNorm = MTV.normalize(returnCopy=True)

... find the dot product between my direction vector and my MTV vector...
dp = vector.dot(MTVNorm)

... and, for CCW winding...
if dp < 0.0: # This inverts the vector. Same path, different direction MTV = -MTV

... and finally, reposition the collider by the MTV
collider.position += MTV

And there you have it! OBJECTS COLLIDING PROPERLY!!

Caveats:
Like I said, this works for N-sided objects. I didn't even look at rounded objects because I wasn't focusing on those (I was pressed for time). Also, the objects MUST be CONVEX objects, but that's more a caveat with SAT than my code. Lastly, there's no compensation here for fast moving objects nor complete inclusion (one object totally within another).

If you want to do concave objects, simply create a group of convex objects and treat them as one object, except during collision testing.

Conclusion:
I hope at least someone finds this useful... but, at the very least, I can always look this back up if ever I need to code up SAT objects again. If anyone would like, I could post up a simple example program (in python), but for now, I need to eat dinner.

## 4X development and holding on Archetype

[BLURB:] Working on a 4X game, and the Archetype Engine is on hold thanks to the flipping camera! Also, my job goes from part time to full time and I've been exhausted!

[DEVELOPMENT: Galaxy vs Archetype]
It's a bit of a bad habit of mine. I'll work on a project for about a month or two, then I want to try something else. Actually, this only happens with my own personal projects, thankfully, and not those I do for work, but still, it's annoying.

In terms of the Archetype engine, my VBOs have kicked my butt and now my camera... which I had thought was rather stable... turns out to be far from. Having spent a solid week trying to get it to work right, I'd decided to put Archetype on hold for a little while and switch over to a new project that, in time, should easily be mergible with the Archetype project. Ok, so I'm legitimizing the switch by thinking to myself that I'm just working on another aspect, but whatever...

To anyone that reads this journal, you may have remembered one of my last posts saying how I was looking at playing some 4X games, but couldn't find one to satisfy me. To that end, I have started working on a project called "Ships"... weak title, I know... which will serve as part one of my 4X development. What Ships will be, is the "ship designer" portion of the 4X game. When the game starts, players will be presented with a ship designer and a starting sum of Production Points in which to assemble a fleet. The player will be allowed to design as many ships as they want, but their fleet would be limited to the number of production points available. Once the player as designed their ships and/or assembled their fleet, they then choose another player's fleet to compete against. At this point, the game will switch to the tactical portion of the 4X game, in which the two fleets do battle.

At the moment, I've been poking at the game for about a week. I have written a custom config loader and a language string loader (for internationalization of the application). I'm currently working out in my head how I want to handle error handling and logging. I'm pretty sure I'm going to use Python's logging module, just not sure exactly how I want to integrate it.

Oh... silly me... Ships is the name of the demo/game that is the first part of my 4X project... Galaxy is the name of the library I'm writing for the 4X game(s). Galaxy contains the currently developed config loader, language loader, and component manager currently developed. I'll be uploading the git repo of the game(s) to gitorious soon.

[BUT WHY?!:]

Like I said, I had a powerful hankering to play a 4X game, and there's so few for linux. Ok, to be fair, I wanted to play a 4X SPACE game, and there are so few of those. I looked into FreeOrion, but, sadly, the forums almost seem dead. The game runs fine, but seems empty of any actual life. More like a tech demo at the moment. Again, to be fair, this tends to be the case for a lot of unfunded open source games... and mine may even end up that way itself... but still. I tried playing some 4X games from Windows through wine, but, between incompatibilities with wine and a current dislike of microsoft at the moment, I couldn't play any of those.

And so... I try to write my own. Still hard because I really want to PLAY the game. Eventually, I hope that'll be the case.

[Personal Side:]
Development on any of my projects has also taken a bit of a hit recently because as of mid February my part time job as database developer turned into a full time job as a database developer. I'm very happy about that, but the new hours are tiring me out by the end of the day. Once I'm home I usually just want to veg on the couch and watch TV or play XBox (yes, I know that's a little hypocritical after my previous statement about not liking Microsoft, but sue me, I'm human). Even on the weekends, once I've finished the errands I need to do, I'm ready to just relax and let my mind drift.

I'm sure I'll adjust to the new schedule eventually and be able to get a little more personal project development in as time goes by, but still... things are a little slow at the moment.

Holy moley! You're still reading this? Ha! Thank you.
I hope to have more interesting news as time goes by. Catch everyone next time!

## Textures and Blenders

[BLURB:] Ummm... Yup. I have textures and I export from Blenders

[DEVELOPMENT: Archetype Engine]

Ok, so I haven't been saying very much this month. I had a bout where I REEEALLY wanted to play a good space based 4x game, but failed to find one that fit my desire. After that, I tried X2: The Threat on Linux. Fun game, but a little too pricey at the moment for me to buy. This lead me to Freespace2 Open. FUN Game. Which just lead me back to wanting to continue my engine. Every false start I had in finding a game to play just kept me saying "well, I'll just make one, then"!

I have a few new ideas kicking around in my head. My original idea is still a goal of mine, but I have new side realms to venture into with my engine as I develop it. Heck, nothing wrong with multiple projects. Anyway... A couple of days ago, I finished writing my first Blender exporter for 3D models. Nothing fancy yet. All it exports are the basics (verts, tex-coords, norms, and faces) and exports them into a OBJ-ish plain text format (I do seem to love adding ISH to all my stuff). Ironically, I haven't written a loader for my engine to load the model file yet because I'm still ironing out the details on how the graphic submodule (which I'm now calling "occular" instead of "view") is going to be organized.

Along THAT line, I finally added textures. The demo I wrote it VERY simple. It creates a basic one color texture. I'll probably expand on that as time goes on, but image loading DOES work.

And... that about wraps up this update.

## Gah! Almost two weeks!

[PERSONAL:]

Ok, I haven't worked on Archetype for almost a week because my favorite RPG table top group suddenly finds itself GMless and I decided to try giving the job a go. Not that I've actually started GMing. It's an online group that used a virtual table top (VTT) and I've been spending a week organizing, to the best of my abilities, stuff for my campaign. With any luck, it'll be worth the time put in.

On top of that, I've suddenly developed a hankering for Space Opera 4X gaming again and, while MOO2 has been helping, I've really developed an urge to try my hand at writing a 4X game. Gah! I hate when my brain does this. But, if I don't sidetrack a little, I'll loose all concentration for any project (the "run and hide" way of dealing with things), so, I figure working on 2 code projects is worth trying. Besides, the code from the Archetype engine could be used for the 4X I'm thinking of... if not in whole, then in part.

[DEVELOPMENT:]

Which leads to a question I've been pondering. Thus far I've been working on Archetype's graphic system. Currently, there's nothing about the graphics system that makes it unusable by any style of game. As such, I've been wondering if I should split out my graphics from Archetype into another library, or just copy the graphic code from Archetype and past it into whatever 4X engine I decide to write. Of course, this question may mean that I have a flimsy idea, over all, on what exactly an "engine" is and what makes it different than a "library" or (in Python terms) a "module".

In any case, I'm still hacking away at my code.

## Possible VBO Victory!

[BLURB:] I think I may have successfully discovered how to integrate VBOs into my library!

[DEVELOPMENT: Archetype Engine]

Having gone round and round and round the google merry-go-round in regards to VBOs with pyopengl, I FINALLY figured out how to get my hands on glGenBuffers and why my tests for always failed! Ok, it seems my drivers (both for my modern ATI and generations old NVidia) do not support glGenBuffers directly. Making the following call...
bool(glGenBuffers)
... would always return False for me. Ok, so, I must have to use the ARB version of the call. However, every test I made to find a valid implementation of glGenBuffersARB would, likewise, fail! I took this to mean I did not have access to the extension for vertex buffers.

Here's where my mistake was (or seems to be)...
My tests involved calling up the python console, importing the modules, and testing for the existence of the functions I wanted. What I didn't realize is, what I needed to find the extensions in the first place was a VALID CONTEXT!!! More or less, when I was running python in the console, I was never creating an OpenGL context, so all of my tests would fail because none of the extensions would load. Once I did my tests with a context created, I was able to find an implementation of the glGenBuffers function...
from OpenGL.GL.ARB import *

Unfortunately, I've been under the weather the last couple of days and haven't been able to concentrate real well on coding, so, all I've managed to do was start a shell of a VBO class. When done, my VBO class will match my VAO class, allowing me to use either interchangeably, allowing me to adapt the engine for systems that may not support VBOs at all.

May the force be with me! And also with you

## ATI hate me, I think.

[BLURB:] A choice made 5 years ago is not effecting my 3D ENGINE!!! Grrrrr.... Have to put VBO development on hold! Grrrrr.... Vertex Array Object works like a charm... YAY!

[DEVELOPMENT: Archetype Engine]

Ok, I busted my mental hump trying to figure out VBOs. For PyOpenGL, most documentation on the subject is almost three years old and given as a code snippet at this website. The problem is, when I tried using that code, glGenBuffers would fail. It's either claim I was passing 2 arguments when it only wanted 1, or that the function didn't exist at all! Grrrrrr!!!!! After well over five hours of painful googling (all hail the Google) AND upgrading my copy of pyopengl from 3.0.0 to 3.0.1 I have generally narrowed the issue down to my ATI drivers... or, at least I believe that to be the case.

See... I'm running on Linux; Ubuntu 10.04 to be exact, and, in general, ATI doesn't think very much about us Linux people. Arguments for the ATI mentality aside, the result is, the ATI drivers for Linux are not as good or as up to date as those on Windows. As such, I wouldn't be surprised if the implementation for VBOs wasn't completed in the Linux ATI driver and that is what's giving me my issue. I could be wrong, but I can't think of an alternate reason at the moment.

So what does that mean over all? Does that mean I cannot code VBOs into my engine? HELL NO it doesn't mean that! It just means I have more research to do. I'll have to look into the extensions method for vertex buffer objects and do something like:

if not bool(glGenBuffers): glGenBuffersARB(1, buff)

Not to mention having to deal with the case of whether or not the extension exists or not. There's ways around it, I suspect, but to get VBOs up and running, I have a lot more reading to do.

[RANDOM THOUGHTS:]

Open Hardware! We have open source software and open hardware exists to a degree (gumstixfor instance). I would LOVE to see an open hardware graphics card! I know, I know... that's a hugely tall order, but think of the total win factor such a device (and the company that produces it) would have if it were done! A hardware device that could be plugged into any computer (mac/windows/linux/other) and have drivers available. If drivers aren't immediately available, the specs are open for driver developers to plunge right in and code some up! No more half-assed features from one OS to another.

Yes... before anyone decides to flame me for what I'm saying, I'm well aware that this is more a dream than anything that could be set into motion. I'd love to take a crack at it, but I am so completely not a hardware guy. Not even to mention ATI and NVidia are so far ahead of the game in terms of graphic processing hardware that any small time company looking to start would be entering with hardware, more than likely, a couple generations behind (or more) and would more than likely collapse due to the imbalance of those who would buy the hardware to support it and the ideals, and those that wouldn't because it wouldn't be able to run the top tier games.

I CAN DREAM, THOUGH, DAMMIT!

...
...
*cough*
...
...

Thank you for playing, please come again

## Working the "view"

[BLURB]: Studying VBOs and trying to determine the best method for rendering.

[DEVELOPMENT: Archetype Engine]

Yes, to be perfectly honest, I've been a little lazy the last few nights. Not that I haven't done any work, but it's been light; reordering classes and files, mostly.
That said, some of the reason I've slowed is I'm trying to wrap my brain around a decent method for rendering geometry. Ok, it's a little more detailed than that, so, perhaps I'll break down the dilemma... I want to keep my "data" and my "renderer" separated, that's just good programing, but there are some points where it gets a little fuzzy on how to do that. For instance, 3D models. Obviously the model loader doesn't need to know anything about the renderer, but the data it loads (vertex, normal, color, tex, etc, etc) is, almost exclusively data used by the view. As for as the logic of the engine is concerned the geometry information doesn't exist. Yet, I know I want to setup a difference between the model data and an "instance" of the model, allowing, for example, two instances to share the same base model, but have two different animations running. When I think of this, it sounds like I should make the "base" model part of the "data" of my engine and the instances part of the "view", but, still, the base model would only be for the view's use, so should it also be part of the view?

This leads to other issues in which I'm trying to do a bit of homework and, as such, has slowed down my work. The slow down is for the better, I suppose. Nothing worse than diving right in then finding I'd need to completely rewrite the engine because I missed something. On the other hand, I hear it's better to just get something working, and worry about refining it later... I mean, tons of developers find they have to start over a few times. Ah well, I'll figure this out eventually.

If anyone has any suggestions I'm more than willing to hear them out!

Short post... no screen shots... ahh well.

## Bug fixes... and a Screenshot Part Duex

[BLURB]: GOT YA! My camera works, finally! I fixed the rendering of the camera too, so it LOOKS like a camera. Nailed an interesting bug in my vector classes, and all is right with the world... oh yeah, another boring screen shot!

[DEVELOPMENT: Archetype Engine]

The blurb basically sums up the massive part of my work. Basically, the camera was screwing up on me. You have ANY idea how much of a PAIN it is to get the horizontal and vertical angles between two objects in 3D space?! Suuure... the arc tangent of the cross/dot products for each of the two planes the objects are sitting on... except one of my objects was sitting at the origin, and, the dot and cross products in that case BOTH come out to zero, so BOTH angles were coming out to zero.

Before anyone points it out, yes, I know that method is actually for two VECTORS not 3D coordinates (well, I know that now, anyway... sue me, my math is a little rusty), but even treating the vectors as two 3D points, I get one accurate angle but the other (the vertical angle), which should be ZERO, flip flops between zero and 180 depending on the quadrant the non-origin object is sitting. Technically, that flip-flopping is mathematically legit, but NOT useful at all!

I wanted to use these angles to generate rotations that I would then enter into a quaternion to generate a rotation matrix... lol, laughable, I know! Then, it hit me... how does gluLookAt generate it's matrix. Soooo... all hail the Google, I looked it up and found a simple formula to generate a rotational transform matrix given an eye, a target, and an up vector (HEY! That sounds like what gluLookAt wants!! Why yes, good sir or madam, it is, that's not the point, moving on please). I will post the method at the end of this entry just for those programmers green enough (as I am) to not know the method by heart, because I know the pain of looking for the answer and you seem sooo close and then the jack-a-mole website you find doesn't tell you!

Anyway, here's a new screenshot of the camera demo...

The demo actually works too! The redish objects are the cameras. Both cameras are set to look at the white cube in the middle. Pressing "W" or "S" will orbit camera A around the cube, while "A" and "D" will orbit camera B around the cube. Very fun... very exciting... will add more depth to this demo over time.

As always, anyone who's interested in downloading and working with the code can get their hands on it here at gitorious... I'm actively working on the development branch, so, if you're looking in the master branch and wondering where everything is, it's still all in the development branch

[TUTORIAL: "LookAt" 4x4 Rotation Matrix Method]

Assuming you have 3 3D vectors, eye, target, and up, where eye is the position of your camera, target is where you want your camera to look, and up to the upward vector of your world, then...
NOTE: up vector should be normalized

vec3d zaxis = normalize(target - eye)
vec3d xaxis = cross(up, zaxis)
vec3d yaxis = cross(zaxis, xaxis)

matrix = xaxis.x, yaxis.x, zaxis.x, 0, # Row1
xaxis.y, yaxis.y, zaxis.y, 0, # Row2
xaxis.z, yaxis.z, zaxis.z, 0, # Row3
0, 0, 0, 1 # Row4

NOTE: For the matrix above to work in OpenGL, the array containing the data is in column order...
Array Index: 1, 5, 9, 13, # Col1
2, 6, 10, 14, # Col2
3, 7, 11, 15, # Col3
4, 8, 12, 16 # Col4

Hope that's useful to someone. Forgive me if it's a little confusing, I'm tired and not thinking with all synapses.

## Bug Fixes... and a Screenshot!

[BLURB]: What can I say? Bug fixes... and a screen shot of a BROKEN demo

[DEVELOPMENT: Archetype Engine]

Still a number of bugs to clean, but I fixed enough of them to get something drawn on the screen now, and it's easier to see the two viewports. Camera's still a LOT funky, though, so a bit of work needs to be done. I DO have a screen shot, however, since someone wanted to see one. Not impressive, but...

Hope you enjoy!

## Technically... a demo is written... errr....

[BLURB]: Viewports and camera and demos... OH MY! Ummm... but demo doesn't work yet... lol!

[DEVELOPMENT: Archetype Engine]

Nothing major to talk about this blog, but I felt I should keep anyone who's still watching this journal apprised... I not have a "viewport" class that handles viewport setup for rendering. It does a little more than simply opening a view port. It can be configured to use "relative" positioning and sizing, and handles the "VIDEORESIZE" event. As such, one can create a viewport that should appropriately adapt it's dimentions and, even position relative to a resized window. Note that I said position... multiple viewports are supported and can be placed in "relative" locations using a 0.0% to 100.0% location scale. Also, position can be based on the center of a viewport.

Of course, that all sounds spiffy, but the one demo I have written now shows a blank, empty blackness (no, it's not suppose to be blank). Therefore, bugs are still abound in my code. However, seeing as I've been writing everything into the library without time to test each unit (horrible of me, I know), I'm actually happy I was able to get a runnable demo at all... yes, it's runnable. A window of the correct dimensions appears and when you press the escape key it closes, as it should. I just need to figure out why my camera wire frames aren't appearing. Ahhh well. Next couple of days I should know.

[PERSONAL DREK]

Just want to thank anyone still reading. Long way to go in general.

## Cameras... soon to be action!

[BLURB]: Archetype engine has cameras! Hope to catch up with the Game Programming Gem series of books!!

[DEVELOPMENT: Archetype Engine]

Did quite a bit of work to give Archetype some camera action. It's a relatively simple camera, using an eye/center scheme ( thank you gluLookAt ). This allows me to move my eye (the camera itself) and it's point of focus (center) independently. There are also a couple of nice methods. One called "pan" which rotates the center coordinates around the eye, and the other is called "orbit" which rotates the eye around the center. Rotations are all handled by quaternion calculations, so there shouldn't be any abnormal rotation artifacts occurring.

Of course, the camera's all well and good, but without anything to see, there's no point to it. I'm close to solving that issue. Firstly, I created a class called iRenderable which, serves as an interface class for all world objects. All it does is store children (for complex constructs... like models), return bounding boxes, and has a couple of empty methods called render and postRender, which are intended to be overridden. There is also a method called renderChildren which calls the render->renderChildren->postRender pipe on all children within an iRenderable object. I dear suggest that, in effect, I've created a scenegraph node structure... and that's where I plan on continuing next... building a scenegraph-esk structure. Ok, maybe not "esk"; maybe an actual scenegraph structure. Once complete, I should be able to write the first demo for the "engine"... exciting!

Of course, if anyone is at all interested in taking a look at the progress, feel free to grab a copy of the repository here at gitorious! NOTE: All the latest updates are in the development branch.

[PERSONAL DREK]

I just got my hands on Game Programming Gems 3 the other day!!! Up until about a year ago, I hadn't even realized they continued the series past the second book, let alone expanded into other gem series, such as GPU Programming and AI Programming. I felt like such a dumb-ass when I learned I fell behind with the series by SIX books! I had a little extra cash the other week (and, technically, that's not true, I just couldn't help myself), so I bought GPG3. I suppose the smart thing would have been to purchase GPG8, but I have a thing about purchasing sequential items in order. I know it's probably silly, but still, I have trouble bringing myself to buy things out of order.

That said, however, I should, hopefully, be starting a new full-time job soon! With the money I'm making there, after I get some personal things settled (broken washer/dryer, fix up car, buy a Droid ... mmmmm... drooooiid... *cough*, and so on) I will be able to continue collecting the gem books and hopefully gain some wisdom that will help me take my engine and games just that once step further

## Singletons

[size="4"][DEVELOPMENT: Archetype Engine]

I hem and haw over these often. Should I use them? Are the necessary? Generally, though, I've come to the conclusion that I need them for Archetype. There are a few components that should not be duplicated in more than once instance. For example, the display class should only be created once. We only need ONE window (and, as far as I can tell, can only create one window), so there should never be any confusion about there being a single one of these objects.

A better argument for my use of singletons, however, is in my events class. I want to be able to access my events class in all objects that need to receive or transmit events, but I want to be able to do it without any object needing to know where to get access to it. So, the question becomes, how do I give my objects access to the global events system, without building into my objects some information about the structure of my engine (and in so doing, causing a breakdown in the reusability of my code)? The singleton has always come to me as the answer to this issue. For each object that needs to send and/or receive events, I can allow them to "create" an event object, send or bind to an event, and I'm done! The beauty of the singleton is, when I "create" an event object, all I'm doing is obtaining a reference to an already existing instance. I make one change to that instance from any object within the game and it's changed system wide! Being that simple, I keep coming back to rely on singletons.

Of course, they also give me a little worry. I haven't even touched threading yet, and there may be some issues that arise when using singletons in a threaded environment. But, for the most part, that's not an issue yet.

So anyway... I've added singletons to the Archetype engine, and, while I've used singletons in other projects, I've come across an implementation which I've been "borrowing" heavily from for my current singleton implementation. For anyone interested, http://www.garyrobinson.net/2004/03/python_singleto.html

[size="4"][RAMBLINGS]

So, ummm... yeah... I'm experimenting with how to organize my journal posts (Yeah... I like the term "journal" over blog). Let's see how this evolves.

GAH! CT is going to get ANOTHER "big storm" in a couple of days. We've got three feet of this white crap in our back yards already... we don't need more! This winter is going to be brutal! If the snow doesn't stop, I'll be spending more time passed out from shoveling than I will be sitting here working on my engine! *Takes a deeeeeep breath*

HEY! I'd also like to thank everyone who's commented so far, and who's been reading my journal. Hope it's been worth the read for you all!!

## I cheated...

Made a few additions to the Archetype engine. Added a very rudimentary display class for opening up an OpenGL window using pygame, a set of vector classes (2D/3D/Quaternion), and improved BinaryFLO's compatibility as a file-like object by adding some of the read-only attributes.

Of course, I cheated a little. For the vectors, specifically, I rummaged through an old 3D project of mine... another library I was working on that wasn't really going anywhere (no focus, unlike this new engine)... and extracted from it, the vector classes I had designed for that project. Looking over them, I have to admit, I like how they had turned out, but the point is, three nice new classes (well, technically 4, but the 4th is a base class) and they were more or less no work to include. That's not to say I didn't do any work at all. I cleaned up a few methods... or dirtied them, depending on your point of view... and enhanced attribute access (long story), so, some work was actually done. I still need to design unit tests for these classes, but, my state got over a foot of snow today, so, I won't be writing those tests right now.

I'm also trying to find myself several good sources for OpenGL programming, especially pyopengl. I have a couple of OpenGL books on my bookshelves, but most of those are almost a decade old (yeah, I've been lazy... and broke) and so they're a little out of date. Good enough to get the basics started, but I think my engine will need a little more than just the basics to be worth anything

So, readers, how's my blog doing? Still of any interest?

## And so, it begins... publicly

In regards to the project issue I spoke of in my last post, I've opted to treat the Archetype Engine as a separate entity from the game that will be developed with it.
If anyone is interested, the repository is public on Gitorious under the team name Bardic Artificers (or bardicartificers seeing as I can't have spaces). Nothing special yet, but anyone interested can track my progress.

## Dieing Hard Drives and Project Organization... Oh MY!

The story begins about a week ago while doing some research on designing an RPG system (as in pen and paper RPG), which I hope to use in the Archetype engine, I begin downloading a small (2MB) PDF file of someone's homebrew game manual. It gets about half way done when firefox promptly reports I have no more room on my hard drive.... Come again?!

Now, when I formatted my hard drive for the Linux OS that now sits within, I opted to create a separate partition for the /, /boot, and /home paths, figuring if I ever need to really really back up any data, it would only really need to be from the /home path and separating it as a partition would make that backup issue simple (not true, as I learned, but that's not the point of this post). In any case, I setup the /home partition with 180GB of space, out of a 250GB hard drive. PLENTY of space, considering I use a lot of external storage (a sort of quirk of mine. I love external hard drives and flash drives).

So, when I looked at the "used" space within the partition (courtesy of "df"), it did, indeed state I had over 95% of my 180GB used up! "BULLSH*T" I replied to the computer, knowing quite well that I tend to clean out my files often enough. Looking up the size of the files within my home directory, I get that I'm only using 36GB of space. Now... I'm the ONLY user on this machine, and, while I'm no expert in linux security, I'm pretty sure nobody else has snuck in a user account behind my back, but still, there's a HUGE difference between 36GB and 180GB, so...

Then I find the issue... using the chkfs (at least, that's the name I recall), I find my system has a handful of bad sectors, for which, I assume, one of them is sitting right on the table describing disk usage, and that's why it's reading 36GB as taking up nearly ALL of my 180GB. I haven't actually let the computer go in and redistribute around the bad sectors, though, which should give me most of my usable space back, but I'm in no big hurry.

Why? Several reasons, actually. I have all my critical files backup on external hard drives anyway, so, there'll be no data loss when then hard drive itself dies. Second, should be starting a full-time job soon soon after which, I hope to be building a new system anyway. Seeing as I plan on building a new system within the next several months, I didn't feel an overwhelming urge to use what little money I have available to buy a new hard drive... not yet. Besides, I do have a second desktop computer and one laptop computer I can move to when and if this hard drive does go before I build the new system. Both the alternative desktop and laptop are a decade and a half decade old, respectively, they're kept in up-to-date state enough to be able to enjoy myself for the interim

The Archetype engine is the only thing I'm nervous about with the death of the hard drive. Not that I'll loose it, because I've already backed it up, but, it has driven me to really think out how I want to organize the project in terms of version control. I know, already, I want to use GIT. I've been a member of Gitorious for about a year now and have a couple personal repos up there already, but the issue to prepping for team work. Most of my projects have been personal. I want to eventually open Archetype to a team of developers, for a number of reasons. This desire has caused me pause and hours of research and thinking both through last evening and most of this morning.

The issue come in where, Archetype is the engine for a game... but not a game in and of itself. I want to build a Neverwinter Nights-ESK game using the Archetype engine, but I don't want the engine technically tied to the game. Perhaps this is me not yet fully realizing exactly where this "engine" of mine should sit in the grand scheme of things. Perhaps I'm over analyzing. In any case, I hope to come up with the project layout by the end of the day... or by tomorrow. Most likely today, though.

For anyone interested in taking a gander, keep an eye out on my gitorious profile for when Archetype goes up!

## Ooooo... New Gdnet & Udc Stage 2

Ah! I love when websites change. It's like unwrapping a Christmas gift. You click on the address and just get all giddy over the new things you will see. In terms of GDNet... yeah, this is pretty dang cool. I like the revamped control panel and how the access to it is right in the upper left corner... very spiffy. The only thing that got me about this whole upgrade is I didn't know it was coming and had JUST subscribed to GDNet+ two days before. I was a little irked when the site just shutdown on me being able to update my blog here, but that's just my fault for not keeping up with the latest GDNet news. All in all, it was worth the day or two I couldn't do anything with the site.

I'm going to say this right now... if my train of thought seems to be rambling on or making little sense, I apologize. I have one person IMing me and another texting me on my cell and my attention seems to be getting pulled in a number of directions. I should just write this blog on a notepad and post it when I'm ready and it's all edited for content, but that's just not my way with blogs. I love free writing.

As for my Archetype engine... the core UDC class and structure is finished and has a working test. At it's core, the UDC structure has "comments" as it's only node type, so, all it can create and load at the moment is a structure for storing and reading in strings. Of course, that's UDCs core... the class is designed to take in handlers for other node types, allowing for the extension of the structure. Did that make sense? Probably not, but moving on...

What's next? I'll probably start putting in some quick code for bringing up a display, then I'll work on using the UDC to create an exporter/importer for Blender. Though, there are other things I realized I need to work on, like a good Exception handling system... something I should be working on sooner rather than later so that I won't be going through so much code to integrate it into the engine. One other thing I'm going to do soon is setup the engine with a GIT repository. My computer already has GIT installed and I've used it with other projects. I even have a small personal server for storing all my backups, but I do need to determine what service I'm going to use to host the public repository... for when I get a team together to work this project with me.

Well, I suppose that's enough for this edition. Next time, more code changes, rants, raves and rabbits... errr... ok, yeah, rabbits!!

## UDC Breakthrough... I think

Gah! Forget nodes within nodes or node trees... I've opted to use a nodes NAME as both a strait name as well as a hierarchy tree!

Example:
N1.name = "Node1"
N2.name = "Node2"
N3.name = "Node1/Node3"
So for this example N3 is a "sub node" of N1!

This is great because this allows me to save nodes in a "flat file" method, but be able to reference them in an tree like way. Also, the naming convention allows me to treat node names like a file system structure of directories and files, making the UDC format great for pack files... which was one half of my intent with the UDC in the first place!

The base class still needs some work. The saving mechanism is a little sloppy, and a lot of the node search methods haven't been implemented yet, but if all goes well, by the start of next week, I can begin designing the 3D model format and building the blender import/export scripts.

With any luck, by the end of next week, I may have some visuals to post with this progress... but let me not get ahead of myself.

## Universal Data Container

So, I spent three hours working on one of the core components for my engine... at least as far as data files are concerned. That would be the UDC, or Universal Data Container.

Basically, I'm stealing an idea from Bioware's Aurora engine. They use a format called the ERF, or Encapsulated Resource File. For the Aurora engine, this mostly contains files, like a package or zip (though, not compressed). The ERF structure is used for the games HAK, MOD, and SAV files (as well as raw ERF files, naturally).

My UDC, I'm hoping, will do the same thing, but on a much more generalized scale. I thought I had drawn out a good design for the UDC, being nodes of data that could, themselves, contain nodes of data. As I poked at it, though, my initial design was becoming quickly cumbersome when it came to calculating out node offsets, since one level of nodes would have to take into account sub-nodes, and those sub-nodes would need to take into account their sub-nodes and so on.

After coming to a moment of pure frustration, I started on a new tactic for tackling this problem. A branching structure where each element in the branch can contain a node and/or child branches. Haven't gotten far with this idea, yet, but tomorrow I hope to tackle some more of it.

What do I want to achieve with the UDC? A single file structure that can be adapted for various custom file-types. One UDC file type for packaging files, one UDC type for a 3D model format, and so on. I suppose we'll see if this idea ultimately holds water or not. I think it will, but I'd be willing to hear anyone's thoughts on the idea.

BTW:
Thanks for the comments on my last post! Hope my journal stays interesting for everyone :)

## Welcome to my bash!

Oh wow! You're reading this! Ok, ok, I guess that means I have to say something a little intelligent! Where to start... Hmmmm...

Oh!
Hello! My name's Bryan, or, I suppose I show up as ObsidianBlk on the forums, not that I've been there much as of yet. I suppose there are a couple things you're curious about. Who I am, what I'm doing here (as in, what is my relation with the great, game development industry), and where the heck did I get the name ObsidianBlk and #!/Bin/Bash?!

I'll begin about 25ish years ago when my father was playing around with his Commadore 64 personal computer. My father has always been a high school math professor, so, his interest in computers was purely "academic", or, rather "Ooooo... cool new gadget!" Ok, for the early 80s, perhaps he was a bit more of a geek than your average guy, and he started learning to program on it. Cyan on darker blue... ahhh the eye strain... anyway... I too, at the early age of 5ish started to learn to program. Did I learn to hack into the Pentagon? Nope, I was more interested in making color blocks flash randomly and scroll across the screen, or (later) Zork-esk adventure games. And so a programmer was born.

On the whole, though, I've made a couple of attempts to get into the industry, to little or no success as of yet. For now, I do game development for fun, but I still want to learn and grow and see where things take me.

As for "ObsidianBlk"... A good game of Wing Commander Armada and earth science in high school bore that name. First time I saw obsidian I fell in love with the rock. Having a call sign "Obsidian Black" sounded so awesome when I blew my fellow classmates out of the stars!

#!/Bin/Bash I'm sure more than a few people on this sight is familiar with. I've played with linux off and on for the last decade, but over the last couple years I have been trying to completely go linux. I love the freedom, but it sucks game-wise. My reaction? Try to rebuild modern games for Linux (and MacOS and even Windows because it's only fair, really). Perhaps I'm biting off more than I can chew, but, then, Linux has plenty of pong and asteroid clones, and, more to the point, I prefer games like NWN and Fallout.

Which, for those of you who've actually read this far, that brings me to what I'm hoping this journal will be about. I'm currently working on design documents and chunks of code that I hope will eventually lead to an Aurora-esk engine I'm currently calling the 7A, or Archetype engine. (Aurora, if you are unfamiliar, is the engine on which Bioware's Neverwinter Nights runs). Within a month or so, I hope to have enough designed where I can start asking for help and building a team. Do I plan on making money of this engine? Nope. Great portfolio piece for those working on it though, wouldn't you say?

Here's to the future! Let's see what happens!