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 | Leave a comment

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 | Leave a comment

Long term contract ended

Today the contract with my biggest client so far ended, I delivered 2 big projects, some libraries and made even a small simple iPhone game one day when bored (sorry, it will not be released, but I can remake it later in flash or something to release for general public).

So, what now? First, I need another contract, I will still receive payments for more 2 months, so I have 2 months to find a new contract, thus I will work on that.

Second, now I have boatloats of free time (since I have no other contracts now), this mean: You can hire me, and also, that I will resume working on games, probably NOT Paddle Wars now, I intend to release some smaller complete games first… To stop leaving behind unfinished games.

And that is it!

Posted in Community News | Leave a comment

Site development

Speeder may not have mentioned it here, so I guess I’ll be the one to tell you all…

I’ve been working on the new site for Paddle Wars, and it was about the middle of April that it was finally opened to the world, after much discussion and decision making with Speeder.

You can view it at http://paddlewars.agfgames.com.

Of course, I’m still busily working with Speeder in order to make this site better for everyone that happens to visit. So why not list the changes since that version and the one I’m currently working on?
Continue reading

Posted in Community News, Development | Leave a comment

We got saved! Sort of…

Hello Awesome Games Factory fans and guests. I wrote some time ago, we were going bankrupt. The good thing is: AGF got not one, but TWO big clients (one is being handled by me, the other by the non-game person of the company, the one that helped me build the Arcade Cabinet). The bad thing is: Now noone is left to work on the games!

But we actually insist… Soon I will resume working on Paddle Wars, probably I will release beta 6, and then decide what to do next. Now we have SURPLUS money, this mean that I can hire a web designer to redo the crap site we have (anyone volunteer? Keep in mind that surplus money does not mean we are rich…)

Also I bought a Dingoo, so maybe I will make Dingoo games. And also I found something else, not related to games, but interesting, but that something else I will talk about it later.

Still want to help us in any way? Send your complaints, suggestions, ideas, questions for self-interview (I only stopped that series because noone send questions!) to agf@agfgames.com

Posted in Community News | Leave a comment

Why Sony is upset with PS3 hackers?


Most people would just say: “Piracy!” But then I say the most people, are wrong. The hackers stated, that their work only enable homebrew, not piracy, and THAT is the dangerous thing to Sony.

Lots of people will come with pitchforks in hand, saying that I am defending pirates, those are missing the point completely, I am not talking about them. Others will come with scythes, trying to harvest from me that the problem is that now anyone can cheat on games (and pirate). Those, don’t realize too what it is at stake for Sony.

In 1983, the market crashed, Atari, the leader in console business, acted like an ass toward their own developers, leading them to quit, and create Activision. Atari sued Activision when they created a Atari game, and lost. Suddenly, hundreds of companies appeared from nothing, like the 2001 internet companies surge, there was in 1983 a game development surge, but the result was disastrous, a huge amount of shovelware, soon when you visited a video-game store, 99% of the games on the display would be utterly crap.

This, coupled with some mistakes from Atari and competitors, caused a market crash, the console game market just died. Nintendo came to rescue us all, enforcing a very strict policy where to make a game for them, you needed to follow very strict guidelines, and had a limit on how many games you could submit every year, meaning that only the best games would get on the system, of course, several crap games showed up, but the ratio was bearable to costumers, if you picked a random cartridge on the store, probably the game was decent enough.

A whole business model came from this, soon all console manufacturers started not only to build gates and guard them, but they also figured they could put toll booths on them, you want make a PS3 game? You have to license some stuff, pay some fees, buy SDKs and debug machines… Some manufactuers even ask for royalties, meaning that every game sold, give them a little money, but when summed all games sold ever, it means humongous amounts of money. All this, allow the payment of the research and development of those marvelous machines.

So, returning to the present, what happened to PS3? First, hackers started to figure how to use the RSX (PS3 video chip) on Linux, something that was not available, but developers pursued, in attempt to make cool stuff. Suddenly, Sony removed the “OtherOS” option. Many people misunderstood, thinking what Sony feared was piracy, but that would make no sense, OtherOS only allows to run another Operating System, a game is NOT a Operating System, to make a pirated game run using OtherOS would be harder than many of the other ways.

The hackers got upset with OtherOS removal, Sony took from them the toys that they bought, it is like if you sold a car, and then popped the tires after the costumer picked it up. Their solution? Put it back. Of course, this started a battle of hackers putting it back, and Sony removing it again. Soon they needed a final and ultimate solution, a way to put OtherOS back permanently.

This proved to be possible, thanks to Sony crap security, when you use cryptography you are supposed to use random numbers, but Sony random number generator is not quite random, allowing the hackers to use simple math and observation skills to figure the key. And then one of them, published that key on internet…

Like those videogame bosses, where they have a single weak point, and if you hit it, the creature starts to scream, flail, yell and smash random stuff and cause lots of collateral damage, that is what happened, the key, a number, that in many situations would be meaningless, is the key to Sony gate, the gate that have a toll booth, with that key, anyone can create any software they want, and ignore Sony demands for fees, suddenly a great source of income for Sony is in danger.

What Sony fears, is that people will figure that with the key, they can make their own PS3 games, and that what happened in 1983 will repeat on the PS3, as soon as a great homebrew game show up and actually gather sales, a new surge of PS3 development will happen, and soon there will be thousands of PS3 games, completely drowning the market in shovelware, and causing Sony to don’t see a dime of it.

THIS is why Sony is insanely upset.

Posted in Business | 2 Comments

Bankrupcy

Hello all usual AGF Games readers, and those that read from Ludumdare Planet we are in trouble.

We spent lots of money on the arcade cabinet, that had only partial success, it worked to test the game, and improve it, but it totally failed to attract more attention.

We are now going bankrupt, without a product done, without any other source of income, and no donations, soon we will run out of money.

What will be done is: The game development will stop, and me (Mauricio/Speeder) will see if I can find a normal job (like, selling games in a GameStop).

But that can be prevented: We are accepting donations on 8-bit funding and we are looking for contracts (or a normal development job to MaurĂ­cio).

So, if you need work done, any work that AGF Games can do, please, contact us at agf@agfgames.com and we will see what can be done. You want your own Paddle Wars: Hit The Wall? Well, you can, just hire us.

So, hire us, or donate, and save Paddle Wars.

Posted in Community News | 3 Comments

Forced in…

Well, Speeder nagged me to write this, so I guess there isn’t a choice. But he didn’t exactly say what I was supposed to be writing about, so…

Hello people, I’m Mingamango181, otherwise known as LawAndContradiction. I’m not known for much, but I do like to design and render things. I also do web coding, which is pretty much the only language that I’m proficient at.

I wasn’t one for making things entirely from scratch. Rather, I preferred to see if I could make objects or things that were suited for a very specific audience. In 2002 however, I had a strong inclination to learn how web pages were built. Reading through, I learnt how things were made up, and the way that tags worked to make the font like this, or that, and etc. I can’t remember what my first page looked like, but it probably had the resemblance of those geocities sites, except with much less.

I only started to make use of HTML properly in 2009, reading through the standards and learning about CSS. I was utilising it in one of my assignments on web development. It went rather well, and I am continuing to learn about it.

2010 was one of those years with the most change. I returned to AnyNowhere in February, my previous time just lurking and being trimmed after a while of inactivity. The year would have been pretty bland, if it weren’t for a certain situation which I couldn’t handle very well.

It was quite damaging, since nothing of the sort had ever occurred before. I withdrew to the corner, a dark corner. Thank goodness there was someone willing to help during a two week break. I was able to recover from it in time for the next wave of attacks.

I had heard about Paddle Wars: Hit The Wall in a post over at AnyNowhere, quite a while before the incident. I was interested, though then, I found it difficult to find the right words to use in my feedback. The closed Beta gave me a chance, to do more, and I took that opportunity.

Well, this post probably has more meaning than my introduction post at the forums. My own corner of the internet is located here. I am also using the one hundred and forty character service, which would be named ‘@contradicthelaw’.

I suppose what Speeder wanted me to promote was this: You can donate to the cause at 8-bit funding here. I’m not sure about why not promoting this older link though…

Posted in Self Interview | Leave a comment

Campus Party is Over

Hello, I am back!

First, I like to say thanks to Mingamango who updated the blog while I was away.

Campus Party is over, it was great, and this post is a report to you people know what happened there. First thing, the cabinet attracted a lot of attention, this is a photo of before the event even started, where only workers (of all sorts, including media) were present, when the photo was taken (the guy in red is a journalist, the guy with a Paddle Wars t-shirt is me).

Having the game run for several hours non-stop made several bugs pop-up, and for the first time I could watch complete strangers play the game, and note their behavior, see what was wrong, and what was right, what worked, and what did not…

During the event I did 4 revisions of Beta 5 (which is the version in the cabinet, it is not available to the public, later I will release Beta 6 to everyone).

So, the changes from Beta 4 to Beta 5:

  • Added music to highscore (props to Skyrunner)
  • Fixed some bugs regarding buttons
  • Added tooltip box on the level set selection screen
  • Improved the background
  • Removed the ugly gradient on the HP bar.
  • Fixed the score font
  • Fixed the multiplier GUI
  • Made powercubes more translucent (to make the ball more distinguishable during hectic scenes)
  • Added a very basic “attract” mode (i.e: what happen when you don’t press a button on the title screen)
  • added a voice-over on the title-screen
  • Made an ‘arcade’ switch (can be used at home, but I won’t explain it now)

On the first revision I fixed some strings.

Changes from Beta 5 Rev 1 to Rev 2:

  • Fixed the level score counter not starting from 0.
  • Fixed some rare bugs of variables getting lost.
  • Fixed that you could “lose” after winning.
  • Made the grid color a bit more faint (so it don’t get in the way).
  • Raised the voice volume.
  • Several improvements on the high-score name screen.
  • Changed the points bonus when passing the last level.
  • Fixed the high-score screen showing up when there was no score to save.
  • Added information version to the title screen
  • Fixed some bugs (not all unfortunately) on the level 6 when you lose.
  • Changed the high-score screen to use mono spaced font for numbers (so you don’t confuse the amount of digits)

Changes in Rev 3:

  • Level 3 got reworked, it is now way easier (but still fun), and has new graphics.
  • Changed some collision boxes on level 6, to make it easier too.
  • Fixed more bugs related to variables disappearing.

Changes in Rev 4:
Fixed the last level collision box, so you don’t have objects “passing through” and going out of the screen forever.

I will take a while before releasing the next version, because I intend to skip Beta 5 entirely, and release Beta 6.

During Campus Party several people showed up, bugs showed up, and I had lots of fun working on the arcade, fixing it, and watching people smiling while playing, one particular guy was really interesting to the point that I borrowed someone else camera to take a photo of him.

The person in the photo is a 3 year old boy, he LOVED the game, and when he was playing no-one else would play… Also he was shorter than the controls, and used a chair, yet with all difficulties he would play over, and over, and over, and over… And he would only leave to grab popcorn (when he did that, other people would play :P )

Also I made a competition, anyone that hit first place in the scores (but at least 1 million points) would get a t-shirt. Two guys did it, and won t-shirts :D (btw: if anyone here make a youtube video of you playing the entire game and hitting more than 2.5 million points, I will send a t-shirt for you too! Keep in mind that after someone manage to do it, I will raise the score needed).

Also, as Mango wrote on his post, I made a twitcam, and we chatted a lot over twitter ^^ Later you people can suggest more twitcam subjects.

Also I got some offers of places to distribute the game. YAY!

So, that is it, follow the twitters (@agfgames and @criadordejogos) and play a bit more.

Posted in Arcade Cabinet, Community News | 1 Comment

Campus Party

Speeder is currently away at the 2011 Campus Party. I don’t know too much about the event itself, but what is known right now is that Paddle Wars: Hit The Wall has its own arcade cabinet, and that it has gone through several revisions at this event alone. That version will be released once the event has concluded.

Current downloadable version: Beta 4
What’s in the arcade cabinet: Beta 5 revision 4

I’m not sure how long this link will last, but the live video of people playing the game (or just passing by) can be found here.

Edit: due to an unexpected stream failure, you can access the fixed stream here.

Posted in Arcade Cabinet, Community News | Leave a comment