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

Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
222
Reaction score
329
First Language
----
Primarily Uses
N/A
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
4,505
Reaction score
3,545
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
504
Reaction score
707
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 Threads

Latest Posts

Latest Profile Posts

What if the Actor Battlers disappeared when your selecting enemies...
ndyhHXV.gif
So, last chance to get RPG Maker Fes games?
That moment when you significantly rewrite about 80% of a course, reduce it from 12 hours to 8, drastically refocus the content, provide several overview briefings to staff on the changes, giving them several weeks to prepare, & they start asking questions 10 minutes before the classes start. I have a bad feeling. :oops:
Forgot to add this to my stream thumbnail collection, nothing to see here. Move along. :kaoswt:

It's been a while again, eh.

Forum statistics

Threads
129,956
Messages
1,206,535
Members
171,175
Latest member
CallyLee
Top