PLUGIN: Lua for AGS

Started by Denzil Quixode, Fri 04/09/2009 19:30:22

Previous topic - Next topic

Denzil Quixode

Hmm, I hadn't even heard of ANTLR before... interesting. Actually I happen to already have most of a hand-written C# parser done already, which creates an object-based representation of AGS Script. I would be happy to extract it from the project I was making it for and fix it up into a reusable middleware DLL that people can use in their own plugins. (I'd release it as open source, too, why not.) I need a few days though - my main laptop is in for repairs at the moment and that's got all my plugin stuff on it...

Joseph DiPerla

Look up GOLD Parser Generator as well. That seems to be a good one. If you like in the General Forum, I posted a topic on it yesterday.
Joseph DiPerla--- http://www.adventurestockpile.com
Play my Star Wars MMORPG: http://sw-bfs.com
See my Fiverr page for translation and other services: https://www.fiverr.com/josephdiperla
Google Plus Adventure Community: https://plus.google.com/communities/116504865864458899575

Monsieur OUXX

Quote from: Denzil Quixode on Tue 14/12/2010 17:06:46
I happen to already have most of a parser done already. I would be happy to extract it from the project I was making it for and fix it up into a reusable middleware DLL.

DO IT!  :D :D :D

<3
 

Denzil Quixode

#43
Quote from: Monsieur OUXX on Thu 16/12/2010 13:14:06
Quote from: Denzil Quixode on Tue 14/12/2010 17:06:46
I happen to already have most of a parser done already. I would be happy to extract it from the project I was making it for and fix it up into a reusable middleware DLL.

DO IT!  :D :D :D

<3
OK, I've started a project at http://spags.googlecode.com/ (SPAGS: Script Parser for AGS :P). If you can use SVN you should be able to get it. It includes a project for a test plugin SPAGSTest that creates a file called scripts_dump.txt in the game's project directory (select the SPAGS > Dump Scripts menu item) which isn't very useful on its own but hopefully demonstrates what the parser has understood. Also the source code for that plugin should hopefully be instructive for how to use SPAGS itself - though things might change a bit in the future, it's still very much a work in progress. Also currently it only handles global scripts, not yet room scripts or dialog scripts - but it should be able to handle any global script that would compile normally.

When it's a bit more mature I'll make a thread about it in the technical forum, but I'm still tinkering with it for now.

monkey0506

You should seriously consider renaming it "SPAGHETTI!"..the YTPers would love you.

Clarvalon

I've had a peek at the code and it's not too dissimilar to how the conversion works in XAGE, i.e. Tokenising the AGS scripts and then spitting it out in a new format.  I have no experience with LUA so I'm unfamiliar with the format, but it's interesting to see the corresponding structure in scripts_dump.txt.  Excellent work as usual, Mr. Quixode :)
XAGE - Cross-Platform Adventure Game Engine (alpha)

Denzil Quixode

Thanks! The scripts_dump.txt output isn't anything related to Lua, by the way, it's just an arbitrary format for demonstrative purposes but doesn't really have any use as it is.

Monsieur OUXX

Quote from: Denzil Quixode on Sat 18/12/2010 13:05:17
SPAGS (SPAGS: Script Parser for AGS :P).

Bump.

@Denzil: Is this going forward?
In other words:
- did you run tests on many arbitrary scripts (i.e. from random modules from the forum) to see if they get parsed properly?
- do you get many "false positive" tests (regarding alleged syntax errors in the scripts) ?

 

Denzil Quixode

I ran it on as many Module scripts as I could find (from the appropriate forum), hoping that they would cover complex and exotic uses of AGS script. That is the best source of freely-available non-trivial source code that I was able to find.

There may well be cases where it parses a script successfully where the real parser would fail (for example, I think assigning to a property of a struct* returned by a function probably works, where the real parser chokes) - but at as far as I know it should parse all correct scripts correctly. I have not looked at it in a while, though.

If you have some examples of scripts that you think I should look at, let me know.

Monsieur OUXX

Quote from: Denzil Quixode on Mon 05/09/2011 16:04:56
If you have some examples of scripts that you think I should look at, let me know.

That wasn't the goal of my post, but come to think of it, I did some extensive use of macros in AGSH (see the link in my signature), and I remember I found onr or 2 glitches in the original parser at the time. I haven't checked if the download links in the AGSH thread are broken or not.

Anyway it doesn't really matter. Your parser seems to be solid by now. COOL.
 

AJA

