FontBuddy 5.0.4

dotnet add package FontBuddy --version 5.0.4
                    
NuGet\Install-Package FontBuddy -Version 5.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FontBuddy" Version="5.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FontBuddy" Version="5.0.4" />
                    
Directory.Packages.props
<PackageReference Include="FontBuddy" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FontBuddy --version 5.0.4
                    
#r "nuget: FontBuddy, 5.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FontBuddy@5.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FontBuddy&version=5.0.4
                    
Install as a Cake Addin
#tool nuget:?package=FontBuddy&version=5.0.4
                    
Install as a Cake Tool

FontBuddy

Simple, flexible text rendering for MonoGame with built-in effects and easy justification.

FontBuddy makes it easy to draw text in MonoGame without wrestling with positioning and effects. It provides simple text rendering with justification options and several built-in visual effects.

Installation

Install via NuGet:

dotnet add package FontBuddy

Or in your .csproj:

<PackageReference Include="FontBuddy" Version="5.*" />

Quick Start

Basic Text Rendering

using FontBuddyLib;
using GameTimer;

// In your Game class
IFontBuddy _fontBuddy;
GameClock _gameClock;

protected override void LoadContent()
{
    _fontBuddy = new FontBuddy();
    _fontBuddy.LoadContent(Content, "Fonts/Arial"); // Your SpriteFont asset
    _gameClock = new GameClock();
}

protected override void Update(GameTime gameTime)
{
    _gameClock.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
    spriteBatch.Begin();
    
    // Draw text with center justification
    _fontBuddy.Write(
        "Hello World!",
        new Vector2(400, 300),
        Justify.Center,
        1.0f,              // scale
        Color.White,
        spriteBatch,
        _gameClock         // GameClock for animations
    );
    
    spriteBatch.End();
}

Text Justification

FontBuddy supports multiple justification modes to make alignment easy:

// Left-aligned text
_fontBuddy.Write("Left", position, Justify.Left, 1.0f, Color.White, spriteBatch, _gameClock);

// Center-aligned text
_fontBuddy.Write("Center", position, Justify.Center, 1.0f, Color.White, spriteBatch, _gameClock);

// Right-aligned text
_fontBuddy.Write("Right", position, Justify.Right, 1.0f, Color.White, spriteBatch, _gameClock);

Available Font Effects

FontBuddy includes several pre-built text effects:

ShadowTextBuddy

Renders text with a drop shadow:

var shadowFont = new ShadowTextBuddy();
shadowFont.LoadContent(Content, "Fonts/Arial");

// Customize shadow appearance
shadowFont.ShadowOffset = new Vector2(0f, 3f);  // Default offset
shadowFont.ShadowColor = Color.Black;           // Shadow color
shadowFont.ShadowSize = 1.05f;                  // Size multiplier (default 1.05)

shadowFont.Write("Shadowed Text", position, Justify.Center, 1.0f, Color.White, spriteBatch, _gameClock);

PulsateBuddy

Animated pulsating text effect:

var pulsateFont = new PulsateBuddy();
pulsateFont.LoadContent(Content, "Fonts/Arial");

// Customize pulsation
pulsateFont.PulsateSize = 1.0f;   // Pulsation amplitude (default 1.0)
pulsateFont.PulsateSpeed = 4.0f;  // Speed of animation (default 4.0)
pulsateFont.StraightPulsate = true; // Pulsate straight out (default true)

// Also has shadow properties (inherits from ShadowTextBuddy)
pulsateFont.ShadowColor = Color.Black;
pulsateFont.ShadowSize = 1.05f;

pulsateFont.Write("Pulsating!", position, Justify.Center, 1.0f, Color.Yellow, spriteBatch, _gameClock);

ShakyTextBuddy

Randomly jittering text for a shaky effect:

var shakyFont = new ShakyTextBuddy();
shakyFont.LoadContent(Content, "Fonts/Arial");

shakyFont.ShakeAmount = 10.0f; // Amount of shake (default 10.0)
shakyFont.ShakeSpeed = 10.0f;  // Speed of shake (default 10.0)

shakyFont.Write("Shaky Text", position, Justify.Center, 1.0f, Color.Red, spriteBatch, _gameClock);

RainbowTextBuddy

Text that cycles through rainbow colors character by character:

var rainbowFont = new RainbowTextBuddy();
rainbowFont.LoadContent(Content, "Fonts/Arial");

rainbowFont.RainbowSpeed = 2.0f; // Speed of color cycling (default 2.0)

// You can customize the color list
rainbowFont.Colors.Clear();
rainbowFont.Colors.Add(Color.Red);
rainbowFont.Colors.Add(Color.Orange);
rainbowFont.Colors.Add(Color.Yellow);
// ... add more colors

// Also has shadow properties
rainbowFont.ShadowColor = Color.Black;
rainbowFont.ShadowOffset = new Vector2(0f, 3f);

rainbowFont.Write("Rainbow!", position, Justify.Center, 1.0f, Color.White, spriteBatch, _gameClock);

OppositeTextBuddy

Text where colors swap/transition between foreground and shadow over time:

var oppositeFont = new OppositeTextBuddy();
oppositeFont.LoadContent(Content, "Fonts/Arial");

oppositeFont.SwapSpeed = 2.0f;  // Speed of color swap (default 2.0)
oppositeFont.SwapSweep = 0.1f;  // Time offset per character (default 0.1)

// Shadow properties
oppositeFont.ShadowColor = Color.Black;
oppositeFont.ShadowOffset = new Vector2(0f, 3f);
oppositeFont.ShadowSize = 1.05f;

oppositeFont.Write("Opposite", position, Justify.Center, 1.0f, Color.Blue, spriteBatch, _gameClock);

OutlineTextBuddy

Text with an outline/stroke effect:

var outlineFont = new OutlineTextBuddy();
outlineFont.LoadContent(Content, "Fonts/Arial");

outlineFont.OutlineColor = Color.Black;    // Outline color
outlineFont.OutlineSize = 5;               // Outline thickness in pixels (default 5)
outlineFont.ShadowOffset = new Vector2(0f, 3f);

outlineFont.Write("Outlined", position, Justify.Center, 1.0f, Color.White, spriteBatch, _gameClock);

NumberBuddy

Animated number counter that smoothly transitions when the value changes:

var numberFont = new NumberBuddy(0); // Start at 0
numberFont.LoadContent(Content, "Fonts/Arial");

// Set outline properties (uses OutlineTextBuddy internally)
numberFont.OutlineColor = Color.Black;

// Add to the number (animates the change)
numberFont.Add(100); // Counts from current value to current+100

// Or set directly
numberFont.Number = 500; // Counts to 500

numberFont.Write("Score: ", position, Justify.Center, 1.0f, Color.White, spriteBatch, _gameClock);

BouncyNumbers

Specialized number display that counts up and then bounces/scales at the end:

var bouncyFont = new BouncyNumbers();
bouncyFont.LoadContent(Content, "Fonts/Arial");

bouncyFont.ScaleAtEnd = 2.5f;   // How big to scale at end (default 2.5)
bouncyFont.ScaleTime = 1.0f;    // How long to scale (default 1.0)
bouncyFont.Rescale = 1.2f;      // Final scale after bounce (default 1.2)
bouncyFont.ScalePause = 1.0f;   // Pause before scaling (default 1.0)

// Start counting from startNum to targetNum
bouncyFont.Start(0, 100);

// Check if animation is done
if (bouncyFont.IsDead)
{
    // Animation finished
}

bouncyFont.Write("Bonus: ", position, Justify.Center, 1.0f, Color.Yellow, spriteBatch, _gameClock);

Core API Reference

All FontBuddy classes implement the IFontBuddy interface and share this common API:

LoadContent

