Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411579 Posts in 69386 Topics- by 58445 Members - Latest Member: Mansreign

May 05, 2024, 03:49:38 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Embeddable Scripting Languages
Pages: 1 [2]
Print
Author Topic: Embeddable Scripting Languages  (Read 5661 times)
salade
Level 4
****



View Profile
« Reply #20 on: February 09, 2010, 06:33:38 PM »

Or, more accurately, I used LUA for embedded scripting in my last project, found a few aspects er... not to my taste, and was looking to try out other options for my next one. I would highly recommend investigating it and experimenting with it as a potential candidate. It it basically my fallback option if I can't get a more preferred language to work.

I know what you mean... at first LUA looks like the end all solution, untill you learn the catch is that you have to to a bunch of stack work to pass data to and from it (which its website actually lists as a benefit of the language for some reason.)

I think I'll still end up going with LUA though, I'll just have to go down the twisty road of keeping all my game specific data inside LUA. Actually, I was just thinking about making an Interpreter class to interface all the LUA in C++, but that's still a bit further down the development road.

I have yet to check out python. I've been learning the language to help a friend get into programming and it looks usable, but I haven't taken a look at the C api yet. I also don't think the language itself is as elegant as LUA (for scripting at least), but that would be moot if its implementation into C was better (i.e. shared variables).

I know there is also SWIG, but meh...
Logged
Garthy
Level 9
****


Quack, verily


View Profile WWW
« Reply #21 on: February 09, 2010, 08:03:48 PM »

I'll propose my Minimal scripting language. Its very simple and a good starting point for making your own scripting language (the code is hopefully easy to follow and its just a pair of .c and .h files). Personally i use it as a starting point for game/engine-specific scripting languages or configuration files so the Minimal lang itself doesn't have much stuff.

At this point I'm probably looking for something a bit more established and documented, with concrete examples, and no need for a great deal of additional work. This is not to disparage your work *at* *all*. It just might not be suited to what I am looking at doing at this point. However, if it came down to rolling my own, I'd be looking around at other people's work, and something with a minimal starting point as you have developed would have a great deal of appeal in such a situation.

Out of curiosity, does it handle the A->B->A stuff I've mentioned, ie. call the script from say C++, and the script can call back?

Another option is AngelScript which can use C++ functions and classes directly and i think even extend them.


This looks interesting- seems like it is designed from scratch to do just what I am describing, and from the doco I *think* it handles the extending/A->B->A stuff I've mentioned. Very interesting. Smiley

What aspects in particular rubbed you the wrong way?  I'd be interested to hear more about your experiences integrating and using it in your game.  Such accounts are pretty hard to come by, and I'm quite curious to hear how things play out for other developers.

I'd made notes somewhere- can't find the cursed things though. Here are a few things off the top of my head, forgive any rustiness, it's been a few years:

- Manually managing the stack is a pain. This makes A->B->A-style extended calls rather painful to work with. They work, but they're a pain.
- Arrays aren't *really* arrays, they're basically maps.
- Arrays begin at 1. Kind of. But not.
- Numbers are actually floats, no separate int type. Justification talks about how floats won't always lose precision, but sometimes you just want an int to be an int.
- Language itself is a bit unwieldy. Some clever things are possible, but it feels more like you are *fighting* the language than *using* it. I ended up simplifying my use of it considerably because it just became too frustrating.
- The API has a nasty habit of changing. The calls that worked for you yesterday may break or refuse to compile when you upgrade. Backward compatibility doesn't seem to be a concern- at least one upgrade *could* have been done with backward-compatible wrappers.. but it wasn't! The "offending" functions were just removed.
- Despite a decent amount of documentation, there tend to be a few ways to do various value manipulation, but it's never clear what the *right* way is. Guess wrong, and the next upgrade will kill your code. Again.
- Weird implementation decisions, such as it being decided that it was actually acceptable to call exit() in an embedded scripting application.

I'd like to emphasise to any LUA fans that these are just my personal experience, and that I'm not looking to debate/argue its merits or hurt anyone's feelings. It just didn't suit my needs, sorry.

I would still always recommend looking at it. It is a well-established embedded scripting language. Some of the problems mentioned above may have been addressed since.

I know what you mean... at first LUA looks like the end all solution, untill you learn the catch is that you have to to a bunch of stack work to pass data to and from it (which its website actually lists as a benefit of the language for some reason.)

And a few more reasons given above. Wink Yeah, agreed. It's a bit of a letdown as it seems to be the perfect solution before you begin.

I think I'll still end up going with LUA though, I'll just have to go down the twisty road of keeping all my game specific data inside LUA. Actually, I was just thinking about making an Interpreter class to interface all the LUA in C++, but that's still a bit further down the development road.

I'd definitely look into writing a A->B->A-style callback function into your code, unless you want to be stuck either putting everything or nothing into LUA. If need be, just write one or two interface functions, and use the args to go off and do useful things, rather than writing a thick interface. LUA is definitely capable of doing such things, even if it is a bit painful.

Personally, I think that once a library or language starts significantly impacting on your design, then there is a problem, either with the library/language, or how you're using it. A good library or language simplifies what you are doing. A bad one changes it. IMHO!

I have yet to check out python. I've been learning the language to help a friend get into programming and it looks usable, but I haven't taken a look at the C api yet. I also don't think the language itself is as elegant as LUA (for scripting at least), but that would be moot if its implementation into C was better (i.e. shared variables).

Python is a good language, it's one of the reasons I was willing to gamble some time on getting it going as an embedded scripting language even though it wasn't really designed for that purpose specifically. Personally, my preferred language is Ruby, but after some horrible experiences and masses of wasted time trying to get it working as an embedded scripting language, I doubt that I'll try it again.

If you prefer LUA scripting over Python, you might prefer LUA overall, for while the API is painful at times, and changes, it's designed to specifically fit the embedded scripting role. I happen to prefer Python over LUA as a language, myself.

I know there is also SWIG, but meh...

SWIG is definitely worth playing with. Whilst I'm not using it for the embedded scripting, I have used it for creating Ruby modules that use some of my C++ libraries. It is very useful.
« Last Edit: February 09, 2010, 08:08:47 PM by Garthy » Logged
Hima
Level 4
****


OM NOM NOM


View Profile WWW
« Reply #22 on: February 09, 2010, 10:04:08 PM »

@Garthy
Thank you for posting all this! It's one of the questions I've wanted to ask for so long :D  I've tried lua, squirrel, and ruby, but none of them doesn't work for me. Well, Lua kinda does, but I was so frustrated with the syntax that I don't feel like using it anymore. I also got ruby to work (1.8.1 or something) It wasn't that bad but I haven't worked more on it yet since the language is pretty slow. Squirrel doesn't work for me at all due to the lack of documentation and examples.

I haven't tried python since I've heard that it isn't designed to be embed. However,I've tried AngelScript and it works great for me. It also does what you ask in the first post. So in case you feel like embedding the whole python is overkill, you should try angelscript Smiley The creator is very nice too. On angelscript gamedev.net forum, he answer questions pretty fast and very clearly too.

Anyway, reading this make me wanna try my hand on python too.

@Bad Sector
I'm really interested in this since I'll have to create my own scripting language of some sort for my visual novel game. I was thinking of using XML but this seems to be better.
Logged

Bad Sector
Level 3
***


View Profile WWW
« Reply #23 on: February 10, 2010, 04:09:48 AM »

@Garthy:
Actually in the current minimal version you can't call a script function. It isn't hard to do though, i just need to expose the function's address and add a 'call' function (the VM is a flat register based VM which is very CPU like and anything you can -and cant- do in a CPU is possible with the VM, including calling code at arbitrary positions). I have done it (with synced functions only, but thats what most languages do anyway) in a modification to minimal for an experimental 3D engine of mine to implement some sort of object oriented scripting by having each script represent an object and message forwarding for implementing inheritance.

Scripts can call host functions though :-P. A host function is a C function defined like:
Code:
static void nat_print(script_t scr, int argc, const int32_t* argv)
{
    int i;
    for (i = 0; i < argc; i++)
        printf("%s", ml_string(scr, argv[i]));
    printf("\n");
}
and registered with
Code:
ml_regfunc(NULL, "print", nat_print, -1); /* -1 means argcount can be variable */
(this is actually the code for the 'print' command)

@Hima:
Yes, minimal can be a good choice for an adventure game or visual novel, i've actually written a JavaScript version of the minimal VM which runs a simple console program, so making a text adventure is well within the abitilies of the system and registering extra functions to handle graphics and sound in order to implement an adventure or VN is very easy :-).
Logged

~bs~
Zaratustra
Level 7
**



View Profile WWW
« Reply #24 on: February 10, 2010, 05:52:41 AM »

Ruby can do this and is extremely awesome.
Logged

Hima
Level 4
****


OM NOM NOM


View Profile WWW
« Reply #25 on: February 10, 2010, 06:43:19 AM »

Ruby can do this and is extremely awesome.
I'd love to hear how you embed ruby since it's one of my favorite scripting languages!
Logged

Zaratustra
Level 7
**



View Profile WWW
« Reply #26 on: February 10, 2010, 08:10:52 AM »

Then behold, my son:

http://metaeditor.sourceforge.net/embed/

http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html#S8
Logged

Bad Sector
Level 3
***


View Profile WWW
« Reply #27 on: February 10, 2010, 08:26:46 AM »

@Garthy:
Forget the part about not being able to call script functions from the host program. I just added this feature to the base Minimal code :-P. So to call a script function you need to obtain its address inside the bytecode using ml_funcaddr and call it using ml_call or ml_callv (the former uses C varargs and the latter uses an array with the arguments). Example:
Code:
/* get the address of the on_collision function */
int32_t on_collision_addr = ml_funcaddr(script, "on_collision");

... later ...

/* call the on_collision function with the IDs of the collided entity and its position.
The on_collision function returns 1 if it handled the collision or 0 if not */

int32_t handled = ml_call(
    script,                     /* the script object */
    on_collision_addr,          /* address of the function obtained with ml_funcaddr */
    3,                          /* number of arguments to pass to the function */
    obj_id, x, y                /* the arguments */
);

The bytecode format has been extended to save the function addresses and their names so you can use the included mlc bytecode compiler (or the ml_getbytecode function) to save the bytecode on disk and use ml_setbytecode later to load it. This is an extension to what i used before in a modified minimal engine which needed the compiler information (and the script code) to be around.
Logged

~bs~
Hima
Level 4
****


OM NOM NOM


View Profile WWW
« Reply #28 on: February 10, 2010, 09:27:27 AM »

@Garthy:
Forget the part about not being able to call script functions from the host program. I just added this feature to the base Minimal code :-P.
More reasons I should try this <3

I was thinking of something more modern Sad I used these as references and I could get it to work, but I was just wondering how other people did it.  Panda
Logged

Garthy
Level 9
****


Quack, verily


View Profile WWW
« Reply #29 on: February 10, 2010, 05:05:26 PM »

@Garthy
Thank you for posting all this! It's one of the questions I've wanted to ask for so long :D  I've tried lua, squirrel, and ruby, but none of them doesn't work for me. Well, Lua kinda does, but I was so frustrated with the syntax that I don't feel like using it anymore. I also got ruby to work (1.8.1 or something) It wasn't that bad but I haven't worked more on it yet since the language is pretty slow. Squirrel doesn't work for me at all due to the lack of documentation and examples.

Not a problem. Since I've been struggling with it for so long, I'm surprised I didn't stop and think "well, perhaps I should ask around" much earlier.

I haven't tried python since I've heard that it isn't designed to be embed. However,I've tried AngelScript and it works great for me. It also does what you ask in the first post. So in case you feel like embedding the whole python is overkill, you should try angelscript Smiley The creator is very nice too. On angelscript gamedev.net forum, he answer questions pretty fast and very clearly too.

Anyway, reading this make me wanna try my hand on python too.

Apart from the initial pain (much of which you can avoid with the notes from the previous page, I think!), it has been a positive experience. The Python OO stuff is a bit poor in comparison to say Ruby, which I didn't remember from my previous uses of Python, but it's certainly "good enough". Smiley The API is good, and documented.

Re Angelscipt, an active, responsive maintainer is a *big* plus. I've added it to my "must try some time" shortlist.

(discussion on Minimal)

Minimal certainly sounds very interesting. I like the no-nonsense host functions.

Ruby can do this and is extremely awesome.