#50
I've finally had the chance to use this plugin in my new project and, boy, it's awesome! Goodbye, restrictions of AGS scripts! Welcome, content that can be modified while running the game and reloaded with the press of a button (requires custom code, but still)! Thanks so much for the plugin, Denzil!

I don't know if you're still willing to maintain it after all these years but here are some things I've noticed:

EDITOR
- Renaming scripts results in duplicate files. (At least inside the editor.)

ENGINE
- Why aren't the game.variables available to the scripts?
- ags.getplayer() doesn't seem to work properly. I tried to get the current room number by calling ags.getplayer():Room() but it returned a table. Calling ags.cEgo:Room() worked just fine.


--edit--

And now suddenly, I keep getting an error that goes something like this: "[Lua] attempting to concatenate a table value". No line number, nothing. And it seems like the error happens after a successful function call from AGS to Lua and before the next call. Maybe it's a bug in the plugin? I'm out of ideas.

If it helps, I've created many different classes (table, metatable, etc.) before this but now that I'm trying to make an Inventory class, it just keeps crashing. Doesn't matter if it's a class or a plain table but sometimes I can define some functions into it and sometimes I can't. Sometimes the error goes away for a while after I comment out some class method call. Very weird.

--edit2--

Maybe it has something to do with the serialization of the Lua state? The crash has always occurred after game_start but before any other events that call the scripts. That's when the default restart point is saved, right?

--edit3--

Probably the same thing that happens sometimes with the editor. I try to compile the game and it says it can't write the exe since it's in use, even though it isn't. After one or more tries it works just fine. Just a moment ago I started the game and it crashed with the error (see above). Then I tried to start the game again. I didn't modify anything but now it started ok. So yeah, what the hell...

--edit4--

Worked around the crash by delaying script loading to the first on_event call. Saving the game produces the crash sometimes, so it's still a very big problem.

And one other thing.. How can I set ActiveInventory to null? ags.cEgo:ActiveInventory( nil / false ) crashes the game because the value isn't an InventoryItem.

Denzil Quixode

Quote from: AJA on Mon 12/03/2012 15:57:08
I've finally had the chance to use this plugin in my new project and, boy, it's awesome! Goodbye, restrictions of AGS scripts! Welcome, content that can be modified while running the game and reloaded with the press of a button (requires custom code, but still)! Thanks so much for the plugin, Denzil!
You're welcome! :)
QuoteI don't know if you're still willing to maintain it after all these years but here are some things I've noticed:
I'm willing to maintain it! I just kinda... haven't been  :-\

Some of the bugs that you describe I think - not certain - but I think they are already fixed in the development version, but it just never got turned into a release version. Either way I will try to sort out a new proper release version soon (and feel free to yell at me if I take too long again :)).

QuoteWhy aren't the game.variables available to the scripts?

This might be a restriction of the plugin API. Accessing struct fields is a different thing internally to accessing properties (which are really just getter/setter methods).

QuoteThe crash has always occurred after game_start but before any other events that call the scripts. That's when the default restart point is saved, right?
Yeah, I think so.

AJA

Quote from: Denzil Quixode on Tue 20/03/2012 01:27:06
I'm willing to maintain it! I just kinda... haven't been  :-\

Understandably. :)


Quote from: Denzil Quixode on Tue 20/03/2012 01:27:06
Some of the bugs that you describe I think - not certain - but I think they are already fixed in the development version, but it just never got turned into a release version. Either way I will try to sort out a new proper release version soon (and feel free to yell at me if I take too long again :)).

I tried saving the game with the dev version you sent me and it hasn't crashed so far! Great! Thanks! :D

The getplayer function is still acting oddly, though. Calling ags.getplayer():Room() to get the room number actually calls my Lua defined table called Room. :-\ And the editor bug is still there too.


Quote
QuoteWhy aren't the game.variables available to the scripts?

This might be a restriction of the plugin API. Accessing struct fields is a different thing internally to accessing properties (which are really just getter/setter methods).

Good point.


I'm thinking of releasing the framework I've written in Lua once I've finished my game. Maybe that'll get more people interested in the plugin. The framework pretty much removes any need for scripting in AGS; you don't even have to link events to their handlers, just the AGS objects to their Lua counterparts.

Calin Leafshade

I like this idea.. I will give it a spin.

Is there anything that you would like to be added to the plugin API in order to improve the functionality of the plugin?

Denzil Quixode

