Scripting implementation progress

Source Code and development in general from a technical point of view. Post Patches here.

Moderator: SMC Team

Scripting implementation progress

Postby Quintus » 25 Mar 2012 21:47

I’m working on scripting and got the basics working, but there’s much left. I chose an event-based architecture, so within the Lua code you register for an event to be fired by SMC sometime. Currently, only the KeyDownEvent is implemented for the shoot key, but as soon as I implement argument passing to the Lua callback function I’m going to aim for more events.

What’s currently possible is to register an event handler like this:

Code: Select all
function myhandler()
  -- Make him small! ;-)
  Player:downgrade
end

KeyDownEvent:register(myhandler)


Put this in an extra <luascript> tag in your level and it will be loaded on entering the level. Each time you press the shoot key, SMC will issue the KeyDownEvent and call your Lua handler, effectively downgrading the player. Oh, and if you do this while being small, you die ;)

I’ve attached a sample level demonstrating the behaviour. If you run SMC from the console, you’ll see some messages printed out from the Lua code, but this is merely to demonstrate it’s working.

Sourcecode available here: https://github.com/Quintus/SMC/tree/integrate-lua

When I’m finished, I’m going to send a pull request to upstream, i.e. the people that can commit directly to https://github.com/FluXy/SMC. Btw. does anybody know whether Tristan Heaven is on the SMC forums? He seems to be the only one working on SMC right now, but I’m wondering why he doesn’t take part in the discussions on SMC’s future here in the forums...

Currently I’ve included the Lua 5.2 interpreter into SMC’s sources (it’s MIT-licensed) and a helper library called LuaWrap I wrote for briding C++ classes more easily to Lua 5.2 that is licensed under the BSD license. Is this OK or do I have to separate this from SMC?
Then I’ve had some problems getting Autohell to recognize the Lua interpreter I wanted it to recognize, it always fell back to my system’s Lua (which is a 5.1 and available as a dynamic shared object instead of a static one) until I forced it with a LDFLAGS="-L/home/quintus/Projekte/Programmieren/SMC/lua/src" ./configure --some-more-opts to use the correct interpreter. Same for the Lua header includes that I had to explicitely do like
Code: Select all
#include "../../../lua/src/lua.h"
instead of just
Code: Select all
#include <lua.h>
. Some Autotools guru here that might help me getting rid of this?

Valete,
Quintus
Attachments
testlevel.smclvl
Test level with Lua code to downgrade the player on hitting the shoot key.
(8.91 KiB) Downloaded 196 times
Aetas nulla ad discendum sera.
User avatar
Quintus
SMC Team
SMC Team
 
Posts: 353
Joined: 14 Sep 2010 18:05
Location: Germany -> NRW -> UN

Re: An easier way to implement scripting

Postby Luiji » 25 Mar 2012 23:00

First off, sweet! This looks great!

I recommend removing the Lua sources from the Git tree, but LuaWrap looks small enough that it is reasonable to just keep a copy. I'd recommend naming everything using lowerCamelCase since that seems to be what most Lua engines handle. Futhermore, I think just using <script> as the tag instead of <luascript> would look nicer. Using SMC::Script as the namespace instead of SMC::Lua might more so match the style of SMC's code, also.

It seems you already have the code necessary to get Lua into the Autotools in configure.ac...are you still having problems or have you fixed it since you posted?
Custom Built IBM-Compatible (Arch Linux w/ KDE)
Dell Vostro (Windows 7)
Dell Inspiron 1440 (Windows Server 2003, Debian w/ KDE)
Dell Inspiron 11z (Linux Mint)
Luiji
MVP
MVP
 
Posts: 2703
Joined: 14 Jan 2010 23:20
Location: The Mushroom Kyngdom

Re: An easier way to implement scripting

Postby DevEd2 » 26 Mar 2012 14:39

This. Is. AWSUM!!1! I never thought I'd live to see scripting implemented in SMC.

I wonder what other breakthroughs have been made...
User avatar
DevEd2
Turtle boss
Turtle boss
 
Posts: 791
Joined: 30 Nov 2010 22:44
Location: Earth :P

Re: An easier way to implement scripting

Postby Quintus » 26 Mar 2012 18:22

Luiji wrote:First off, sweet! This looks great!
Thank you :)

Luiji wrote:I recommend removing the Lua sources from the Git tree
[...]
It seems you already have the code necessary to get Lua into the Autotools in configure.ac...are you still having problems or have you fixed it since you posted?


I didn’t, I was forced to pass the LDFLAGS environment variable each time I wanted to use the "internal" Lua. But I now did as you suggested and removed Lua from SMC’s sources, making it a normal external dependency that has to be installed on your system when building SMC. This wasn’t too hard to implement in configure.ac. Is it possible to enforce a statically linked Lua library in configure.ac? Otherwise a user might build against the correct Lua, but links it dynamically, and on the final system there might be an incorrect version installed, resulting in segfaults or other bad things. Or do I worry too much here?

Luiji wrote:I'd recommend naming everything using lowerCamelCase since that seems to be what most Lua engines handle.
Hm. I’ve reworked the sourcecode to look more like the rest of SMC’s code, hopefully I met your expectations?

Luiji wrote:Futhermore, I think just using <script> as the tag instead of <luascript> would look nicer.
Done.

Luiji wrote:Using SMC::Script as the namespace instead of SMC::Lua might more so match the style of SMC's code, also.
Done.

DevEd2 wrote:This. Is. AWSUM!!1! I never thought I'd live to see scripting implemented in SMC.
Thanks :) But keep calm, it’s still a long way to go...

DevEd2 wrote:I wonder what other breakthroughs have been made...
I didn’t change many other things, and I did those mainly to get comfortable with SMC’s code and to get an understanding of how the whole thing works. You can read what I changed in the commit log if you like.

Quintus wrote:Currently, only the KeyDownEvent is implemented for the shoot key, but as soon as I implement argument passing to the Lua callback function I’m going to aim for more events.
I’ve implemented argument passing and added support for the other keys recognized by SMC, plus some more methods on the Player object. You can now do stupid things like this:

Code: Select all
function myhandler(key)
  if key == "jump" then
    Player:kill()
  elseif key == "shoot" then
    Player:set_type("ice")
  elseif key == "action" then
    Player:warp(400, -500)
  end
end

KeyDownEvent:register(myhandler)


Note I don’t recommend this as this would effectively forbid the player to jump inside your level (when he jumps, he will immediately be killed).

Luiji, is there something like a syntax-highlighting editing control in CEGUI? This would allow for easy editing of the Lua script from inside the SMC editor rather than having to do it manually in the XML file (which is tricky as you have to escape things as " -> &quot; yourself...).

SMC is great. I’m really glad I can help with this great project.

Valete,
Quintus
Aetas nulla ad discendum sera.
User avatar
Quintus
SMC Team
SMC Team
 
Posts: 353
Joined: 14 Sep 2010 18:05
Location: Germany -> NRW -> UN

Re: An easier way to implement scripting

Postby DevEd2 » 26 Mar 2012 18:32

Kill players for jumping. Nice. :evil:
User avatar
DevEd2
Turtle boss
Turtle boss
 
Posts: 791
Joined: 30 Nov 2010 22:44
Location: Earth :P

Re: An easier way to implement scripting

Postby Jonn » 26 Mar 2012 19:55

A start of scripting! Finally some process! SMC is going to be awesome again!
OK, I'm a bit overstating, but I think its great,
but there are a few thing that I think are important:

  • I think scripting should be implemented on such way that a script never can damage a computer, so that you can safely download a level.
  • The player is now a singleton, but what if we add multiplayer in the future? It would be nice if scripting was implemented on such a way that scripts don't need to be rewritten if/when we add multiplayer. A way to solve this is to make a function that return an array with players (which currently always has a length of 1). At the other hand, scripting should be not to difficult, and looping through an array is maybe too difficult for newcomers...
No pizza is perfect, and SMC is not a pizza!
chicken+egg=dilemma
User avatar
Jonn
Eato
Eato
 
Posts: 57
Joined: 31 Oct 2011 17:46

Re: An easier way to implement scripting

Postby -DarkAceZ- » 26 Mar 2012 22:11

Ummm... Seriously? Hasn't Quintus been working on this for a long while by now? This is news?
User avatar
-DarkAceZ-
Maryo small
Maryo small
 
Posts: 1062
Joined: 28 Oct 2010 17:24
Location: The Level Editor

Re: An easier way to implement scripting

Postby Luiji » 27 Mar 2012 01:36

I've been working on this for awhile (or so I've said...), Quintus just started and has made much more progress than I have. So yes, this is news.

