Originally Posted by UrbanMonk This kinda ruins the whole idea behind using lua. I was gonna use it to make dialog easier.
Do you think I could perhaps store the lines inside of a text array, and call each line from there?
I could just make my own pause command. hmmm.
Since I'm not using c code for anything I'll most likely just use the regular lua object for simplicity sake.
Thanks so much guys. If you think of another way around this let me know! I'm curious about this now.
"c" in this case just means mmf, since that's what it is on the level lua is working with
and yeah that error is resulting from trying to yield from a c function which is not allowed... why that works in lua' but not xlua i'm not sure, unless it's due to differences in communication. apparently this is one of the things being looked at for lua 5.2 but no telling when that will be released
as an alternative to coroutines i would do something along the lines of what bigredron suggested; this sort of system could actually be done easily without coroutines... i may come up with some system later that's pretty much equivalent to this
ah, I see. What I originally thought was kinda weird anyways!
Ok, so forgetting coroutines for a second. Is it still possible to create a custom scripting engine with my own functions that call functions from within mmf?
If so, how would I load my custom functions into mmf? Do I have to load the functions after the main script that calls them, or could I load them before hand?
If I made my own engine to stop and start lua scripts doesn't this just add extra overhead that lua was supposed to remove in the first place?
When running a lua script does the whole script run through completely when it is called in an action, or after the mmf loop is complete? Because as far as I know when a mmf function is called from within a lua script mmf has to search for the function in the regular mmf loop code in order to execute the actions it contains.
Sorry for all the questions! Hope this all makes sense to you all!
Ok, so forgetting coroutines for a second. Is it still possible to create a custom scripting engine with my own functions that call functions from within mmf?
yes, although without coroutines you have to handle the "pausing" between lines yourself. manually going through lines in a table is easy and does this, but then you can't use functions as you normally would, because they'll automatically execute during the table construction (which you don't want). in this case you'd have to use string commands mixed in with your text strings, but then you'd also make it automatically jump through a set of consecutive commands (while executing them) without stopping... it's not hard it's just annoying and error-prone
If so, how would I load my custom functions into mmf? Do I have to load the functions after the main script that calls them, or could I load them before hand?
your custom functions (if they're lua ones) can just stay inside the same lua script as the rest of the engine
If I made my own engine to stop and start lua scripts doesn't this just add extra overhead that lua was supposed to remove in the first place?
technically, though with this kind of script system the overhead is pretty much negligible; you don't start seeing the difference between lua<->mmf and lua alone until you start calling a ton of functions per second (in the thousands)... a simple script system shouldn't be doing this
When running a lua script does the whole script run through completely when it is called in an action, or after the mmf loop is complete? Because as far as I know when a mmf function is called from within a lua script mmf has to search for the function in the regular mmf loop code in order to execute the actions it contains.
that's just a design issue in mmf. everything in lua is stored in a table (including the global environment, in a table called '_G'). when you call a function, lua just does a table index like _G["function_name"](param1, param2, ...). since it uses hash tables this is pretty much an immediate effect: it KNOWS where the function is (or it has a really good general idea), it doesn't have to search every index for it
it's probably overboard compared to what you want but it works fine (at least as far as my limited bug testing went). there's a few things i don't like code-wise (related to passing), but oh well. it makes a decent example at least
it uses the "table full of strings" approach including the aforementioned text commands
You even have a method of storing dialog outside of the script!
So from a normal users point of view would it be possible to simplify the scripts for creating dialog in such a way that it would be extremely easy for someone who's never scripted before to pick up.
I was thinking of something along the lines of the original example. Except I didn't want to encounter the bugs that the original lua extension had. (not that I even knew what they were! ) That's why I was trying to "convert" it.
I wanted to have more commands than just dialog however. (ex: open door (1) or saveplayerstate("Dark Caves",3,"blah") )
My initial plan was to be able to pass variables into the script itself (without having to parse anything, direct variable injection!) This is so I could create one script that could apply to many objects. Like a spring script that allows one to change the bounce height, but at the same time be editable on the script level.
Another reason to do this the lua way instead of making a custom scripting engine is the fact that it's able to do math within the script itself. Which is a big problem with my current setup. (I overlooked it)
Anyways Thanks Sooo much, I'm gonna examine this and see if I can figure it all out!
Hopefully I can figure out how to do what I want without too much hassle!
EDIT: I like how you made your script easy to edit! Awesome! All those little comments!
yeah my example isn't as transparent as it could be, but other ways to do it would look ugly without having to use an entirely new system. bringing up that problem with table constructors calling functions, you'd instead need something like:
person = Dialogue {
"hi",
"calling a function",
function () saveplayerstate("Dark Caves", 3, "blah") end, -- bleh
}
and make appropriate changes in the line reader to check the type of the line to see if it's a function, then run that instead of the parser (which would probably be removed entirely)
it's not entirely impossible to implement a pseudo-variable system inside text strings, but it's not clean either. you could have something like:
replacing anything starting with '$' with the value of whatever is stored in the variable with the same name. however that still makes math messier since you have to use temporary variables for some things
adding more commands would be easy since there's that section where they're all defined, so you'd just have to implement the functionality of that command in mmf and call it through that command
Hmm, soooo, would I have to attach all those functions to whatever script I'd want to run, or could I have separate scripts that could piggy back off the functions already defined in the main script? EDIT: wait, I think this is somehow linked to coroutines which you said wasn't possible in Xlua, right?
Sorry for bothering you, it's just that this seems so difficult to implement in a clean way.
I don't want users to have to bother with all the extra syntax needed to make a script function properly, but at the same time I want to keep it clean on the mmf side of things. Perhaps what I want to do is impossible with lua alone...
Thanks for your great work again! I'm gonna have to go read up on some lua documentation this weekend!
after that you could use it in other scripts simply by using the 'require' function:
talk = require("textengine") -- "textengine" being the filename of the dialogue engine. note that you don't include the '.lua'!
talk.Dialogue {
"blah",
}:begin()
you'll probably have to make a global alias for 'MMF_Next' since it will now be inside the module, so you could just do 'MMF_Next = text.MMF_Next' inside your scripts
Interesting. Would it be possible to get rid of the "talk.Dialogue {" bit in user made scripts on a lua level? (by that I mean by not adding it later from within mmf) So that it would be easier to edit for the less experienced.
Also would there be a way to add modules at run time. Like calling scripts when the objects that they represent are interacted with, or "called" if you will.
Interesting. Would it be possible to get rid of the "talk.Dialogue {" bit in user made scripts on a lua level? (by that I mean by not adding it later from within mmf) So that it would be easier to edit for the less experienced.
off the top of my head i can't think of a way, at least not a way that would be any cleaner. it is in fact just a normal function. it'll have to be used at some point
however, if you've checked the 'external_dia.txt' file you'll see it's just the dialogue (and commands) only, not even requiring the quotation marks, so as long as your main script somehow has a way of making text.Dialogue{}:load("whatever.txt"):begin() hidden from the user it may work out. imo the way it is now isn't all that confusing (it could be worse!), and newcomers shouldn't have a problem if they were given a couple of examples
Also would there be a way to add modules at run time. Like calling scripts when the objects that they represent are interacted with, or "called" if you will.
i'm not totally sure what you mean with this... you want scriptable objects that are their own separate modules?
Also would there be a way to add modules at run time. Like calling scripts when the objects that they represent are interacted with, or "called" if you will.
i'm not totally sure what you mean with this... you want scriptable objects that are their own separate modules?
Exactly. I want to have different types of "objects" as well, but this would be handled mmf side. Most of the scripts would just be checking variables and changing the animation/interactions of the object when a change occurs.
Actually come to think of it all I'd need is for the script to activate once the object is touched (for the most part)
But I'd also like to be able to make objects that can be changed by other objects, or objects that can retrieve outside information and use it within itself. Like $name = getplayername() (if that's even how lua works with setting variables)
Or:
$door = getunlockedstate()
if ($door > 0) then
setframe(2,4)
end
But in this case the script would have to run at the beginning of the frame, or at least when it becomes visible on screen.
If it were run at the beginning it would have to iliterate through all the scripts that are supposed to run at the beginning.
I also considered doing a system that is part lua and part mmf, where mmf handles the variables and the object setup, but this would be less seamless.
This may just be too much to ask, but it would be awesome if it were possible.
With xlua you can do what you want as you can modify objects position/values etc if you have MMF interact selected.
I guess what you would have to do is give each objects an alterable string with a unique ID or something and then export that object to LUA so you can load it into your custom script and do your checks there. You would need to store your IDs into a table in LUA so you can loop through it and do checks etc.
Yes that's what I meant, but I think I'll just use the regular lua object and make a system that selects which script to run based on variables that mmf retrieves externally, and just make a special editor for it or something.
Although it's a more complicated solution it would be easier my users in the long run.
not to plug xlua more or anything but rii just fixed the coroutines thing
also that one xlua'd coroutine example you were using was in fact not ported entirely correctly; the first LF_StringReturn$() should be replaced with MF_StringParam$() and the Val(LF_StringReturn$()) is better replaced with MF_NumericParam()