For the editor plugin, one problem I remember is there is no way to investigate audio clips through the IGame interface. (There's some other things that are missing from IGame, but I needed them for a custom exporter plugin, not the Lua plugin: which character is the player character, global messages, text parser information, property schema, lip sync information.)

For the runtime plugin, there are things that work but it would be great if they could be more official/documented: the way you have to pass "float" arguments/return values, for example. And getting the address of global variables using the function for getting the address of functions.

AJA

#55
It would be nice if we could od simple Lua to AGS script function calls using the CallGameScriptFunction and QueueGameScriptFunction plugin API functions. Even though it's limited you can at least pass the proper parameters by reading them from Lua inside the AGS script function. Right?

And what about the undocumented bool Character.on property? That would be useful to easily hide the player character.


-edit-
Oh, Lua + AGS, how have I ever been able to live without you?

Anybody ever wanted to do something like this?

Code: ags

player.Say( "Who's that behind the door? Hello?" );
dude.Say( "It's me. The dude." );

cutToRoom( ROOM_ON_THE_OTHER_SIDE_OF_THE_DOOR );

// Now we're in the other room and the script continues running...
dude.Say( "I'm right here, can't you see me?" );
player.Say( "Oh, there you are." );

cutToRoom( ORIGINAL_ROOM );

// And we're back...
player.Say( "Well, that was fun." );


Well, you can! I'll share all the neat stuff I've hacked up in my AGS-Lua framework sometime in June, once I'm finished with my game. Just don't expect everything to be consistent and pretty. :P

ShadowStalker

#56
I can't use Run without debugger it gives me an error:
---------------------------
Illegal exception
---------------------------
An exception 0xC0000005 occurred in ACWIN.EXE at EIP = 0x0281E51E ; program pointer is -23, ACI version 3.21.1115, gtags (0,0)

AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and post the details on the AGS Technical Forum.



Most versions of Windows allow you to press Ctrl+C now to copy this entire message to the clipboard for easy reporting.

An error file CrashInfo.dmp has been created. You may be asked to upload this file when reporting this problem on the AGS Forums. (code 0)
---------------------------
OK   
---------------------------
this only happens if i have the Project tree node activated and the run-time plugin activated :(
EDIT:i use version 3.21

Denzil Quixode

Quote from: AJA on Sat 07/04/2012 15:32:26
It would be nice if we could od simple Lua to AGS script function calls using the CallGameScriptFunction and QueueGameScriptFunction plugin API functions. Even though it's limited you can at least pass the proper parameters by reading them from Lua inside the AGS script function. Right?
I did attempt something like this, but it looks like I commented it out. You would call Lua.RegisterGlobalScriptFunction("myfuncname", <number of parameters>); in AGS script and it would add ags.myfuncname(...) to the Lua side, but there must have been some problem with it.
QuoteAnd what about the undocumented bool Character.on property? That would be useful to easily hide the player character.
That is another struct field, rather than a property with getter/setter methods. I am very unsure about getting/setting fields seeing as it's getting to the point of poking into arbitrary memory.

AJA

Any chance there'll be a fix for the nil/null problem I mentioned earlier, Denzil?

I ran into another case where it was a bit troublesome: You can't actually cancel FollowCharacter calls since you can't call ags.cEgo:FollowCharacter(nil). That just gives an error that a Character was expected for arg #1.

Luckily in my case I only wanted to undo following because I hit AGS's limit of following characters. So, it was easy to fix by changing the limit in the engine. But if I needed to cancel following, I'd be in big trouble right about now. :P

Denzil Quixode

#59
Here is a bleeding edge dev version that hopefully fixes the nil/null problem:

http://dl.dropbox.com/u/29133560/agslua-dev-2012-05-02.zip
http://dl.dropbox.com/u/29133560/agslua-dev-2012-05-02_2.zip (EDIT: Replaced with a version with a fixed compat.lua)

...however, there is also a new feature which breaks compatibility with existing scripts, but I have included a script called "compat.lua" - run this script straight away before any other Lua script (probably in game_start()) and the compatibility problems should be sorted.

If you don't run this script, then there is different ways of accessing the player object and properties of AGS objects:
ags.player instead of ags.getplayer()
ags.player.ActiveInventory = nil instead of ags.getplayer():ActiveInventory(nil)
ags.Game.SpriteHeight[5] instead of ags.Game.SpriteHeight(5)
...and so on. This way is better, but I know it's a pain when you already have a lot of code that uses the old way, which is why I provide the compat script.

SMF spam blocked by CleanTalk