Joined
Jun 27, 2021
Messages
2
Reaction score
1
First Language
English
Primarily Uses
RMMZ
I have been working on a plugin for making message windows fit to the size of messages, and I noticed something quite odd. In some cases, the message would be cut off where in others it would fit just fine. I assumed at first this to be an error with my own code, but was surprised when disabling all plugins and even resetting to the default font did not prevent the text placement from deviating.

After some testing, it seemed to me that when text in message windows is shown instantly, it has the proper spacing. But when you allow the game to draw it one character at a time, it seems to stretch out. I've cropped a couple of samples to show the difference here. I didn't notice anyone else mentioning this bug, so I figured I probably should bring it up. And again, this happens with NO plugins enabled and the default font on. If there's anything else I might have overlooked to have this be a problem on my end, do let me know.
 

Attachments

  • sample.PNG
    sample.PNG
    109 KB · Views: 28

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,862
Reaction score
2,198
First Language
EN
Primarily Uses
RMMZ
I tried this event in a new project and saw no difference in line length:

◆Text:None, Nature(4), Window, Bottom : :Hello this is some text and this is more text. : :\>Hello this is some text and this is more text. ◆Text:None, Nature(4), Window, Bottom : :Hello this is some text and this is more text. ◆Text:None, Nature(4), Window, Bottom : :\>Hello this is some text and this is more text.
Can you share the steps necessary to create the issue you're seeing in a new project?
 

Shaz

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
43,761
Reaction score
15,319
First Language
English
Primarily Uses
RMMV
I am also not able to reproduce the issue, but in my case, I didn't use escape codes - I simply let the message play character by character in the first instance, but in the second I clicked to make it skip to the end.

Sometimes people think plugins are not active, but they actually are. Can you try in a brand new project without ANY plugins added/activated, and see if you can make it happen? Can you show a picture of the event so we can see the command, and explain what you're doing to make it show instantly vs character-at-a-time, as @caethyril assumed you meant one thing and I assumed you meant something else (and we might both be wrong)?
 
Joined
Jun 27, 2021
Messages
2
Reaction score
1
First Language
English
Primarily Uses
RMMZ
Yeah, actually trying it in a new project I can't seem to get it to happen anymore. I was testing it in my main one with like, all the plugins disabled, but there's a real possibility that I overlooked something there. I'd done some fiddling with the font settings and I THOUGHT I'd gotten them all back to default but I think the error was probably on my end. Must admit, there was a little bit of frustration at not being able to figure out why the message windows I'd slaved away on for weeks were bugging out on me, I think I didn't do due diligence in testing.

Funny thing is I actually managed to fix it for my project. Going back through the old versions of the source code:

Bitmap.prototype.measureTextWidth = function(text) { const context = this.context; context.save(); context.font = this._makeFontNameText(); const width = context.measureText(text).width; context.restore(); return Math.ceil(width); };

Changing return Math.ceil(width) back to just return width caused the problem to stop occurring for me.

Figured I'd share as much in case anyone else runs into a similar problem. But, yeah, this is not a bug in MZ, it's a bug in me.
 

Archeia

Level 99 Demi-fiend
Staff member
Developer
Joined
Mar 1, 2012
Messages
15,501
Reaction score
15,943
First Language
Filipino
Primarily Uses
RMMZ
Reopened this just in case and for me to refer back later.
This is the bug in action. It is easier to replicate it with a wider font:
1631611136118.png

The bug is related to Text Flushing. Somewhere around here:
Code:
Window_Message.prototype.updateMessage = function() {
    const textState = this._textState;
    if (textState) {
        while (!this.isEndOfText(textState)) {
            if (this.needsNewPage(textState)) {
                this.newPage(textState);
            }
            this.updateShowFast();
            this.processCharacter(textState);
            if (this.shouldBreakHere(textState)) {
                break;
            }
        }
        this.flushTextState(textState);
        if (this.isEndOfText(textState) && !this.isWaiting()) {
            this.onEndOfText();
        }
        return true;
    } else {
        return false;
    }
};

Solution should be simple as to rewrite flushing or the flush aspect so that it checks the textState index. Then continues to draw from that point onwards in a single frame. I'll see if I can do an independent fix.

Here is a sample project that will 100% replicate it.
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,862
Reaction score
2,198
First Language
EN
Primarily Uses
RMMZ
I did a quick test and removing the rounding on Bitmap#measureTextWidth (rmmz_core) seems to make all lines the same length:
JavaScript:
/*:
 * @target MZ
 * @plugindesc quick fix for text flushing bug?
 */

// Override! Do not round up the return value.
Bitmap.prototype.measureTextWidth = function(text) {
    const context = this.context;
    context.save();
    context.font = this._makeFontNameText();
    const width = context.measureText(text).width;
    context.restore();
    return width;   // <- removed Math.ceil
};
As I understand it, though, rendering at fractional coordinates can cause aliasing/blurriness. I don't know if it'd be better to flush each character separately with integer coordinates instead?
 

Archeia

Level 99 Demi-fiend
Staff member
Developer
Joined
Mar 1, 2012
Messages
15,501
Reaction score
15,943
First Language
Filipino
Primarily Uses
RMMZ
I did a quick test and removing the rounding on Bitmap#measureTextWidth (rmmz_core) seems to make all lines the same length:
JavaScript:
/*:[/INDENT][/INDENT]
[INDENT][INDENT]* @target MZ[/INDENT][/INDENT]
[INDENT][INDENT]* @plugindesc quick fix for text flushing bug?[/INDENT][/INDENT]
[INDENT][INDENT]*/[/INDENT][/INDENT]
[INDENT][INDENT][/INDENT][/INDENT]
[INDENT][INDENT]// Override! Do not round up the return value.[/INDENT][/INDENT]
[INDENT][INDENT]Bitmap.prototype.measureTextWidth = function(text) {[/INDENT][/INDENT]
[INDENT][INDENT]    const context = this.context;[/INDENT][/INDENT]
[INDENT][INDENT]    context.save();[/INDENT][/INDENT]
[INDENT][INDENT]    context.font = this._makeFontNameText();[/INDENT][/INDENT]
[INDENT][INDENT]    const width = context.measureText(text).width;[/INDENT][/INDENT]
[INDENT][INDENT]    context.restore();[/INDENT][/INDENT]
[INDENT][INDENT]    return width;   // <- removed Math.ceil[/INDENT][/INDENT]
[INDENT][INDENT]};
As I understand it, though, rendering at fractional coordinates can cause aliasing/blurriness. I don't know if it'd be better to flush each character separately with integer coordinates instead?

Yeah if we do it this way, it will cause "Text and actor faces extremely blurry sometimes due to non-integer coordinates" bug to reappear. Maybe let's try this instead:

Code:
Bitmap.prototype.measureTextWidth = function(text) {
    const context = this.context;
    context.save();
    context.font = this._makeFontNameText();
    const width = context.measureText(text).width;
    context.restore();
    return this._window_message ? width : Math.ceil(width);
};

Window_Message.prototype.textWidth = function(text) {
    this.contents._window_message = true;
    return this.contents.measureTextWidth(text);
};
 
Last edited:

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,862
Reaction score
2,198
First Language
EN
Primarily Uses
RMMZ
Looks good! Just need to reset the flag after it's been used, e.g.
JavaScript:
Bitmap.prototype.measureTextWidth = function(text) {
    const context = this.context;
    context.save();
    context.font = this._makeFontNameText();
    const width = context.measureText(text).width;
    context.restore();
    if (this._noIntTextWidth) {
        this._noIntTextWidth = false;   // <- reset
        return width;
    }
    return Math.ceil(width);
};

Window_Message.prototype.textWidth = function(text) {
    this.contents._noIntTextWidth = true;
    return Window_Base.prototype.textWidth.apply(this, arguments);
};
I included a couple of other edits here, just suggestions:
  • Renamed the flag to reflect its effect rather than its situational use,
  • Invoke the textWidth super for better modularity.
:kaohi:
 

Archeia

Level 99 Demi-fiend
Staff member
Developer
Joined
Mar 1, 2012
Messages
15,501
Reaction score
15,943
First Language
Filipino
Primarily Uses
RMMZ
@caethyril Thank you for the suggestions. There's only one thing I'm unsure of. I'm not sure if the reset flag is necessary? Because you don't port over bitmaps from one window to another from my understanding? :kaoblush:
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,862
Reaction score
2,198
First Language
EN
Primarily Uses
RMMZ
@Archeia - good point, I guess the reset is unnecessary! :kaothx: In that case I think the flag could be set in Window_Message#createContents instead?

(Alternatively, it looks like Bitmap#measureTextWidth is only called in two places in the core scripts: Sprite_Gauge#measureLabelWidth and Window_Base#textWidth. So another approach might be to move the rounding to those methods instead, and have an override for Window_Message that doesn't use rounding. That would avoid the need for a "rounding" flag altogether.)

I also realised that the \i[x] text code could be affected by this change. Maybe the drawIcon method should also be updated to round its draw coordinates?
 

Latest Threads

Latest Profile Posts

I'm gonna put my project on pause for a tiny bit so I can explore the engine outside of it... Winging it can only get you so far LMFAO
Have seen some of my favorite people here posting and helping others with questions today -- love to see it!
Haven't been on here actively in awhile, project is going strong my biggest issue is the STORY, i'm refining the plot and learning so much i decided to take a writers class to improve even more but the programming and functionality of the game is stepping up nicely!
Hi everyone! Here's what I'm working on today! It's one of the dorms on campus. I know I said I wouldn't use assets but I reused a few things from the cafeteria hehe.
FCuxBOMXMAICK5e
I added a little squish effect when characters change direction to try and make things a bit more lively. Though it's a bit hard to see on the fast moving guys.
2f4fiuy.gif

Forum statistics

Threads
116,126
Messages
1,095,983
Members
151,537
Latest member
Anrirck
Top