Unicode characters inside wrap()

16 views
Skip to first unread message

Kristian Hansen

unread,
Jun 4, 2026, 8:57:51 AM (6 days ago) Jun 4
to tinymux
Hi hi,

Just noticed a bit of odd behaviour in v2.13 - perhaps it's my use case, but thought I'd point it out.
I've experimented with using Unicode symbols in my most recent work, and it seems they're not accounted for in wrap() width - removing the symbol removed the "ripple" in the <righttxt> "wall".

Screenshot - TinyMUX - MUSHClient.png

This example screenshot taken in MUSHclient.

Can't wait for 2.14 by the way! Super excited, thanks for all the little improvements in 2.13.

Stephen Dennis

unread,
Jun 4, 2026, 4:57:32 PM (5 days ago) Jun 4
to kris...@2moathouse.net, tinymux
Hi Kristian,

Thanks for this — and for the screenshot. Your read is exactly right: wrap() in 2.13 isn't accounting for the display width of your symbol, which is why the right-hand <righttxt> wall ripples out by a column or two on the lines that contain it, and snaps back when you remove it.

What's happening. 2.13's wrap() measures a line by counting characters (code points), not the columns they actually occupy on screen. Most characters are one column wide, so this is usually fine — but a wide glyph (CJK, many symbols, emoji) takes two columns. wrap() thinks that line is one column shorter than it really is, pads it as if it were short, and the wall ends up pushed out. That's the ripple.

The fix. wrap() was rewritten for 2.14 to be width-aware: it measures every line in real console columns using the Unicode width tables, so a wide character counts as two, a combining mark as zero, and color codes as nothing. Each line is padded to the requested width in columns before the wall is drawn, so the wall stays flush regardless of what's in the text. I just went through this with fresh tests — a line like wrap(Hello 世界 there ..., 12, left, >%b, %b<) keeps the < wall perfectly aligned. 2.14 also adds a vwidth() function if you ever want to measure a string's display width yourself.

On 2.13. Unfortunately the change is the whole new wrapper, not a small patch — backporting it to 2.13 essentially means shipping 2.14's wrap(). So rather than a 2.13 point fix, this lands properly in 2.14.

One thing to watch on the client side. Even a perfectly width-aware server can still ripple for a specific symbol if your client draws it at a different width than the server's table assigns — emoji and "ambiguous-width" characters are the usual culprits (a terminal/font may render them as 1 or 2 columns depending on settings, while the Unicode tables pick one). MUSHclient is generally good here, but if a particular glyph still misaligns under 2.14, it's almost always this. If you can tell me the exact code point (or paste the symbol), I'm happy to check what width 2.14 assigns it versus what MUSHclient is drawing — that's a quick thing to reconcile.

 Thanks again for the careful report — it's the kind that's easy to act on.
 
— Stephen

--

---
You received this message because you are subscribed to the Google Groups "tinymux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tinymux+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/tinymux/1b9fea24-a171-4ac2-ad2c-5d8301296d72n%40googlegroups.com.

Kristian Hansen

unread,
Jun 4, 2026, 9:31:40 PM (5 days ago) Jun 4
to tinymux
Hi Stephen,

Thanks for the comprehensive reply, and I'm happy I could help. 

I'm still undecided on the value of using glyphs and emoji in my MUX, but intend to continue playing with it so your explanation is really valuable. But the current incarnation of my game, while being updated and tweaked on 2.13, is not intended for production until 2.14 is fully released (though I will probably run a beta version) as it's being angled towards making use of the Lua integration which opens up some really exciting possibilities. I'll just wait until then to properly bring glyphs and emojis into the design.

Thanks again!

/<
Reply all
Reply to author
Forward
0 new messages