Don't worry about static linking. Distributing shared libraries in the same directory as SMC's binary should fix any problems that might be associated with that (although you might have to state -Wl,-rpath=. to the LDFLAGS). Note that such self-contained packages should be installed in /opt/custom-directory instead of /usr[/local] by FHS standards.

As for the lowerCamelCase stuff, I meant reworking the scripting API, not the C++ code. Sorry for not being clear... however, the source code tree looks a bit cleaner now. It looks really easy to add new modules.

CEGUI does not have a syntax-highlighting control, although I could probably write one fairly easily since I've been practicing with syntax parsers and CEGUI has rich text widgets. Don't worry too much about syntax-highlighting, though, since I don't think it's really _necessary_ at this point.

I actually have some code on my computer that removes all harmful functions from Lua 5.1, and I can probably update it to 5.2. We'd have to make sure that only pure Lua code, and not binaries, are accepted if we wanted to have secure scripts.

I think that the player being singleton is good for now. If we add multiplayer support, we can just make the old-fashioned player object just refer to the player 1. I'm not totally sure, though.

Killing people for jumping is the best script ever, by the way.

Happy coding!
Custom Built IBM-Compatible (Arch Linux w/ KDE)
Dell Vostro (Windows 7)
Dell Inspiron 1440 (Windows Server 2003, Debian w/ KDE)
Dell Inspiron 11z (Linux Mint)
Luiji
MVP
MVP
 
Posts: 2703
Joined: 14 Jan 2010 23:20
Location: The Mushroom Kyngdom

Re: An easier way to implement scripting

Postby -DarkAceZ- » 27 Mar 2012 02:00

Luiji wrote:Killing people for jumping is the best script ever, by the way.

Oh yes. The game wouldn't be fun if we couldn't do that!
User avatar
-DarkAceZ-
Maryo small
Maryo small
 
Posts: 1062
Joined: 28 Oct 2010 17:24
Location: The Level Editor

Re: An easier way to implement scripting

Postby Luiji » 27 Mar 2012 04:29

Or maybe it just means you have to think a bit differently about level design... ;)
Custom Built IBM-Compatible (Arch Linux w/ KDE)
Dell Vostro (Windows 7)
Dell Inspiron 1440 (Windows Server 2003, Debian w/ KDE)
Dell Inspiron 11z (Linux Mint)
Luiji
MVP
MVP
 
Posts: 2703
Joined: 14 Jan 2010 23:20
Location: The Mushroom Kyngdom

Re: An easier way to implement scripting

Postby -DarkAceZ- » 27 Mar 2012 05:01

Luiji wrote:Or maybe it just means you have to think a bit differently about level design... ;)

No, seriously! It would be awesome to have a no-jump level!
User avatar
-DarkAceZ-
Maryo small
Maryo small
 
Posts: 1062
Joined: 28 Oct 2010 17:24
Location: The Level Editor

Re: An easier way to implement scripting

Postby Luiji » 27 Mar 2012 05:17

Ah, I thought you meant the game wouldn't be fun if we couldn't jump, but now I see you mean it wouldn't be fun if we couldn't kill people for jumping. Yes, very true. Very true indeed.
Custom Built IBM-Compatible (Arch Linux w/ KDE)
Dell Vostro (Windows 7)
Dell Inspiron 1440 (Windows Server 2003, Debian w/ KDE)
Dell Inspiron 11z (Linux Mint)
Luiji
MVP
MVP
 
