Lua filepath changes in 1.3b?

Have a question, suggestion, or comment about Aleph One's features and functionality (Lua, MML, the engine itself, etc)? Post such topics here.
Post Reply
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

Lately I've been using loadfile() to pull disparate chunks of lua together. Specifically, I've been loading modular chunks of lua into a level's merged map lua. It definitely speeds up debugging, as I need only merge once, and simply modify the lua outside of the merged map. And of course the lua is modular, which is important, given all the ridiculous stuff I've got going on in lua.

On a whim I decided to try out 1.3b2 tonight, and suddenly all the lua is broken?! No. The lua file being loaded by the map's lua simply could not be found. Originally, the base for the filepath was whatever directory Aleph One is in. On a hunch, I assumed the new base is the *volume* that Aleph One is in... Bingo.

I'm curious why this happened, and if it's configurable in any way?
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

I wouldn’t recommend using loadfile. I’m surprised that ever worked.
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

Works like a charm, honestly. I mean, if nothing else it's great for developing large scripts. I could see it being trivial enough to go back and jam stuff together into one lua file for a scenario release, but the benefits in terms of managing all this code through debugging and modification are substantial.

I recall years ago we briefly touched on IO and your reasons for why it is only implemented slightly, and only for solo lua, but I'd be curious to understand your take on loadfile in more detail.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

For the same reasons as IO, loadfile should only be available to solo scripts. That'll get fixed, so don't count on it working like a charm!
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

Mm. Well, no biggie, aside from some refactoring. Thanks for letting me know.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

I think Atque should merge multiple Lua scripts? And IIRC all the LUAS run in the same state. So, should barely be any refactoring?

If any of that isn't true, hopefully we can fix it before disabling loadfile.
User avatar
Wrkncacnter
Vidmaster
Posts: 1953
Joined: Jan 29th '06, 03:51
Contact:

AOPID uses many separate lua files merged into each map. Works great.
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

Haha, yeah. I just unmerged AOPID last night to see what you did and noticed that. Really cool work, Wrk!

Hmm, seems like the refactoring is no biggie at all, just removing the loadfile() calls would probably do it as-is. If all the scripts are in the same state, the functions and what-not are all global within that state if they were otherwise, no?
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Yes, looks like globals (including functions) are shared for any scripts in each of the four separate Lua states (level embedded, net script, solo/console, and stats). So any embedded Lua can access other embedded Lua globals, but, for instance, you can't access embedded globals from a net script.
User avatar
Wrkncacnter
Vidmaster
Posts: 1953
Joined: Jan 29th '06, 03:51
Contact:

To make changing and testing code easier, I had a bash script set up for AOPID that would just copy the .lua files from a git repo to all of the map directories, and then it would call the command line atquem to do the merge.

Not sure what your setup is like, but that worked amazing for me. You can just change a line of code, run the script, and start up the game without having to worry about the whole merge process all the time.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

^
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

That seems to be the optimal solution. At this point I'm still plugging away as-is, but eventually I'll migrate to 1.3. My setup would probably be amenable to that. I'm already headed there anyway since I've been infrequently throwing the lua up to a repository on my github for peace of mind.
User avatar
Wrkncacnter
Vidmaster
Posts: 1953
Joined: Jan 29th '06, 03:51
Contact:

treellama wrote:Yes, looks like globals (including functions) are shared for any scripts in each of the four separate Lua states (level embedded, net script, solo/console, and stats). So any embedded Lua can access other embedded Lua globals, but, for instance, you can't access embedded globals from a net script.
Would there be any chance of adding some way to share variables between the embedded lua, net scripts, and HUD lua? Not like all globals, but maybe a specific thing like Shared._custom_variable. Anything in Shared would be common between the 3 types of lua?

I'm just wondering because I had to do some pretty hacky weird stuff to communicate information between the 3 things for AOPID.
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

Wrkncacnter wrote:Would there be any chance of adding some way to share variables between the embedded lua, net scripts, and HUD lua? Not like all globals, but maybe a specific thing like Shared._custom_variable. Anything in Shared would be common between the 3 types of lua?
At the very least, some way to pass stuff to HUD other than texture palettes? :D
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Yeah I had considered that before, like a Level.shared_state or something.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Wrkncacnter wrote:Would there be any chance of adding some way to share variables between the embedded lua, net scripts, and HUD lua? Not like all globals, but maybe a specific thing like Shared._custom_variable. Anything in Shared would be common between the 3 types of lua?

I'm just wondering because I had to do some pretty hacky weird stuff to communicate information between the 3 things for AOPID.
Is string -> string enough? Try Level.stash in git master. Because it's shared by EVERYBODY, I recommend prepending some hash or something (GUID, haha) to the front of your keys so nobody accidentally messes with your stuff.

There are probably ways to improve this--if they are easy, I'd like to get them in before 1.3.
User avatar
Wrkncacnter
Vidmaster
Posts: 1953
Joined: Jan 29th '06, 03:51
Contact:

Awesome. I did a very simple test between embedded lua and the HUD and it seemed to work. This is most likely powerful enough to do anything I could think of. Being able to store a table would be nice, but certainly not necessary. I wonder if lua has a way of serializing a table to a json string or something similar? I dunno, doesn't matter too much. It sure as hell beats using a combination of team color + number of uplink chips to communicate stuff :P

While I'm asking for stuff, is there any way to make it so multiple solo lua scripts can be run at once? For example, right now for AOPID, there's a solo lua script active because of the ability to talk to the dead, but it prevents anyone else from making a plugin that changes any type of behavior with lua.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Wrkncacnter wrote:Being able to store a table would be nice, but certainly not necessary. I wonder if lua has a way of serializing a table to a json string or something similar?
Aleph One actually has its own binary serializer that we use to save state in saved games, and to pass state between levels. It's kind of heavyweight though, so I didn't know if it was suitable to do multiple times per tick. Especially if you store your whole state in there, and especially especially if it's automatic.

I suppose I could expose the serializer, make the stash accept serialized strings, and make it the scripter's problem if he wants to put entire tables in there.

I guess there are two ways to use the stash:

1. Store all the shared state in there (in addition to the copy in each Lua state where it's deserialized). I am guessing this is how you plan to use it.
2. Use it to pass lightweight messages to keep the states in sync. Strings are probably fine for this, and a little more efficient.
While I'm asking for stuff, is there any way to make it so multiple solo lua scripts can be run at once? For example, right now for AOPID, there's a solo lua script active because of the ability to talk to the dead, but it prevents anyone else from making a plugin that changes any type of behavior with lua.
I don't think that's going to happen for 1.3. But, now that you have Level.stash, you could move talking to the dead into embedded Lua.
User avatar
Wrkncacnter
Vidmaster
Posts: 1953
Joined: Jan 29th '06, 03:51
Contact:

treellama wrote: 1. Store all the shared state in there (in addition to the copy in each Lua state where it's deserialized). I am guessing this is how you plan to use it.
2. Use it to pass lightweight messages to keep the states in sync. Strings are probably fine for this, and a little more efficient.
Yeah, I would probably just stick with strings for the most part. If I did want to use tables, it'd be more of a code readability thing, and I haven't thought too much about it at this point, or if I'd even have a use for it. I could maybe see someone wanting it, but I don't know for sure. Maybe I'd have to store the entire inventory table into saved state, if I wanted 3rd party plugins to be able to mess with it, but that's not really something I'd have to worry about now.
treellama wrote: I don't think that's going to happen for 1.3. But, now that you have Level.stash, you could move talking to the dead into embedded Lua.
You'd still need the solo lua script running to capture function calls from the console, right? Anyway, I'm not too worried about this one, as I doubt anyone would be making plugins anyway.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Wrkncacnter wrote:You'd still need the solo lua script running to capture function calls from the console, right? Anyway, I'm not too worried about this one, as I doubt anyone would be making plugins anyway.
You can set Level.stash values from the console with MML macros, then check if they're present (and clear them out) from embedded Lua.
User avatar
Ku-rin
Born on Board
Posts: 59
Joined: Feb 15th '19, 15:14
Location: Not Invented Here

treellama wrote:Try Level.stash in git master. Because it's shared by EVERYBODY, I recommend prepending some hash or something (GUID, haha) to the front of your keys so nobody accidentally messes with your stuff.
Noice!
Wrkncacnter wrote:I wonder if lua has a way of serializing a table to a json string or something similar?
http://lua-users.org/wiki/TableSerialization

It appears it has too many ways. :wacko:
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

I modified Level.stash to accept binary strings, and exposed Aleph One's binary serializer (that is used for restore_all and restore_passed) as Game.serialize/Game.deserialize.

Code: Select all

Level.stash["itsgonnabeyuge"] = Game.serialize(my_bigly_table)
Post Reply