Breaking Radio Silence

Wow, it's been forever! I've been... distracted indeed. I did a bunch of medical tests for my stomach troubles that have been bothering me for upwards of 15 years (about time?), I played the Diablo 3 beta test, I started letting Titan Quest sink its vicious hooks back into me (out of desperation for Diablo 3 not coming out soon enough), I began playing Assassin's Creed 2 (It's a-me, Ezio!), I obsessed a bit into WoW again (never stopped, but the amount of obsession does vary), I spent a bunch of time dealing with artist considerations (gonna work with a couple soon, I think, but not on my current game!) and the main thing is:

I've been working on my next game! This ties back into Diablo 3. I've been working hard because I am not allowed to play Diablo 3 until it's done. So that's a big deadline. May 15. I don't know if I'm going to make it, but if not, well, no Diablo and no TV make Homer something something. Note: TV isn't disallowed. But the game is feeling really good. Lots of skill points and all that stuff I love, and what I think is turning out to be satisfying kung fu action. It's hard to tell since only the beginner parts are available, so you can't do amazing combos yet.

Wanna know what it is?
Comments Off

Dynamite Jack: Game will launch with map editor

Hey there .. a bunch of my beta testers really wanted the map editor to be part of the game, so .. well .. I went ahead and just got it done. So Dynamite Jack will launch on May 10th with the Map Editor! I created a tutorial video that both demos the editor and turns you into a Master-Of-Maps in about 3 minutes. Check it out.

This was pretty much a last minute decision, and a bit of a hair raising experience, as the first build I created and sent to the beta testers that included the editor actually broke some of the game levels. Fortunately, the fix was pretty easy and I got that under control. It’s always a bit risky adding new features this late in the development cycle, but I felt that it would really add a lot of value to the game for people who enjoy creating levels.

It also includes a whole community section where levels will be shared, so people who just enjoy playing will get way more than just the 28 included levels :)

Disclaimer: this is coming to the desktop version of the game. I can’t guarantee that it will be included in the iPad version of Dynamite Jack. That will really depend on how well the editor interface transfers over. If it doesn’t work well, I will not include it.

-Phil

Posted in dynamitejack | Comments Off

Chickens and eggs

As we know, using nil is a little bit heavy in sool: optional variables must be “casted back” to non optionals using the if as syntax, or the boolean operator or. I was trying to write a simple linked list class without using nils, just for the sake of it, and realized it was simply impossible.

A non optional member must always be initialized, and if it is an object class, that means that it must point at an existing object. Which implies that an object class may never have a non optional member of its own class. Indeed, how would you ever build the first one?

That’s too bad. There are legitimate uses of objects pointing at other objects of the same class, in which these references are always valid (never nil). For instance, a circular linked list: the last one always points at the first one. Or even a simple linked list, where you mark the last element by making it point at itself. Trees may want to do the same for their leaves.

Even though we know for certain that these references will eventually all be filled with valid objects, the simple fact that objects are created one after another forces us to make some references optional, for the time span between the object creation and the references’ initialization.

Could there be a magical workaround? Certainly. A trivial way would be through a default initializer. In an object class Foo, a member of class Foo that is not explicitly initialized can be set to point at the object itself:

object Foo
    Foo member
end

-- elsewhere
foo = Foo               -- implicitly does foo.member = foo
bar = Foo(member = Foo) -- normal explicit initialization

Of course, we could never do that before, because the instantiation syntax is a normal expression, and in this expression, variable foo doesn’t exist yet:

foo = Foo(member = foo) -- what, I don't know any "foo"!

There could be a special keyword, to avoid the implicit stuff (implicit means slightly equivalent to black magic, which is bad):

foo = Foo(member = this)    -- yay, C++ keyword

But too many keywords is bad, and this is a really special case. Further more, it does not solve mutual references. Indeed, the problem is more general. If an object refers to an object of its own class through any number of non optional references, it cannot be created, because none of the objects on the loop can be created in the first place.

object A
    B b
end

object B
    C c
end

object C
    A a
end

And here, the “point at itself” trick will not work, nor a hypothetical “the object being created” keyword. To make anything like this work, we would need a magical “simultaneous instantiation” system, in which we could use special names to refer to the objects being created. Something like:

make a,b,c with A(b = b),B(c = c),C(a = a) end

In fact, maybe simply this would be enough, provided that the compiler “registers” the names a, b and c as available for the right hand side expression:

a,b,c = A(b = b),B(c = c),C(a = a)

That is highly irregular and weird. However, if we only have a chain of objects, only one special name (pointing back to the outer object) is required:

a = A(b = B(c = C(a = SPECIAL)))

Then again, that really solves only the chain situation, and no other: there could be graphs of objects of different classes pointing at each other:

object A
    B b
    C c
end

object B
    C c
    D d
end

object C
    A a
    C c
end

object D
    C c
    B b
    A a
end

Good luck with that one. There, only a fancy simultaneous instantiation would do, with some kind of name reserving. It would need to:

  • declare local names with their future types
  • run initialization methods with “placeholders” values where we don’t have objects yet
  • resolve the placeholders by filling in the actual references after the memory is allocated and we get pointers

Sadly, this is completely crazy. Then again, having a graph of different objects that all point non optionally to each other may not be a good idea in the first place either.

Conclusion: a linked list without nil is impossible in sool. Adding the “initialize member to self” feature would be really just a hack to make this specific case possible, but it wouldn’t solve the general issue.

In any case, even with objects that point at themselves, you simply replace nil check with self checks, or comparison with a dummy object. Not sure it’s a useful tradeoff.

Having to explicitly to nil checks, and name a new local variable to take the valid reference might seem heavy, but it is a necessary evil. After all, in Rust (the inspiration for this feature), you need to do the same:

Optional types are defined as enums:

enum option<T>
{
    none,
    some(T)
}

And used with the pattern destructuring thing:

/* var is our variable of optional type */

alt var
{
    none
    {
        /* the nil case */
    }
    some(x)
    {
        /* the non-nil case, use x */
    }
}

You need to use a new local name to match the enum and “catch” the value in the some case. Heavyer syntax is the price for memory safety. And I think it’s a price worth paying.

Like in Lua, where locals in for loops often take the same names:

for i,v in ipairs(tab) do
for k,v in pairs(tab) do

one can imagine that habits will come in sool for naming the non-optional promoted variable:

if opt as x then
if opt as nopt then

x = opt or Foo
nopt = opt or Foo

In any case, this should remind us that optionals are expensive, and should be used with care and moderation.

Update on generic fors

Still trying to write a hypothetical linked list class, I came across the question of the iterator function, so that my list works with the built-in generic for.

If you recall, I had decided that the generic for would work somewhat like in Lua, with:

for elem in expr do
    -- block
end

being replaced by something like:

do
    obj = expr
    iter = nil
    while true do
        iter,elem = obj.next(iter)
        if not iter then
            break
        end

        -- block
    end
end

with iter some kind of hidden variable. It starts at nil, and it’s passed to the object’s next method, which increments it (whatever that means for the given class), returns the next one, and the associated value.

This is a nice “all in one” mechanism, where the next function has to deal with every case:

  • if the iterator is nil, set it to the first valid “index”
  • if it’s not nil, increment it
  • if it’s still valid, return it and the associated value. If not, return nil

The last “return nil” thing would signal to the loop that the job is done.

That’s semantically nice, but in practice, I see a few annoying things:

  • the big “all in one” function will have lots of nil tests and branching, which might make it look bulky or unclear.
  • additionally, this single method combines different tasks (initialization, incrementation, final test) which are in a way “selected” at each invocation depending on arguments. This results in more testing and branching at each iteration than a traditional for.
  • during the last iteration, once the index becomes invalid, we still have to return a (dummy) value, even though it won’t be used (the loop will break right after). That didn’t happen in Lua, where you can return a different number of values at at invocation, but it appears here, where types are static.

I had a look at D’s generic for: foreach. Not only is it built-in for every possible interesting type, but it also works on user defined classes, as long as they follow a certain interface:

foreach (e; range) { ... }

translates to:

for (auto __r = range; !__r.empty; __r.popFront())
{
    auto e = __r.front;
    ...
}

That looks a lot more like a traditional for, in C or C++. It uses a separate object, here called range, which reads the data from the outside, and keeps the state of the iteration. In sool, we could have something like this:

interface Iterator|(Any T)
    bool    done()
    T       current()
            next()
end

All the collections that want to work with the generic for would need to have a helper class that implements these methods. Then,

for elem in obj do
    -- block
end

would be:

do
    iter = obj.iter
    while not iter.done do
        elem = iter.current
        -- block

        iter.next
    end
end

with the iter variable hidden, as usual. As we discussed before, in order to have several different iterations possible, the loop could skip the iter = obj.iter step if the given expression is already compliant with the Iterator interface. That way you could have a default iterator, and the others accessible with methods:

for elem in obj.rev_iter do

and also, there could be several element variables, if the iterator needs to return several:

interface Iterator2|(Any T, Any U)
    bool    done()
    T,U     current()
            next()
end

for i,v in somearray do end

I wrote these interfaces using the language syntax, but they do not need to be actual sool-side interfaces, since the iterator variables are hidden anyway. When validating code, the analyzer will simply check:

  • does the expression answer to current()?
  • if yes, does the number of return values match the number of local names provided?
  • does it also answer to next() and bool done()?
  • if it fails for any of these, check if the expression answers to iter()
  • if yes, check the same conditions for the return type of iter
  • if not, complain

And now, oh joy, the three methods are always statically bound, each does only exactly its task, and if these tasks are smallish, they will likely be inlined, and we end up with something exactly as efficient as classic C++ for loops, even for built-in types and arrays. Just remember to use value classes for the iterators, so that they end up being strictly equivalent to local variables holding the state of the iteration.

Now we can happily have nice helper classes like ranges:

value Range
    uint current
    uint stop

    method bool done()
        return start == stop
    end

    method next()
        current = current + 1
    end
end

extend uint
    method Range ~(uint other)
        return Range(start = this, stop = other)
    end

    method Range iter()
        return Range(start = 1, stop = this)
    end
end


-- elsewhere

for v in 2 ~ 10 do
    -- fuubar from 2 to 10
end

for v in 20 do
    -- fuubar from 1 to 20
end

Pretty!

In fact, we could even combine the current and next methods: since they are called each exactly once per iteration, there is no need to keep them separate:

value Range
    uint current
    uint stop

    method bool done()
        return start == stop
    end

    metho uint popfront()
        tmp = current
        current = current + 1
        return tmp
    end
end

And then,

for v in something do
    -- use v
end

would be in fact:

do
    iter = something.iter       -- or directly "iter = something" if something is an iterator
    while not iter.done do
        v = iter.popfront
        -- use v
    end
end

The proof by example

I did a few tests in C/C++ with these different models of iterations, using clang at the highest optimisation level

I have a dummy class Fubar, and an array of references to a hundred of them:

Fubar *arr[100];

for(int i = 0 ; i < 100 ; i++)
    arr[i] = new Fubar(i);

Then I make an array iterator, which simply holds a current pointer, and an end pointer, similarly to what std::vector might do:

class FubarArrIter
{
    Fubar **first;
    Fubar **end;

    public:

    FubarArrIter(Fubar **f, Fubar **e) : first(f), end(e)
    {
    }

    // ...

And the iteration methods we discussed:

    // ...

    bool done()
    {
        return first == end;
    }

    Fubar *popfront()
    {
        return *(first++);
    }
};

Then I iterate as discussed before:

ObjArrIter it(arr, arr + 100);
while( !it.done() )
{
    Fubar *elem = it.popfront();
    printf("%d\n", elem->v);        // Fubars have a member 'v'
}

Thanks to inlining, this code is equivalent to writing loops by hand:

for( Fubar **ptr = arr ; ptr < arr + 100 ; ptr++ )
{
    printf("%d\n", (*ptr)->v);
}

Really! The LLVM assembly generated by clang is exactly the same (except some instructions that are not in the same order). This is great, because it means that our model is not only semantically valid, but also realistic in a performance point of view.

For the sake of comparison, I also wrote a method that would be closer to the Lua iteration model (one function that does it all, returns NULL once iteration is over):

Fubar *Fubar::next()
{
    if(first < end)
    {
        Fubar *tmp = *first;
        first++;
        return tmp;
    }
    else
    {
        return 0;
    }
}

and it is used as such:

ObjArrIter it(arr, arr + 100);
while( Fubar *fu = it.next() )
{
    printf("%d\n", fu->v);
}

Of course, it works as well. However, even with the same amount of optimization, the low level code is not as simple: it contains two branches, instead of one for the “classic” loop. Indeed, two branching comparisons are done. The first is inside the function: if(first < end). It checks if the iteration is done, and signals it by returning NULL instead of the next pointer. But then, outside this function, another test is done: checking if the inner function returned NULL: while(fu). So basically, the same thing is tested twice: once from the actual information, which is “signaled” to the while loop, and once by the while loop to check the signal.

In the other model, the popfront method does not check if the current state is valid, and always returns a value. It assumes that the compiler checked done before calling it. Since the iterator does not need to “signal” the end of iteration through the same channel as the normal results, there is no use of NULL, and therefore no additional NULL check. Of course, when writing an iterator, if the done function is incorrect, things will probably go wrong. But then it’s really your fault.


Posted in sool | Comments Off

Dynamite Jack: The “Stealth Target” post-post mortem

So at the end of 2010, Ludum Dare hosted the “October Challenge” .. This was the CHALLENGE:

Make a game — take it to market — sell 1 copy (or license it, or earn $1 in ad rev) in one month.

So, with my dream of making a commercial game out of Dynamite, this seemed like a perfect opportunity. With a single month time frame it was perfect for seeing what I could do.

Gameplay

Here’s a video of the gameplay. You’ll see it’s almost the same as Dynamite, though I’ve added several types of bombs, which kinda just makes things more complicated. One BIG advantage over classic dynamite is that the “shadow” along the one wall is actually visible so that makes a lot more sense logically, for the stealth part of the game.

Challenge Month

Oh man, it was a ton of fun! I blogged the whole experience. Here’s a “short version” of what went down:

I used the same free graphics I used in Dynamite for the character art.

And started whipping the game into shape really quickly. I was doing this all in my own custom 3D renderer. Which is a crazy thing to do, I think. At the same time, the progress in the first week was really exciting, and I was quite pleased with how the lighting and stuff was coming out. In this game the lighting had little purpose other than to “be pretty.”

Here’s a newer shot of my level editor. The level editor could be used in overhead mode (which was easier to use) or in the iso-view, which was way cooler.

And before the end of the month, I even added in sharing / community features for the level editor to the game. It’s crazy how much stuff I got done in that month!

Paid Beta

So on November 5th, I launched the Paid Beta of the game.

I gotta say, I was pretty stoked about the sweet game I had just made! But that was all about to change … well, eventually :)

I got about 50 pre-orders of the game, which was, honestly a bit underwhelming. Lots of indies talk about “we did this pre-order and it paid for our 3 person team’s dev for the last 9 months of development time”. 50 pre-orders paid for .. well .. not that much.

Refunds

So, people seemed to sort of like the game. But over the next couple of months of working on it, I was realizing that it wasn’t coming out as the epic desktop game I had originally envisioned. It seemed to be a better mobile title. So I cancelled the beta. Here’s an excerpt from my blog with the lessons I learned.

Here’s some analysis on the subject, and why it didn’t work for Stealth Target .. and at the same time, the factors I think that would be important to having a successful paid-beta project.

  • Commitment to a larger vision. In the case of Stealth Target, I had a larger vision, but I eventually realized it was too grand for me to realize.  I’m more of a small-scale game kind of guy at this point.  Perhaps later in my game development career I’ll be doing larger projects, but right now, a “Galcon-sized” game is about as large as I can manage.  I think paid-beta games need to be larger to justify the whole “user-buy in to help fund an epic game” concept.
  • Commitment to regular updates. I’m only one dev, and when I take a month to work on Galcon updates, and then take another month to take a break, suddenly the beta users haven’t heard a peep from me about the game in 3 months.  Pretty weak “paid beta”.  If I had a team and I had someone always working on the beta so it kept living despite my other obligations / plans, it might have gone better.
  • Building a development team. Yeah, I just touched on that, but it really does make sense.  I could have a team, but my lifestyle doesn’t allow for it at the moment.  My hours are too random and my work schedule too unpredictable.  To have a team you have to have some consistency in your life, otherwise (I’m pretty sure) your team-members will get pretty tired of you.  I think having a team would help deliver the quantity and quality of content and updates to make a paid beta make sense.
  • You can’t change your mind and be crazy. I still plan on finishing Stealth Target, however, I’m no longer planning on doing a desktop release of the game.  The paid beta was for a desktop version of the game.  So changing to a iOS-only plan really isn’t possible.  The only way to cleanly resolve this was to terminate the entire beta and issue refunds.  Really, for a paid-beta to make sense, the users have to have something they can depend on, and changing platforms mid-stream is just asking too much.

But the game was still in development, I was just switching over to targeting iOS instead of a desktop game.

Canceling the Project

So a couple months later I went to GDC with a build of the game in hand. I showed it to a handful of peers and demoing the game was extremely cumbersome, the user interface was .. well .. AWFUL. I could barely play the game on the iOS device I had in hand. I also was starting to feel that the visual feel of the game wasn’t “coming together” in a neat way at all. It looked 3D and all, but it was looking very dodgy overall.

Also, the code was starting to buckle under the weight of what I was doing. I was trying to add fancier lighting effects, which were not working very well :(

Adding things like shadows to the player and guard was not going to be possible. Shadows for different height pilars wasn’t working. There was an endless list of issues. And as you can see, the character art just plain looks bad when close up, which is how it was being shown in the game.

After demoing it to some friends at GDC, I decided to cancel the game. Which was really hard to do, I had put 5 months of effort into this game, and putting it down wasn’t easy at all. I realized that though I had some good ideas here, things weren’t working out. It would have taken me at least another 6 months to get the game ready for release and it wasn’t going to come out the way I wanted. I definitely think this was the right decision.

One of the things I’m thankful for is, by being an indie, I GET TO MAKE MY DECISIONS. So even though it was one of the hardest things I’ve done as a game dev, it was my choice. It wasn’t made by some corporate overlord, who suddenly took away the last 6 months of my life. It was my choice. I can’t imagine how hard it is to have part of your life taken away like that when you have no say in it. I’m very thankful that I’m able to make games as an indie.

Going Forward

Thankfully, six months later, I began work on what is now called Dynamite Jack. If you haven’t seen it, here’s the trailer, to give you an idea of how it came out.

Some of the lessons I learned because of the Stealth Target failure:

  • Don’t use 3D. For a small-scale indie, using 2D is soo much easier. I’m able to do all these cool lighting effects without having to be some kind of genius.
  • Don’t use weird controls. Arrow keys / Gamepad works WAAAY better for this type of player navigation.
  • Don’t confuse the user with too many types of bombs. In Dynamite Jack, there is one. And it gets the job done.

Those aren’t LAWS for everyone, but learning those lessons while creating Stealth Target enabled me to finally create the game I wanted to make.

I’ll be blogging about more of the dev of Dynamite Jack over the coming week. The game is coming out on May 10th to Steam on PC and Mac.

Posted in dynamitejack | Comments Off

Shifting Focus

For this, the blog’s 200th post, I wanted to share some ideas that I have been pondering recently. Long time readers of the blog will recall an article I wrote about how the challenges presented in games are a core component of the design and to a large extent, “define the gameplay…”. In that article, I mentioned a classic game of old called Descent by Parallax Software. Lately, some friends and I have been getting back into the multiplayer portion of the game by way of the DXX-Rebirth project which adds some features and updates it to compatibility with modern machines. Descent is as excellent and classic as I remembered.

I can give some summary and identify some key points, but it’s hard to convey what makes Descent so special without you playing it for yourself, so if you haven’t, I highly recommend it. The full rotation and free-flying freedom are the golden basis of this game. Descent’s circle-strafing, dodging, rolling, flipping, fast-paced flight takes the combat of a typical first-person shooter and elevates it to true thrill-ride status. Every aspect of the game is multiplied by the additional freedom in movement, including tactics. Each of the weapons and missiles uniquely contributes another possible tactic. The game’s core design is fairly simple, but its implications are deep and varied. Modern designers could learn a few things by firing up some matches of this game with some colleagues.

Now that I’ve established the game’s quality for you, think about this: Descent was released a mere year and a half after Doom, and over a year before Quake. I recognize the accomplishments of id Software’s titles, such as classic FPS gameplay and the use of BSP trees for rendering and so on, and I like their games – I have nothing against them, let’s get that out of the way. Still, I don’t understand why Descent isn’t regarded with the same level of acclaim. While Doom has you running and gunning against demons in flat, minimally 3D environments, Descent gives you the freedom to fly without restriction in creatively designed, completely 3D areas. While Quake improves the technology, the gameplay still struggles to eclipse the lasting appeal of Descent. Don’t get me wrong, I like Quake and Descent. But what would the gaming world be like today if its participants had latched so tightly onto Descent instead of the origins that led to the flood of first-person shooters we see today? Better yet, what if it had learned from the best parts of both?

It’s food for thought, to say the least.

If you have comments on these classic games, or if you would like to throw in another great game that deserves more attention, leave a comment!


Posted in Descent, design, Doom, games, Links, Quake | Comments Off

Ludum Dare 23 – Week 1 Games

This is a list of all of the games I played during the first week of rating. On Sunday I planned to just play two games per night, but Monday decided that I should do five per night, that way I will have slightly over 100 games at the end of the rating period, yet still be consistent in rating games each night.

Sunday:

T-Pod by Spiridos - First Ludum Dare 23 game I have played. A defend the tiny planet game, complete with sound, music, and how to play text. Its a bit on the hard side.

Urth Defense By Kylerhoades- This is a tiny game, about defending a tiny planet, from tiny nuclear missiles, while being inside a tiny ship.

Monday:

Tiny World Defense Force by Beanalby - This is one of the games that stand out so far. In the game, you defend a large planet…by controlling a tiny planet. The game is a well rounded and complete entry.

When Worlds Collide by AlwaysGeeky – A voxel style game featuring a tiny planet that you goal is to destroy. You can fire asteroids at it, send comets crashing into it, or vaporize the surface, and to destroy the planet within the time limit you will have to use all three.

Creature Collect by Moop – A retrieve and deliver game set in space. You have to collect creatures form tiny planets and take them to a merchant.

Genesis by Tyruspeace – This is a game about guarding plants from buzzsaw robots, on a tiny hexagon grid planet.

Gravity by RÉMI- A really cool take on the theme, that has to making the background music, while defending your tiny world. Very well done entry.

Tuesday:

Escape By Chrismcr - This game has you on a mission to collect a number of resources, deliver them back to the starship, and then leave the planet all before your time runs out. No sounds or music, but the gameplay and graphics are solid.

Homedefender by Hopps - A defend the planet game, you use a turret that is mounted to a tiny planet to destroy incoming missiles.

Stade 2 (Mr. Oizo) by 30Dogs - An abstract music platformer, that you have to get the correct timing, and quickly respond. A really cool game, looks great and the music fits really well.

The Tiny World of Fiorella by Strega – A cool rouge-like adventure game, the art and music are great.

Pro Stew Chugger by Tourgen- A shooter game with multiple rooms and doors that link back to each other.

Wednesday:

Microbial By Lukrissacher - The first puzzle game I have played. Set at a cellular/ microscopic setting. The game is complete, and has fourty levels.

Tiny World Adventure by Pabloam - A 2D adventure game, you play a cell with the goial of reaching the end of the tiny world.

World Pong by Poohshoes - An interesting interpretation on the theme, that has you playing pong by yourself. Lacks in the gameplay department.

Invasion of the Planet Snatchers! by icefox - Another interesting idea, but lacks in the actual gameplay department.  Has sounds and a solid game idea.

Celluloid2D by Vertebro- An Asteroids style game played at a microscopic scale. Overall a solid game. I found it interesting that it was written in AutoIt3.

Thursday: (Web Game Day…aka being lazy)

Ant Surf Hero: The Surfening by Jigxor – A platform game that has you kicking ass and taking names, while surfing an ant that is larger than you.

Magic House By Vitou3d – A 3D puzzle game that you shrink or grow to complete the room.

Balance by Hadesfury – A 3D game set on a tiny world, you control a ball, and have to herd creatures to the middle point.

Spittoon by Sestren – A 2d puzzle game, using three colors you have to activate colored switches by spitting the colors at them. Lack sound effects and music, but is otherwise a really nice game.

Pet Planet by BMouse- A gameish simulation that has you taking care of a tiny planet.

Friday:

Nook by POV – A platformer game, that you play a lizard that grows and shrinks to complete the level.

LittlePlanetBigRocket by daredevildave – A puzzle game set on a tiny planet, you are in control of a space faring being, and must escape the planet within the time limit.

A Load of Bulls… by Frib – A 3D survival game, that you have to survive bulls coming after you for as long as possible.

Nineties Holywood Hacker by Casino Jack – A 2D maze like game that you build a maze, using an interface like a pipes game, connecting a start to an end, then you have to fly a ship through it and defeat firewall enemies. When you finish a level you can upgrade your ship with damage, and buy more health. Overall its a good idea, and for a game made in 48 hours its quite good.

The Green Planet by Munch- A 2D score game, that you gain score by forcing the asteroids into Jupiter and picking up the chunks that flake off.

Saturday:

Nano Ascension by MikeLovesRobots3 – A 3D puzzle game, a very good entry that is complete with voice acting, sound effects, music, and a storyline.

Haxe Planets By jrfoco - A 2D platformer game created in Haxe, you have to guide your character to the end of the level, but the only control you have is jump.

Men Not Wearing Hats by Nilstastic – A 2D platformer game, that you have to steal diamonds from the men not wearing hats, without getting caught.

Rocket Boat by Rhy3756547 – A 2D platformer? (kinda) that you control a boat set on a tiny world, and your goal is to destroy the city.

Tiny Defenders by Raptor85 - A tower defense game, you play ant defending their colony, against other ants. There are three tower types, and they can be upgraded.

Posted in Game Development, Game Jams | Comments Off

Dynamite Jack: Enable Roger Wilco Mode

While developing Dynamite Jack, my pal and co-host from Ludum Dare, Mike Kasprzak suggested that the deaths didn’t have enough emotional impact. So I added more awesome deaths. ROGER WILCO STYLE.

Enjoy the Anathema Mines Chamber of Commerce Video:

When I first added in these crazy post-death animation sequences, I kind of felt they might be a bit “over the top” for my game .. So I added an option to toggle them on or off:

But they are so much fun, well, I’ve got it default to have them on :) But if you find them too gruesome (or silly), you have the option to turn them off.