Ruby is an awesome scripting language, by far my favourite, and I use it heavily in my project. IMHO, as a language, it is superior to every other scripting language I have used, bar *none*. When I first tried moving on from LUA, attempting to embed it was a natural choice. Based on my experiences, my recommendation is to try it only if you have a lot of spare time free and a good plan B. As mentioned previously, my experiences in this regard were very poor.

I could go into a lot of detail, but the gist is:

- The documentation for embedding/extending is poor. You'll be hitting Google and mailing lists quite a lot to get any basics done. At the time, not many people were doing it.
- The means of performing even basic operations is extremely unintuitive through the API.
- I uncovered a bug in the garbage collector that caused intermittent crashes when Ruby is in heavy use, which made embedding Ruby completely useless to me as it made my app buggy. Until I produced a test case, it was "must be your code". When I did, along with hours of testing results and a highly detailed description, it was silence, or "works for me on my system" (the bug only affected some systems, so such a statement is useless and misleading). Nobody seemed to know what to do with bug reports. I tried submitting a bug report on a couple of systems I found. On one, I was told, after a while, that "nobody really uses this one any more". The "correct" one was down for days. Every so often I was asked to try it on the latest version. After spending my time doing so, and confirming it was still broken, no response. So basically, I was given busy-work to try to make the problem "go away". Each time by someone new. This was in response to my offering to help where I could. I tried digging around to find the proper place to submit a report on the Ruby homepage, and (at the time at least) I just couldn't find it. At this point I just gave up in frustration, and won't touch it again until there is someone both passionate and knowledgeable enough to clean up the documentation and take bug reports seriously. I know that person won't be me, due to the experiences I had.

Now don't get me wrong, I *love* Ruby as a scripting language, I just hate it as an embedded scripting language. I wasted huge amounts of time trying to get it to work, and afterward too, when trying to do the right thing and get the details to the right people.

@Garthy:
Forget the part about not being able to call script functions from the host program. I just added this feature to the base Minimal code :-P.

You are very obviously proud of your work on Minimal, with your natural response to hearing about a shortcoming being to immediately add a feature to address it. Smiley Good libraries are the ones that are worked upon by people who obviously care about the code. I sincerely hope that a whole bunch of people pick it up and have positive experiences with it. Smiley

I'll probably have a skim through it at some point, even if I don't use it, simply because your discussion of the tech behind it is intriguing. Smiley That, and a bytecode-based embeddable VM may have other uses in my current or future projects. Smiley

Have you considered putting up a page showing examples of the language in use, and examples of using the API, so that a casual browser can see what it looks like as a language, and how easy it is to use in their own applications? Just a thought. I'd be very interested in such a thing. Don't do it for me, of course, just if you'd like to attract more people to using it and think it would be a good idea. If you already have, and I just don't know the link, my apologies for assuming that you hadn't done this!

Logged
Bad Sector
Level 3
***


View Profile WWW
« Reply #30 on: February 11, 2010, 03:22:27 AM »

@Garthy:
Actually the case with Minimal is that i started it as something like a quick 'n dirty lib (that wouldn't be in a library format - thus the decision to keep it as a pair of .c/.h files) to put scripting wherever a simple scripting system was needed.

