Lua wrapperThis is not very bright feature for users, but for developers it is. Wrapper can provide cleaner code and faster development process. Now, I looking in the direction of sol2 (
GitHub).
Four level abstraction of code executionThis is idea of code hierarchy. Like how in the operating system exist core level and user mode level, in the UniMod will be four levels. But do not be afraid it is not so complicated - there is some logic inside and Lua will do most work.
- C++ level
- Core-script level - scripts that can affect the whole game
- Mod-script level - users scripts
- Map-script level - scripts that affect only the current game on the current map.
Now I will try to explain each level. When it supposed to start and when - turn off.
C++ levelUniMod will use the follow method of loading: there are many dll that Nox load by default. We put one - fake dll in the Nox root folder. This dll will do two things: load UniMod3.dll and original one.
This will enable you to use your favourite Nox executable, of course if it's binary compatible with UniMod (last original update, if I correct remember - 1.2b).
The loading of UniMod3.dll consists of following process:
- Lua initialization.
- Loading configuration from UniModConfig.lua. This file contain values of important flags.
- With respect of setted flags some actions take place. (more about in flags section)
- Core-scripts loading.
Examples of flags:
- DebugMode - allow user to use unsafe functionality (standard debug module). It's necessary for debug purpose. In fact, this mode breaks safe code execution.
- AllowStartMultipleNoxs - allow to start another example of Nox if there is one already.
- EnvhanceConsole - activate enchanted console (in original UniMod were added some features: history and edit opportunity).
- CoreLevelFiles - list of Lua files that will be loaded on the core-script level.
Core-scriptAfter the first stage of initialization (C++ level) done - core-script scripts begin to load.
At this moment, I vaguely imagine what this scripts must do. I think it's part of C++ code that can and must be done in Lua for the purpose of flexibility. It's part of what developers write and configure - not users.
Maybe it's best place for mod loader part of UniMod.
Maybe it's best to form this scripts into modules and distribute like standard library with addition privileges - on that functionality can rely user's mods.
Mod-scriptUser's global mod scripts. It will be loaded after the core-level scripts finish its job. I don't think much about it - because I do not plan to include this feature in the first version of UniMod3.
But Mod-scripts planned as a addition user library for Map-scripts. As an example they may add particular functionality for several maps. Or may be they can... do what you want? It's like core-level but can be disabled and can't break level above.
Map-scriptThis scripts loaded with the concrete map. It's will be supplied with a map in .tar archive like in the original UniMod. When a map changes, or a player exit from game mod - all active scripts and effects that was started on this level will be turn off. All created object - destroyed.
In Lua will be several function that user can apply for initialization: before everything loaded (for way to affect process of loading, for example turn off standard scripts) and after that moment.
Full userdata for every objectEvery object that you retrieved from Nox or created from Lua will be full userdata with it's own type. This will allow next advantages:
- Function that operate on an object can be implemented as object's methods (through Lua operator colon - ":").
- There will be no problems with "hanged" light userdata. If object deleted - its userdata will know about it.
- We can tight the Lua object and the Nox object not only in direction from Nox to Lua but in reversed too. More in the Event System section.
- Different types of object will offer different sets of methods. Like laser century can have method "setSpeed", or wizards and conjurers - "setMana".
Event systemIn the original UniMod there was opportunity to execute scripts regarding to time, or when certain monster dies, but that was completely unmanageable. I even don't remember was it possible to set off timer or not (it was possible to break timer loop). Not speaking about that, setting script on monster death not allow you to control when original function called.
The new event system will be salvation. Every such event (timer expire or monsters dies) will be represented with handle object. Through this object you can control event. Turn it off or somewhat else. Nice bonus, that if you delete this object, and it will be garbage collected - it's possible to make that corresponding script will never be called.
Lua scope - main security toolBy default if Lua debug feature is disabled then there is no way out of your environment table. We can use it to easily set up the code sand-boxing explained above!
Consider the following example for map-script level.
For the current loading map Lua table created. In that table all necessary function loaded (or they will be available through meta-method _index). Remember that there is no way for a user go beyond this table - she forced to save her objects in this table or in tables that original table contains (difficult moment here - we must guarantee that it is only place where strong references to object is). As soon as map destructed - we delete map table and ask to garbage collector do it's job. After that map can't leave any effect on other game in context of UniMod.
We can implement sand-boxing through Lua standard mechanisms. In fact this was intended by Lua developers.
DocumentationOriginal UniMod have a very very poor documentation. There was uncountable undocumented features. And it's not only about the user interface but about sources too.
Shhh! I didn't said this to my Russian fellows, but documentation must be in English...