void LoadContent(ContentManager content, string resourceName, bool useFontBuddyPlus = false, int fontSize = 24)

Loads a SpriteFont for rendering.

  • content - ContentManager to load from
  • resourceName - Path to the font asset (e.g., "Fonts/Arial")
  • useFontBuddyPlus - Use FontBuddyPlus (FontStashSharp) instead of SpriteFont (optional, experimental)
  • fontSize - Font size for FontBuddyPlus (optional, default 24)

Write

float Write(
    string text, 
    Vector2 position, 
    Justify justify, 
    float scale, 
    Color color, 
    SpriteBatch spriteBatch, 
    GameClock time
)

Parameters:

  • text - The string to render
  • position - Screen position to draw at (alignment depends on justification)
  • justify - Text alignment: Justify.Left, Justify.Center, or Justify.Right
  • scale - Size multiplier (1.0 = normal size, 2.0 = double size, etc.)
  • color - Text color (may be modified by effects)
  • spriteBatch - MonoGame SpriteBatch to render with
  • time - GameClock for animations (from GameTimer library)

Returns: The X position at the end of the drawn text

MeasureString

Vector2 MeasureString(string text)

Returns the size in pixels of the given text.

Helper Methods

// Break text into multiple lines that fit within a width
List<string> BreakTextIntoList(string text, int rowWidth)

// Calculate scale needed to fit text exactly within width
float ScaleToFit(string text, int rowWidth)

// Calculate scale to shrink text to fit (returns 1.0 if already fits)
float ShrinkToFit(string text, int rowWidth)

// Check if text needs to shrink to fit at current scale
bool NeedsToShrink(string text, float scale, int rowWidth)

// Draw text directly without justification handling
void DrawString(string text, Vector2 position, float scale, Color color, SpriteBatch spriteBatch)

Properties

SpriteEffects SpriteEffects { get; set; }  // Flip text horizontally/vertically
float Rotation { get; set; }                // Rotation angle in radians
float Spacing { get; }                      // Character spacing from the font

Examples

See the /FontBuddySample folder in this repository for a complete working example showing all the different text effects.

Requirements

  • MonoGame 3.8+
  • .NET Standard 2.0+

Platforms

FontBuddy works on all platforms supported by MonoGame:

  • Windows
  • macOS
  • Linux
  • iOS
  • Android
  • Xbox
  • PlayStation

License

MIT License - see LICENSE.txt

Contributing

Issues and pull requests welcome! This is a hobby project but I maintain it for my game development.


For LLM/AI Agents

Quick Integration Guide:

  1. Add the package: <PackageReference Include="FontBuddy" Version="5.*" />

  2. Add GameTimer dependency: FontBuddy requires the GameTimer library for the GameClock parameter

    <PackageReference Include="GameTimer" Version="*" />
    
  3. Common pattern:

    using FontBuddyLib;
    using GameTimer;
    
    IFontBuddy font = new FontBuddy(); // or ShadowTextBuddy, PulsateBuddy, etc.
    GameClock clock = new GameClock();
    
    font.LoadContent(Content, "Fonts/YourFont");
    
    // In Update:
    clock.Update(gameTime);
    
    // In Draw:
    font.Write(text, position, Justify.Center, scale, color, spriteBatch, clock);
    
  4. All available classes:

    • FontBuddy - Base text rendering
    • ShadowTextBuddy - Drop shadow effect
    • PulsateBuddy - Size animation (inherits shadow)
    • ShakyTextBuddy - Random jitter
    • RainbowTextBuddy - Character-by-character color cycling (has shadow)
    • OppositeTextBuddy - Foreground/shadow color swapping (has shadow)
    • OutlineTextBuddy - Stroke/outline effect
    • NumberBuddy - Animated number counter (uses outline)
    • BouncyNumbers - Counting number with bounce effect (uses outline)
  5. Key enum: Justify with values: Left, Center, Right

  6. Important interfaces:

    • IFontBuddy - Main interface all font buddies implement
    • IShadowTextBuddy - Interface for shadow properties (ShadowColor, ShadowOffset, ShadowSize)
  7. Namespace: FontBuddyLib

  8. Key pattern - GameClock is required: The Write method signature is:

    float Write(string text, Vector2 position, Justify justify, float scale, 
                Color color, SpriteBatch spriteBatch, GameClock time)
    

    Note: It's GameClock time, NOT GameTime time. You must use the GameTimer library's GameClock class.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on FontBuddy:

Package Downloads
MenuBuddy

A complete MonoGame library for building menu systems and managing game state transitions

FlashCards

MonoGame library for making little flashcard games

FrameRateCounter

MonoGame component to display the frame rate.

ToastBuddyLib

MonoGame library to easily show messages to the player via toast popups

FontBuddyPlus

Put some text on the screen easier with MonoGame

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.0.4 55 1/25/2026
5.0.3 288 12/30/2025
5.0.2 368 10/10/2025
5.0.1 148 10/10/2025
5.0.0 214 9/13/2025
4.0.0 1,399 7/5/2023
2.1.0 1,045 6/9/2023
2.0.31 1,379 11/23/2022
2.0.30 1,540 5/4/2022
2.0.29 1,492 5/3/2022
2.0.28 1,491 4/4/2022
2.0.27 1,490 11/1/2021
2.0.26 1,457 11/1/2021
2.0.25 1,398 10/29/2021
2.0.24 1,458 10/21/2021
2.0.23 1,381 9/14/2021
2.0.22 1,446 7/21/2021
2.0.21 1,456 4/13/2021
2.0.20 1,419 3/22/2021
2.0.19 1,519 3/15/2021
2.0.18 1,724 6/10/2020
2.0.17 1,731 4/28/2020
2.0.16 1,827 3/18/2020
2.0.15 1,857 1/7/2020
2.0.14 1,740 1/7/2020
2.0.13 1,811 1/4/2020
2.0.12 1,855 1/2/2020
2.0.11 1,823 12/30/2019
2.0.9 1,827 12/30/2019
2.0.8 1,854 12/30/2019
2.0.7 1,924 12/30/2019
2.0.6 1,842 8/21/2019
2.0.5 1,815 7/15/2019
2.0.4 1,831 3/12/2019
2.0.3 1,813 3/12/2019
2.0.2 1,819 3/12/2019
2.0.1 1,817 3/12/2019
2.0.0 2,238 10/23/2018
1.0.35 2,043 10/11/2018
1.0.34 2,009 10/11/2018
1.0.33 1,973 10/8/2018
1.0.32 1,994 10/2/2018
1.0.30 1,940 9/27/2018
1.0.29 2,486 6/11/2018
1.0.28 2,490 6/11/2018
1.0.27 2,227 6/11/2018
1.0.26 2,520 6/11/2018
1.0.25 2,635 4/26/2018
1.0.24 2,511 4/26/2018
1.0.23 2,481 4/25/2018
1.0.22 2,602 1/23/2018
1.0.21 2,307 10/18/2017
1.0.20 2,273 10/18/2017
1.0.19 2,244 10/18/2017
1.0.18 2,276 9/26/2017
1.0.17 2,274 9/26/2017
1.0.15 2,293 9/24/2017
1.0.14 2,312 9/22/2017
1.0.13 2,262 9/22/2017
1.0.12 2,269 9/22/2017
1.0.11 2,439 5/11/2017
1.0.10 2,270 5/2/2017
1.0.9 2,326 5/2/2017
1.0.8 2,560 8/5/2016
1.0.7 2,403 8/5/2016
1.0.5 2,576 6/14/2016
1.0.4 2,447 5/27/2016
1.0.3 2,466 5/27/2016
1.0.2 2,398 5/27/2016
1.0.1 2,641 4/23/2016
1.0.0 2,596 4/23/2016