mkxp-z / mkxp-z

Open-source cross-platform player for (some) RPG Maker XP / VX / VX Ace games. A very heavily modified fork of mkxp. RGSS on steroids with a stupid name.
https://github.com/mkxp-z/mkxp-z/wiki
GNU General Public License v2.0
140 stars 39 forks source link

Postload Scripts #158

Open Nathan-MV opened 5 months ago

Nathan-MV commented 5 months ago

Scripts that load before rgss_main

WaywardHeart commented 5 months ago

Joiplay calls this functionality postload scripts. The way they decide when to run them looks a little error prone to me, but it'd be a good starting point if you wanted to expand this to work for XP and VX.

You should also note in the config file that it's only for Ace games, unless you manage to fix that.

Splendide-Imaginarius commented 5 months ago

Joiplay calls this functionality postload scripts.

Alright then, if Joiplay did it first, I guess we should use the name they picked so that we don't cause unnecessary fragmentation. It's not a bad name either.

Splendide-Imaginarius commented 5 months ago

The way they decide when to run them looks a little error prone to me, but it'd be a good starting point if you wanted to expand this to work for XP and VX.

I'm not going to block this PR on XP/VX compatibility, but I would definitely be amenable to merging a follow-up PR that adds support for those. The Joiplay logic you linked looks rather scary; I'm guessing there's a less crazy way to do it, but maybe they know something I don't.

Splendide-Imaginarius commented 5 months ago

You should also note in the config file that it's only for Ace games, unless you manage to fix that.

Yes please note this.

WaywardHeart commented 5 months ago

The Joiplay logic you linked looks rather scary; I'm guessing there's a less crazy way to do it, but maybe they know something I don't.

$scene appears to simply be an instance of a game-defined class with a main method on it, so... I think the only "good" way of hooking it is to monkey patch the base class constructor. Here's an example written in ruby, because it was easier.

Postload scripts monkey patch for XP/VX ``` postloadScriptsRan = false baseClassNew = Class.instance_method(:new) mainWrapperModule = Module.new mainWrapperModule.send(:define_method, :main) {|*args, &block| if (!postloadScriptsRan && $scene.equal?(self)) postloadScriptsRan = true mainWrapperModule.send(:remove_method, :main) # Comment this out if you're concerned about some other maniac messing with # the Class#new method Class.send(:define_method, :new, baseClassNew) System.run_postload end return super(*args, &block) } Class.send(:define_method, :new) {|*args, &block| ret = baseClassNew.bind(self).call(*args, &block) if (!postloadScriptsRan && self.method_defined?(:main)) ret.singleton_class.send(:include, mainWrapperModule) end return ret } ```