Multi-colored SpriteFont text rendering engine

Edit: I decided to post the code on GitHub. You an find it here.

Not entirely sure where to post this, but I recently stopped development of a big game to focus on getting through the end of highschool and getting through college. I decided to use some of my free time to come up with a multi-colored text rendering algorithm in MonoGame since I don’t get time to play with MonoGame very often. I did it just because I can, and decided to post about it here to see if people would be interested in me releasing the code or potentially continuing development.

This is a really basic screenshot of it. The implementation is fairly quick and dirty, but it’s still quite fast on my system. I could definitely optimize it a bit though.

Basically, it allows you to render multi-colored paragraphs. You do this by giving the renderer some special characters and telling it which colors to map those characters to. In my demo, I mapped # to Red. Then, in my paragraph, I can surround a block of text with #'s and it’ll appear red.

If I want to render an ACTUAL # as a character, I can prepend it with a backslash: \# gets rendered as # and not as a color. And I can do the same to render a literal backslash, \\ becomes a \.

This is actually similar to how Hacknet renders tutorial text with multicolor, I think. Though I did notice that Hacknet drops down to a new line when a color code is detected, possibly to make the layout code a little easier. Either way, my algorithm doesn’t.

My algorithm actually has three passes. It first does some basic word-wrapping, if given a max line width. The word-wrapping makes sure to compensate for color codes and escape sequences so that they don’t count as actual text. Then, my algorithm will find all linebreaks, escape sequences, and color codes in the wrapped text and create a list of indexes where they’re found. Then the renderer will split the text into blocks, rendering each block in the correct color on the correct spot on-screen. No block will ever span multiple lines either.

Theoretically, I could also add support for things like text shadows, and alignment. Let me know what you guys think, if I should open-source it, or what other features I could implement. :slight_smile: This should be pretty easy to just drop into your code and start using it right away.

3 Likes

Update: I’ve added three new things to my renderer.

  • Measurement functions, so you can measure a string accounting for color codes.
  • TextRenderer.Default allows you to have a “default” instance of the text renderer class that can be used anywhere, which is important for:
  • Extension methods for SpriteFont and SpriteBatch:
    • SpriteFont.MeasureString(string text, float lineWidth) - measure a word-wrapped string, accounting for color codes, using this font.
    • SpriteBatch.DrawColoredString(SpriteFont font, string text, Vector2 position, float lineWidth) - draw a multicolored string to this sprite batch at the given location with the given maximum line width.
1 Like