chris-cote

Villager
Member
Joined
Aug 11, 2023
Messages
19
Reaction score
2
First Language
English
Primarily Uses
RMMZ
There seems to have been a lot of discussion about RPG Maker MV's jitter issues relating to frame updates. There were a few plugins made (both for frame updates and pixel rounding), but there is almost no discussion regarding these issues for MZ.

The problems still exist (see my thread here), and they can be major deal-breakers for lower-res games that really show a 1 pixel frame update lag when things fall out of sync.

This is a plugin from MV which addressed this issue.

Would anyone out there be interested in tackling this? This is a problem that affects anyone doing parallax mapping (either natively or with plugins), so it would help a lot of users.

Thanks for your time!
 

JorgeMaker

Regular
Regular
Joined
Jan 14, 2020
Messages
71
Reaction score
62
First Language
Português - BR
Primarily Uses
RMMZ
Looking at the video in your thread, I don't think it has anything to do with the frame update function.
It also doesn't seem to me to be a native MZ problem, since by default there is no smooth displacement in the camera, which must be provided by some plugin, which is usually what causes or accentuates this type of problem.
Let me know if the problem is attenuated or totally fixed by removing the camera plugin, so that we can be sure of the origin of the problem.
 

chris-cote

Villager
Member
Joined
Aug 11, 2023
Messages
19
Reaction score
2
First Language
English
Primarily Uses
RMMZ
Looking at the video in your thread, I don't think it has anything to do with the frame update function.
It also doesn't seem to me to be a native MZ problem, since by default there is no smooth displacement in the camera, which must be provided by some plugin, which is usually what causes or accentuates this type of problem.
Let me know if the problem is attenuated or totally fixed by removing the camera plugin, so that we can be sure of the origin of the problem.
The problem is there (and just as bad) without the camera plugin.

I actually don't normally use a camera plugin, I just added it for the sake of showing the issue more prominently.

This issue persists with nearly no plugins. If I set a parallax natively ( a "!" map-locked parallax in the map settings) and use a 16x16 tile size and add any zoom plugin to crop the image in (as is necessary for a 16x16 game), this issue will always happen. This happens even when trying a few different map zoom plugins (I mainly use MultiTweaks for this).

This issue also persists when using a 32x32 tile size and using less zoom. As long as a one-pixel inconsistency is noticeable, it is there.

using a parallax mapping plugin (I use GALV's) will still have this issue, but the offset is usually different (as seen in the demo video, which has native parallaxing, a GALV's layer for the treetops etc., and some events). All 3 update differently.
 

JorgeMaker

Regular
Regular
Joined
Jan 14, 2020
Messages
71
Reaction score
62
First Language
Português - BR
Primarily Uses
RMMZ
I developed some low resolution game prototypes similar to 2K3 (320x240) on MZ and had no issues with jitter. But I also never used parallax and I use my own camera plugin.
Tell me, does the problem only happen when using parallax or when using the zoom plugin or both together?
If it's the zoom plugin causing the problem, you can simply discard it and scale the canvas instead (System 2/Advanced Settings/Screen Scale).
 
Last edited:

Choraß

Indie Dev
Regular
Joined
Apr 13, 2015
Messages
97
Reaction score
33
First Language
German
Primarily Uses
RMMZ
@chris-cote
If you exactly mean this issue which mentions there, it have also a plugin to fix this. For me it's also fixed it in MZ.

 

chris-cote

Villager
Member
Joined
Aug 11, 2023
Messages
19
Reaction score
2
First Language
English
Primarily Uses
RMMZ
I developed some low resolution game prototypes similar to 2K3 (320x240) on MZ and had no issues with jitter. But I also never used parallax and I use my own camera plugin.
Tell me, does the problem only happen when using parallax or when using the zoom plugin or both together?
If it's the zoom plugin causing the problem, you can simply discard it and scale the canvas instead (System 2/Advanced Settings/Screen Scale).
For me, Screen Scale does nothing, which is the only reason I am using zoom plugins. Even with no plugins enabled at all, changing Screen Scale from 1 to a higher number doesn't change anything. I need to scale my screen 3x, but setting it to 3 has no effect.

It only happens with Parallax. Just events on a tilemap do not jitter, and native parallax vs plugin parallax jitter at different rates.

@chris-cote
If you exactly mean this issue which mentions there, it have also a plugin to fix this. For me it's also fixed it in MZ.

This is very interesting. I gave it a go with Fossil, and it does indeed fix the jitter for events. However, it causes the screen to stutter when moving quickly, and causes the character sprite to jitter when moving quickly. It sort of inverts the problem.
 

JorgeMaker

Regular
Regular
Joined
Jan 14, 2020
Messages
71
Reaction score
62
First Language
Português - BR
Primarily Uses
RMMZ
For me, Screen Scale does nothing, which is the only reason I am using zoom plugins. Even with no plugins enabled at all, changing Screen Scale from 1 to a higher number doesn't change anything. I need to scale my screen 3x, but setting it to 3 has no effect.

It only happens with Parallax. Just events on a tilemap do not jitter, and native parallax vs plugin parallax jitter at different rates.
You're probably using an older version of MZ Corescript. The Screen Scale option was only properly implemented later.
To update the Corescript, go to the MZ toolbar and: Game/Update Corescript. Make sure you have a backup in case the process breaks something.
 

chris-cote

Villager
Member
Joined
Aug 11, 2023
Messages
19
Reaction score
2
First Language
English
Primarily Uses
RMMZ
You're probably using an older version of MZ Corescript. The Screen Scale option was only properly implemented later.
To update the Corescript, go to the MZ toolbar and: Game/Update Corescript. Make sure you have a backup in case the process breaks something.
I'm on v1.7.0, and there is no option to update to any newer version. I only just installed recently, so I imagine I am on the latest version.
 

JorgeMaker

Regular
Regular
Joined
Jan 14, 2020
Messages
71
Reaction score
62
First Language
Português - BR
Primarily Uses
RMMZ
It's really weird that it's not working, since I'm sure the code for it is there in version 1.7.0.
In any case, try this plugin:

JavaScript:
//=============================================================================
// * Dragon Refuge - RPG Maker Plugins                               by Jorge *
//=============================================================================

var
Dragon               = Dragon               || {};
Dragon.CommunityBoot = Dragon.CommunityBoot || { VERSION: [1, 0, 0] };

/*:@pluginname Dragon_CommunityBoot
 * @plugindesc [MZ] [V1.0.0]
 * @url http://dragonrefuge.net
 * @target MZ
 * @author The Dragon
 */

