Skip to content

feat: Width and Height, an object's drawn size - #22

Merged
LucasAntunesdeAlmeida merged 1 commit into
masterfrom
object-size
Sep 29, 2026
Merged

LucasAntunesdeAlmeida merged 1 commit into
masterfrom
object-size

Conversation

@LucasAntunesdeAlmeida

Copy link
Copy Markdown
Owner

What

o.Width() float64 and o.Height() float64: the size an object is drawn and clicked in.

  • Size when set; else a Rect's size, a sprite's image size (once the object is in a scene), or a text's measured size: its fonts with fallbacks, TextSize, the Wrap column, lines LineHeight apart, plus a button's plate margins.
  • Never the Hitbox, which only affects collisions.
  • Text is re-measured on every change already (measureText runs in Text, SetText, Font, TextSize, Wrap, LineHeight), so both getters are current in the same frame, headless and in go test, with no window and nothing drawn.

Games no longer have to guess len(s)*size, which is wrong for multi-byte and fallback-font text. They can lay out labels by their edges and test that every translation fits its box.

Design choices

  • Name. .Size(w, h) is already the setter. Width()/Height() match the existing g.Width()/g.Height(), and a single value can be used inline: label.X = left + label.Width()/2. A (w, h) pair can't be used that way.
  • Drawn size (bounds()), not the collision box(). Layout and fit checks need what the player sees. Agents keep getting the hitbox in observations.
  • No package-level Measure(s) helper. engine.Text(s).Font(...).TextSize(n).Wrap(w).Height() already measures a string with no game or scene. A text object is cheap, and this form takes exactly the same styling calls the real label uses. A separate helper would copy that styling as parameters.
  • Restart fix. restoreState now re-measures a restored text with the font, size and wrap it has now. Before, a text restyled after setup came back with its old box and was drawn in it. The new test fails without this fix.

Proof

  • size_test.go:
    • Rect, Size and Hitbox, and a sized text area.
    • Latin, then Cyrillic after SetText (measured per glyph, not per byte), TextSize, Font, and a button.
    • CJK through testdata/fallback.ttf: Latin-only text, all-CJK text, and a mixed line.
    • Wrapped CJK text (column x 3 lines), LineHeight(40), and "\n" lines.
    • Headless: SetText then Width inside OnUpdate, anchoring by the left edge in that same frame, checked against the observation, then Restart.
    • A sprite before and after Add, with and without Size.
  • examples/dialog: the speaker's name is placed at the speech's left edge using Width after each SetText, which replaces the Wrap-column workaround. The CLICK hint's right edge is placed at x 770. Over MCP, English lays out pixel-identically to before (ELDER at x 250 w 120, CLICK at 740 w 60), so demo.gif stays valid. zh-CN gives 长老 with its left edge at 190 and 点击 with its right edge at 770.
  • README: cheat-sheet row, Dialog row, and contract item 13 ("Text is measured the moment it changes").
  • Full local gate passes: gofmt, vet, staticcheck, test, plus js/wasm and windows vet+build.

o.Width() and o.Height() read the size an object is drawn and clicked
in: its Size, a Rect's size, a sprite's image once it is in a scene, or
a text as measured with its fonts (fallbacks included), TextSize, the
Wrap column and LineHeight, plus a button's plate. Never the Hitbox.

Text is already measured on every change, so both are current right
after SetText, Font, TextSize, Wrap or LineHeight, in the same frame,
headless and in go test with no window. Games can lay labels out by
their edges and test that every translation fits its box instead of
guessing len(s)*size, which is wrong for Cyrillic, CJK and fallbacks.

Restart now re-measures a restored text with the font, size and wrap it
has, so a text restyled after the scene's setup reports (and draws in)
the right box after Restart.

The dialog example anchors the speaker's name at the speech's left
edge and the CLICK hint at the frame's right edge by their Width. The
README gains a cheat-sheet row and contract item 13.
@LucasAntunesdeAlmeida
LucasAntunesdeAlmeida merged commit 8efa5fe into master Sep 29, 2026
1 check passed
@LucasAntunesdeAlmeida
LucasAntunesdeAlmeida deleted the object-size branch September 29, 2026 17:58
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.

1 participant