The weekend after the next (from the 23th to the 25th), there will be another 48-hour competition on Ludum Dare.
In these competitions, you get a theme at an appointed time (3am in the morning of Saturday, in my case), and you have to build a game from scratch in 48 hours based on that theme… By from scratch it means you have to make all code, all graphics, all sound, all design, etc, in 48 hours, and release it with source code.
With time, the rules got a bit relaxed (you can do a code framework beforehand, or use a game maker), but it’s all good fun, and I’ve been participating since the first one (although I stopped for a while in the middle).
Thinking on this, I got this idea of doing a retrospective of the games I made in 48 hours… Note that most of these games were created before Spellcaster Studios even existed formally (only on my mind…), and that I did _everything_ you see in the game, in raw C++ with DirectX.
Competition 1 (July 2002)- Theme was “Guardian” and I actually did 1.5 games for this one… it was my first competition, and I was overly ambitious, so I had to scratch my first idea halfway through, and try to finish up something… I ended up with “Supahero – Protector of the Panicking Idiots“, in which you control Supahero and have to defeat some geometric forms before they kill 3 panicking idiots… If I remember correctly, I won 3rd place in the sound category, using only my electric guitar and my wife to do the sounds… this game is almost 8 years old! 🙂
Competition 2 (November 2002) – The theme this time was split between a cosmetic theme (“Sheep”) and a gameplay theme (“Construction/Destruction”). I had this idea of building a FPS in which you could destroy and build platforms in which you stand… Again, it was overly ambitious and I ended up with a game that wasn’t finished… I just got the construction/destruction part, and it has no AI and gameplay… But still, “Sheepdome” is still an idea I’d like to work out one of these days…
Competition 3 (April 2003) – The theme was “Preparation”, and I remembered a very old ZX Spectrum game called “Star Trail” (a ripoff of Star Trek in game form, featuring a procedural universe), and I did a game that featured shooting with angles and power to destroy some targets, considering gravity. It was called “Battlefield: Stars” and after that one, I always wanted to revisit that kind of strategic space combat game (with ships moving and stuff).
Competition 3.5 (Christmas 2003) – This was not an official competition, more of something to do because there was a big hyatus. Theme was Christmas, and the objective was to make a game in a the whole month preceding Christmas (since people were very busy, nobody could allocate a whole weekend to it)… I finished up doing “The Nightmare Before Christmas“, which wasn’t completed… the idea was to use influence markers to steer the elves away from traps and into Santa’s Workshop, so they could make the toys… Only had about 16 hours to work on this total (in a month… 🙁 ), but the result was some of the best graphics I’ve ever done!
Competition 4 (April 2004) – The theme this time was “Infection”, and I created a game called “Virgil“, in which you controlled a virus that had to infect cells, while avoiding and destroying antibodies… It was the first time I gave up on 3d for a 48-hour competition, and the result was that I actually finished this one… And it was fun playing it at the time… I mostly stayed within 2d games for the next competitions… 3d games might be cool to make, and easy aswell, if you have an engine, but if not, it’s just painful and you loose too much time with details, and not enough with gameplay and completion of the game. I went into a two-year hyatus from competitions after this game, for some reasons I can’t remember anyway… I came back in:
Competition 8 (April 2006) – Theme was “Swarms”, and I wanted to create something that would incorporate the concept of natural swarms into the gameplay, and hence “Ant Swarm” was born. The idea was to control one of the ants, which would leave a pheromone trail behind her and the other ants will follow to gather food for the winter. The game worked so well, in terms of concept (not implementation, but it served as a proof-of-concept) that afterwards, Spellcaster Studios (as a company now) would take the concept and pitch to a publisher, which actually agreed to finance it and build a “good version” of it. Unfortunately, the publisher ultimately pulled out, and we couldn’t figure out how to get the game past some design issues it had… But the game is more or less complete in my hard-drive, with decent graphics (two sets of them actually, since we weren’t happy with the first real iteration of them and redone them).
Because of all the Spellcaster Studios issues, I didn’t have time to participate in anymore competitions until 2008…
Competition 12 (August 2008) – The theme was “Tower”, and I was thinking of creating a procedural RPG game for the competition, taking places in the different levels of some mage tower, but I decided against it, for two reasons: one, I was out of practice with this kind of speed-coding, and two, I had a work trip to Dublin schedulled in the middle of the competition, which meant I started the game in Portugal and finished it in Dublin… Anyway, “Brick Tower” was a simple puzzle game, and it was complete, and had some nice ideas in it, although it wasn’t very sophisticated design-wise. Unfortunately, I don’t have the original version of the game (the competition one), only a version with redone graphics by an artist, so it looks a bit better than the version I submitted…
Competition 14 (April 2009) – The theme this time was “Advancing Wall of Doom”, and it was a small nightmare comming up with something to do with it… I finished up doing an “Indiana Jones” kind of game, in which an explorer goes into some caves and has to fight off ghosts and traps to get the treasure. It was called “The Haunting“, and I was quite happy with it… Remindeded me of the spirit of “Rick Dangerous” on the Commodore Amiga, and it is certainly one game I’ll revisit when I have the time for it…
Competition 15 (August 2009) – The theme was “Caverns”, and it marked my return to 3d games for the competitions… and it was a mistake… The game was going very well, it was a game in which the player had to control a robot inside a procedurally generated cavern, to help another robot (AI controlled) get all the minerals in it. Problem was that I wasn’t having fun doing the game, for some reason, and I kind of gave up on it in the middle (48-hour competitions are about fun, so just doing something for the sake of doing, and losing a whole weekend at it didn’t appeal to me). Out of curiosity, the game was similar to what was the initial pitch concept for “Blitz and Massive”, before it turned into a graphical adventure.
Competition 16 (December 2009) – The theme was “Exploration”, and I created “Cursed” for it. The game was about a cursed pirate crew that had to find 8 relics in a procedurally generated pirate world, by getting map pieces, digging around, fighting other pirates, etc. It was one of my best 48-hour games ever, since it was very complete and it really was pleasurable doing… I even did an initial cutscene for this one, and the procedural generated game world and map system was pretty awesome for 48-hours… I even got the hang for some pixel art (hence the cutscene). Hope I can repeate this experience for the next competition…
And that’s it, all the 8 games I did for competitions in the last years… Check them out and have fun (if you can, some are terrible and don’t work too well in modern PCs)…
Can’t wait for the weekend after the next, I’ll be doing updates on my blog on the progress of the game I’ll build…
Lately, on the gamedev side of life, I’ve been working on a platform game structure, so I could create a more or less complete platform game from an editor…
I was considering three engines on which to build the “Game Player” itself: Flash (Flex-based), Torque (Torque Game Builder, more exactly) and Spellbook (my own engine).
One of the most important aspects for me was the ability to use my pipeline to build the game… so that would imply creating the assets in 3d Studio, use a tool we call IBGen to build the sprite images and then use that for the game.
So, I started with a Actionscript exporter for my Flash tries… Although I got a platformer structure working pretty fast, Flash is just too slow for my purposes, which is too bad, since it was going very well:
Flash would have the advantage of running on lots of platforms (Mac, PC, Linux, and so on), with a huge ammount of compatibility, from a HW standpoint (the old PC-dev nemesis!).
I tried Torque Game Builder (TGB) next, with the Platformer Starter Kit (PSK). And while it had some nice ideas, the ammount of work on the code itself that would have to be done to adjust itself to the needs of my project would have been too big, considering that I would have to learn the inner workings of Torque and PSK… But the state machine that the PSK uses was very nice, so I kind of designed a similar system for my own platform system.
So I decided to go Spellbook, and all was good… until I had to do collision detection…
Normally, I do collision detection in 2d either using tilemaps and circles, or by cheating, testing horizontal and vertical displacements separatly and reacting accordingly, but at the end of all projects, I end up with an extremely ugly piece of code that’s too finicky to work with again… and each time I swear I’m going to do a better job at that…
Well, this time I decided to try to do it correctly from the start, using 2d polygons as collision primitives and reacting appropriately (more or less physically correct) to the collisions.
On my initial formulation of the problem, I’d like to find out if a polygon A that will want to move a certain delta will collide with polygon B, and if so, find out when and where.
Some quick searches later, I didn’t seem to find a general swept-polygon test, so I had to implement my own.
My own test is not as efficient as it could be, I think… For example, I can probably take advantage of the fact that the polygons are convex to speed up the process, but the algorithm outlined below is fast enough for my needs…
My algorithm is all designed around of checking if the line segment formed from points Pn and P’n intersect any side of the other polygon:
Pn is the nth point of the first polygon, P’n is that point offset by the delta, so P’n=Pn+delta.
So, check if that segment collides with any of the segments that define the second polygon, taking the one that will take less “time” to hit.
To discover the intersection of two line segments, La and Lb, you just have to solve the equation:
La=Lb
Since La=P1+ua(P2-P1) and Lb=P3+ub(P4-P3), and we’re working in 2d, we get the following two equations:
x1+ua(x2-x1)=x3+ub(x4-x3)
y1+ua(y2-y1)=y3+ub(y4-y3)
Solving for ua and ub, we get something like:
den=(y4-y3)(x2-x1)-(x4-x3)(y2-y1)
ua=((x4-x3)(y1-y3)-(y4-y3)(x1-x3))/den
ub=((x2-x1)(y1-y3)-(y2-y1)(x1-x3))/den
If den=0, the lines are parallel and will never intersect, unless the numerator of both equations are also 0, in that case the lines are coincident.
Finally, if 0<ua<1, the lines intersect, and point of intersection is PC=P1+ua(P2-P1).
One thing I’ve noticed is that since the polygons are convex, you only have test half the segments in the polygon, the segments that are facing the opposite direction from the delta (green ones, in the example below):
The whole function would look similar to:
t_min=FLT_MAX For all vertexes(V) in poly A For all edges(E) in poly B P1=V P2=V+delta t=point_of_intersection(P1,P2,E) if (in_range(t,0,1) and in_range(t,0,t_min)) then best_vertex=V best_edge=E t_min=t end end end For all vertexes(V) in poly B For all edges(E) in poly A P1=V P2=V+delta t=point_of_intersection(P1,P2,E) if (in_range(t,0,1) and in_range(t,0,t_min)) then best_vertex=V best_edge=E t_min=t end end end if (t_min==FLT_MAX) return NO_INTERSECTION TimeOfContact=t_min PointOfContact=V+delta*t_min NormalOfContact=E.normal()
One important thing about this routine: it just handles collisions through movement (if the object is already colliding when the test is done, it will acknowledge no collision).
Now, collision response is as important as collision detection, since that’s where lots of things can go bad…
When we don’t detect a collision on object A moving a certain delta, end position of said object is just:
posA=posA+delta
But what happens if we have a collision?
Well, we have to contemplate some movement and modify the delta, according to the normal:
if (test_collision(A,delta,TimeOfContact,PointOfContact,Normal)) then posA=posA+delta*TimeOfContact else posA=posA+delta end
But imagine you have gravity and are moving to the right, so that delta=(10,10) and you detect the collision time is 0.2 (from a possible 0..1).
So, you would move down 2 units, and to the right 2 units, and then stop, instead of moving 10 units to the right, since nothing is stopping the player from doing that!
So, we need to account for multiple collisions during the whole time interval, and we get to something like:
float total_time=1 while (test_collision(A,delta,TimeOfContact,PointOfContact,Normal)) then posA=posA+delta*min(TimeOfContact,total_time) total_time=total_time-TimeOfContact delta=delta-normal*dot_product(normal,delta) if (delta.is_null) break end
The “delta=delta-normal*dot_product(Normal,delta)” removes the offending movement component from the displacement vector. In the above example, the new delta would be (10,0), and we would only have 0.8 time to move on that vector. This would create the correct final position of (10,2), instead of the incorrect (2,2) of the first version.
Now, there’s a final problem with this solution… Since our poly/poly intersection function can’t handle cases where a collision is already existing, this would fail, since the first intersection would make the first polygon be lying just on top of the the second polygon, intersecting the edge (correctly), but future movement would pass right through it…
You could handle this case by checking for colinearity and a series of other processes, but I found out that the simpler way to work this through is now to allow the movement that would bring us to that limit case, by just changing the order of a couple of operations:
float total_time=1 while (test_collision(A,delta,TimeOfContact,PointOfContact,Normal)) then delta=delta-normal*dot_product(normal,delta) if (delta.is_null) break posA=posA+delta*min(TimeOfContact,total_time) total_time=total_time-TimeOfContact end
While this isn’t as correct from a formal standpoint, it works great in practice, stopping those small edge cases that can be quite tricky to get working correctly…
Any questions, or suggestions of improvements, let me know… I’m sure I can make this a better algorithm by taking in account the fact that the polygons are convex.
Note that this algorithm works with concave polygons aswell, but you’d have to remove the dot_product test on the poly/poly intersection test, and make sure the scale of the objects are very different, so that you don’t have simultaneous collisions to handle, which happens quite easily in concave polygons.