(($) => {
    //-----------------------------------------------------------------------------
    // Graphics
    //
    // The static class that carries out graphics processing.

    const alias_Graphics_initialize         = Graphics.initialize;
    const alias_Graphics__switchFullScreen  = Graphics._switchFullScreen;
    const alias_Graphics__cancelFullScreen  = Graphics._cancelFullScreen;
    const alias_Graphics__requestFullScreen = Graphics._requestFullScreen;
    const alias_Graphics__onKeyDown         = Graphics._onKeyDown;

    Object.assign(Graphics, {

        initialize() {
            const flag = alias_Graphics_initialize.apply(this, arguments);
            this._setStretchMode(false);
            this._canvas.style.imageRendering = 'pixelated';
            document.body.style.overflow = 'hidden';
            nw.Window.get().setResizable(false);
            return flag;
        },

        _switchFullScreen() {
            const win = nw.Window.get();
            win.setResizable(true);
            alias_Graphics__switchFullScreen.apply(this, arguments);
            win.setResizable(false);
        },

        _cancelFullScreen() {
            if (this._scaleBeforeFullscreen) {
                this.defaultScale = this._scaleBeforeFullscreen
            } else {
                this.defaultScale = this._getSystemScreenScale();
            }
            alias_Graphics__cancelFullScreen.apply(this, arguments);
        },

        _requestFullScreen() {
            this._scaleBeforeFullscreen = this.defaultScale;
            this.defaultScale = this._getMaxIntegerScale();
            alias_Graphics__requestFullScreen.apply(this, arguments);
        },

        _getSystemScreenScale() {
            if ($dataSystem && "screenScale" in $dataSystem.advanced) {
                return $dataSystem.advanced.screenScale;
            } else {
                return 1;
            }
        },

        _setStretchMode(flag) {
            const last = this._stretchEnabled;
            this._stretchEnabled = !!flag;
            if (this._stretchEnabled !== last) {
                this._updateAllElements();
            }
        },

        _getMaxIntegerScale(screenWidth = window.screen.width, screenHeight = window.screen.height) {
            const
            game = [Graphics.width, Graphics.height],
            client = [screenWidth, screenHeight],
            min = Math.min(...client),
            i = client.indexOf(min);
            return Math.max(1, Math.floor(min / game[i]));
        },

        _onKeyDown(event) {
            if (!event.ctrlKey && !event.altKey) {
                switch (event.keyCode) {
                    case 112: // F1
                        event.preventDefault();
                        if (this._isFullScreen()) {
                            this.defaultScale = Math.max(1, (this.defaultScale + 1) % (this._getMaxIntegerScale() + 1));
                        } else {
                            this.defaultScale = Math.max(1, (this.defaultScale + 1) % (this._getMaxIntegerScale(window.screen.availWidth, window.screen.availHeight) + 1));
                            this._updateWindow(0.5, 0.5);
                        }
                        break;
                    default:
                        console.log(alias_Graphics__onKeyDown);
                        return alias_Graphics__onKeyDown.apply(this, arguments);
                }
            }
        },

        _updateWindow(ox = 0, oy = 0) {
            if (Utils.isNwjs()) {
                const win = nw.Window.get();
                console.log(win)
                win.setResizable(true);
                const xDelta = (this.width * this.defaultScale) - window.innerWidth;
                const yDelta = (this.height * this.defaultScale) - window.innerHeight;
                window.moveBy(-xDelta * ox, -yDelta * oy);
                win.resizeBy(xDelta, yDelta);
                win.setResizable(false);
            }
        }

    });

    //-----------------------------------------------------------------------------
    // Scene_Boot
    //
    // The scene class for initializing the entire game.

    Object.assign(Scene_Boot.prototype, {

        adjustWindow() {
            Graphics.defaultScale = Graphics._getSystemScreenScale();
            Graphics._updateWindow(0.5, 0.5);
        }

    });

})(Dragon.CommunityBoot);

This should make the window scale. You can also press F1 to change the scale of the window ingame.
 

chris-cote

Villager
Member
Joined
Aug 11, 2023
Messages
19
Reaction score
2
First Language
English
Primarily Uses
RMMZ
It's really weird that it's not working, since I'm sure the code for it is there in version 1.7.0.
In any case, try this plugin:

JavaScript:
//=============================================================================
// * Dragon Refuge - RPG Maker Plugins                               by Jorge *
//=============================================================================

var
Dragon               = Dragon               || {};
Dragon.CommunityBoot = Dragon.CommunityBoot || { VERSION: [1, 0, 0] };

/*:@pluginname Dragon_CommunityBoot
 * @plugindesc [MZ] [V1.0.0]
 * @url http://dragonrefuge.net
 * @target MZ
 * @author The Dragon
 */