In fact i was blind about it for a while: i started designing (and implementing) a Lisp-like language (Former) that would be easy to implement because i tend to use a bunch of different languages and environments (C, FreePascal, Java and haXe are the most common but sometimes i might use something else like C# or Python) and i'm a strong believer of data/script driven programs and games. However what i didn't noticed was that i already had one, Minimal, which i already had implemented in C and Java for the compiler and C, haXe and JavaScript for the VM (the Java compiler and haXe VM was for my RayFaster 2 Flash game engine). Former is still more powerful than Minimal (having a more advanced garbage collector, high-order functions, closures, dynamic macros as values, etc) but on the other hand Minimal is simpler to work with, much faster, has a familiar (C-like) syntax, doesn't consume heaps of memory, etc. It was only recently that i decided to keep Former as an experimental language and "re-purpose" Minimal as the portable language to use (well it like that since always but i didn't notice it :-P). Because no matter how awesome Former's features are, practically speaking the language (implementation) is too slow, consumes too much memory and the parentheses make most people dizzy :-P.

As for the site, its a good idea. I'll see what i can do :-).
Logged

~bs~
Bad Sector
Level 3
***


View Profile WWW
« Reply #31 on: February 11, 2010, 07:52:55 AM »

Aaand here is the site. At least an initial version of it i just threw together :-P

http://realm.badsectoracula.com/minimal/
Logged

~bs~
Klaim
Level 10
*****



View Profile WWW
« Reply #32 on: February 11, 2010, 04:10:45 PM »

For my game, I'm using Falcon (http://www.falconpl.org/) :

 1. It's a powerful language, at least as much as python or ruby
 2. It's multi-paradigm -- meanging it's not "full oriented object" and it's a good thing -- read : http://www.falconpl.org/index.ftd?page_id=facts
 3. It's made to work with C++ : it's made of C++ and the language itself is made of C++ modules -- you can also add your own modules, specific lib for your game for example;

The only thing to know is that it's still under dev so it can change some features implementation between versions, but it's globally stable. Also it's not the more straightforward embedding inside a game, but it's well thought and very modulable and they are working on making embedding even easier.

Before that I used lua but for my game I wanted a more powerful language (for some game-specific reasons...) AND wanted a solution really targeted to be used with C++. I thought about Python... but discovered Falcon and thought it was worth trying it instead of Python in my case. I didn't consider Ruby because implementations are too slow and embedding is just another representation of hell.

Someone on the Ogre forum pointed to a simple scripting language targeted at C++ devs: http://www.chaiscript.com/
It's not what I need but I think a lot of C++ people around here might be interested in this one...

Logged

Garthy
Level 9
****


Quack, verily


View Profile WWW
« Reply #33 on: February 11, 2010, 09:21:15 PM »

Aaand here is the site. At least an initial version of it i just threw together :-P

http://realm.badsectoracula.com/minimal/

Looks good. Smiley I wish *I* could throw together a nice looking page that fast! :D

A suggestion if I may: If you were to include sample code consisting of a main() function and the setup/loading code that handles VM creation and launching the script, you (presumably?) would have a complete set of code that someone can copy into a file and use as the base of any experimentation that they did. I'm guessing it would call (with the right args): ml_init(), ml_regfunc(), ml_create() or ml_setcode() or something similar, maybe ml_compile(), and ml_call(), followed by ml_shutdown?

For my game, I'm using Falcon (http://www.falconpl.org/) :

Looks *very* interesting as a language. Sort of a smorgasboard of language paradigms. Wink

License is a bit weird- use it and you have to not only announce that you are, but say which bits you're using it for. :}

As a question, are you stuck refixing everything inside a class with "self."? I know Python has the same problem too, just wondering if there's a better way. For example, C++ doesn't need it (but you can use "this->"), and Ruby cheats by using "@".

Also it's not the more straightforward embedding inside a game, but it's well thought and very modulable and they are working on making embedding even easier.

A look at the embedded doco that mentions a ground-up rewrite certainly goes along with this! Wink

Despite the difficulties, has integrating it into your project been worthwhile, do you think? Do you have any instances where the app calls the script and the script calls the app, and how hard was it to do?
Logged
Klaim
Level 10
*****



View Profile WWW
« Reply #34 on: February 12, 2010, 03:01:50 AM »

Quote
Despite the difficulties, has integrating it into your project been worthwhile, do you think? Do you have any instances where the app calls the script and the script calls the app, and how hard was it to do?

It's still too soon to tell, but you can wath there what I did with it until now (not much) :



I embedded a Falcon vm in my game and for test I put one vm to each "3D console" in the game (that you see in the video). You can do that with any scripting language so I don't think it's relevant.

In few months I'll have to make several modules for Falcon to manipulate the game state and add custom scripts to the "maps" of the game... At that moment I'll see the real pros and cons in practice.
That said, some serious developers are using it and the most important thing is that almost anytime you can go to the irc chatroom and discuss with the creator of the language, maybe to point a bug that he will fix "live" for the next version. Feels good to help in a programming language design :D

About the self thing, it's the same as Python and Ruby :
Quote
In lines 6 and 7 there is a new keyword: self. Its use is to remind to Falcon that the item (we are looking from inside the class!) or the method is a member of the class. Inside a class we have to use self when we use a member of the class.
source : http://falconpl.org/index.ftd?page_id=sitewiki&prj_id=_falcon_site&sid=wiki&pwid=Manual:Chapter2&wid=Manual:Classes1

I guess for those languages the "context" of each line of code is more volatile, making some things having to be explicit. Not like in C++ where the context is often "black-boxed" if you see what I mean.
Logged

Klaim
Level 10
*****



View Profile WWW
« Reply #35 on: February 12, 2010, 03:12:39 AM »

About the video, Falcon is used to execute the "/script" commands, the commands themselves are not scripts but C++ system (open source and available online if you want).
Logged

jonnymind
TIGBaby
*


View Profile
« Reply #36 on: February 12, 2010, 03:24:45 AM »

License is a bit weird- use it and you have to not only announce that you are, but say which bits you're using it for. :}

The spirit of the license is that you have NOT TO HIDE the fact that you use Falcon, and why you're using it. For example, if you script your game bots and bot scripts are visible to the user (i.e. available somewhere in source format), then the license requires nothing else. It would be nice on you to say you're using Falcon, and nicer to say you're using it for bot scripts, but you're not required to.

Saying you're using Falcon (and more or less why) becomes a requirement if your users can't possibly see the scripts, i.e. because you store them in pre-compiled form in an internal crypted database.

Also, if your game scripts are hidden, but you publish some game script samples in clear form, i.e. as a base for your users to write their own mods, again, you're NOT REQUIRED to do anything else. The fact that the users interested in scripting ability POSSIBLY KNOW that you're using Falcon is the only requirement for the license to apply.

We designed the license exactly with general -and also embeddable- open source scripting languages in mind (targeted to both open source and commercial users), and we hope the community will press for adoption.
Logged
Bad Sector
Level 3
***


View Profile WWW
« Reply #37 on: February 12, 2010, 04:11:31 AM »

A suggestion if I may: If you were to include sample code consisting of a main() function and the setup/loading code that handles VM creation and launching the script, you (presumably?) would have a complete set of code that someone can copy into a file and use as the base of any experimentation that they did. I'm guessing it would call (with the right args): ml_init(), ml_regfunc(), ml_create() or ml_setcode() or something similar, maybe ml_compile(), and ml_call(), followed by ml_shutdown?

Yes. The run_script() function in the Minimal demo program has the code. The demo does a little more than that (basically it can compile the example program to bytecode and store to a file or load and execute the stored bytecode).

Logged

~bs~
Garthy
Level 9
****


Quack, verily


View Profile WWW
« Reply #38 on: February 12, 2010, 11:20:25 PM »

Quote
Despite the difficulties, has integrating it into your project been worthwhile, do you think? Do you have any instances where the app calls the script and the script calls the app, and how hard was it to do?

It's still too soon to tell, but you can wath there what I did with it until now (not much) :



Cheers, thanks for that. Smiley

License is a bit weird- use it and you have to not only announce that you are, but say which bits you're using it for. :}

The spirit of the license is that you have NOT TO HIDE the fact that you use Falcon, and why you're using it.... Saying you're using Falcon (and more or less why) becomes a requirement if your users can't possibly see the scripts...


Cheers, thankyou for the clarification. In the context that I'm using a scripting language, they are internal, not exposed to the user, and are used to run "things that work better via scripting". As such, should I use it, I'd need to have some sort of mention to that effect, basically: I'm using Falcon (that bit is easy), and the "what I'm using it for" becomes a little more difficult, since the lines are a bit blurred. :} Whilst I'd figure it out, of course, I just found the clause a little unusual, and a touch atypical, hence "weird".

A suggestion if I may: If you were to include sample code consisting of a main() function and the setup/loading code that handles VM creation and launching the script, you (presumably?) would have a complete set of code that someone can copy into a file and use as the base of any experimentation that they did. I'm guessing it would call (with the right args): ml_init(), ml_regfunc(), ml_create() or ml_setcode() or something similar, maybe ml_compile(), and ml_call(), followed by ml_shutdown?

Yes. The run_script() function in the Minimal demo program has the code. The demo does a little more than that (basically it can compile the example program to bytecode and store to a file or load and execute the stored bytecode).


Cool, good to know. Smiley
Logged
Pages: 1 [2]
Print
Jump to:  

Theme orange-lt created by panic