PLUGIN: Lua for AGS

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

Previous topic - Next topic

AJA

Nice, thanks! Seems to be working fine so far. :)

Denzil Quixode

Excellent! Sorry for the delay in getting to this stuff  :-[

statelessrich

Hi All,

I am new to the forum and AGS, and I am trying to make use of the Lua plugin in my first game.
After I enable the plugin and run my game, the game crashes and I get the following error: "Error: [Lua] Type not literally persistable by default." Here's a screenshot: http://oi47.tinypic.com/34eqhcm.jpg

Can anyone offer some advice?
Thanks!


Denzil Quixode

#63
That's an indication that there exists a value somewhere in the Lua "universe" that it does not know how to save in a restoreable format. It knows how to do this for every standard Lua object, but not non-standard custom objects (except ones that have had special handling specifically written for them in the plugin).

One example is an open file-handle object. If you do this in a Lua script and run it from game_start():

Code: ags
f = io.open('test.dat', 'wb')


...this opens a file for writing, and saves the open file-handle object in global variable 'f'. When the time comes for the game to be saved (which is immediately - AGS needs to create a restart point as soon as the game begins, which works by creating a save-game) there is no meaningful way for the variable 'f' to be saved, so you will get the "not literally persistable" error. (So make sure, if you do want to read/write files from Lua, that you do not keep a reference to the file handle around!)

Another example would be objects created by Lua C libraries that come as a DLL (for example, LuaSocket sockets or LPEG patterns). Are you doing anything like that? If not, maybe there is a bug in the plugin and one of these unsaveable values is being created accidentally by the plugin itself. It's not a bug I remember ever encountering myself, though.

statelessrich

Thanks for the reply, Denzil... but I receive this error even when I have zero Lua scripts in my project...

Denzil Quixode

Okay, so it must be a bug in the plugin. Thanks for the report! Is this an empty/new project, or does it have lots of existing rooms etc.? If it's an existing project, does the same thing happen if you try with a new one?

statelessrich

When I create a new project using "empty" or "default," I don't receive the error.
I only receive it when I create a new project using a saved template.

Denzil Quixode

Aha, interesting - can I get a copy of the template? If it's a private one, but you don't mind just me seeing it, send a PM - I promise to keep it confidential.

(Sorry about this!)

AJA

Hmm, here's a weird bug. When I restart the game or restore a saved game, something (the plugin?) seems to override the compat.lua script. When I normally run the game, everything works fine but when I restart, the game crashes with the first call to set a character's x coordinate (because now it's a number value). I load all the scripts in game_start.

Denzil Quixode

Oops. Here is a new dev version with a fix for that AJA:

http://dl.dropbox.com/u/29133560/agslua-dev-2012-05-14.zip

statelessrich, I think this should work for your problem too (I tried building a new game with your template and it works) - could you try it with this version and see if it works for you too?

AJA

Still doesn't quite work. :( Different error, though, so that's progress. It seems ags.object[id].Clickable is nil after a restore/restart. Visible and Baseline are also nil, didn't try any more of them. If I comment out the instantly crashing part of code, everything seems to work fine until I a script tries to access an object.

Is there any way to make the error message clearer in this kind of a case where stuff is read from a saved game? Since now it's just: Error: [Lua] [string ""]:0: attempt to call method 'Clickable' (a nil value)

Denzil Quixode

We're getting there! We're getting there!  :X

http://dl.dropbox.com/u/29133560/agslua-dev-2012-05-15.zip

Try that one.

Quote from: AJAIs there any way to make the error message clearer in this kind of a case where stuff is read from a saved game?

Mm, no, I don't see a way of doing it, sorry :( The error isn't actually occurring while the saved-game is being loaded, and once it's loaded there's no easy way of telling that an error happened because of "something that was just loaded" as opposed to any other kind of error.

AJA

Works great! Thanks! :D

And yeah, the error message thing was a bit of a long shot.

Calin Leafshade

#73
Ok, so I've spent the day putzing around with this plugin and frankly I see literally *no reason* why someone would not want to use it. There seems to be no disadvantages (unless you consider lua itself to be a disadvantage). This plugin is literally the best thing ever.

@Denzil

I assume this is fully portable? Do you plan to release the source so that JJS can have a go at recompiling it for other platforms?

Also, if your code is fairly general i reckon we could implement angelscript in a similar fashion.

Denzil Quixode

Thanks very much! The source code is up on GitHub:

https://github.com/duncanc/Lua-for-AGS

...the code is extremely messy, partly auto-generated, and difficult to compile (I know the VS project files refer to specific paths on my hard drive and there are some static lib dependencies that don't seem easy to find or compile, and so on :P) but it's there. I've always lived in hope of cleaning all this up, and I'd been putting off releasing the code for a while because of that, but decided that was silly. "Release early, release often, fix eventually" as I believe the saying goes.

Denzil Quixode

Quote from: Calin Leafshade on Thu 26/07/2012 22:59:29
I assume this is fully portable?
I don't believe the run-time plugin uses anything Windows-specific.

Quote from: Calin Leafshade on Thu 26/07/2012 22:59:29
Also, if your code is fairly general i reckon we could implement angelscript in a similar fashion.
It isn't very general, I'm afraid, pretty specific (and convoluted). I'm sure you're right that something very similar could be done with other scripting languages, Lua is just one that I happen to know very well.

What I would really love to do is use the incredibly (and increasingly) high-powered version of Lua, LuaJIT2. It really is ridiculously fast, beating even state-of-the-art accelerated JavaScript JIT compilers on some benchmarks. But the big problem is that the serialization functionality that Lua For AGS needs for the save/load functionality is not compatible with LuaJIT2...

Calin Leafshade

Are there any plans to implement QueueGameScriptFunction from the plugin API?

This would allow users to call their own scripts.

My reasoning as to why this would be useful is that a lua script could request a hook from the game script if there were a LuaControl module or something.
like this:

Code: lua

    requestHook("repeatedly_execute_always", "nameOfLuaFunction")


requestHook would look something like

Code: lua

function requestHook(hook, callback)
    index = storeHookAndCallBackInAnArrayOrSomething(hook, callback) -- return a table index
    ags.QueueScriptFunction("LuaRequestHook",index)
end


and the ags would look something like this:

Code: ags

void LuaRequestHook(int index)
{
    String funcName = Lua.CallScript("GetHookFromIndex", Lua.IntValue(index)); // or whatever, i dont remember the syntax
    String hook = GetTheHookToo(index) //whatevr
    StoreHookAndCallBack(funcName, hook); // just store it in an array

}

void repeatedly_execute_always()
{
    IterateThroughHooksAndFireIfAppropriate();
    
}


I dont think the code was necessary to explain my point... whatever

Denzil Quixode

#77
The issue of QueueGameScriptFunction/CallGameScriptFunction is one that I do want to return to at some point. I made a start at it but I think I hit a problem (that I helpfully can't remember now) and left it for later...

But having said that, it looks like you shouldn't need it in this particular example, because in Lua you can put functions themselves into arrays - there's no need to burden AGS with the task of storing the hook and callback.

For example, say you have a script like this that you run in game_start():

Code: Lua

-- callbacks.lua

local callbacksByEventName = {}

function addCallback(eventName, callback)
  -- get a list of callbacks for this event
  local callbacks = callbacksByEventName[eventName]
  -- if the list doesn't exist yet, create it
  if callbacks == nil then
    callbacks = {}
    callbacksByEventName[eventName] = callbacks
  end
  -- add the provided callback function to the end of the list
  callbacks[#callbacks+1] = callback
end

function runCallbacks(eventName, ...)
  -- iterate through all callbacks registered to this event name
  for i, cb in ipairs(callbacksByEventName[eventName] or {}) do
    -- call the function, passing through any extra parameters
    cb(...)
  end
end


Then, in AGS, set up runCallbacks("repeatedly_execute_always") to be called every frame:

Code: AGS
function repeatedly_execute_always()
{
  Lua.Call("runCallbacks", Lua.StringValue("repeatedly_execute_always"));
}


Now, to add a function to be called on, you would do:

Code: Lua
function DoThisEveryFrame()
  -- (...whatever you like...!)
end

addCallback('repeatedly_execute_always', DoThisEveryFrame)


...or, alternatively, even:

Code: Lua

addCallback('repeatedly_execute_always', function()
  -- (...whatever you like...!)
end)

Calin Leafshade

You make a good case. For some reason I didnt think of having lua store the callbacks which is, in hindsight, a far better idea.

Crimson Wizard

Do I understand correct that the plugin basically adds a lua-scripts interpreter to the engine?
Sorry, that's probably obvious, just wanted to make it fully clear for myself.

SMF spam blocked by CleanTalk