(($) => {
    //-----------------------------------------------------------------------------
    // Graphics
    //
    // The static class that carries out graphics processing.

    const alias_Graphics_initialize         = Graphics.initialize;
    const alias_Graphics__switchFullScreen  = Graphics._switchFullScreen;
    const alias_Graphics__cancelFullScreen  = Graphics._cancelFullScreen;
    const alias_Graphics__requestFullScreen = Graphics._requestFullScreen;
    const alias_Graphics__onKeyDown         = Graphics._onKeyDown;

    Object.assign(Graphics, {

        initialize() {
            const flag = alias_Graphics_initialize.apply(this, arguments);
            this._setStretchMode(false);
            this._canvas.style.imageRendering = 'pixelated';
            document.body.style.overflow = 'hidden';
            nw.Window.get().setResizable(false);
            return flag;
        },

        _switchFullScreen() {
            const win = nw.Window.get();
            win.setResizable(true);
            alias_Graphics__switchFullScreen.apply(this, arguments);
            win.setResizable(false);
        },

        _cancelFullScreen() {
            if (this._scaleBeforeFullscreen) {
                this.defaultScale = this._scaleBeforeFullscreen
            } else {
                this.defaultScale = this._getSystemScreenScale();
            }
            alias_Graphics__cancelFullScreen.apply(this, arguments);
        },

        _requestFullScreen() {
            this._scaleBeforeFullscreen = this.defaultScale;
            this.defaultScale = this._getMaxIntegerScale();
            alias_Graphics__requestFullScreen.apply(this, arguments);
        },

        _getSystemScreenScale() {
            if ($dataSystem && "screenScale" in $dataSystem.advanced) {
                return $dataSystem.advanced.screenScale;
            } else {
                return 1;
            }
        },

        _setStretchMode(flag) {
            const last = this._stretchEnabled;
            this._stretchEnabled = !!flag;
            if (this._stretchEnabled !== last) {
                this._updateAllElements();
            }
        },

        _getMaxIntegerScale(screenWidth = window.screen.width, screenHeight = window.screen.height) {
            const
            game = [Graphics.width, Graphics.height],
            client = [screenWidth, screenHeight],
            min = Math.min(...client),
            i = client.indexOf(min);
            return Math.max(1, Math.floor(min / game[i]));
        },

        _onKeyDown(event) {
            if (!event.ctrlKey && !event.altKey) {
                switch (event.keyCode) {
                    case 112: // F1
                        event.preventDefault();
                        if (this._isFullScreen()) {
                            this.defaultScale = Math.max(1, (this.defaultScale + 1) % (this._getMaxIntegerScale() + 1));
                        } else {
                            this.defaultScale = Math.max(1, (this.defaultScale + 1) % (this._getMaxIntegerScale(window.screen.availWidth, window.screen.availHeight) + 1));
                            this._updateWindow(0.5, 0.5);
                        }
                        break;
                    default:
                        console.log(alias_Graphics__onKeyDown);
                        return alias_Graphics__onKeyDown.apply(this, arguments);
                }
            }
        },

        _updateWindow(ox = 0, oy = 0) {
            if (Utils.isNwjs()) {
                const win = nw.Window.get();
                console.log(win)
                win.setResizable(true);
                const xDelta = (this.width * this.defaultScale) - window.innerWidth;
                const yDelta = (this.height * this.defaultScale) - window.innerHeight;
                window.moveBy(-xDelta * ox, -yDelta * oy);
                win.resizeBy(xDelta, yDelta);
                win.setResizable(false);
            }
        }

    });

    //-----------------------------------------------------------------------------
    // Scene_Boot
    //
    // The scene class for initializing the entire game.

    Object.assign(Scene_Boot.prototype, {

        adjustWindow() {
            Graphics.defaultScale = Graphics._getSystemScreenScale();
            Graphics._updateWindow(0.5, 0.5);
        }

    });

})(Dragon.CommunityBoot);

This should make the window scale. You can also press F1 to change the scale of the window ingame.
Hmmm, this doesn't seem to have worked. It makes the fullscreen game only take up the "true" scale (1280x720) in the corner of my screen, while showing the rest of my screen normally outside of it, but with no window commands etc. Pressing F1 also doesn't change anything.

Changing it with F1 is also not necessary, as my game is intended to always be zoomed in 3x by default.

Currently, I have been using this plugin: https://forums.rpgmakerweb.com/index.php?threads/map-zoom.126012/post-1279717 which has been doing the job well enough.

I don't think the zoom plugin is the source of the jitter however, as I also tried setting the native resolution to a smaller resolution (even though the UI gets murdered in the process), and that small resolution with no plugins (like a 600x300-ish res) still has the same problems.

It seems to be like RMMZ is updating the parallax and the events 1 frame apart from eachother when scrolling the screen, no matter what.
 

Latest Threads

Latest Posts

Latest Profile Posts

So the concept for my Game Jam project is way more than I can complete before the deadline. But I think I found a way to get the core done and make the incomplete parts either not really noticeable or make them a part of the story for now. That sneaky, dastardly Krampus! Then I can complete the rest. Did I mention that this is fun?
I've been working on a game called "Eternal Sunset". Is there anywhere here i can "show it off" maybe? Wondering what others think.
What do you do when there are lots of offers online but you don't have even a slight chance of ever playing those myriads of games?
Ugh, mispelled my username.

Forum statistics

Threads
136,542
Messages
1,267,339
Members
180,215
Latest member
Itohera
Top