Posts: 2703
Joined: 14 Jan 2010 23:20
Location: The Mushroom Kyngdom

Re: An easier way to implement scripting

Postby DevEd2 » 27 Mar 2012 12:25

ON-TOPIC: Quintus, can you implement block-touch events? (script that activates when Maryo touches a block) THAT is something I want to see implemented. If you can do that, then we will finally be able to make lava that instantly kills you! Like real lava! (ok, not really, you would burn to death in a couple minutes. But still!)

OFF-TOPIC: We should hold a contest to see who can build the best level that can be completed without jumping.
User avatar
DevEd2
Turtle boss
Turtle boss
 
Posts: 791
Joined: 30 Nov 2010 22:44
Location: Earth :P

Re: An easier way to implement scripting

Postby Quintus » 27 Mar 2012 13:57

Luiji wrote:Don't worry about static linking. Distributing shared libraries in the same directory as SMC's binary should fix any problems that might be associated with that (although you might have to state -Wl,-rpath=. to the LDFLAGS). Note that such self-contained packages should be installed in /opt/custom-directory instead of /usr[/local] by FHS standards.
OK, then Im just going to go ahead. Thanks.

Luiji wrote:As for the lowerCamelCase stuff, I meant reworking the scripting API, not the C++ code.
So you want something like this in the Lua code?:

Code: Select all
sPlayer:kill()
cFurball:new()


I don’t really like this. It makes the Lua code harder to read, and scripting should be understandable by the people using the game. It may be that I’m coming from Ruby rather than C++ where it’s just normal to name classes in CamelCase, variables in snake_case, and that’s about it as Ruby enforces things like these or the @ sigil for instance variables. Lua neither has statically-tped variables nor pointers, so there’s no need for these cryptic prefixes neither. The Hungarian Notation used in C++ in my opinion reflects that the language isn’t properly designed. However, just my 0,02€.

Luiji wrote:Don't worry too much about syntax-highlighting, though, since I don't think it's really _necessary_ at this point.
I agree. This isn’t a priority right now and can be added later, when scripting has been completed.

Luiji wrote:I actually have some code on my computer that removes all harmful functions from Lua 5.1, and I can probably update it to 5.2. We'd have to make sure that only pure Lua code, and not binaries, are accepted if we wanted to have secure scripts.
Plain Lua without any libraries opened is quite limited. Isn’t it enough to just load the core library (see section 6 in the Lua manual)?

Luiji wrote:I think that the player being singleton is good for now. If we add multiplayer support, we can just make the old-fashioned player object just refer to the player 1.
I don’t think that SMC would be a good multiplayer game. However, adding multiplayer facilities would require a major change in the codebase and making scripting compatible with this shouldn’t add too much work to this, so keeping the Player singleton is the right way for now in my opinion.

DevEd2 wrote:ON-TOPIC: Quintus, can you implement block-touch events? (script that activates when Maryo touches a block) THAT is something I want to see implemented. If you can do that, then we will finally be able to make lava that instantly kills you! Like real lava! (ok, not really, you would burn to death in a couple minutes. But still!)
I can assure you this will get implemented, but before I can do so I have to bridge the relevant SMC classes over to Lua. I’ve some nice level ideas for this, namely things with switches that make things appear or disappear.

There’s a problem with identifying objects, though. Currently there’s no way to distinguish two objects of the same type by something other than their positions, and even that may not be enough. Even worse, when the user moves an object, it’s position changes and he would have to update the Lua code. I think objects should get assigned a numeric ID automatically that is displayed when hovering the cursor over the object, just the same way the X and Y corrdinates currently are. This way it would be easy to uniquely identify an object, and a user could reference a specific object like this from Lua:

Code: Select all
Furball[33]:kill() -- Pick the furball with ID 33 and kill him


DevEd2 wrote:OFF-TOPIC: We should hold a contest to see who can build the best level that can be completed without jumping.
I just posted a senseless script and now you all want to use it... What the world has come to? ;)
Seriously: If you want to make a no-jump level you shouldn’t instantly kill the player. This is quite disappointing for the player I think.

