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

Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
159
Reaction score
256
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,529
Reaction score
2,656
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
389
Reaction score
544
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

Current status screens for Shadows of the Earth: The Vrila'an Legend. Need to do something about the color scheme lol
Captura de pantalla (259).pngCaptura de pantalla (260).png
My first serious victim in game hacking - Pawnbarian.
Diana Path 2.png
I love these two design wise lol... The high school principal and the captain of the women's wrestling team. they team up as bosses to save the school's accreditation.
Kanori24 wrote on TheRamenGirl's profile.
I love your profile pic. Definitely one of my favorite scenes from OPM :D

Forum statistics

Threads
122,074
Messages
1,146,309
Members
160,360
Latest member
bleach
Top