OpenXcom Forum

Modding => OpenXcom Extended => OXCE Builds & Ports => Topic started by: Whispers on September 15, 2018, 04:55:31 pm

Title: [OXCE+] Lua Integration
Post by: Whispers on September 15, 2018, 04:55:31 pm
I started work on extending OXCE+ to include LUA hooks and so far the results are promising.

I wanted to start this thread to discuss the progress and also address any design considerations with how the OXCE+ LUA API is constructed.

First up, the progress.

I've set up a new rule which allows you to specify a script to load. The rule syntax is fairly straightforward.

Code: [Select]
game:
  script: scripts/game.lua

This will simply tell the engine that you have a script in <mod root>/scripts/game.lua. When a game is loaded or a new game is started, it then executes the script for the first time. When the script is executed, it is responsible for registering the hooks that it requires in the engine. Currently, it's implemented in such a way that you can only have one hook per script per callback, so you can call xcom.geoscape.register1HourCallback(function) multiple times, but it will only execute the last function you pass to it on every hour.

In the current version on github, there is one callback at the moment. I'll be refactoring the code a bit to make it more generic so other callbacks will be quicker to implement, however, start small and work your way up :D

With that working, the next steps are to add in a ton of global callbacks and hooks.

I set up the github repo. The repo with the Lua additions is here:

https://github.com/xxWhispers/OpenXcom

Why Lua? Well, to be honest, it's a widely known language that I have familiarity with implementing and developing with. That's literally the only reason why. Oh, and functions are data, which allows you to overwrite other functions to extend functionality in ways that are limited only to your imagination(and coding skills).

From a design perspective, I want to be clear that the idea is not to replace or port any of the existing code over to Lua. I don't want to port OXCE+ over to Lua. Instead, the goal is merely to provide the ability to get/set data internally without having to modify the engine code for new features.

With that said, there are things I do have in mind to allow you to extend certain features already built into the engine. For instance, one of my goals is to allow you to write your own terrain generation algorithms and hook into the existing terrain generation to allow you to overwrite or skip certain terrain passes. Another thing I want to allow you to do is customise almost every screen in the game by exposing the active UI elements and allow you to move/add/remove all UI bits around as you see fit. Then there's the obvious stuff, like being able to change soldier stats, add new fields, and completely new game mechanics(soldier mana stat anyone?)

Future plans:

* Have the ability to set/get existing base information such as stores, tiles, crafts, soldiers, etc.
* Add more triggers like onEnemyCraftDetected, onEnemyLanded, onEnemyBaseDiscovered, etc
* Have custom terrain generation scripts
* Have battlescape scripted events
* Hook into save/load game to allow mods to save their stuff.

Questions for modders:

* Should there be scoped/privileged Lua calls that are only accessible to certain mods?
* Any special requests for features? ( I have a feeling I may regret asking this :P )

So I'd really like to get your thoughts on this. Any questions, please feel free to give me a shout! I will be back here to post new updates as they come, so stay tuned!
Title: Re: [OXCE+] Lua Integration
Post by: bulletdesigner on September 15, 2018, 05:09:50 pm
Sound promising 8)
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 15, 2018, 08:04:23 pm
Updated the OP... more updates to come
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 15, 2018, 08:30:56 pm
There are already scripts in OXCE, right now only available in battlescape but can be expanded to geoscape too.
And now adding new scripts that are incompatible with old ones?
Of corse my scripts are right now limited (not even Turing complete right now) but are closely coupled to C++ and support `const`.
Another thing is that limitation is good thing that I can control what is possible in each script and what it have access to.

For me this make hard do justify dropping my scripts in favor of LUA especially that I doubt it will be capable of fulfil all current usage.
Example of that is how much overhead have running LUA script? How many thousand of times can be call per frame?
What you need to change in source to allow this integration, and what dependency will be needed to compile with LUA enabled?

Of corse I can't stop doing this as this is open source project and you can do any thing you want with code.
Simply I not convinced to adding it to main branch of OXCE or OXCE+.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 15, 2018, 08:50:16 pm
Hi Yankes!

Yes, I heard all about the yankesScript and I've briefly browsed through what you have there. Yes, you've done a really great job at making a logic graph, and I'm not trying to replace yours for the thousands of scripts that already exist. However, I do think there is a need for something more accessible to the modding community, and Lua fits that description. Instead of having to learn about the quirks of one language in order to make something unique, you can learn a language used by thousands of other games(or re-use your existing knowledge of Lua, if you are already familiar with it).

I can see that you are very much someone who cares about performance. I used to be that way also. LuaJit exists to fill that gap by precompiling the Lua on the target platform, if performance ever becomes an issue, which I doubt it ever will be. For now, I don't think it will be an issue. Back in 2006, I used Lua on Supreme Commander, and we had thousands of units running multiple scripts every frame, and that was 10 years ago.

Const correctness is an interesting topic, and one that even C++ developers often get wrong. Did you know that the C/C++ compilers(GCC, Clang, and MSVC) completely ignore const when it comes to optimisations(use preprocessor definitions if you want a true const)? Reason why is that you can easily un-const something without the compiler ever knowing. All it is is simply a hint to the programmer that they shouldn't modify the value. Anyway, I digress. I don't want to start a C/C++ standard discussion because those could go on for days. I do, however, want to discuss Lua :D
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 15, 2018, 08:53:33 pm
Oh, and the only dependency is Lua5.1. It consists of a handful of source files and can be retrieved and compiled on any platforms with one bash call. You're using Boost in OXCE and OXCE+, so I hardly think the 1-2k size would make a difference.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 15, 2018, 09:31:27 pm
Hi Yankes!

Yes, I heard all about the yankesScript and I've briefly browsed through what you have there. Yes, you've done a really great job at making a logic graph, and I'm not trying to replace yours for the thousands of scripts that already exist. However, I do think there is a need for something more accessible to the modding community, and Lua fits that description. Instead of having to learn about the quirks of one language in order to make something unique, you can learn a language used by thousands of other games(or re-use your existing knowledge of Lua, if you are already familiar with it).
Graphic was only start point of developing this scripts, right now they expand to other places. My concerns is that each script engine is burden on source code (for me my script is lesser burden but for other programmers this could be opposite) to maintain to incompatible engines.

I can see that you are very much someone who cares about performance. I used to be that way also. LuaJit exists to fill that gap by precompiling the Lua on the target platform, if performance ever becomes an issue, which I doubt it ever will be. For now, I don't think it will be an issue. Back in 2006, I used Lua on Supreme Commander, and we had thousands of units running multiple scripts every frame, and that was 10 years ago.
Speed of my script engine rely on it simplicity (implementation is complex but it all boils down to switch in loop) and using same memory model as C++. LUA have different model and need some conversions to transfer data (I could be wrong there, best if you would show code in action).
Another thing is LuaJit have cost too (on start up) and probably is big as whole OXC exe (again I did not see your implementation to be 100% sure).
In some UI parts it not matter but it should replace my script that need this.

Const correctness is an interesting topic, and one that even C++ developers often get wrong. Did you know that the C/C++ compilers(GCC, Clang, and MSVC) completely ignore const when it comes to optimisations(use preprocessor definitions if you want a true const)? Reason why is that you can easily un-const something without the compiler ever knowing. All it is is simply a hint to the programmer that they shouldn't modify the value. Anyway, I digress. I don't want to start a C/C++ standard discussion because those could go on for days. I do, however, want to discuss Lua :D
You completely misunderstood meaning of `const` especially in context of my script (where I do not allow removing it). This allow me send some object to script and do not worry that someone modify it without my permission. This is great tool to reason on what happens in code and script that are called.


Oh, and the only dependency is Lua5.1. It consists of a handful of source files and can be retrieved and compiled on any platforms with one bash call. You're using Boost in OXCE and OXCE+, so I hardly think the 1-2k size would make a difference.
OXCE do not use boost. This was yaml dependency that was drop by them when they switch to C++11. And more importantly it will work with VS? this is windows that do not have bash. Another important toolchain to consider is mxe (gcc based but have predefined libs available). This is why I ask ablaut dependencies.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 15, 2018, 10:37:23 pm
My concerns is that each script engine is burden on source code (for me my script is lesser burden but for other programmers this could be opposite) to maintain to incompatible engines.

Ah, okay. Well, having modders make demands/hacks into code I see as a larger burden, and one that leads to more issues as it progresses. Having a script API that you agree upon at the start and then slowly adding to it is more flexible, IMO.

Speed of my script engine rely on it simplicity (implementation is complex but it all boils down to switch in loop) and using same memory model as C++. LUA have different model and need some conversions to transfer data (I could be wrong there, best if you would show code in action).

If you implemented Lua using default stack operations only, then yes, you have to convert values to/from script. However, there are user variables that you can define which use the memory address you give it and type you specify, however, I wouldn't go that route. Lua is FAST. I mean, seriously fast. I suppose we could do a side by side comparison using some algorithm(s), like md5, or perhaps something more memory intensive like huffman encoding, but I totally see your point about it being too slow for graphics purposes. For that, you would need something a little closer to the metal.

For comparison, the setting of 1 variable actually sets 3 points in contiguous memory. The first point is the ref counter, the second is the data type, and the third is the data itself. There isn't a single conditional in that code, which  means that it runs faster then your average if statement. Getting a value has one conditional, which is merely a conditional to ensure the value in memory is in the correct format - otherwise convert it, or throw an exception the old school longjmp way, not the fancy and expensve stack unwinding C++ way. Since the logic is run by token static single assignment, it's just as fast, and in a lot of cases faster than a logic tree switch statement.

I didn't build Lua, but if I were to build a scripting language, I would do something very similar to what they have done.

Another thing is LuaJit have cost too (on start up) and probably is big as whole OXC exe (again I did not see your implementation to be 100% sure).
In some UI parts it not matter but it should replace my script that need this.

Yes, and that is one of the biggest drawbacks of LuaJit. I'm not a fan of using it unless we do run into performance issues at runtime. I don't see that being an initial problem though, unless someone writes a script for every tile tha tgoes through every other tile of the level and every pixel at the same time. (I could totally see someone attempting to do that). In those cases, there's Lua's interrupt ability, which allows you to pause currently executing scripts and report errors/warnings to developers basically telling them to stop hogging all the resources!

You completely misunderstood meaning of `const` especially in context of my script (where I do not allow removing it). This allow me send some object to script and do not worry that someone modify it without my permission. This is great tool to reason on what happens in code and script that are called.

Oh, that's handy! Out of curiosity, instead of creating a whole system that then needs to be guarded by conditional if(s) which cause pipeline execution slowdowns(branch prediction is the largest CPU performance killer after cache misses because it causes pipeline flushes)... why not just copy it and let them modify the copy of the const so it doesn't have any effect on the original const variable?

OXCE do not use boost. This was yaml dependency that was drop by them when they switch to C++11.

Yeah, I've never used YAML in any projects before. This is my first time playing with it and I've already got mixed feelings about it. I did, however, quickly pull the latest luaYaml to allow me to get the config stuff exposed to Lua. So far, no problems there :D

Also, do you know what version they switched to C++11? I'm running 0.5.1 at the moment, but have considered updating that.

And more importantly it will work with VS? this is windows that do not have bash. Another important toolchain to consider is mxe (gcc based but have predefined libs available). This is why I ask ablaut dependencies.

Ah, yes, of course Lua works on MSVC. For MXE, I may need a bit of help on that, but I don't see that as a major issue.

I suppose the question I have is what would it take to get you to accept this? I'm not going to start up another branch just because of adding in Lua. That seams excessive and would further fragment the modding community. My biggest reason for doing this is because I wanted to do a quick mod and someone told me I'd have to muck about the engine code and release my own executable version if I wanted to do it, but that doesn't feel like a mod anymore. Simply exposing a bunch of stuff from the engine to a scripting interface is sufficient for what I wanted to do, so I started looking in to it. If you're saying you won't take it, then there's no point in doing it.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 16, 2018, 03:04:21 am
Ah, okay. Well, having modders make demands/hacks into code I see as a larger burden, and one that leads to more issues as it progresses. Having a script API that you agree upon at the start and then slowly adding to it is more flexible, IMO.
We compare not "script<->not scripts" but "2 scripts engine <-> 1 script engine". I add script exactly because of this reason you mentioned, but this can't be justification for another engine if one exists.

Another thing is demand for scripts in OXCE, right now I only one who push for new scripts (as my pet feature). Current interest is moderate (could be caused by limited scope of my scripts).

If you implemented Lua using default stack operations only, then yes, you have to convert values to/from script. However, there are user variables that you can define which use the memory address you give it and type you specify, however, I wouldn't go that route. Lua is FAST. I mean, seriously fast. I suppose we could do a side by side comparison using some algorithm(s), like md5, or perhaps something more memory intensive like huffman encoding, but I totally see your point about it being too slow for graphics purposes. For that, you would need something a little closer to the metal.
Probably best benchmark for me would be custom bliting (altering pixel values on drawing surfaces).
Simply replace `ScriptWorkerBlit::executeBlit` with LUA call that will do same work without any slowdown.
Some thing like this: https://www.youtube.com/watch?v=FKzqCOg2DrQ (only units graphic, around 24 at once on screen).

For comparison, the setting of 1 variable actually sets 3 points in contiguous memory. The first point is the ref counter, the second is the data type, and the third is the data itself. There isn't a single conditional in that code, which  means that it runs faster then your average if statement. Getting a value has one conditional, which is merely a conditional to ensure the value in memory is in the correct format - otherwise convert it, or throw an exception the old school longjmp way, not the fancy and expensve stack unwinding C++ way. Since the logic is run by token static single assignment, it's just as fast, and in a lot of cases faster than a logic tree switch statement.

I didn't build Lua, but if I were to build a scripting language, I would do something very similar to what they have done.
And there is big difference, because my scripts do not allocate any memory only get buffer from C++ stack where they place variables. I simply traded speed for some limitations. If I would need allocate something then I would ask game code to create if for me.


Yes, and that is one of the biggest drawbacks of LuaJit. I'm not a fan of using it unless we do run into performance issues at runtime. I don't see that being an initial problem though, unless someone writes a script for every tile tha tgoes through every other tile of the level and every pixel at the same time. (I could totally see someone attempting to do that). In those cases, there's Lua's interrupt ability, which allows you to pause currently executing scripts and report errors/warnings to developers basically telling them to stop hogging all the resources!

Oh, that's handy! Out of curiosity, instead of creating a whole system that then needs to be guarded by conditional if(s) which cause pipeline execution slowdowns(branch prediction is the largest CPU performance killer after cache misses because it causes pipeline flushes)... why not just copy it and let them modify the copy of the const so it doesn't have any effect on the original const variable?

This object that script edit is pointer to `BattleUnit`. you can't have copy of unit because this will miss point of using game objects.
Another thing my scripts are static typed. This mean if you try modify const object then script will refuse to parse.

Yeah, I've never used YAML in any projects before. This is my first time playing with it and I've already got mixed feelings about it. I did, however, quickly pull the latest luaYaml to allow me to get the config stuff exposed to Lua. So far, no problems there :D

Also, do you know what version they switched to C++11? I'm running 0.5.1 at the moment, but have considered updating that.
If this is from current github repo then its need C++11, if it from some else it probably still use C++98 and boost.

Ah, yes, of course Lua works on MSVC. For MXE, I may need a bit of help on that, but I don't see that as a major issue.

I suppose the question I have is what would it take to get you to accept this? I'm not going to start up another branch just because of adding in Lua. That seams excessive and would further fragment the modding community. My biggest reason for doing this is because I wanted to do a quick mod and someone told me I'd have to muck about the engine code and release my own executable version if I wanted to do it, but that doesn't feel like a mod anymore. Simply exposing a bunch of stuff from the engine to a scripting interface is sufficient for what I wanted to do, so I started looking in to it. If you're saying you won't take it, then there's no point in doing it.
a) Have better capabilities that my scripts (easy to do).
b) It do not have big overhead (probably harder).
c) Can replace all current usage of my scripts.
d) Do not disturb code base to much (e.g. you do not change multiple of functions signatures to pass some state).
e) If LUA have state it should be able to restore it after game save and load.
f)  Meridian is fine too to change script engine.
g) mxe work without any hacks
h) Have "killer app" for people like Dioxine,  Solarius Scorch, Hobbes or other big modders
With all this I will happy kill my scripts and replace it with LUA

btw If your mod feature align with my or Meridian goals then is possible to include it to OXCE+ directly without need for script engine.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 16, 2018, 01:59:14 pm
I had a longer post typed up, but due to power loss I guess I'm being forced to be brief :D

We compare not "script<->not scripts" but "2 scripts engine <-> 1 script engine". I add script exactly because of this reason you mentioned, but this can't be justification for another engine if one exists.

One of the biggest design tenants is that I do not want to replace or port any existing functionality so I do see yankesScript continuing for now. I'll maintain and expand the Lua API, and you can continue to focus on expanding yankesScript if you would like.

Another thing is demand for scripts in OXCE, right now I only one who push for new scripts (as my pet feature). Current interest is moderate (could be caused by limited scope of my scripts).

There's a huge demand from the modders I've spoken to on Discord.

Probably best benchmark for me would be custom bliting (altering pixel values on drawing surfaces).
Simply replace `ScriptWorkerBlit::executeBlit` with LUA call that will do same work without any slowdown.
Some thing like this: https://www.youtube.com/watch?v=FKzqCOg2DrQ (only units graphic, around 24 at once on screen).

Sounds like a good benchmark! I'll sneak that in as a "psychedelic" mod :D

And there is big difference, because my scripts do not allocate any memory only get buffer from C++ stack where they place variables. I simply traded speed for some limitations. If I would need allocate something then I would ask game code to create if for me.

The Lua context(which holds the memory for the Lua scripts) will initialise only with function pointers to allow the user to CRUD(create, read, update, delete) game objects. This means we can limited things to just "read only" if we want, but also means that no game state information will be held in the Lua context itself.

This object that script edit is pointer to `BattleUnit`. you can't have copy of unit because this will miss point of using game objects.
Another thing my scripts are static typed. This mean if you try modify const object then script will refuse to parse.

As mentioned above, we can limit access to read only since nothing will be stored in the Lua context.

If this is from current github repo then its need C++11, if it from some else it probably still use C++98 and boost.

Thanks! I'll pull the latest and compile from there instead of using Boost(that should cut compile time down a bit)

a) Have better capabilities that my scripts (easy to do).

Done :D

b) It do not have big overhead (probably harder).

Lua doesn't have a big overhead.

c) Can replace all current usage of my scripts.

Why is this a requirement? I'm not trying to replace yankesScript, at least, not initially. I'm only trying to provide a mod(der) friendly interface for other people to make what they want.

d) Do not disturb code base to much (e.g. you do not change multiple of functions signatures to pass some state).

Might need to define "too much" :D

I'll have to change the interface for loading/saving objects(almost everything in SaveGame, and most things that already take YAML node as a parameter) to include the lua context so that I can pass data to/from the game state.

e) If LUA have state it should be able to restore it after game save and load.

Yeah, still thinking on the best way to handle persistence. My current thoughts are to create a yaml node for game objects that stores the data per each mod, but some saves are already getting too large, so I might need to think about this some more.

f)  Meridian is fine too to change script engine.

Cool!

g) mxe work without any hacks

I don't think this'll be an issue

h) Have "killer app" for people like Dioxine,  Solarius Scorch, Hobbes or other big modders

"Hello World" isn't enough :P

I'm compiling a list of "example mods" as a way of specifying a Minimal Viable Product(MVP) milestone. So far, I have the following:

* add new field to the soldier for mana, and show how that can be used to implement new gameplay mechanics
* modify world zones and restrict missions in the zones to allow for diplomacy as a new mechanic
* implement "traitors" which are enemies that flip sides during battle and join your team
* open for more suggestions!

With all this I will happy kill my scripts and replace it with LUA

Like I said, the goal is not to kill yankesScript, but to supplement it initially. If there comes a point where the two collide, then yeah, we may want to revisit this strategy, but otherwise I don't see a problem with them co-existing :D

btw If your mod feature align with my or Meridian goals then is possible to include it to OXCE+ directly without need for script engine.

Yeah, but that simply continue the current process for writing custom logic in mods, which is to modify the engine in order to make something new. I would like to see what else the modders come up with given nearly full access to the internals of the engine :D
Title: Re: [OXCE+] Lua Integration
Post by: Meridian on September 16, 2018, 02:39:38 pm
I would like to see what else the modders come up with given nearly full access to the internals of the engine :D

FWIW, I would like to see what "nearly full access to the internals of the engine" actually means... because even after reading all of this, I still have no idea.
For me, right now, this is something I can't even imagine, let alone implement.
Or maybe I just imagine too much and it means something a lot less full-access-ey.

Also, please be careful with such words... our modders are not developers (with a few exceptions)... and they will believe you when you say they will be able to do "anything they want"... which is just unfair to them. E.g. I'm pretty sure Hobbes will not be able to "script" an online multi-player support, which he wants so much.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 16, 2018, 02:54:31 pm
Ah, yes.. forgot my audience for a minute there :D

By "full access" I mean basically anything you can see in the save file, and also what is loaded in the rules, with some exceptions to anything that may totally break the game(for example, you are allowed to see what mods are loaded, but you can't add new mods to that list on demand)

Cheers,
-Ken
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 16, 2018, 03:29:37 pm
For lack of a better place to put it, I'm going to start putting the lua API documentation in github.

https://github.com/xxWhispers/OpenXcom/wiki

Right now I've only just started putting together the list of available functions, but I suppose I should start somewhere :D

I'll add a "getting started using lua" once the project is in more of a stable state.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 17, 2018, 02:41:10 am
Sounds like a good benchmark! I'll sneak that in as a "psychedelic" mod :D

The Lua context(which holds the memory for the Lua scripts) will initialise only with function pointers to allow the user to CRUD(create, read, update, delete) game objects. This means we can limited things to just "read only" if we want, but also means that no game state information will be held in the Lua context itself.

but Lua shroud obey game objects life cycle, if some object right now is created by function A then Lua should use this function too to create object. Same with deleting. If something is not changeable by game engine scripts usually should not change this too, this is important in case when some game logic really on that value is not changed.


As mentioned above, we can limit access to read only since nothing will be stored in the Lua context.

Best if you could control per script call, some scripts could be allowed to change unit in any way other can only read.


Why is this a requirement? I'm not trying to replace yankesScript, at least, not initially. I'm only trying to provide a mod(der) friendly interface for other people to make what they want.

https://www.youtube.com/watch?v=sqcLjcSloXs
Overall only thing that need to work is scripts that are used by biggest mods there. And it would be good that after transition they do not loose any functionality.

Might need to define "too much" :D

I'll have to change the interface for loading/saving objects(almost everything in SaveGame, and most things that already take YAML node as a parameter) to include the lua context so that I can pass data to/from the game state.

You can compare it with current scripts, if your changes will be deleting my function parameter and replacing by your then its 100% fine. But if you need change every game logic class then is not fine.

Cool!

small clarification, this was condition not statement, you should read it "[if] Meridian is fine too to change script engine."

I don't think this'll be an issue

"Hello World" isn't enough :P

I'm compiling a list of "example mods" as a way of specifying a Minimal Viable Product(MVP) milestone. So far, I have the following:

* add new field to the soldier for mana, and show how that can be used to implement new gameplay mechanics
* modify world zones and restrict missions in the zones to allow for diplomacy as a new mechanic
* implement "traitors" which are enemies that flip sides during battle and join your team
* open for more suggestions!

This could be good start.

Like I said, the goal is not to kill yankesScript, but to supplement it initially. If there comes a point where the two collide, then yeah, we may want to revisit this strategy, but otherwise I don't see a problem with them co-existing :D

Whole point is that I'm not interesting in maintaining two script engines in OXCE (and probably Meridian too) this is way I set high-bar that new script engine is objective better in every aspect compare to my engine. Otherwise I will stick to my creation :) This mean you will need do more work but I would be unwise to give up couple of years of work for free :>

[ps]

Instead of wiki I would be more interested in WiP commits that show how it will work.
Title: Re: [OXCE+] Lua Integration
Post by: SupSuper on September 17, 2018, 06:49:23 am
Figured I'd throw my two cents in, because I've always been curious about integrating Lua scripting (I've played with it in other games), but have no idea how. :P Usually when people talk about scripting they think about modders doing anything, limitless possibilities! I don't think that's the point. OpenXcom is already open-source, the possibilities are already limitless, so clearly it's not that simple. At the end of the day, modders are modders and programmers are programmers and I don't think scripting is what will convert them. But in my eyes it has the potential to help solve one of OpenXcom's biggest problems: maintainability. Now that vanilla is basically done, all that's left is adding modding features, forever and ever...

Everytime a mod needs a feature, a modder has to convince a programmer to add that feature, and that feature is then available to every single mod. This poses multiple problems. Every feature has to be compatible with every other feature, and as mods grow, so will the engine. Features are never removed, only added, and the weight is on every programmer that follows. Every feature, no matter how specific and particular, has to be generalized to work for everyone. Etc. Does it make sense for the weight of every mod to be on every other mod? On every programmer? Probably not. It's a maintainability and scalability nightmare, and in the end programmers have to be choosy and decide what is worth supporting or not, fragmenting the modders and codebases.

So, instead of the engine having to support every feature for every mod, what if mods could carry their own code? Their own features? Instead of Items needing 100+ properties, what if they could instead have scriptable functions for onFire, onUse, onHit, etc. This would both give mods more power and make code lighter and easier to maintain for programmers. Now I don't think this means exposing everything and creating a completely generic scriptable engine, that's its own nightmare. Just exposing the most common "game events" from which modders can manipulate the simulation would suffice, letting them add their own associated state and UI if needed. A happy middleground between modder potential and programmer scope.

So why Lua vs Yankes scripts? Well it's pretty clear adoption has not been great, modders would rather bug programmers than deal with it, and the only programmers that deal with it are... Yankes. And I think a big factor is because modders aren't programmers. You can give them all the code and potential in the world, if they don't know how to use it, it's useless. So will they code Lua? Probably not. The draw of scripting isn't to the modders who can't code, but to the programmers who can't code C++ but can deal with something simpler like Lua, which in turn help the modders. I doubt they're itching to learn a whole new bespoke scripting language.

As for performance... honestly, you could do a lot worse than Lua. It's the most common lightweight scripting language around, designed for embedded, runs on every platform on the planet. It'll never beat native, it's a bytecode VM, but for anything outside a tight game loop it should be fine. After all, OpenXcom struggles on anything under a 2Ghz and does all its graphical operations on the CPU, so I don't think we're winning any awards for performance either. :P
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 17, 2018, 01:35:28 pm
but Lua shroud obey game objects life cycle, if some object right now is created by function A then Lua should use this function too to create object. Same with deleting. If something is not changeable by game engine scripts usually should not change this too, this is important in case when some game logic really on that value is not changed.

Best if you could control per script call, some scripts could be allowed to change unit in any way other can only read.

Hmm, not really easily done with the way I have started implementing the API. I do have a container class I quickly wrote which maps user objects to their respective class pointers, so maybe in that container class I could write some access rights management, but there will be HUNDREDS of hooks. On<Whatever Event I Put A Hook For> would then set the access rights to object classes, but that seams extreme. Can you point to a situation where one thing can be read, but not written during a single event, yet can be read/written on other events?

You can compare it with current scripts, if your changes will be deleting my function parameter and replacing by your then its 100% fine. But if you need change every game logic class then is not fine.

The hooks will need to be implemented in the logic classes so I do imagine it touching most logic classes

Whole point is that I'm not interesting in maintaining two script engines in OXCE (and probably Meridian too) this is way I set high-bar that new script engine is objective better in every aspect compare to my engine. Otherwise I will stick to my creation :) This mean you will need do more work but I would be unwise to give up couple of years of work for free :>

I get that. I'm actually saying I will maintain the Lua stuff and you could continue to maintain the existing script stuff.

Instead of wiki I would be more interested in WiP commits that show how it will work.

Problem is that I'm not allowed to touch a source code editor over the weekends. My wife is very strict about that :D

Writing the wiki also helps me clear my thoughts. It helps make sure what I'm working on will actually work.

I'll push up something later today to show progress.

Figured I'd throw my two cents in, because I've always been curious about integrating Lua scripting (I've played with it in other games), but have no idea how. :P Usually when people talk about scripting they think about modders doing anything, limitless possibilities! I don't think that's the point. OpenXcom is already open-source, the possibilities are already limitless, so clearly it's not that simple. At the end of the day, modders are modders and programmers are programmers and I don't think scripting is what will convert them. But in my eyes it has the potential to help solve one of OpenXcom's biggest problems: maintainability. Now that vanilla is basically done, all that's left is adding modding features, forever and ever...

Everytime a mod needs a feature, a modder has to convince a programmer to add that feature, and that feature is then available to every single mod. This poses multiple problems. Every feature has to be compatible with every other feature, and as mods grow, so will the engine. Features are never removed, only added, and the weight is on every programmer that follows. Every feature, no matter how specific and particular, has to be generalized to work for everyone. Etc. Does it make sense for the weight of every mod to be on every other mod? On every programmer? Probably not. It's a maintainability and scalability nightmare, and in the end programmers have to be choosy and decide what is worth supporting or not, fragmenting the modders and codebases.

So, instead of the engine having to support every feature for every mod, what if mods could carry their own code? Their own features? Instead of Items needing 100+ properties, what if they could instead have scriptable functions for onFire, onUse, onHit, etc. This would both give mods more power and make code lighter and easier to maintain for programmers. Now I don't think this means exposing everything and creating a completely generic scriptable engine, that's its own nightmare. Just exposing the most common "game events" from which modders can manipulate the simulation would suffice, letting them add their own associated state and UI if needed. A happy middleground between modder potential and programmer scope.

So why Lua vs Yankes scripts? Well it's pretty clear adoption has not been great, modders would rather bug programmers than deal with it, and the only programmers that deal with it are... Yankes. And I think a big factor is because modders aren't programmers. You can give them all the code and potential in the world, if they don't know how to use it, it's useless. So will they code Lua? Probably not. The draw of scripting isn't to the modders who can't code, but to the programmers who can't code C++ but can deal with something simpler like Lua, which in turn help the modders. I doubt they're itching to learn a whole new bespoke scripting language.

As for performance... honestly, you could do a lot worse than Lua. It's the most common lightweight scripting language around, designed for embedded, runs on every platform on the planet. It'll never beat native, it's a bytecode VM, but for anything outside a tight game loop it should be fine. After all, OpenXcom struggles on anything under a 2Ghz and does all its graphical operations on the CPU, so I don't think we're winning any awards for performance either. :P

Yup
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 17, 2018, 02:33:31 pm
Hmm, trying to think of a way to do terrain generated pressure plates. Something that is only executed once a soldier is standing on it. That could be another mod that I write to showcase the API.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 17, 2018, 07:40:46 pm
Updated OP with more updates :D
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 17, 2018, 08:38:48 pm
So why Lua vs Yankes scripts? Well it's pretty clear adoption has not been great, modders would rather bug programmers than deal with it, and the only programmers that deal with it are... Yankes. And I think a big factor is because modders aren't programmers. You can give them all the code and potential in the world, if they don't know how to use it, it's useless. So will they code Lua? Probably not. The draw of scripting isn't to the modders who can't code, but to the programmers who can't code C++ but can deal with something simpler like Lua, which in turn help the modders. I doubt they're itching to learn a whole new bespoke scripting language.

And ohartenstein23 :) Even if I myself would use this scripts it still would be useful as way to write features that I do not like or do not wan't to hardcode.
I'm aware that my script engine is not perfect but adding another script engine on top of this will not fix it but even worse that.
This is why I agree to include Lua but only when it completely replace my engine without loose of most of functionality.

As for performance... honestly, you could do a lot worse than Lua. It's the most common lightweight scripting language around, designed for embedded, runs on every platform on the planet. It'll never beat native, it's a bytecode VM, but for anything outside a tight game loop it should be fine. After all, OpenXcom struggles on anything under a 2Ghz and does all its graphical operations on the CPU, so I don't think we're winning any awards for performance either. :P

This depend on usage, in most cases this not matter but if it allocate memory per pixel drawn? This is one of my script usages and some mods use this.
I can only guess how Lua will behave and what will be performance. If Whispers will show it work fine, then is not problem to drop my scripts but if otherwise it will be problematic.
My whole point is that can be only one script engine in code base (Lua or my) other wise will be one big maintaining mess.


Hmm, not really easily done with the way I have started implementing the API. I do have a container class I quickly wrote which maps user objects to their respective class pointers, so maybe in that container class I could write some access rights management, but there will be HUNDREDS of hooks. On<Whatever Event I Put A Hook For> would then set the access rights to object classes, but that seams extreme. Can you point to a situation where one thing can be read, but not written during a single event, yet can be read/written on other events?
only read when you draw unit or calculate fire reaction, both should not change any thing because it could break code.
on event wen unit is hit you can alter unit (kill it, change damage values, change some custom property).

Another important thing is random seed, when you would access it on unit draw this would make that bugs become ultra hard to debug.
This why in my scripts access to random is only allowed in moments when other data is changed.

Overall it could be simplify to two global states, one is allowed to modify thins other is not.

The hooks will need to be implemented in the logic classes so I do imagine it touching most logic classes

For number of changes/modifications to source code, look how I manage my scripts. If your solution is comparable then is fine.
In my case most "mess" is in save game objects `.cpp` files where I define all bindings and scripts api:
https://github.com/Yankes/OpenXcom/blob/OpenXcomExtended/src/Savegame/BattleUnit.cpp#L3882

And "links" visible publicly:
https://github.com/Yankes/OpenXcom/blob/OpenXcomExtended/src/Savegame/BattleUnit.h#L148
or
https://github.com/Yankes/OpenXcom/blob/OpenXcomExtended/src/Mod/RuleItem.h#L183


If your changes are similarly localized and do not leak every other place then is fine.

I get that. I'm actually saying I will maintain the Lua stuff and you could continue to maintain the existing script stuff.

And after year you get bored and stop updating it or opposite I get bored and stop contributing to OXCE. In both cases will stay big blob of code that nobody want to touch. Right now I not interested in changing script engine or maintain another one but if you fulify my condition then I will accept it and take responsibility of maintaining it further.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 17, 2018, 09:22:18 pm
Overall it could be simplify to two global states, one is allowed to modify thins other is not.

Unfortunately it's not that easy. Once a Lua context is created, the API is injected into the context. Once the API is injected, I can't easily turn functions on or off depending on the context that they are run in, unless I block out functions based on the calling event.

If your changes are similarly localized and do not leak every other place then is fine.

Yeah, I go one step further. I have to insert source in events in the logic object that, well, triggers the event, but otherwise all functions and script bindings are done in completely separate source files and only access public member functions of existing objects. There's never any concern about "leakage" since I never allocate anything.

I did have to tweak how mods are loaded in order to get the path of the mod that is trying to execute the script, but otherwise it's just a matter of putting in hooks and creating get/set functions

And after year you get bored and stop updating it or opposite I get bored and stop contributing to OXCE. In both cases will stay big blob of code that nobody want to touch. Right now I not interested in changing script engine or maintain another one but if you fulify my condition then I will accept it and take responsibility of maintaining it further.

Heh, not likely to happen, but I get your point. Being honest, I'm a bit disappointed in myself for not finding OpenXcom earlier. I could have done this years ago :D
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 17, 2018, 09:45:52 pm
Unfortunately it's not that easy. Once a Lua context is created, the API is injected into the context. Once the API is injected, I can't easily turn functions on or off depending on the context that they are run in, unless I block out functions based on the calling event.

One solution is create two contexts, if Lua job is only glue code then it will work fine, but if you want put lot of custom state in it then it will not work.
Another is add two different bindings for same type, it will be `BattleUnit` and `BattleUnitConst`, depending on details it could end up as big hack.

Yeah, I go one step further. I have to insert source in events in the logic object that, well, triggers the event, but otherwise all functions and script bindings are done in completely separate source files and only access public member functions of existing objects. There's never any concern about "leakage" since I never allocate anything.

"leak" not like from "memory leak" but like in "abstraction leak".

I did have to tweak how mods are loaded in order to get the path of the mod that is trying to execute the script, but otherwise it's just a matter of putting in hooks and creating get/set functions

All refactors are welcomed, if you refactor half of code base and it simplify and improve code quality and then it fine, I only do not want brutal force solution that make code ugly (like function with 20 arguments, 100 copies of same code, e.t.c.). Change of `FileModInfo`  is good example because I can throw away Lua changes and still include it to OXCE.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 17, 2018, 10:12:46 pm
One solution is create two contexts, if Lua job is only glue code then it will work fine, but if you want put lot of custom state in it then it will not work.

Contexts store all the globals for a lua script, and I imagine there will be a lot of people who want to access their globals of the ordinary script execution.

Instead, this means the concept of using the registerHook is more applicable. When the code executes a registered hook, it simply sets a flag in ModLuaScript as to what is calling the hook, then when the script calls into a C function, its up to the bound C function to get the current ModLuaScript to check the calling context and can then selectively throw an error. I'm not a fan of doing that, but it fills the requirement.

Another is add two different bindings for same type, it will be `BattleUnit` and `BattleUnitConst`, depending on details it could end up as big hack.

Eeeeks... My eyes, my eyes! :P

All refactors are welcomed, if you refactor half of code base and it simplify and improve code quality and then it fine, I only do not want brutal force solution that make code ugly (like function with 20 arguments, 100 copies of same code, e.t.c.). Change of `FileModInfo`  is good example because I can throw away Lua changes and still include it to OXCE.

Heh, so you're snooping on my changes already :P

Yeah, not a fan of using std::pair the way it was being used, so I threw that in there quickly because I needed to get the path to the mod, and refactoring felt better than hacking in another std::pair
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 17, 2018, 10:51:29 pm

Yeah, not a fan of using std::pair the way it was being used, so I threw that in there quickly because I needed to get the path to the mod, and refactoring felt better than hacking in another std::pair


`std::tuple` for rescue ;P

But for more serious answer, pair or tuple are good as implementation detail, not as public interface. Adding name give greater meaning to code that some random pack of values.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 17, 2018, 11:06:07 pm
`std::tuple` for rescue ;P

Where's my hammer? I've got to knock some sense into...

But for more serious answer, pair or tuple are good as implementation detail, not as public interface. Adding name give greater meaning to code that some random pack of values.

Oh, okay, I'll put my hammer away now. :D
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 18, 2018, 12:22:00 am
Quick question to @Yankes and @Meridian.

What are your thoughts on std::shared_ptr and std::unique_ptr, etc?

Reason I ask is because it would make a large portion of the Lua code a lot easier. Instead of having to check for invalid inputs, I can guarantee a pointer will never be null simply by increasing a reference count.

It's not necessary, but thought I would ask.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 18, 2018, 12:40:22 am
for me ++++++++++++i;

I my self use `std::unique_ptr` in in my recent refactor of surfaces to enable `std::move`.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 18, 2018, 03:18:56 pm
Ugh, I'm not really happy with the "register callbacks" mechanism. It lacks a certain grace that I usually like my APIs to have, but I simply can't think of a better way to deal with it.

Scenario:

As a mod developer, I want a show, every day in game time, my current funds

Solution:

Using the register callback mechanism, you can specify a lua function to be called. Something like this:

Code: [Select]
function on1Hour(gametime)
  print("Your current funds are " .. tostring(xcom.game.getFunds()))
end

xcom.geoscape.registerOn1HourCallback(on1Hour)

Now, every hour, on the hour, the function will be called. If you try to register more than one function, then it will simply overwrite whatever callback you had previously. Perhaps I should return the previous function? Maybe set it up so there is a has<x>Callback and clear<X>Callback? Hmmm, I'm not sure. I need to get this right because the callbacks are the key to the whole API.
Title: Re: [OXCE+] Lua Integration
Post by: ivandogovich on September 18, 2018, 04:22:33 pm

Scenario:

As a mod developer, I want a show, every day in game time, my current funds
<snip>

Or just go with the option built into the game engine currently. ;)
(https://i.imgur.com/BsnNqqf.png)

(https://i.imgur.com/hmB5gnF.png)

and Yeah, I know you were just giving an example, just pointing out that in this instance, its already there.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 18, 2018, 04:49:49 pm
and Yeah, I know you were just giving an example, just pointing out that in this instance, its already there.

The point was not to showcase new features, but how I go about building the API functions.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 18, 2018, 08:09:52 pm
In my version I solve this as:
- You only add callbacks (no remove)
- Each callback have floating point "index"
- Callbacks are call in order of index

After load index can be drop as only relative order is important. Float vales are for finding unique position between two other events.
Another thing is that in my version I have global and local scripts. Local mean that it belong to some game object and global are shared between all objects of same type. At index `0.00` local script is called that is unique for each object, if some global script have `-1` index it will be call before local, for `1` it will be call after.

Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 18, 2018, 08:43:29 pm
So far all events I have planned are global events. I can see circumstances where you want to "only run this function on this particular instance of an object" , but that would be too intrusive for a first pass API. I'd have to go in and modify every spot where an instance of an object is created and either do multi-inheritance to a common base class which holds the necessary functions to allow binding functions to that instance, or I'd have to do some other method of allowing local instance callbacks which would touch more files than I would like to at the moment.

I think for the first version I will only have global events. Things like xcom.geoscape.register5SecCallback, xcom.battlescape.registerTurnBegin and even xcom.geoscape.registerUpdateCallback for those needing frame to frame updates. For other things, like xcom.soldier.get(soldier).registerDamageCallback(), I don't think the initial API will handle it like that. Instead, you could have something like xcom.soldier.registerDamageCallback() which takes a function that has a parameter for which soldier was damaged. It covers the same use case, but perhaps not as cleanly because you'd get that callback for EVERY soldier that receives damage instead of one specific soldier.

has<x>Callback and clear<x>Callback appear to be okay, so I'll move forward with that idea for now.

I'm still toying with ideas on how to architect the API that is less intrusive on the engine, yet allows controlling as much of the underlying data as possible.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 18, 2018, 08:50:32 pm
One detail, in my version scripts are per armor not per battle unit/solder. Overall I think mods should live in "Mod" folder and modify things from "SaveGame" folder.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 18, 2018, 10:23:20 pm
I'm loosely shaping the API by the save game structure, so the xcom.soldiers api is a bad example(cause soldiers could be in a craft, in a base items list, in transfer, or on the battlescape somewhere.)

But yeah, I see your point

--- posts merged, please don't double-post ---

Updated OP with more details on progress
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 19, 2018, 08:55:37 pm
Would be possible to get ride of `getGameFromLuaState` and use some kind of `this` pointer?

Code: [Select]
    if(lua_isuserdata(luaState, -1))
    {
        game = *static_cast<Game**>(lua_touserdata(luaState, -1));
    }
What if someone replace `Game` in that global variable? I think only way it could work properly is have only one type available in user data.
Some thing like this:
Code: [Select]
class DataPtr
{
    int _tag;
    void* _ptr;
public:
    template<typename T>
    T* Get()
    {
        return isType<T>(_tag) ? static_cast<T*>(_ptr) : nullptr;
    }
    template<typename T>
    const T* Get<const T>()
    {
        return isType<T>(_tag) ||  isType<const T>(_tag) ? static_cast<const T*>(_ptr) : nullptr;
    }

    static DataPtr GetPointer(lua_State* luaState)
    {
        if(lua_isuserdata(luaState, -1))
        {
            return *static_cast<DataPtr*>(lua_touserdata(luaState, -1));
        }
        else
        {
            return DataPtr{};
        }
    }
}
And `GetPointer` will be only way to get OXCE data from lua. This will allow checking for correct type and even allow encoding const in typeless language.
I used similar trick in my script engine.

Another thing is existing of `lua_gameGetFunds` and `execute1HourCallbacks`, in both cases it should be generic function that is responsible for boilerplate.
You can compare it to `ScriptBind.h` that I used for this. In best case I could add `so.add<&getRankScript>("getRank");` that convert normal C++ member function to special function that obey my "calling convention".
With this and `Get<T>` you can build one generic function that will convert and check prams before there are send to original C++ function.
Similar case when you call Lua scripts.

[ps]
one picnicking: OXC use tab for indents and it would be good to stick to it.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 19, 2018, 10:06:00 pm
Would be possible to get ride of `getGameFromLuaState` and use some kind of `this` pointer?

What if someone replace `Game` in that global variable? I think only way it could work properly is have only one type available in user data.
Some thing like this:

And `GetPointer` will be only way to get OXCE data from lua. This will allow checking for correct type and even allow encoding const in typeless language.
I used similar trick in my script engine.

Well, firstly, I'll be moving "xcom.__self"(the game pointer) to private metadata ASAP(or stick it directly in the registry, a hidden area accessible only to C/C++). Once I do that, I can set the access patterns(making it protected, hidden, and read only - http://lua-users.org/wiki/MetatableEvents), but I just wanted to play around with it and make sure I set it up correctly, so leaving it public for now just allows me to see it. At this moment, it's the only user object I plan on implementing, but once I get to the point where we are implementing local callbacks for objects, then yeah, I'll need to be more careful.   

There is no concept of "this" in Lua. Everything is done on a stack, so while it would be possible to create userdata objects in every metatable for use as an object pointer in C/C++, that is a lot of objects I don't think are necessary at the moment.

Also, the type is stored in the metatable(referenced as "Game") so there is type checking already available by using luaL_checkudata, but for brevity sake, just getting things in and testable is my first goal. Using a wrapper class is a bit extreme for now, but I will likely move to that eventually. Using luaL_checkudata is much better since it is already built in to Lua, just didn't spend the 2 secs to put that in. I'll do that now.

Another thing is existing of `lua_gameGetFunds` and `execute1HourCallbacks`, in both cases it should be generic function that is responsible for boilerplate.
You can compare it to `ScriptBind.h` that I used for this. In best case I could add `so.add<&getRankScript>("getRank");` that convert normal C++ member function to special function that obey my "calling convention".
With this and `Get<T>` you can build one generic function that will convert and check prams before there are send to original C++ function.
Similar case when you call Lua scripts.

Oh, that's exactly where I am going with this, but one thing I know about playing with templates is you ALWAYS want to have a working non-template version before you start wrapping things in nested template classes to make debugging and diagnosing issues easier. Today was hectic at work so I didn't get the chance to start the work on moving over to making it more generic and adding in the required templates. I do plan on showing off a little and using the variadic templates to allow for multiple parameter passing to script execute functions :P

[ps]
one picnicking: OXC use tab for indents and it would be good to stick to it.

Yeah, problem is when I switch from my laptop to desktop they both have different settings which aren't synced at the moment. I'll switch it to tabs for the next checkin :D

--- posts merged, please don't double-post ---

Sorry about that. I'll edit existing posts in cases where I was the last post :D

Yankes, I just saw the github comments. Just FYI that all github emails go to my spam folder.

To answer your question on github, yes, scripts are only ever loaded and executed once during game load. Their context is persisted though, which means that they have to register callbacks or else no part of the script will be run again, as such, yes, they are loaded from disk every time they are run, but they are only ever run once as a normal script. That was/is intentional.
Title: Re: [OXCE+] Lua Integration
Post by: Yankes on September 19, 2018, 11:03:23 pm
Ok, I thought that event binding will be in yaml/c++,

And for "this", I recall (from some minor WoW Lua tweaks) that you call call some function that will pass object as one of arguments, syntax was probably `a:func()` or something. This call effective `func(a)`aka "this" pointer. Idea was that getting `game` through arguments will be faster than grabbing it from global context.
Of corse this whole could be wrong because I misremember some import details.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 19, 2018, 11:26:42 pm
Yeah, event binding needs to be done in Lua to get the pre-indexed function ref. Also allows you to reference nested functions inside tables without the need for writing a function string to lua function ref, err, function.

Basically, if you did the function binding in rules, then I would have to parse out the function name. If the function name was global, like "on1Hour" was in the example, then it's easy, but if the function sits withing an object, then it would need to know what was on the stack prior, so something like "MyTable.on1Hour" would be possible, and "MyTable:on1Hour" would need to be handled as a special case. I'm lazy, so I didn't want to do that :D

On that topic, the call to get the game pointer as it is is slightly more expensive than using a function metamethod table. I might move that direction in a future revision, but having one, and only one userdata object in the xcom table made sense when I first started this. In fact, now that I think about it a little more, with the recent change where I split out the LuaGeoscapeBinding class, I might as well create a LuaGeoscapeApi class and use that for the metamethod table and store the game object there.

Edit: but it's not an optimisation, so much as it is cleaner for the API user
Title: Re: [OXCE+] Lua Integration
Post by: Valmont on September 22, 2018, 06:02:07 pm
I hope that one day this Lua Integration could be used by modders to add multiplayer to OPEN X-COM in a similar way that Multi Theft Auto adds multiplayer to GTA San Andreas. That would make my life finally complete and I will be able to die in peace =)
Title: Re: [OXCE+] Lua Integration
Post by: Meridian on September 22, 2018, 06:07:56 pm
I hope that one day this Lua Integration could be used by modders to add multiplayer to OPEN X-COM in a similar way that Multi Theft Auto adds multiplayer to GTA San Andreas. That would make my life finally complete and I will be able to die in peace =)

@Whispers: called it

Also, please be careful with such words... our modders are not developers (with a few exceptions)... and they will believe you when you say they will be able to do "anything they want"... which is just unfair to them. E.g. I'm pretty sure Hobbes will not be able to "script" an online multi-player support, which he wants so much.
Title: Re: [OXCE+] Lua Integration
Post by: Hobbes on September 24, 2018, 10:39:48 pm
E.g. I'm pretty sure Hobbes will not be able to "script" an online multi-player support, which he wants so much.

I better start by clarifying this: it's not in my plans to have online multi-player added to OXC

I love talking about UFO2000 because it was the xcom community where I really started modding terrains, and it was very fun to play against human opponents, but I also remember the endless synchronization bugs between players and how limited it was to only being able to mod the tactical part.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 25, 2018, 11:59:07 pm
Well, I would love to continue the neural network discussion, but today I'm back at my normal keyboard and so I've begun the process of making the interfaces generic and adding in a TON of hooks.

As for the next steps, I want to see if I can get some basic geoscape coverage of events. This includes the usual, onUpdate, on1Hour, on1Day, etc, but also events when the aliens decide to do things(onAlienBaseCreated, onSubMissionStarted, etc) and basic detection (onCraftDetected, onActivityDetected, onTerrorDetected, etc). I'm trying to find ways to make it so that it's possible to override default behaviour so you can skip the popups that come up in a mod.

For instance, I made a quick script today that automatically finds the nearest base for when an alien craft is detected, and if the sub has weapons, has fuel, and isn't damaged, it sorts all subs matching the criteria and selects the one with the highest damage per second. It then allows me to add a button to the detection screen to auto-deploy the craft. That last part I'm still working on.
Title: Re: [OXCE+] Lua Integration
Post by: Hobbes on September 26, 2018, 03:52:28 am
As for the next steps, I want to see if I can get some basic geoscape coverage of events. This includes the usual, onUpdate, on1Hour, on1Day, etc, but also events when the aliens decide to do things(onAlienBaseCreated, onSubMissionStarted, etc) and basic detection (onCraftDetected, onActivityDetected, onTerrorDetected, etc). I'm trying to find ways to make it so that it's possible to override default behaviour so you can skip the popups that come up in a mod.

I've been thinking since we last discussed somewhere possibilities for the Geoscape and one simple graphical addition I've remembered would be to display infiltrated countries with a different color outline. Or when those countries see UFO activity on their borders, which would make it easier to for the player to spot them than having to constantly check the Graphs. And, from there add a 'contested' outline, for when a country sees both alien and XCom activities on their borders.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on September 26, 2018, 10:25:18 pm
That is definitely within the scope of the Lua work. You will be able to read and write the region data, so it's simply a matter of setting the colour of a region and then capturing when a craft is launched and changing the behaviour via overrides.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on October 05, 2018, 10:56:38 pm
Just figured I would give an update since I've been silent for the last week. My day job has been rather demanding recently, but I haven't given up on the Lua integration. I will keep you posted once the new version is up on GitHub.
Title: Re: [OXCE+] Lua Integration
Post by: Whispers on November 06, 2018, 11:03:42 pm
Another update - I'm back!!! Okay, so my real job significantly took up more time than I had planned for, but that is the nature of game development. no, for the record, I had nothing to do with Red Dead Redemption so don't ask :P

New geoscape bindings are pushed up to github. I'm still playing with the API a bit more, so the usual preamble of future changes may break compatibility applies :)