Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Lua Binding  (Read 9081 times)

0 Members and 1 Guest are viewing this topic.

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
Lua Binding
« on: December 14, 2013, 12:18:50 pm »
Hi,

During a long time I was looking for a simple and fast GameEngine but I could find something as simple and light weight as SFML. So I found myself writing one, but more the time pass, less I wanted to lost time with C++. I wanted to be able to fast prototyping like it can be done with GameMaker for example.  And here I am porting SFML to Lua.

I wanted it to be simple (mirroiring SFML API) light weight (no Boost at all). It's not finished yet (no network for example). I've added some extra classes like TileMap or SceneGraph Item.

I've not reach yet my objective to fast prototyping but it's been pretty fun. I hope you will enjoy it.

The source code is avaible https://github.com/Canadadry/luaSFML
On the repo you will find some test project I've made in the demo folder. There is a Tetris, a pong, and a Minesweeper.

Here an example of script :

math.randomseed(os.time())

window = sfRenderWindow.new(sfVideoMode.new(640,480,32),"Test",sfWindowStyle.Default);
window:setFramerateLimit(30)


circle = sfeSGItem.new();
circle:move(50,50);
circle:setWidth(100);
circle:setHeight(100);

child1 = sfeSGItem.new(circle);
child1:setWidth(50);
child1:setHeight(50);


clearColor = sfColor.new(math.random(256)-1,math.random(256)-1,math.random(256)-1);

event = sfEvent.new();
while window:isOpen() do
    i = 0;
    while window:pollEvent(event) do
        if(event:type() == sfEventType.Closed) then window:close(); end
        if(event:type() == sfEventType.KeyReleased and event:key():code() == sfKey.Escape ) then window:close(); end
        if(event:type() == sfEventType.KeyReleased and event:key():code() == sfKey.Q and event:key():system() == true ) then window:close(); end
    end

        circle:rotate(1);
        child1:rotate(-2);

    window:clear(clearColor);
        window:draw(circle);
    window:display();
end
 


Thanks for reading me :)
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Lua Binding
« Reply #1 on: December 14, 2013, 01:53:29 pm »
There have already been a few attempts to create a Lua binding for SFML:
  • LuaSFML in the very beginnings of SFML, back in 2007 (link)
  • An announced (but never seen) binding in 2010 (link)
  • sfengine in 2010 (link)
  • One in 2012 (link)
Most of the authors have never shown any code at all, and all projects have been abandoned. Apparently, none of the developers was seriously interested in maintaining the binding over a longer time. I think you should not underestimate this endeavour: In the beginning it may be fun because you can use it for your own game, but when you start porting features you don't use yourself (and new features) the process may become tedious, especially if you want to do things well (which includes a lot of testing and debugging). Another thing to consider is that there are already popular Lua libraries like LÖVE, so it may be difficult to get users. That just as a remark ;)

Do you use the Lua C API directly? I can recommend LuaBridge, it's a header-only dependency-free library that allows you to connect C++ and Lua very easily. It would probably save a lot of trouble, and you can progress much faster. This blog post might also be worth reading.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Lua Binding
« Reply #2 on: December 14, 2013, 02:47:47 pm »
I also interfaced my small framework from Nexus' book with Lua, well, I mean you can inteface your entities/nodes with it. But nothing so evolved.

Congratz, it will be useful !

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
Re: Lua Binding
« Reply #3 on: December 15, 2013, 12:33:57 am »
Awesome stuff :). Will be really nice once it's more Lua-like. e.g.,

window = sf.RenderWindow{w=640, h=480, title = "Test"}

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua Binding
« Reply #4 on: December 15, 2013, 02:15:44 am »
I really like Lua and such but I don't think that completely/automatically mirroring the c++ API 1 to 1 is a good idea.
Also there is LOVE which packs Box2D, PhysFS and some other things along graphics/input.
I'm semi interested in this because if I wanted to write a game in Lua I'd take LOVE not the c++ library I like. :P
But at the same time I like Lua and SFML and this is related to both. ;D

Lua has convention of using strings as enums(and so do I in SFG unless it's bitflag enum).
It's a bit weird event is object, maybe it should be a table made by user and get filled with right fields and then you check them directly with . and compare with strings. Also it could be so that if type is key pressed then the event table has set field event.code, not event.key.code, because that's just side effect of needing struct for even union in c++.

if(event:type() == sfEventType.KeyReleased and event:key():code() == sfKey.Escape ) then window:close(); end
vs.
if event.type == "KeyReleased" and event.code == "Escape" then window:close() end
The second one looks much nicer IMO(I don't use semicolons or redundant parenthesis but that's not the point here).

Same for color and video mode, both are just few bytes of numbers, color could be a single number or four numbers and video mode could be replaced by 3 number args with one being optional.

math.random(256)-1
is same result and number of characters as
math.random(0,255)
but that one is more clear. ;)

Maybe also creating preloader for SFML module and removing sf from front so it'd be possible to do:
local sf = require"SFMLua"
--use sf.ClassName just like a c++ namespace
 

Perhaps there could be even some Lua code to go along the binding, for example, iterator for events.
event = sfEvent.new();
while window:pollEvent(event) do
-- do stuff...
end
 
vs(iterative + non c++ events).
for event in window:iterateEvents() do
-- do stuff...
end
 

Iterate events could be:
function iterateEvents(self)
    local event = {}
    return function()
        if self:pollEvent(event) then return event end
    end
end
I think.. I'm writing from memory ;) , I'm still lacking in Lua.
« Last Edit: December 15, 2013, 02:20:55 am by FRex »
Back to C++ gamedev with SFML in May 2023

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Lua Binding
« Reply #5 on: December 15, 2013, 10:59:31 am »
There are no enums in Lua anyway, the expression
sfEventType.KeyReleased
is just a shortcut for
sfEventType["KeyReleased"]
i.e. you use a string as table key.

I wonder however if it would be worth investigating an error reporting mechanism if an invalid string is used?
if event.key.code == "Backspace" -- correct would be "BackSpace"
will just always be false, and such errors may be tedious to debug.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Canadadry

  • Hero Member
  • *****
  • Posts: 1081
    • View Profile
Re: Lua Binding
« Reply #6 on: December 15, 2013, 12:35:05 pm »
I'm not sure if I will maintain it over time, since I'm doing this this mainly for me. It's development is directly link to what I need, which project I'm working on. So don't get to excited. At least I provide my sources ^^.
Even if it's not complete you can already do a lot with it.

Thank a lot for the link Nexus I was looking for something simple and light to do the binding. But I've found nothing. So i've directly use lua C-API. It's been hard but I've learn a lot.

I will try to simplify the binding, but I'm currently limited by my knowledge of lua c-api and my time. ^^
I'm aiming something like LOVE for the simplicity and I also wanna add physics, 2D engine and stuff.
I don't know when it will be done, or if it will be done. I'll try to improve it until I get bored or I find something that fit all my need.

I'm not fan of using string instead of enum. It doesn't seems right.

I really like Lua and such but I don't think that completely/automatically mirroring the c++ API 1 to 1 is a good idea.

I know I should adapt to lua convention, but I'm not used to it and it could force me to write a documentation. Currently C++ doc is enough. It's a huge project I don't want to get bored or frightened by doing thing like this.
This is not the best but better is enemy of good.

Awesome stuff :). Will be really nice once it's more Lua-like. e.g.,

window = sf.RenderWindow{w=640, h=480, title = "Test"}


It could be great but I'm not sure how to achieve this ^^

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Lua Binding
« Reply #7 on: December 15, 2013, 12:53:19 pm »
Thank a lot for the link Nexus I was looking for something simple and light to do the binding. But I've found nothing. So i've directly use lua C-API. It's been hard but I've learn a lot.
You could have just looked at this page ;)

I'm not fan of using string instead of enum. It doesn't seems right.
As already mentioned, there are no enums in Lua, and the apparent member variable is just another syntax for a table access using a string key.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Lua Binding
« Reply #8 on: December 15, 2013, 04:33:59 pm »
There are no enums in Lua anyway, the expression
sfEventType.KeyReleased
is just a shortcut for
sfEventType["KeyReleased"]
i.e. you use a string as table key.
Believe me, I know. :P It's still a convention in Lua to pass and return strings not numbers as enums.
And == "KeyReleased" is* one compare and constant(in 5.2 at least, that's what I have) and == sfEventType.KeyReleased is fetching the table by name, then fetching a field by name and then comparing(= two constants, two fetches from table, one compare).
Also it's longer and uglier.
Same for event:type() vs. event.type, first is fetch 'event', fetch 'type' for self call and (cross language) call, second is fetch event, fetch field.
event:key():code() is even worse: fetch, self, call, self, call vs. event.code fetch, fetch.

Quote
I wonder however if it would be worth investigating an error reporting mechanism if an invalid string is used?
Lua doesn't do that in it's own library.
Also the first approach has the same error, if you use wrong key you get nil that'll compare as different from anything. ;D

*checked by luac.
« Last Edit: December 15, 2013, 04:39:40 pm by FRex »
Back to C++ gamedev with SFML in May 2023

denismr

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Lua Binding
« Reply #9 on: December 19, 2013, 05:50:44 am »
Maybe you don't know this: if you are using luajit, then you can use the official C binding almost directly with the FFI built in library.

http://luajit.org/ext_ffi.html

I tried it and it worked perfectly for me.

But, since love 0.9 adopted luajit for its default distribution, I rarely consider anything else for prototyping (idk if this is your purpose).

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: Lua Binding
« Reply #10 on: December 20, 2013, 07:12:51 pm »
By the way, i'm using OOLua to create bindings. Very fast, almost easy and not abandoned. =) There are three branches OOLua-1 (old), OOLua-2 (stable) and shared_ptr - new one, with shared pointers support. =)