During the game play, deaths are frequent, so they are only 2 seconds long. This keeps the flow and rhythm moving at a nice fast pace. The leaderboards of the game include the time it took you to complete the level as well as how many times you bit the dust :)

Anyway, the game is coming out May 10th! Hope you’ll enjoy it!

-Phil

Posted in dynamitejack | Comments Off

Nook and Emscripten: A technical look at C++ GameDev in the Browser

I run an online game-jam event called Ludum Dare, and this past weekend I got together with a friend (Derek Laufman of Halfbot) and we made a game. What did we make? A platformer about size.

Nook - A game where size matters. Click the image to Play!

The game was created over a period 72 hours. Somehow, amazing to me, we managed to pull it together despite our responsibilities.

  • Me running the event (Ludum Dare)
  • Family gathering at my brothers I attended on the Saturday
  • Car appointment on Monday
  • Derek taking care of his baby

Fortunately, running Ludum Dare is only busy for me before the event, and at submission time (two of them, 3-5 hours each). During the event I’m free to sit down and do whatever I want. This weekend was the Diablo 3 beta test, and if I was a lesser man, I’d have played that. Fortunately for me, Derek came to me a couple weeks ago and suggested we make a game together, I said yes, and the rest is history.

It’s totally silly, but I’m actually proud of the fact that I managed to attend the family gathering and the car appointment. Stupid me, I could have actually cancelled/rescheduled the appointment for Tuesday or Wednesday, but I decided to go ahead with it anyway. The car appointment was my yearly service for my smartcar, and I ended up staying in the neighborhood of the dealership for about 5 hours of that day. Working on my Ludum Dare game on my laptop, I had WIFI at the dealership, and also McDonalds, where I parked myself for a couple hours. To be honest, this was probably the first time I seriously “Coffee Shop Developed”, and where I actually got some serious work done. It was fun, because it was out of the ordinary. :)

Anyways, that’s enough back story. Lets get nerdy.


Emscripten

Emscripten is a wonderful tool. I’ve been jokingly referring to it as witchcraft and other colloquialisms for evil, since it does something rather outrageous: Compiles C++ to JavaScript. To some programmers (vocal programmers), that just might be one of the greatest heresies ever committed to page (thou shall not mix chocolate and peanut butter). Me, I actually quite like JavaScript, having developed a taste for it last Ludum Dare.

I’ve been a big supporter of the idea behind similar “C++ to Web” technologies (Adobe Alchemy, Google Native Client), but both seem to have some issues to deal with today (was not part of the early access program, not enabled by default in Chrome). Emscripten on the other hand is out there, it’s free for everyone, and it works on all browsers today. Emscripten’s problem seems to be one of obscurity (success stories forthcoming), how unbelievable the idea of C++ to JS is to most developers, and the technical know-how needed to use it.

Setting Up Emscripten

I wont bother with a step by step description. You should go here for details:

https://github.com/kripken/emscripten/wiki/Tutorial

I will however talk about my specific configuration.

Me, I run Emscripten inside MSys, which is MinGW‘s faux Unix shell. If you’re not familiar with MinGW, it’s a GCC compiler suite and libraries needed for building apps for Windows. Emscripten’s “emcc” works just like GCC, but generates JavaScript code. So a nice bonus with my setup, I have everything needed to make both Windows and Web “binaries”.

To use Emscripten, you need version 3.0 of LLVM and Clang installed. As a Windows user, for whatever reason, 3.0 binaries were unavailable (older binaries were). So I had to manually build them on my PC via the MSys shell.

Read the instructions on installing Clang. Clang and LLVM are built at the exact same time via LLVM. Building is done in a typical “./configure; make; make install”, like you would do on a Linux. Browse to the LLVM root folder, run configure (“./configure”), make it (“make”), and make install it (“make install”).

If configure complains about a missing Linux’y package, you can use the tool “mingw-get” from the command-line to install additional packages (just like on a Linux). mingw-get install package

Grab Python 2.7, and add the path to it to your “path” environment variable. Parts of Emscripten are Python.

Grab Node.js. This is needed to run JavaScript code from the command line. Parts of Emscripten are written JS.

Grab the Java Runtime (OpenJDK if on Linux). This is needed by Google’s closure compiler, which is a tool that will later help you obfuscate and optimize.

That’s everything. Follow the tutorial and build something pretty now.

Using Emscripten

Emscripten uses magic, also known as LLVM and Clang to convert C and C++ code to bytecodes, and reconstructs new JavaScript code based on those generated bytecodes. You should have an understanding of JavaScript coming in to this, as it’s often wise to check the generated code to see what LLVM+Clang+Emscripten are doing, especially when starting out. The project is mature and functional, but you will learn more from seeing and doing than you will from reading documentation. The documentation is good for filling in the gaps of things that aren’t typical with a normal GCC-like C and C++ compiler.

A typical project generated by Emscripten will be an HTML file (eg. index.html) and a JS file (eg. mycode.js). I like having a separate HTML file, as it means you can include other things (external map data files) inside it. If you wanted to though, you could include the JavaScript code right inside the HTML file.

Crunch Time Compile Script

I didn’t have much time this weekend to think, so I did all my compiling via simple shell script that I tweaked and added to whenever I needed. Normally I’d have a proper makefile system for building, but I was still learning the ins and outs of Emscripten, so I opted for more hackibility.

#!/bin/sh

#export CC='~/Code/emscripten/emcc'
export CC='/d/Build/em2/emcc'

export CFLAGS='-O2 --closure 0'
export DEFINES='-D NOT_GCC -D EMSCRIPTEN -D USES_UNIX_DIR'
export INCLUDES='-I ../GEL -I ../External/cJSON'
export FILES='src/Main.cpp ../GEL/Math/Real.cpp ../GEL/Debug/LogEmscripten.cpp ../GEL/Math/Vector/Vector3D.cpp ../External/cJSON/cJSON.c'

mkdir -p obj output

echo "// Begin PreJS.txt //"&gt;obj/PreJS.txt
cat external/buzz.js&gt;&gt;obj/PreJS.txt
#cat external/soundmanager2-nodebug-jsmin.js&gt;&gt;obj/PreJS.txt
#cat GelHTML/GelAudio.js&gt;&gt;obj/PreJS.txt
cat GelHTML/GelAudioBuzz.js&gt;&gt;obj/PreJS.txt
#cat GelHTML/GelAudioDummy.js&gt;&gt;obj/PreJS.txt

#echo "var ContentMapData = "&gt;&gt;obj/PreJS.txt
#cat Content/MapData.json&gt;&gt;obj/PreJS.txt
#echo ";"&gt;&gt;obj/PreJS.txt

cat GelHTML/GelUtil.js&gt;&gt;obj/PreJS.txt
cat GelHTML/GelMath.js&gt;&gt;obj/PreJS.txt
cat GelHTML/GelGeometry.js&gt;&gt;obj/PreJS.txt
cat GelHTML/GelGraphics2D.js&gt;&gt;obj/PreJS.txt
cat Main.js&gt;&gt;obj/PreJS.txt
cat Load.js&gt;&gt;obj/PreJS.txt


$CC $DEFINES $INCLUDES $CFLAGS $FILES --pre-js obj/PreJS.txt -o output/nook.emcc.js 

java -jar bin/compiler.jar --compilation_level WHITESPACE_ONLY --js output/nook.emcc.js 2&gt;output/nook.emcc.js.txt&gt;output/nook.js

Some notes:

  • I explicitly disabled the closure compiler in the optimizations (–closure 0). Eventually I re-added it, but manually (last line). I tracked down some very very unusual Chrome only performance bugs that were caused by closure Compiler optimizations. Whitespace removal works fine and is totally safe, so I’m doing only that now.
  • –pre-js takes only a single file, so I had to combine all my JS code in to a single file first. Someone should really put in a feature request in to allow multiple –pre-js calls. :D
  • Audio support in browsers is *shrug*, so I have 3 audio libraries I enable/comment out between (SoundManager 2, Buzz, and none).
  • For a brief time, I was including my map file alongside my other JS code. I eventually moved mention of it in to the HTML file, so that file would be read every time (without the need to re-link the binary).

C and C++ Code

A C function named “MyFunction” will become “_MyFunction” inside JavaScript scope. Conversely, a JavaScript function prefixed with an underscore will be accessible from your C code. Just prototype it before hand (“void MyFunction();”) and you’re golden.

I’d recommend using basic types when passing data between JS and C++. Floats and Integers where possible, and char*’s for strings. Strings require a little more work to use, but aren’t bad. See the “Other Methods” section for details:

https://github.com/kripken/emscripten/wiki/Interacting-with-code

C++ functions are a little tricker. If you’ve ever tried mixing and matching C and C++ code, you’re probably familiar with C++ Name Mangling. You need to deal with mangling here if you want to use C++ code.

void GameDraw() becomes __Z8GameDrawv();
void GameInput( float X, float Y, int New, int Old ) becomes __Z9GameInputffii( var, var, var, var );

The encoding isn’t too hard to decipher, but it’s probably easiest to just open the output JavaScript file, and search for the symbol. “GameDraw”, and keep looking until you get one that’s wacky like those mangled names above.

Too keep things simpler on the JS->C++ side, I’d recommend sticking with single underscores and wrapping your prototypes in “extern C” sections.

// - --------------------------------------------------------- - //
extern "C" {
// - --------------------------------------------------------- - //
	void gelGraphicsInit( int Width, int Height );
	void gelGraphicsExit();
	
	void gelSetColor( int r, int g, int b, int a );
	void gelDrawCircle( float x, float y, float Radius );
	void gelDrawCircleFill( float x, float y, float Radius );
// - --------------------------------------------------------- - //
};
// - --------------------------------------------------------- - //

Graphics

Emscripten ships with a version of the popular SDL game library. In addition, there’s a bunch of work done on a OpenGL port, based on WebGL. I’d expect to see more and more things ported as the GL libraries mature.

Me I’m slightly impatient, and have my own libraries that wrap OpenGL on the PC/Mobile side. I didn’t use any of my existing graphics code, but created a new JavaScript library based on the same naming scheme. Before this weekend, I had only minimal experience using Emscripten, so I didn’t want to pigeonhole myself in to my existing libraries. I don’t use floats in my libraries, but instead I use a type “Real” which is synonymous, and includes some extra features. After today, a change I would make is have my drawing libraries accept floats, and lightly wrap them with versions that take Real’s. That would make building a consistent interface across targets nicer.

For understanding Canvas 2D’s rendering capabilities, I recommend Mozilla’s tutorial.

https://developer.mozilla.org/en/Canvas_tutorial

All my art assets are PNG files that I load from disk.

var ImageData = new Array();
var CurrentImage;

function _gelLoadImage( FileName ) {
	var NewImage = new Image;
	NewImage.src = Pointer_stringify(FileName);
	
	var Index = ImageData.length;
	ImageData.push( NewImage );
	return Index;
}

function _gelBindImage( ImageId ) {
	CurrentImage = ImageData[ ImageId ];
}

function _gelDrawImage( sx, sy ) {
	Module.ctx.drawImage( CurrentImage, sx, sy );
}

Music and Audio

I wrote a generic interface to load and play sound files. All JS sound libraries use MP3 or OGG files, which makes them suitable for music playback too. However, unfortunately, no matter what library you use, looping of music has an annoying gap and isn’t seamless.

Options include:

I use both. I started with SoundManager 2, because I occasionally notice weirdness in native HTML5 playback. But for the updated version (the link above), I switched back to Buzz. There are cases when the sound gets broken on Chrome, but SoundManager 2 has a delay. I prefer delayless.

SoundManager 2 also supports multi-shot sound playing (i.e. the sound doesn’t interrupt the last one played), but only with its Flash 9 based noisemaker. This is cool, but for the style of game we were making, interrupting sounds wasn’t a problem.

Optimizations and Performance

If you’ve ever implemented a scripting language in to a game engine, you’ll be familiar with the idea that native code is faster. A “Draw” function that blits a sprite or renders some 3D geometry should always be in native code, and not implemented in script. Working with Emscripten is a bit of that. For the most part, Emscripten does a really good job optimizing, and often does things you would forget if optimizing by hand. However, there are times when going native (in this case JavaScript) will speed up your game.

File IO

Emscripten includes a suite of function for faking data in a filesystem. They work fine and are totally easy to use (can be automatically done via command-line arguments to the linker). However, using a JSON parsing library written in C to read a 400k JSON file that has been artificially encoded in to the virtual file system can be … wasteful.

This is actually what I did at first. The map was originally a 200k JSON file, exported by Tiled. It was a bit horrible, taking about 4 seconds to parse, but tolerable. Once we grew the map to a >400k file, things got out of hand (12 seconds).

Since JSON stands for JavaScript Object Notation (duh, the native object format of JavaScript), my solution was to include the JSON file alongside the rest of the JavaScript code in the HTML page.

&lt;script src='Content/MapData.json.js' type='text/javascript'&gt;&lt;/script&gt;

A JSON file however lacks an actual usable name in JavaScript. So to avoid weird cross-file crying by a “secure” browser, I wrote a tool to append an appropriate name on to the file.

#include &lt;stdio.h&gt;

#include &lt;Core/DataBlock.h&gt;
#include &lt;Core/GelFile.h&gt;

int main( int argc, char* argv[] ) {
	if ( argc == 1 ) {
		printf( "You did it wrong!\n" );
		return -1;
	}
	
	char Text[4096];
	sprintf( Text, "%s.js", argv[1] );
	
	DataBlock* InData = new_read_DataBlock( argv[1] );
	GelFile* OutFile = open_writeonly_GelFile( Text );
	
	sprintf( Text, "var ContentMapData = " );	
	write_GelFile( OutFile, Text, strlen( Text ) );
	
	write_GelFile( OutFile, InData-&gt;Data, InData-&gt;Size );

	sprintf( Text, ";" );	
	write_GelFile( OutFile, Text, strlen( Text ) );
	
	close_GelFile( OutFile );
	delete_DataBlock( InData );
		
	return 0;
}

The tool was placed alongside the JSON file, so we could simply drag+drop the exported JSON file on top of it to regenerate a usable game map. Oh and my apologies, the above code uses a FileIO library of mine, but what it’s doing should still make sense. A better tool would generate a type name based on the filename. Me, I hardcoded it to save time and thinking.

Finally, I wrote a series of functions for looking at the data. With the JSON C loader, I would pinpoint the map data and the dimensions of the map file inside the JSON file. I wrote similar functions, one for each piece of data I wanted, and dropped them in to my existing loader code.

Done. We now had instant file loading, and a way for the artist to change/edit the map and see his changes.

Graphical Rendering and Performance

Firefox and Chrome both have good profiling tools. If you happen to fire them up, and play the game for about 30 seconds, you’ll notice a few functions stand out. The one I want us to take note of is “_gelDrawTiles“. This is a function written in JavaScript that draws a layer of the map. That’s lots and lots of little 8×8 tiles. The function itself is rather complicated, but it’s an improvement before. Originally, the C++ code called a function “_gelDrawTile” (note the lack of S on the end), one for every single tile in the world. At 40 by 30 tiles, by 4 layers, that’s potentially A LOT of overhead wasted by function calls. Since this draw function was written in JS, it couldn’t exactly be inlined (as expected in C++).

So, I changed the tilemap layer rendering in to a single function call written in JavaScript.

The map data was located inside the C++ code though, so I had to get a pointer and call an Emscripten provided function “getValue” to get the actual data. However, this was a BRAND NEW wasteful excessive function call, so like the author of Emscripten suggests, I went in to the code to see how to access the data I wanted (HEAP16[Pointer+Offset]).

The other heavy functions seen by the profiler relate to the collision detection. While writing this though, I just realized I might be able to improve that, so *ahem* disregard them, okay? :)

Standard Template Library – STL

This isn’t particularly a speed optimization, but a size one. If you’ve ever worked with STL as both a C and C++ programmer, you’ll note that STL adds quite a lot of size to program. It performs well, but depending on the compiler, you can see a whopping 500k to 1MB increase in file size over a C program, or a C++ program simply using your own C++ containers.

If you read above, you’ll see that I have my own suite of libraries for doing various things. I use C++, but a number of my libraries use a C style aesthetic (or Pure Functions if you’re in a buzzword mood). So instead of STL, I used my own equivalents and variants.

That said, I’m not saying don’t use STL. If you like it, use it. I like it actually, but I’ve been coding professionally for over a decade now, and have built up my own libraries and ways of doing things. There are some things STL does well, and others STL doesn’t. I actually was planning to use it at first, but after I saw the code size grow by ~500k, I decided not to.

RequestAnimationFrame instead of setInterval

This I was informed of after Ludum Dare.

http://paulirish.com/2011/requestanimationframe-for-smart-animating/

In my tests, it seemed to make Chrome work a little better.

I did like the elegance of this better though:

IntervalHandle = setInterval( Main_Loop, FrameRate );

And manipulating the IntervalHandle to stop (lost focus), and restarting it via setInterval again (focus gained).

But hey, the RequestAnimationFrame stuff is supposed to be better.

Wrapup

That’s all I can think of at the moment. If there’s something you want to know about that I didn’t cover, feel free to ask. I may expand this post accordingly.

Posted in Ludumdare, Technobabble | Comments Off

Help me runtime debug this code

Hey there… This happens to me sometimes. I want to be able to turn on a debug mode or a tool that will crash my code during runtime. I can use Xcode, MSVC 2008, or GCC under Linux. Anything. Though, XCode is preferred. This must work with C++, not just C code.

// I don't want to change my code.  I don't want to use Array templates.
// I just want a debugging tool that will crash my code when I do
// array out-of-bounds, even if they are "safe."  Here's my example.

struct Goods {
    int x[10];
    int y[10];
    int z[10];
};

int main(int argc, char *argv[]) {
    Goods data;

    int k = 11;
    for (int i=0; i<k; i++) { data.y[i] = 1; } // SHOULD ERROR ON i == 10

    int j = -1;
    for (int i=j; i<10; i++) { data.y[i] = 1; } // SHOULD ERROR ON i == -1

    return 0;
}

Changing my code, using STL, using “new”, using “malloc” are not options.

Help me!
-Phil

Posted in C++ | Comments Off

Stellar Nurse premature post mortem

First thoughts. This is the first post I've written since I updated wordpress, and, what the fuck wordpress. You're going to destroy a good piece of software.

Why is this post mortem premature? Because we aren't done with it yet. At least, I'm not. A 'post-compo' version is on the way with some gameplay tweaks and performance improvements. I'm going to keep this short for that reason, and just dive right into the lists.

What went right:

Working with an artist and a musician. I couldn't have asked for better. Participating in the jam with a team allowed me to focus entirely on what I was good at and crank out code. It didn't hurt that they are both incredible at what they do.

Using libraries I knew. Flashpunk I've used quite a bit and I can confidently dig into it and hack things. I've got a deal of experience with Box2D, so when I needed a physics library it was the logical choice (And it made for quite good physics). The last library, GUM, is a gui library that I wrote. Can't know it better than that.

Not caring about how horrible my code was. Arne delivered brilliant art; but he didn't always deliver it in a sensible layout. This isn't really the best example of this (I'll give one of those in a moment), but I could have spent a lot of time re-arranging his tiles, or I can just hack some code to deal with it. I hacked some code to deal with it. I did a good job this time avoiding the itch to make it perfect, and concentrated on just making it work. Of course, without the time pressure, I have to fix everything now!

So what went wrong? Not having a clear idea of the goal. I don't think any of us really knew how we wanted the game to play. I experimented a lot with it, but some bits of it threw me for a loop. Like detecting completed planets. The method I came up with can detect any pattern at all, but I never actually got around to doing anything interesting with it. The post-compo version will, I promise.

Ambition. I bit off way too much with the world-tile-soup. Oh sure, it looks like it works, but I poured a solid forty hours of work into it over the weekend and it still doesn't work right half the time.

Play it now at http://www.ludumdare.com/compo/ludum-dare-23/?action=rate&uid=418

Posted in Daily Update | Comments Off

Dr. Nano – tiny surgeon

You are a microscopic doctor. A hero. A marvel of modern science.

Shrink down to the size of a single cell and enter the bloodstream of your patients. Destroy the bacteria, and fight the evil cancerous tumor to save the day! Survive three BOSS BATTLES to get to the final credits. CLICK HERE TO PLAY!

This game was written in AS3 for Flash 11 using the Stage3D API over a period of 48 hours for the Ludum Dare 23 game jam and speed-coding competition. The theme of the jam was “TINY WORLD”.

Tools used:

- FlashDevelop for code editing and compiling.
- A marker and paper for the sprites.
- Photoshop for processing the scanned images.
- A microphone for the background “music”.
- BFXR for the gun and explosions sounds.
- CoolEditPro for sound processing.

NOTE: this game is designed to be run FULLSCREEN in a 1080p HD monitor.
Be sure to maximize your browser window so you get a better view. Flash 11 required.

P.S. Happy 10th anniversary, Ludum Dare. Here’s wishing everyone another decade of gamedev goodness. Ludum Dare is my favourite online community – I’m so happy I discovered it. I had SO much fun making this, and I hope you have fun playing it! ENJOY! =)

Posted in 12in12, as3, Compo, Flash, Flash11, game, Molehill, Stage3D | Comments Off

LD-23 Timelapse

Posted in game dev | Comments Off

My LD-23 entry: In The Beginning.

So I participated in the 10 year anniversary of ludumdare and this is what I came up with. It’s a game where you play as god creating the world.

How to play:
Build the world as you see fit. No other goal than to make the planet you want.

Hold right mouse to pan
Middle mouse is zoom.
Click a segment of the world to build.
Pick up item drops to get more stuff to build.
You can change your currently selected item using the left menu.

Download

Posted in game dev | Comments Off

Simple Object Orientation in Lua

Lua is not object oriented… But some people like it, and it has some advantages…

I decided to use a simple form of it on my project, it does not support multiple inheritance and many other features, it was made to be very, very simple, only to organize the project and advance some form of code reuse.

So, what features I tried to support?

First, very ease of use to create a class
Second, ease to create a instance.
Third, automatic constructor if you do not want to make one.
Fourth, easy “operator overloading” support.
Fifth, static variables (I like them).

Some people will tell me now that there are lots of already done implementations of this, that you only need to search the web… So why make a new one? Well, almost all of the ones I found were too complex for my taste, and mostly for Lua 5.0. Lua 5.1 has a new particular feature, that I really wanted to use to make my class system, a powerful feature.

What we need to use from Lua? Mostly metatables, and the metamethods __index and __call, the second one being available only in Lua 5.1 and onward.

So, how we do it? First, we need to create a new chunk (I suggest you do it creating a file… I will make later a tutorial on how to make a non-file chunk).

My file is named kidclass.lua (the “kid” comes from Kidoteca, the company where I am working now to make children games).

This file will follow my usual style to make “modules”, without using the module() function (that got removed in Lua 5.2 and rightfully so… module() was just plain stupid).

  1.  
  2. local kidclass = {};
  3.  
  4. –content will go here
  5.  
  6. return kidclass;
  7.  

Important, remember to make kidclass (or whatever name you want) local, so you do not end polluting the global namespace (ie: _G) and also avoid some accidental name conflicts…

How you use files made in that style?

  1.  
  2. mymodulename = require "somemodule"; –this is the line that matters, the next two is example of how to use mymodulename
  3. mymodulename.someMethod();
  4. local myvar =  mymodulename.somevar;
  5.  

Note that doing just require without assigning its return value to something, would be useless, because back when we created the module, we made it local.

Now, how we achieve the first objective, the ease of use to create a class?

The most easy way would just do: myclass = {};
But that would prevent us from achieving the other features, so we need a function, to the sort that creating a class would be “myclass = kidclass.new();”
So we know a kidclass.new, that would at most basic return a {} (this means a empty table), the following could would be the result:

  1.  
  2. function kidclass.new()
  3.     local class = {};
  4.     return class;
  5. end
  6.  

And how we make the second object work now?

I thought that the nicest way to create a instance, would follow the style of C++ (more or less) so “instance = Object()” except Lua does not have a way to create a constructor that is named like a Object… Oh, actually it does have something like that, since 5.1! This is the reason why our code will be different from what you usually see on internet. We will use the might __call.

So, what __call do? __call is a metamethod (a method from a metatable) that is called when you attempt to call a table (ie: you do “table = {}; table()”).

__call is a metamethod, this means that we need to use metatable… I thus define the metatable that contains call on our “new” function we already created.

  1.  
  2. function kidclass.new()
  3.         local class = {};
  4.         setmetatable(class, kidclass); –we define kidclass as metatable for class.
  5.         return class;
  6. end
  7.  

Since kidclass is what we defined as metatable for class, we need to create __call on kidclass:

  1.  
  2. kidclass.__call = function ()
  3.     local instance = {};
  4.     return instance;
  5. end
  6.  

Ok, so what we did for now? We made a way to create a class using a simple method.

Thus doing “myClass = kidclass.new()” will create a empty table that has kidclass as metatable.

And we created a way to create a instance.

Thus doing “myInstance = myClass()” will make Lua check if myClass has a metatable (it has… it is kidclass), and then it will check in the metatable (kidclass) if it has a __call. And then it will run the function contained in __call (this is why __call is defined as “= function()”)

But what if we want for example to create a Point class, that supports Point(x, y) as constructor? This mean now we need to create a support for constructor…

We change __call to this:

  1.  
  2. kidclass.__call = function (class, …)
  3.         local instance = {}; –Remember to make this local, or every time you call a constructor inside another constructor you will destroy the first object
  4.         if class.Constructor then
  5.                 class.Constructor(instance, …);
  6.         end
  7.        
  8.         return instance;
  9. end
  10.  

Alright, now a constructor can be created for our class, following the following format:

  1.  
  2. function ourClass.Constructor(self, randomVars)
  3.     self.defaultVar = 123;
  4.     self.anotherVar = randomVars;
  5. end
  6.  

This actually already works as very simple OOP, so if you want, you can stop here… But I still want to support operator overloading!

Operator overloading is done in Lua using metamethods too, they are __add for +, __mul for * and so on (look on the Lua manual for all of them, there are also overloading for = and >= and more)

This means we need to add a metatable for the instances, that will look for __add function for example. Since we are making something OOP, the most logical place for __add is the class…

Thus when we do instanceOfBallC = instanceOfBallA + instanceOfBallB; Lua will look for __add in Ball.

We modify again our __call to that:

  1.  
  2. kidclass.__call = function (class, …)
  3.         local instance = {};
  4.         if class.Constructor then
  5.                 class.Constructor(instance, …);
  6.         end
  7.        
  8.         setmetatable(instance, class);
  9.         return instance;
  10. end
  11.  

Static variables we already support, just add them to class (ie: myClass.staticVar = 23) but I think we can add one last cool feature… We can make our instances read from their class any variable that does not exist, thus creating default variables that are also static variables… We do that in lua by setting the __index of the table that is missing a variable… since __index is a metamethod too (we can set it to a table, as a shorthand version of sorts) we need to put it in the metatable.

Thus just before setmetatable(instance, class); line we add class.__index = class, meaning now that any time someone try to read something that does not exist from instance (that has class as metatable) it will read from what the metatable __index pointed (class itself too), thus in practice instances actually inherit from our class.

This is the final version of the code (PLEASE do not just copy paste it… it is here for studying, I am placing a commercial private code here in a goodwill gesture to educate you, not to you just leech it without understanding it).

  1.  
  2. – Mauricio Gomes
  3. – Kidoteca object oriented system.
  4.  
  5.  
  6. –[[
  7.         How to use:
  8.        
  9.         To create for example a Dog class, we do:
  10.        
  11.                 local class = require "kidclass"
  12.                
  13.                 local Dog = class.new(); --If you forget the local here, it will pollute your _G
  14.  
  15.                 local function realBark(...) --Private function
  16.                         print(...)
  17.                 end
  18.  
  19.                 function Dog.Constructor(self, initialbarks) --This is a optional constructor...
  20.                         self.barks = initialbarks or 0; --This is a variable initialization plus default variable
  21.                 end
  22.  
  23.                 local spots = 76; --This is a private static variable.
  24.  
  25.                 Dog.color = "white"; --This is a public static variable.
  26.  
  27.                 function Dog:bark()
  28.                         self.barks = self.barks + 1;
  29.                         realBark("We have " .. self.color .. " color and barked " .. self.barks .. " times");
  30.                 end
  31.  
  32.                 function Dog.blacken(amount) --static function (or rather, a function that alter static variables )
  33.                         spots = spots + amount;
  34.                         print(spots);
  35.                        
  36.                         if spots > 100 then
  37.                                 Dog.color = "black";
  38.                         end
  39.                 end
  40.  
  41.                 return Dog;
  42.        
  43.         To create a instance of Dog
  44.        
  45.                 local Dog = require "dog.lua";
  46.                 Max = Dog(4);
  47.        
  48.        
  49.        
  50. --]]
  51.  
  52. local kidclass = {};
  53.  
  54. kidclass.__call = function (class, …)
  55.         local instance = {};
  56.         if class.Constructor then
  57.                 class.Constructor(instance, …);
  58.         end
  59.        
  60.         class.__index = class;
  61.         setmetatable(instance, class);
  62.         return instance;
  63. end
  64.  
  65. function kidclass.new()
  66.         local class = {};
  67.         setmetatable(class, kidclass);
  68.         return class;
  69. end
  70.  
  71. return kidclass;
  72.  
Posted in development, Game Technology, tutorial | Comments Off

Dynamite Jack: The second prototype, post-post mortem

So about six months after I created “Escape from Anathema Mines” during the Ludum Dare game jam, I created a game called Dynamite in the PyWeek game jam.

Theme

So the theme of PyWeek #1 was “Power” .. I worked with my brother-in-law Tim on this game, and we spent a fair amount of time working with the idea of using a “mind control power” over the characters in game. So I wrote some A* code to navigate things around and whatnot. This was boring. So I made it so you could blow something up. This was exciting. We decided “the power of dynamite” was what the game was about, since the dictionary definition of dynamite said something about “a powerful explosive.” Not my best “theme compliance” for a game jam, I’ll admit.

Gameplay

The best way to see the gameplay is to PLAY THE GAME if you have Windows :) (Download the post-compo version, it’s a little shinier.) But short of that, watch me play through one of the levels. There’s a ton of interesting differences between this and Dynamite Jack. The most significant one is that in Dynamite you can “fail” really easily. You can block yourself into a corner by destroying the floor, and you can run out of bombs. Those are both design decisions I changed for Dynamite Jack.

Fun facts

Tim created all the music for this game, one of the tracks is based on a fiddle tune as well. You may be able to tell that the character art in this game is the same character art I ended up using in Dynamite Jack. It’s all from Reiner’s Tilesets. It definitely helped a ton to have that art work. It ends up looking really sharp in Dynamite Jack because I scale things down so small.

I also brought the “dynamite drop” sound effect from this game into Dynamite Jack. It just sounds so cool.

Post-Mortem

I think one of the big gameplay mechanics I like in that game is that when you sneak along the walls you are invisible to the guards. It kinda leaves the “lighting effects” to your imagination. But one of the problems with that is that it’s not very obvious. I used the different colored cursor to help the player be able to know where the safe zones were.

This game introduced the fun of having guards running to check out whatever you just exploded. I did the voice acting in this prototype of the game.

The idea of this game really stuck with me for a long time, so for the next several years I always talked about going back and re-making it.

TO BE CONTINUED …

(Dynamite Jack is coming to PC / Mac in mid-May. Check out the trailer to see the difference from the original shown here.)

Posted in dynamitejack, pygame, python | Comments Off

We are not dead!

Well, we almost died, but in a miraculous manner, at the nick of time some work showed up… And even more surprising, using Lua, this means more time without paddlewars, but I will start to post here some Lua stuff and maybe some other info.

Posted in Community News | Comments Off

Ludum Dare 23: Hero of Rain

Finished another Ludum Dare! The theme this time around was Tiny World, which I satisfied in Hero of Rain by placing the world within a raindrop.

The fall is near its end.

See the Ludum Dare competition entry. This fleshes out some of the plot and describes the controls (although they are presented in-game), so it would be wise to go here.

Directly to the game.

Posted in games, Ludum Dare | Comments Off

Aether

Another Ludum Dare is over, number 23 to be precise, and my game is submitted. It’s called “Aether” and is a mix of an explorer platformer and missile command, where you have to run through a landscape to reach a mountain with a secret weapon, while at the same time fighting off alien spacecraft.

You can play it here: Play Aether. Have fun!

Posted in aether, Flash, ld23, ld48, Ludum Dare, Ludumdare | Comments Off

Ludum Dare 23 is over, Through the Blue Sea is finished.

This isn’t a Postmortem post, but I wanted to post a wrap up of my experience this Ludum Dare.

I went to a car show Friday Night, just before Ludum Dare started, I figured it would give me a chance to brainstorm before I even had a computer in front of me. Then the theme was announced, and of all the theme it could have been it was the one I liked the least. The theme to me just inspired you to create a Tiny World that was copied out of Dragon Ball Z. I struggled with an idea that wasn’t to typical

The first idea, that was abandoned quickly was to use the Build It, Then Use It theme mixed with Tiny World. You would have customized a  huge gun turret and had to come in under budget to score higher. Then you would just blow up a Tiny Planet. I thought the idea was to simple, and I hadn’t made anything for it at that point so I ditched it.

The idea for Through the Blue Sea was to make a quick and simple platformer that used the minimalism theme, overall I am happy with it, here are some screenshots if you haven’t seen it yet.

Main Menu

Tiny Green Planet gameplay

You can read my post made during the event, and see the progression at my Ludum Dare author page. I will be playing two five games each night, and at the end of the week I will post a list of the games that I played. I want to be consistent this time, rather than play a bunch at the end of the voting period.

You can view and rate my entry here.

I will also be posting timelapse and gameplay videos soon.

Posted in Game Development, Game Jams | Comments Off

Project Break

Lately I’ve been on a break from the game. I’ve come to realise I don’t really have a very clear vision of what I want, and I’m taking my time re-evaluating the project.

At first, I thought I was sure of what I wanted, but I’m not at all sure now. As I was writing that prototype I was unfocused, trying to get in features I thought I wanted but not focusing on any particular thing. When I write the next prototypes, they will only be used to do One Thing. I tried to put in Everything I Could and wound up losing sight of what I was trying to do.

I’m still motivated to work on this, but I need to spend more time figuring out what I’m trying to accomplish. I suspect writing small prototypes for Single Features will be an important part of the answer.


Comments Off