Closed ivan-mogilko closed 1 month ago
I stopped liking my initial idea. Perhaps saving script's name along with the function name for event would be a smarter approach. This may be done both in the Editor and compiled game.
Uhm, I know we are currently limited to 128 modules but if we readjust the assembly it's easy to go for something like 32768, so if the Character or GUI or whatever had a property to set the script they link to, they could even have their own dedicated scripts - like say a save/load GUI that you would export with the script.
I am imagining here how it works in game maker where each element gets it's own script file - not sure on going that far, as this seems more useful for something like prefabs that you instantiate in multiple places, so this is why I thought about a property. I imagine people would maybe have a script for handling all their items or perhaps they would divide them by game area - would this make more sense for adventure games?
Perhaps asking in the forums about this, someone could give additional ideas.
Okay, I managed to do something interesting. I put the property, but not in the object itself, but inside a Interactions class, and made it displayed on Events tab, closer to events themselves, for convenience.
Furthermore, this property displays a automatically refreshed selection of script modules for global objects, and a fixed room script for room contents.
This is how it looks like:
There are still few things not working as expected, for instance, I found that GUIs use different tab class to display their events, which unfortunately does not share any common base class with object interactions... so they do not work yet. Another thing is that this module selection is used only by the Editor right now. I was thinking that it's possible to avoid saving this property in the compiled game, and instead prepend module name as a prefix to the function name (i.e. something like module.asc::functioname
), then it could all be written into existing fields; the downside being be duplicate prefix for all interactions. But this is still something to think about.
Your solution to the UI looks great, and it does look better having the field right there in the events tab! It feels intuitive. :)
The project upgrade approach here would be to fill all of these with GlobalScript.asc, right?
I was thinking that it's possible to avoid saving this property in the compiled game
Uhm, right, going this route only thing I think would be to confirm that these event function name entries support variable length strings as entries - thinking that the function name may be slightly bigger with the added file name.
Added ScriptModule property for GUIs. Controls use their parent GUI's setting.
The PR is complete for testing.
Midway I changed my mind about saving module's name in compiled game. At first I wanted to concatenate it with the event function names for simplicity, but then realized that this may lead to extensive data duplication for no real gain. Plus, this is not required for room interactions. So I added "ScriptModule" field to InteractionEvents list and - separately - GUI class. This mirrors the changes in the Editor and project data, so is also consistent in my view.
There's another thing: previously I thought that this structure may come handy if we support delegates, but later realized that is not likely to be a thing, because for the "function pointers" assigned at runtime we will need a different kind of data for quicker calls. In fact, we may do the same to these events too. The existing "InteractionEvents" lists may serve as a loaded data, which may be resolved to script function addresses after everything is loaded and scripts initialized. Well, this is all a future matter, but the point is that there's probably no need to plan existing structs for use as "function pointers" at the moment...
Anyway, this rambling aside, current PR now amends the compiled game format with a new extension, but it does not amend compiled room format, since room interactions don't need any new data.
Fix #485
When running a global object's interaction function, the engine will search in all modules in their order, until it finds a matching function. Only the first found callback is run, the others (if any exist) are skipped.
There's still a question of how to handle this in the Editor. I can try to make Editor jump to the correct place when user presses "..." button in events table with existing function. But all the new functions will be still generated in GlobalScript. I cannot see any easy way to reconfigure this.
EDIT: Hmm, here's what I may try: