Text becomes blurry on scaling

Hi, new to Phaser.

I’m building a NES Mario clone as a first exercise to get to know Phaser 3.

I’m using a 16x16 tile map. I want the game to scale with the screen size, since a 16x16-based world is tiny, So I added a scale property to the config object:

scale: {
      parent: 'game_container',
      mode: Phaser.Scale.CENTER_BOTH,
      width: 350,
      height: 208
}

I gave the parent container (‘game_container’) a max width of 800px.
I added a score text in the corner of the screen - at the original size (350px width), text looks good.
The problem: at 800px width, it looks blurry:


Is there anything I can do to make the text stay crisp even on scaling?
or would I have to rebuild everything with bigger tiles and give up on scaling?

Thanks!

You have a couple of different options here. I would probably reccomend 1 as its the easiest (IMO):

  1. Create the text into another scene, and have its own class handle all of it’s state. This will not scale if you apply scaling to the parent (or main game) scene. But given you’re code, you’re trying to scale the entire game with parent game_container. I do most of my scaling in a “main scene” and the other scenes all remain unscaled.

  2. Apply .setResolution(10) to the text. You want to avoid doing this as it is Rich posted in the docs that it’ll eat up memory quick, but its there:
    https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.Text.html#setResolution__anchor

  3. Use a bitmap text and apply scaling to that. This is better for performance than option 2, but I’ve never personally done it and imagine it probably is a PITA.

I tried setResolution, made the text even worse
I’ll try to do bitmap text.

Thanks!

I see you don’t actually define scaling in the init config just centering? Are you using something like:
scale: { mode: Phaser.Scale.ScaleModes.FIT } ?

Another option for retro type game that looks great is using retrofonts which are monospace tileset type picture fonts. They seem to scale pretty well. Anyway with FIT scaling normal fonts work pretty well aswell.

I ended up creating and using a bitmap font which turns out to work pretty well.
I used BM Font to create it, if anyone’s wondering.

1 Like

Since this is a popular topic, I’ll review a bit:

Phaser Text is Canvas text drawn onto the game canvas via an intermediate texture (i.e., a bitmap, not a vector). It can’t appear any sharper than the texture or game canvas resolution allow. If you scale it up, it loses detail and can appear either blurry or jaggy depending on the rendering settings.

The problem most often appears, as in the OP, on a low-resolution canvas scaled up — e.g., 12px text on a 320×240 retro game scaled by 300%. But on very high resolution displays like an iPad, even larger canvases (e.g. 1280×720 CSS pixels) are still much smaller than the physical resolution, so text can still look blurry, although not terrible.

Text resolution was introduced a long time ago when Phaser 3 could do multi-resolution rendering; the idea was you could match the Text texture resolution to the rendering context resolution for the best appearance. But now Phaser’s rendering context always has resolution 1, so setting Text resolution above 1 is only useful if you’re scaling up a Text object or zooming a camera on it.

If you need super-sharp text, you can use DOMElement game objects with game scale NONE or RESIZE. Other game scale modes might look OK too if not scaled up too much.

BitmapText, being bitmap, can show a similar problem when scaled, but for “pixel”-style bitmap fonts, scaling up by integers (2, 3, 4) can still look OK. For the best appearance you would want to use a separate bitmap font for each size.

2 Likes

What is your opinion on this approach for sharper/non-blurry text in container:

this.text = this.scene.add.text(this.width * 0.5, this.height * 0.5, '', {
  fontFamily: 'InterBlack',
  fontSize: '80px',
  color: '#121214',
  align: 'center',
});
this.text.setScale(0.25);
this.text.setOrigin(0.5);

Im increasing the font size by 4 and scalling down text by same amount. Is there a better way to do this?

I assume the container is being scaled by 4?

For that case you could use fontSize: '20px', resolution: 4 instead.

Text with origin 0.5 can be a little blurry in the WebGL renderer when roundPixels is off.

2 Likes