Valete,
Quintus
Aetas nulla ad discendum sera.
User avatar
Quintus
SMC Team
SMC Team
 
Posts: 353
Joined: 14 Sep 2010 18:05
Location: Germany -> NRW -> UN

Re: An easier way to implement scripting

Postby DevEd2 » 27 Mar 2012 14:04

Quintus wrote:I just posted a senseless script and now you all want to use it... What the world has come to? ;)
Seriously: If you want to make a no-jump level you shouldn’t instantly kill the player. This is quite disappointing for the player I think.


I meant for SMC 1.9. Some of us can't compile the Git.

EDIT: He logs in just to make a single post. And then he logs out! WTF?
User avatar
DevEd2
Turtle boss
Turtle boss
 
Posts: 791
Joined: 30 Nov 2010 22:44
Location: Earth :P

Re: An easier way to implement scripting

Postby Luiji » 27 Mar 2012 23:06

Most people log in, make a single post, then log out.

I meant naming things like player:kill(), with the class name lower-case, because it seems to be what most Lua scripts do. If you are treating Player as a singleton class, then I see how it makes sense to make it capital, though. After I looked at the API more so, I had realized that you were using Ruby-style naming, which I think works well. At the time of my postings I had just not realized certain aspects of your API design.

Plain Lua without any libraries open lacks some pretty useful functions. Furthermore, it is still vulnerable; a user could load up Lua/C libraries installed on the user's computer and do some damage.

Also, you _can_ make Lava that instantly kills you already.
Custom Built IBM-Compatible (Arch Linux w/ KDE)
Dell Vostro (Windows 7)
Dell Inspiron 1440 (Windows Server 2003, Debian w/ KDE)
Dell Inspiron 11z (Linux Mint)
Luiji
MVP
MVP
 
Posts: 2703
Joined: 14 Jan 2010 23:20
Location: The Mushroom Kyngdom

Re: An easier way to implement scripting

Postby -DarkAceZ- » 28 Mar 2012 00:10

Luiji wrote:Also, you _can_ make Lava that instantly kills you already.

But wouldn't you have to have it close to the end/pit/ground/deathline/falldownplace/killhole/whatever for that to work?
User avatar
-DarkAceZ-
Maryo small
Maryo small
 
Posts: 1062
Joined: 28 Oct 2010 17:24
Location: The Level Editor

Re: An easier way to implement scripting

Postby DevEd2 » 28 Mar 2012 12:14

I think he means make a static enemy with lava-like graphics. That should do the job. Plus, you don't have to have it close to the end/pit/ground/deathline/falldownplace/killhole/whatever.

...or do static enemies not instantly kill you?
User avatar
DevEd2
Turtle boss
Turtle boss
 
Posts: 791
Joined: 30 Nov 2010 22:44
Location: Earth :P

Re: An easier way to implement scripting

Postby Luiji » 28 Mar 2012 22:32

Ah, good point, I'm not sure if static enemies are capable of instant-kill...although that feature could easily be added. I might even have time to add it myself. I'll look into it later tonight and see if I can make a patch.
Custom Built IBM-Compatible (Arch Linux w/ KDE)
Dell Vostro (Windows 7)
Dell Inspiron 1440 (Windows Server 2003, Debian w/ KDE)
Dell Inspiron 11z (Linux Mint)
Luiji
MVP
MVP
 
Posts: 2703
Joined: 14 Jan 2010 23:20
Location: The Mushroom Kyngdom

Re: An easier way to implement scripting

Postby -DarkAceZ- » 29 Mar 2012 01:10

Yaaay!

O_O Of course they can't! Play SMC once in a few years, guys! :P
User avatar
-DarkAceZ-
Maryo small
Maryo small
 
Posts: 1062
Joined: 28 Oct 2010 17:24
Location: The Level Editor

Next

Return to Development

Who is online

Users browsing this forum: No registered users and 2 guests

cron