# Who's using GameMonkey Script?

This topic is 4850 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

The guys behind GameMonkey Script have just released version 1.22. The syntax of GM is similar to Lua, except it's more C-like - I prefer GM over Lua because I find the API to be more intuitive, passing parameters and setting up new types feels a lot easier, mainly because I didn't really like Lua's stack interface. I'm now using GM as my main scripting language, with SpiderMonkey second (maybe I like monkeys?). One of the main things I found when starting out in GM was the lack of documentation, so I've started creating my own tutorials for it here. For those who want to port their C++ classes over to the environment, I've been working on gmBind, a templated class library that really eases the process. I'm nearing a release of it soon so I'll post it if anyone's interested. So who else has tried GameMonkey Script? What's your thoughts on it? What would you like to see added to the library?

##### Share on other sites
Well, I haven't used GameMonkey but I'll post a reply anyway ;)

Is GameMonkey some sort of javascript variant? Or was it some other monkey language.. The language looks nice and I bookmarked your tutorials. It looks nice enough that I might even use it in my next project (whatever that will be :)

Currently I'm using lua in my game and it has worked fine but a more C-like language would perhaps be more easier to use along with C++ (I always start writing lua code when I should be writing C++ and vice versa).

##### Share on other sites
It's nothing like javascript, really. It uses the tables concept that was popularised by Lua. It's also typeless, like Lua. In all fairness, the language itself is much like a C-like version of Lua... So

//GMmyTable = table( Name = "Test", Age = 24, Add = function(a, b) {   return a + b; });print( myTable.Name );print( myTable.Age );print( myTable.Add( 2, 2 ) );// LuamyTable {  Name = "Test", Age = 24, Add = function(a, b)   return a + b end}print( myTable.Name )print( myTable.Age )print( myTable.Add( 2, 2 ) )

It's very similar in syntax, but as I said GM is more C-like (line noise for some, but familiar to others). The real difference for me is how binding is done on the host application side. I grew very frustrated with Lua and it's stack offsets, GM provides a simpler way of accessing parameters (just access them through the gmThread parameter passed to your callback).

As I said, I can imagine the main problem being that there's more documentation around for Lua, hence my reason for writing the tutorials (there's more being written right now).

[Edited by - evolutional on November 8, 2004 5:37:32 PM]

##### Share on other sites
Ah, that IS quite similiar to lua. I never learnt how to do binding with the Lua C API. I just downloaded luabind and used that instead :)

By the way, does GM support classes/OOP?

##### Share on other sites
It supports them in the same way as Lua does, with the use of the table object, the table can contain functions and attributes. If you create your own types in C++, they can also then be used in GM with little trouble. For example, I create a Alien type in C++ and create instances of it with myAlien = Alien();. Properties and functions of the Alien 'class' can then be called as expected. You can even 'fake' inheritance as per the Lua examples.

Here's an example of creating a 'class' in GM.

// Function 'CreateMap' will create a new object and define// it to be a tile map//global CreateMap = function(){  new_map = table();  new_map.Width = 0;  new_map.Height = 0;  new_map.Layers = table();  new_map.Name = "New Map";  new_map.ShowName = function()  {   print( this.Name );  };      return new_map;};// Now, to create a 'map' in the script, you can go:myMap = CreateMap();//Change it's namemyMap.Name = "My Map";// Say my name!myMap.ShowName();

The example above will use a function to create a 'map' type (scriptside only). From here, you're free to alter properties of the map. The call to myMap.ShowName() will print "My Map" instead of "New Map" as you've just altered the property 'Name'.

##### Share on other sites
GameMonkey is a small extensible language with C style syntax and typeless variable declarations.

It works in a very similar way to Lua, so if you like Lua, you will love GameMonkey. GameMonkey was designed for use in video games and to be used by game programmers and designers. It is 'combat proven' as it has already been used in commercial video games.

For example you might write some code that looks like:

myDoor = CreateDoor();myDoor.name = "BigWoodenDoor";if( myDoor.IsOpen() ){  myDoor.Close();}

What does this do?
myDoor is a variable that is made to contain what ever is returned by the function CreateDoor(). CreateDoor may be a C++ bound function. myDoor could be a 'user' object that represents some kind of game object, possibly implemented as a C++ class. myDoor.name could add "BigWoodenDoor" as a table member to the myDoor table. However, the programmer may have implemented a Dot operator so that "name" is actually bound to a C++ object member. IsOpen is called as a member function of myDoor. It may be a C++ function common to all 'doors' or a script function unique to that instance only. When IsOpen() is called, its return value is evaluated and the script executes the condition statement causing Close() to be called or not.

What I'm trying to say is that the code, that looks a bit like C/C++ can represent whatever you want. The script simply
calls C/C++ bound functions to do what you ask. It does not force you to use it a particular way, or tod design your C/C++ code following a particular structure.

The script is designed to easily pass data and call functions back and forth between script and C/C++. Some people may find that binding functions is still cumbersome as it requires writting a few lines of code for each function. Evolutional's upcoming gmBind will nearly automate this operation.

o 'States' allow program control to simply switch code execution, even in the middle of a function.
o 'Threads' though cooperative, are built into the language by design, not tacked on as an afterthought.
o Incremental, soft real-time garbage collection means that the script will not pause for long periods (milliseconds or more) while reorganising memory like other scripts will.
o Compile code on the fly, compile to libs and execute byte code later, generate and execute code from within the script. It's very flexible.
o 'Type' functions allow common functionality to be available to any object of that type without storing the function in each instance.
o ints and floats, like you are used to in C, not forced to use double size generic 'numbers' where speed or conversion count.

##### Share on other sites
I like the fact that the syntax looks a lot like C, and I like the apparant simplicity with which it can be used from a C++ program. It did take me about half an hours messing about and guessing to get it compiled on linux, but then it doesn't say linux is supported on the site, so what do I expect?

After all that, however, it doesn't seem to work, so I had a quick look at the lexical analyser... it matches strings such as "and" which means my very first line of script:

andy = function(thing) { return false; }

resulted in:

error (1) syntax error, unexpected KEYWORD_AND

doh :)

I will stick something in the forums regarding this - my lex is a little rusty but I can do better than that!

##### Share on other sites
Ah, yeah - they might want to know about that little bug ;)

##### Share on other sites
Actually - which version are you using?

Under 1.22 on my machine the problem with your file is that you forgot the terminating ';'

So: andy = function(thing) { return false; }; works fine. It also works in the managed wrapper I'm coding :x

##### Share on other sites
You do have to watch the old semicolon. In GameMonkey, functions are variables like any other, so a function assignment is also a statement, and statements end with a semicolon, same as C/C++. Simlar reason to why C++ class declarations end with semicolon. It would be possible to declare functions using syntactical sugar to look even more C like, but that hides what is really going on. There's more info on this subject in the FAQ.

##### Share on other sites
I thought I had also posted this comment to the game monkey forum, but apparantly I didn't, so since their forum is obviously too hard for me to understand, and since this is a scripting forum, we can discuss lex here ;)

I'm using 1.22.
gmScanner.l specifies an action to be taken on matching "and".
lex (and flex) should find that as a match to the first three characters in "andy", so if a function called "andy" works for you people there is something I don't understand going on. That or the flex.exe which comes with the source is modified from the original, which seems more than just unlikely.

Anyone know?

PS - yes, semi-colon comment understood, but that doesn't explain the "unexpected TOKEN_AND". That would cause an error like "couldnt find $end" or something. #### Share this post ##### Link to post ##### Share on other sites How odd that we're not seeing the same problem. I really don't see why compiling on *nix would have an effect on the scanner. I've had a look at the gmScanner.l file and whilst my Lex is rustier than yours I can't really see a problem. Have you tried using the other keywords as a test case? So: whileme = function() { return 0; }; If that matches KEYWORD_WHILE then it looks like a problem in the scanner. Incidentally, if you get it working under *nix, I think the authors would appreciate the makefiles and gmConfig_p.h file you used ;) #### Share this post ##### Link to post ##### Share on other sites The scanner will try to make the longest token possible, so it can't grab 'and' from 'andy'. The missed semicolon will cause an error to occur somewhere later as the code doesn't terminate where expected. The KEYWORD_AND may have come from a later line of code. #### Share this post ##### Link to post ##### Share on other sites I've not tried GM although I've looked at it. I'm looking for a script language for our Game engine. Does anyone know if it's possible to access instances from GM that have been made in C++? Something like: aClass someClass; and access someClass from GM IF not which scripting language support such system (if any) styx #### Share this post ##### Link to post ##### Share on other sites styx, I'm almost ready to release a utility called gmBind, it's a templated class library that lets you quickly interface GM with C++ classes and access them in script. gmBind allows you to create native C++ objects from script, as well as 'port' an existing C++ object to GM. I'm already using the alpha in my own projects with great success, but I'm tidying it up and adding extra features ready for the full release. #### Share this post ##### Link to post ##### Share on other sites Nice! Is there a project page somewhere, where I could try it out? Would be nice. Oh and btw, nice tutorials! Keep up the good stuff mate cheers! #### Share this post ##### Link to post ##### Share on other sites The project page will be the same one as the tutorials - but as I say I've not released it yet - but I'm looking to in the next few weeks once I decide to commit myself to a particular design decision regarding the properties. And thanks for the compliments - I'm aiming to add more to the tutorials to cover more advanced topics too [smile] #### Share this post ##### Link to post ##### Share on other sites Just one more thing, has anyone ever succeeded compiling GM on Linux? I saw on the project page it has been compiled on Mac so my guess is it should compile on Linux without to much tweaking. #### Share this post ##### Link to post ##### Share on other sites In the new 1.22 release, there's a file called platform/win32gcc/gmConfig_p.h which I believe could be tweaked (or even just used outright) for GCC on *nix operating systems. The only thing left to do would be to create a makefile to build the library - If you do this I can imagine that it'd be useful for others so I'd be happy to pass it onto the guys maintaining the library if you wish to share it :) #### Share this post ##### Link to post ##### Share on other sites Sharing is good :) I'll look into it. Thanks #### Share this post ##### Link to post ##### Share on other sites To compile on linux, you need to edit the gmConfig_p.h file from win32gcc so that it uses strcasecmp instead of stricmp. There are a bunch of warnings too, but you can just ignore those. I fixed the one about the #endif MACRONAME with no comment markers ;) After that there is absolutely nothing special. Flex and Bison are both supported and run fine, but you can't use the windows binary version supplied (obviously) - you need to install your own instead. You can almost but not quite run the .bat file for these as it stands, as if it was a shell script. #### Share this post ##### Link to post ##### Share on other sites Greg is right in that it shouldn't match AND from ANDY because it goes for the longest match. Like I said, it's been a long time since I touched this stuff. Looking at the various errors I get suggested to me that the generic pattern match was failing. Since everything up to that point presumably works I made another quick guess and got the answer :) When you run flex in linux it expects normal end-of-line markers, instead of the Microsoft double-character thingy (\n\r or \r\n or whatever it is). Thus, ANDY became AND because it didn't match [a-zA-Z_]^M If you remove all the ^M characters it all starts working. *sigh* Thankyou for being patient [smile] #### Share this post ##### Link to post ##### Share on other sites Would that fix work under Windows too? #### Share this post ##### Link to post ##### Share on other sites I don't know, since I don't run windows, but I would expect it to. It all depends on what flex.exe does when it hits a newline character with no return character to cuddle up to. Notepad draws little squares and puts it all on one line. Suck it and see I suppose :) #### Share this post ##### Link to post ##### Share on other sites I just found this in the Flex docs: Quote:  Original Source hereNote that flex's notion of "newline" is exactly whatever the C compiler used to compile flex interprets '\n' as; in particular, on some DOS systems you must either filter out \r's in the input yourself, or explicitly use r/\r\n for "r$".

So, it seems as if a prepass needs to be done on the source file to remove all the extra padded line endings. But, wouldn't doing this bork it in Windows? What happens if you compile flex and re-lex the gmScanner.l file under Linux?