Skip to content

Improve player nametag rendering#479

Open
domdomegg wants to merge 3 commits into
PrismarineJS:masterfrom
domdomegg:improve-nametags
Open

Improve player nametag rendering#479
domdomegg wants to merge 3 commits into
PrismarineJS:masterfrom
domdomegg:improve-nametags

Conversation

@domdomegg

@domdomegg domdomegg commented May 1, 2026

Copy link
Copy Markdown

The current player nametag is rendered as black 50pt Arial text on a transparent 500×100 canvas with text packed to one corner. The sprite scales the result, so the aspect ratio is wrong and the text reads as a horizontally-squashed black blob hovering above the player — at distance it's effectively invisible against any non-light background.

This PR replaces it with a vanilla-MC-style nametag:

  • White text with a soft drop shadow on a translucent black background.
  • Canvas sized exactly to the measured text + padding, so the sprite's aspect ratio is correct and the text doesn't squash.
  • 80px sans-serif rendered with linear filtering so the tag stays legible at any distance.
  • depthTest: false so the tag is visible even when partially occluded by the player or terrain (matches vanilla).

Before / after

Both bots in spectator mode at fixed positions; observer (camera) at the same coords for each pair.

before after
near (~2 blocks)
mid (~5 blocks)
far (~9 blocks)

The current nametag is rendered as black 50pt Arial text on a 500×100
transparent canvas with the text packed to one corner. The sprite
scales the result, so the aspect ratio is wrong and the text reads as
a horizontally-squashed black blob hovering above the player.

Replace it with a vanilla-MC-style nametag:
- White text with a soft drop shadow on a translucent black background.
- Canvas sized exactly to the measured text + padding, so the sprite
  preserves the correct aspect ratio.
- 80px sans-serif rendered with linear filtering so the tag stays
  legible at any distance.
- depthTest: false so the tag is visible even when the player is
  partially occluded (matches vanilla).
Comment thread viewer/lib/entities.js Outdated
const fontPx = 80

const measure = createCanvas(1, 1).getContext('2d')
measure.font = `${fontPx}px sans-serif`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should include a better set of font-family defaults something like minecraft,mojangles,monospace (or sans-serif) and maybe making this option customizable

Address review: replace the bare `sans-serif` nametag font with a
fallback stack so it picks up a real Minecraft font when one is
installed and degrades to monospace otherwise. Hoisted the font string
into a single `font` const so the measure and draw contexts can't drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@domdomegg

Copy link
Copy Markdown
Author

Good call — done. Switched the nametag font from a bare sans-serif to a fallback stack minecraft, mojangles, monospace, so it picks up a real Minecraft font if one's installed and degrades gracefully to monospace otherwise. (Also hoisted it into a single font const so the measure and draw contexts can't drift apart.)

I left the font non-customizable for now — happy to add an option to override it if there's a concrete need, but erring towards fewer knobs to keep things simple unless someone actually wants it.

@extremeheat extremeheat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for monospace but otherwise looks good beyond the nit that a new canvas is unnecessarily created for every call here

Per review: minecraft, mojangles, sans-serif (sans-serif is a fine
generic fallback; monospace isn't needed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@domdomegg

Copy link
Copy Markdown
Author

Thanks! Dropped monospace from the fallback — now minecraft, mojangles, sans-serif.

Good catch on the per-call measuring canvas too. I've left it as-is for this PR to keep it focused on the nametag rendering, but happy to hoist a shared 1×1 measuring canvas into a module-level const in a quick follow-up if you'd prefer it in here.

@domdomegg
domdomegg requested a review from zardoy May 25, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants