Posts: 45
Threads: 13
Joined: Apr 2016
Hello everyone,
I was just wondering if there is a way, a script or separate software that you know, that would measure other scripts computer resources consumption (processing power, memory, graphics processing etc.) or just indicate what script or which part of the code is the "heaviest" at the moment. I have very basic knowledge about coding and I'm unable to figure it out myself.
Long story short - if something is making my game lag, I would like to know what, so I can try to improve it.
Pleeeeeease, no ignorant comments like "if you inserted a new script and it started to lag, its probably this script". I'm not stupid and it really draining my patience when I get comments that only goal is to irritate me
I'm using RPG Maker XP, Windows 11, my game uses 60+ extra scripts; making this game is just my hobby
Posts: 4,606
Threads: 543
Joined: Dec 2009
05-27-2023, 01:59 AM
(This post was last modified: 05-27-2023, 02:02 AM by kyonides.
Edit Reason: another detail
)
First of all, we still ignore what those 60+ scripts actually are. Some of them might be well known for being actual resource hogs but we can't tell you about it if we don't get their names first.
One of the things that can create lag on any map are hundreds of events being placed there, and it only gets worse if they're created on the fly. Any other feature related to events might also cause the lag, I mean, like adding a new sprite or bitmap to the player and the existing events, especially if the total number of events are over 100...
Other stuff like custom weather effects that keep creating new bitmaps like crazy could also make your game run slow. The default script should NOT be able to make your game get to that point, anyway.
What about battles? What have you experienced so far while fighting the enemy troops? What BS are you using?
Loops that have bad conditions that don't break them soon enough could also be a possible root cause. There are for and each loops. times loops are limited by nature so they couldn't become the culprit at all.
There are times when it's the BGM or BGS the one causing the issues, at least for a while because they're not preloaded but loaded on demand.
Again, we do need a lot more information to be able to help you properly, Whisper.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
My Original Stories (available in English and Spanish)
List of Compiled Binary Executables I have published...
HiddenChest & Roole
Give me a free copy of your completed game if you include at least 3 of my scripts!
Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Posts: 11,228
Threads: 648
Joined: May 2009
05-27-2023, 04:52 AM
(This post was last modified: 05-27-2023, 04:59 AM by DerVVulfman.)
There is no script per-say to rate others. The issue with game lag, how fast maps and systems update, cannot be traced by a single script or tool. It would require the script/tool to be able to go through the Script Database (or Scripts.rxdata) file and watch every instance of the Graphics.Update system being slowed down... and by which script and what is preventing. That is likely not going to happen.
However, knowing the scripts themselves helps.
HUD scripts, if well written, offer little lag. They would have timers to only test for changes in displayed data every 1/2 a second, second or whatnot. If such a HUD doesn't, then it would try to update the display every graphics update and would begin to cause lag.
As Kyonides stated, an extreme number of events may cause lag. However, the use of an anti-lag script tends to reduce that drastically. The premise is that the default map system tests every event on the entire map while an anti-lag system overrides that mechanic.
Knowing is key so... Anti-Lag scripts will instead update only those the events within an area covering the 20x15 tile area the player sees (and maybe a 2-tile buffer around). Some anti-lags even allow custom flags on events to determine if they may update outside the area (like a required parallel process event), or refuse to update graphics updates that slow them down. Events run two processes, graphic updates and map behavioral updates.
Rewrites of the hidden classes, replacing that stored primarily within the RGSSXXXX.dll, tends to slow things down. This especially with rewrites of the hidden Window, Plane or Tilemap classes or the like. Its not just that you are rewriting an existing class, but replacing compiled Ruby code with a scripted Rubyscript code (compiled machine language in the dll is always faster). Ruby and Rubyscript are basically the same, but 'scripting' versions (like javascript instead of java) are slower as they are executed from an outside executable.
Decently written ones may knock down only 1 frame in speed. But it depends on the script, and usage. Of note, Mode7 scripts tends to 'supercede' the Tilemap class by storing the entire map within a bitmap in memory. But then it must deal with the maximum bitmap size for RPGMaker... 500x500 maps exceed that.
Menu systems should 'not' cause lag. However, the Moghunter meuns (PRETTY AS THEY ARE) are a bit slow and laggy. You may have seen I did rewrites to try and cut down lag.
In general, it is a case of how often each script demands graphics to be updated by RPGMaker. If you have a script that changes content within just the Game, that shouldn't lag. If it changes content in the Window classes, it should be made to only refresh window contents when it changes... redrawing takes time. And if it updates the Scene classes, you need limiters there too.
Otherwise, hitting [F2] when running the game from the Editor (aka debug mode) is your only way to see if the framerate decreases.
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)
Above are clickable links
Posts: 937
Threads: 101
Joined: May 2009
One of the most expensive functions in RPG Maker is the Window#draw_text function. Even if a window is not visible, calling these draw commands would still consume resources.
One way to diagnose the problem is figure out which scene (or scenes) have the worse lag. Are you experiencing a slowdown on the map, in battle, or in a specific menu screen? Does this scene have a large window with a lot of things that get redrawn?
Other things to look for...
- Scripts with a bunch of complex math calculations.
- Scripts with a bunch of draw / draw_text functions.
- Scripts that redraw gradient bars constantly.
- Scripts which may be constantly re-sorting an array.
- Two or more scripts which may be contradicting each other's functions.
- Scripts which have recursion issues; do you randomly get Stack Level Too Deep?
If you want to profile a specific block of code you can do...
Code: time = Time.now
# ...The function...
puts("Execution Time: #{Time.now - time}")
...which should tell you how long it takes for a function to complete. Most functions should take fractions of a second. If it takes a half second or longer, you've probably found the culprit (or one of many culprits.)
A HUD is an easy example of a script which can lag if not done correctly. For instance, if the HUD constantly redraws HP and SP (even when those values haven't changed), it will lag. If Hero 1's HP changes, but the entire HUD gets redrawn from that single change, that can cause lag too. Clearing the rect of only the item that needs to be redrawn, and redrawing only that item, is more economical than redrawing everybody's everything because of 1 person's change.
Hope this helps. Best of luck to you.
Posts: 45
Threads: 13
Joined: Apr 2016
05-27-2023, 10:17 PM
(This post was last modified: 05-27-2023, 10:18 PM by Whisper.)
@kyonides @DerVVulfman @Kain Nobel — Wow, you guys are amazing. Thank you for the time you dedicated for these answers. Even, though it won't directly solve my problem, you provided me with valuable advice. I didn't expect such a through answers.
I asked this question after I found that one of my scripts is aliasing 'update' method in 'class Scene_Map' incorrectly, what resulted in "running update within update" and causing horrible lags on the map.
@kyonides — I'm not asking for direct help, you already helped enough. Also, majority of the scrips is modified by me (sometimes heavily), so it wouldn't give you a good idea how much resources these may consume. Battles are pretty smooth, I'm using a variation of RTAB 1.16
@DerVVulfman — yea, HUD script was the one lagging, but fortunately it wasn't large script so I could fix it even with my newbie programming skills. I have one more HUD to review (different, simple HUDs for different situations). I have bad experience with anti-lag scripts, but maybe I will test one in the future. The game is really big and even occasional bugs could give me hundreds of hours of work at this point, so I will try that only if absolutely necessary. Funny that you mentioned that Menu Systems shouldn't lag, because my is lagging, but... I know why and I'm ready for this sacrifice; it imports (or load to memory IDK) all saved games info in order to display it in save/load screen. I really like the possibilities it gives me so I can sacrifice this 1, max 2 second delay (depends how many saved games), when changing scene to menu. If I remember correctly, it was actually you, who helped me implement that, good sir. Thank you for all your help!
@"Kain Nobel" — yea, I noticed that drawing text is pretty 'expensive', when debugging using 'puts' I noticed that many times. I had a few "Stack Level Too Deep" in the past, but I probably fixed these already. Thank you for the idea how to measure certain function; it can actually be very helpful in some situations and I will definitely use it!
Thanks to everyone again! I guess topic can be closed now.
Posts: 4,606
Threads: 543
Joined: Dec 2009
05-27-2023, 10:43 PM
(This post was last modified: 05-27-2023, 10:59 PM by kyonides.
Edit Reason: Rewritten code
)
Since you mentioned a HUD, you might wanna learn how to easily implement a trigger that will properly update the HUD only once instead of every second or even a fraction of a second.
Code: class MyHUD
@@need_refresh = 0
def self.need_refresh
@@need_refresh
end
def self.need_refresh=(number)
@@need_refresh = number
end
def update
if @@need_refresh > 0
refresh
return @@need_refresh = 0
end
end
end
There were have a mock of a HUD, its update method only. (There are 2 other methods but we will ignore them for the time being.)
It will only redraw its contents IF and only IF the @need_refresh variable is equal to any number above 0. Once it got updated, it will set it to 0 so it can't be triggered over and over again.
How would you make sure it will ever update the stats when needed only?
Use something like the following:
Code: class Game_Actor
def hp=(new_hp)
old_hp = self.hp
super(new_hp)
MyHUD.need_refresh = 1 if self.hp != old_hp
end
def sp=(new_sp)
old_sp = self.sp
super(new_sp)
MyHUD.need_refresh = 2 if self.sp != old_sp
end
end
As you can see, we are calling one of the unexplained methods of MyHUD class. It's a singleton method that calls a very specific class variable that can be used at any time, even from another classes or objects, i.e. from an actual Game_Actor alias one of the heroes!
That call will make sure that your HUD will only update itself when and only when the hero's HP or SP (or even both at the same time) activate it right after their values have changed.
By the way, I used a number instead of a boolean (true or false) because this way I do prevent the SP update to cancel an HP update for not having changed simultaneously.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
My Original Stories (available in English and Spanish)
List of Compiled Binary Executables I have published...
HiddenChest & Roole
Give me a free copy of your completed game if you include at least 3 of my scripts!
Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Posts: 45
Threads: 13
Joined: Apr 2016
(05-27-2023, 10:43 PM)kyonides Wrote: Since you mentioned a HUD, you might wanna learn how to easily implement a trigger that will properly update the HUD only once instead of every second or even a fraction of a second.
Code: class MyHUD
@@need_refresh = 0
def self.need_refresh
@@need_refresh
end
def self.need_refresh=(number)
@@need_refresh = number
end
def update
if @@need_refresh > 0
refresh
return @@need_refresh = 0
end
end
end
There were have a mock of a HUD, its update method only. (There are 2 other methods but we will ignore them for the time being.)
It will only redraw its contents IF and only IF the @need_refresh variable is equal to any number above 0. Once it got updated, it will set it to 0 so it can't be triggered over and over again.
How would you make sure it will ever update the stats when needed only?
Use something like the following:
Code: class Game_Actor
def hp=(new_hp)
old_hp = self.hp
super(new_hp)
MyHUD.need_refresh = 1 if self.hp != old_hp
end
def sp=(new_sp)
old_sp = self.sp
super(new_sp)
MyHUD.need_refresh = 2 if self.sp != old_sp
end
end
As you can see, we are calling one of the unexplained methods of MyHUD class. It's a singleton method that calls a very specific class variable that can be used at any time, even from another classes or objects, i.e. from an actual Game_Actor alias one of the heroes!
That call will make sure that your HUD will only update itself when and only when the hero's HP or SP (or even both at the same time) activate it right after their values have changed.
By the way, I used a number instead of a boolean (true or false) because this way I do prevent the SP update to cancel an HP update for not having changed simultaneously.
That may be extremely helpful. I have no time to review it now, but I will do it eventually for sure.
My current HUD doesn't noticeably lag, but if I can make it even more efficient, count me in!
I will make a new post or edit this one once I will finish reviewing my HUD, I would paste it here for you to see, but it's full of my unskilled code, global variables, $game_switches and $game_variables, plus some extra graphical files. I think it would be annoying for you to even try to run it.
People here are really helpful, I'm amazed. One day, hopefully I can return the favor.
|