RMMZ Is there a way for a method to continuously run without needing a window object?

Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
113
Reaction score
148
First Language
English
Primarily Uses
RMMZ
I'm working on a game clock and the problem is that I'm having to rely on an "invisible"(no width/height and is closed for all eternity) window in order to use the update so that my clock method(the one that does the time calculations, not the actual clock display which uses a visible window) is constantly running whenever the player's scene is Scene_Map. While this would do what I want, it's not what I consider a proper solution to the problem.

So what I'm aiming for is this:

  1. backgroundClock() starts running when current scene is Scene_Map as it's the most common scene.
  2. backgroundClock() stops when current scene is anything else.
  3. backgroundClock() is not relying on xxx.prototype.update and the call to Window_Base.prototype.update
Or is the current solution actually an ok route?

Also my game clock is intended to function similar to Skyrim's game clock, where it runs whenever the player isn't in any menu.
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,045
Reaction score
2,358
First Language
EN
Primarily Uses
RMMZ
Roughly speaking:
  • The browser signals the start of each frame to the SceneManager.
  • The SceneManager invokes the current scene's update method each frame.
  • When it updates, the scene also updates each of its child elements: sprites, game windows, etc.
  • Each of those elements update their own attributes/appearance.
So no: if you don't need a window, just move one step up the chain. Consider hooking into the scene's update method instead, e.g.
JavaScript:
(function(alias) {
  Scene_Map.prototype.update = function() {
    alias.apply(this, arguments);  // invoke original method
    // your update code here
  };
})(Scene_Map.prototype.update);
 

Nolonar

Veteran
Veteran
Joined
Feb 18, 2018
Messages
334
Reaction score
458
First Language
French, German
Primarily Uses
RMMZ
Alternatively, you can just do the following:

JavaScript:
function updateBackgroundClock(deltaMs) {
    requestAnimationFrame(updateBackgroundClock);

    // do your stuff
}

updateBackgroundClock(0);

This will call the updateBackgroundClock() function on every browser frame update (this is dependent on your screen refresh rate; it will run 60 times per second on a 60 Hz screen, 120 times per second on a 120 Hz screen, etc.). The deltaMs variable will tell you how much time has passed since the last frame update.

However, running your code on each frame might be a bit overkill for a background clock. It makes sense for the visible clock, but since it's already got a window, it can just use its update() function instead.

For the background clock, consider executing your code only where necessary. For example:

backgroundClock() starts running when current scene is Scene_Map as it's the most common scene.

You could hook into Scene_Map.prototype.start(), and remember the current timestamp using Date.now(), which returns the number of milliseconds since 1970-01-01 00:00:00.000 UTC time. You can then use that timestamp to calculate how much time has passed since the map started.

For example, your background clock could have the function:
JavaScript:
this.getPlayTimeMs = () => Date.now() - this.startTime;
which will calculate the amount of time (in milliseconds) that has passed while the player was on the map. This can be used to calculate the ingame time, if necessary. For example, if 1 real second represents 1 ingame minute:
JavaScript:
this.getIngameTimeMinute = () => this.getPlayTimeMs() / 1000;
which will tell you how many minutes have passed ingame.

backgroundClock() stops when current scene is anything else.

Similarly, hook into Scene_Map.prototype.stop() to remember how much time has elapsed since the start. For example:
JavaScript:
this.elapsed = this.getPlayTimeMs();

Next time the map starts, you can use this.elapsed to set your new startTime:
JavaScript:
this.startTime = Date.now() - this.elapsed;

You might also want to set something like this.isClockRunning = false; so you know the background clock is supposed to be disabled (remember to set this.isClockRunning = true; when the map starts). This will be useful in cases where the player saves the game, and you want to automatically update this.elapsed before the game saves. If this.isClockRunning is false, you know that this.elapsed is already up to date.
 

Latest Profile Posts

Been playing through Skies of Arcadia again, and it really makes me wanna see someone try to implement how ship battles were done in the game into RPG Maker (or really just in general).
split.png
split view of both versions of the pocket city you traverse through. there's differences like areas only being accessible in one version of Autumn Bay. or events that only happen in one or the other.
theortically if there were a developer who spied on people's game playthroughs and changed things in real time to make it harder for them, what might be said game developer's motivation?
Hi everyone! Enjoying this nice long weekend. How are you all doing? :)
I just successfully tested having events check if specific actors are in a particular party slot and then changing image to match. This will let me make scenes take into account who is in the party at the time and arrange them accordingly - this is important since I'll have extra actors beyond current party. The script used is the same from MV and is compatible with my current core plugin setup in MZ. Thank goodness.

Forum statistics

Threads
118,435
Messages
1,115,942
Members
155,392
Latest member
otarianny
Top