VladimirMakeev / D2ModdingToolset

Mss32 proxy DLL for Disciples 2
GNU General Public License v3.0
32 stars 13 forks source link

Information on what is this project about, and how to write scripts #163

Closed soanvig closed 1 year ago

soanvig commented 1 year ago

I'm really impressed by what is happening in this repository, and I will keep an eye on it, and eventually help with some things.

It stands for modding toolset, but currently it looks like a script loader, which is fine, but what is a "script"? What are script's capabilities? Is the script name connected somehow to its content, or is it irrelevant?

I looked through scripts directory, and I see some functions, and the implementation is clear, but when and by what they are called? Are scripts self-sufficient or the actual triggers etc are contained in some other directories in the project?

Some big-picture of all of that could actually ease contribution.

VladimirMakeev commented 1 year ago

This project is about modding toolset for a Disciples 2: Rise of the Elves game, v 3.01. Modding toolset is a collection of various tools that helps game modders to easily extend game mechanics. Some of the tools are made through Lua scripts, others are simple settings in the configuration file. It means that the main audience of this project are game modders and people interested in Disciples 2 game engine and its logic. There is no much to see for an ordinary player.

As for the scripts, they all can be placed in several categories:

Scripting api is the same for all script categories. What script writer can use completely depends on input parameters of script callback functions. For example, battle state exists only during a battle, therefore callbacks in attack ranges scripts have such parameter, while scripts for event conditions are called outside of a battle and are unable to access battle representation.

Check the readme, though it's a bit long a boring, but I hope you will find even more answers.

VladimirMakeev commented 1 year ago

You should also check api documentation in luaApi.md file. It describes entities of the game that are accessible and shows couple of examples for each script category mentioned previously by me.

soanvig commented 1 year ago

Thank you a lot. But Lua/scripts are only "scripting" layer. What about logic that allows the scripting to happen at all (I see some C++ code)? You wrote " There scripts are also called from the game engine", yeah, but game engine natively supports such things, or does it require some injection?

Maybe I'm just a noob when it comes to hacking the game to allow modding, but big-picture of architecture how everything is connected with each other (and how it works under the hood) would be interesting.

I'm not asking to write anything like that, just dropping thoughts on interesting project.

VladimirMakeev commented 1 year ago

This project mostly consists of c++ code. The scripting used only for users convenience - each mod author can customize game mechanics (to some degree) as they wish without c++ knowledge. The project itself is a proxy dll, so all the c++ part is compiled into single file named mss32.dll. This name is intentional - its the same name as one of the original game libraries. By doing so we can trick game to load our logic by only replacing dll file. Original dll's logic (original mss32 is used for music in the game) is reused - thats why original dll needs to be renamed to mss23, as described in readme. Game engine logic is reverse-engineered using tools like IDA. Classes and data structures as well as functions that is useful were described in this repo for easier interaction and integration into the game. Stuff that is not useful is not included in the repo, so please don't expect to see full game engine source code here. To put it simple:

  1. Player runs game exe file as usual
  2. Game loads mss32.dll thinking it is original dll for sounds and music
  3. Our dll gets called from DllMain.
  4. Our logic sets up the hooks - it rewrites assembly instructions of game engine function calls inside memory of a running process. This allows us to substitute game function original logic with our own. The only trick here - original and our functions must have the same signatures. All hooking and assembly tricks within process memory is done by Detours library. List of hooks can be found in hooks.cpp.
  5. Lua api is implemented by using 'vanilla' Lua VM v 5.4.1 and c++ <-> Lua wrappers/interop library sol2. Reverse-engineered data structures and functions are bound to Lua api function calls. This way we save time by reusing game engine logic without reimplementing them.
soanvig commented 1 year ago

Awesome, that closes the topic. I find it useful though, maybe it can be put in some docs then. Have a great day!