A lightweight, open-source text rendering module for Roblox,
featuring custom fonts and fine-control over all characters.
More creativity!
Roblox developers suffer from a wide range of limitations.
This module aims to fix text limitations, allowing more
developers to unleash their creativity with text.
What it really does:
-
Custom fonts: You can use
.ttf
and.otf
files, either custom fonts or fonts you find online. -
Fine-control: Transform and style any individual character, word or line. Useful for dialogues.
Check it out below!
🎬 Showcases
Dialogue
A really simple ‘dialogue’, featuring:
- Custom font.
- Text appear and disappear animation.
- ‘Shining’ word animation.
Text explosion
A neat text explosion effect.
Features a custom font too.
Efficient, typed, robust.
- It’s blazingly fast.
- It has types for all functions & arguments.
- It catches nearly all mistakes, providing detailed error messages.
And it’s light as a feather!
Learn how to use it!
🚀 Fundamentals
Getting the module
Let’s first get the module. There are two ways:
-
Get it from the creator store:
- Click
Get
at the top of this post. - Click
Get Model
on the store. - Open the ToolBox in Roblox Studio.
- Go to the
Inventory
tab. - Click on
Text+
.
- Click
-
Get it from GitHub:
- Click
Git
at the top of this post. - Go to
Releases
. - Download the latest
.rbxm
file. - Find the file in your file explorer.
- Drag the file into Roblox Studio.
- Click
Find a great place for the module in your explorer.
Introduction
You’ll be creating text using frames as parents and boundaries, like this:
local textPlus = require(path.to.TextPlus) -- Put the actual path to the module.
local frame = path.to.frame -- You should actually get or create a frame.
textPlus.Create(
frame, -- Parent and boundary.
"This text is awesome!", -- Text.
{ -- Customization (optional).
Size = 24,
Color = Color3.fromRGB(255, 255, 255),
XAlignment = Enum.TextXAlignment.Center,
YAlignment = Enum.TextYAlignment.Center,
}
)
The text will be wrapped inside of the frame.
Note that it will ignore any UIPadding.
Customization
The customization works with a table, where you can provide any customizations you want.
You don’t have to provide all, or even any, because they all have defaults.
Full list of customization options:
- Size: number
- Font: Font
- Color: Color3
- Transparency: number
- LineHeight: number
- CharacterSpacing: number
- XAlignment: Enum.TextXAlignment
- YAlignment: Enum.TextYAlignment
- WordSorting: boolean
- LineSorting: boolean
Fonts
The font is one of the customization options, and generally works like all the others.
It’s slightly different though.
It uses a Font
object, usually created with Font.new()
.
You can use it like this:
textPlus.Create(
frame,
"This text is awesome!",
{
Font = Font.new(
"rbxasset://fonts/families/Arial.json", -- Family.
Enum.FontWeight.Regular, -- Weight.
Enum.FontStyle.Normal -- Style.
)
}
)
Built-in fonts
You can find a lot of fonts on the documentation page.
Simply copy the asset id from the font list and paste it into the Font
object’s Family
(first argument).
Creator store fonts
Alternatively, browse many more fonts at the creator store.
Click Get Font
.
Create a TextLabel
in Roblox Studio and apply the font to it.
Make sure you have the TextLabel selected and run this in the command bar:
print(game.Selection:Get()[1].FontFace.Family)
It will output the asset id, that you need.
Simply copy and paste it into the Font
object’s Family
(first argument).
Custom fonts
If it’s still not enough, custom fonts offer endless possibilities.
But that has it’s own section (also in this post). Consider checking it out.
Modification
You can also modify a text frame after the creation. It’s done the same you create it to begin with:
textPlus.Create(
frame, -- Frame that already has text created within it.
"This text has been modified!" -- New text.
)
You can even modify the customization after the creation like this:
textPlus.Create(
frame, -- Frame that already has text created within it.
"This text has been modified!", -- New text.
{ -- New customization (optional).
Size = 12 -- Overwrite size.
-- Everything else will stay like before!
}
)
It will keep all previous customization options, only overwriting with those you provide in the table.
⚙️ Fine-control
Introduction
The sorting options in the customization are crucial to fine-control.
Using word and line sorting, you can not only modify individual characters, but whole words and lines.
Use the sorting customization options like this:
textPlus.Create(
"Text",
frame,
{
LineSorting = true,
WordSorting = true
}
)
Both lines and words will be sorted using folders, and will be named numerically:
Full looping
If you want to loop through them in correct order, you will have to use numerical loops like this:
for lineNumber = 1, #frame:GetChildren(), 1 do
print("Line "..lineNumber) -- "Line 1", "Line 2" etc.
local lineFolder = frame[tostring(lineNumber)]
for wordNumber = 1, #lineFolder:GetChildren(), 1 do
print("Word "..wordNumber) -- "Word 1", "Word 2" etc.
local wordFolder = lineFolder[tostring(wordNumber)]
for characterNumber = 1, #wordFolder:GetChildren(), 1 do
print("Character "..characterNumber) -- "Character 1", "Character 2" etc.
local character = wordFolder[tostring(characterNumber)]
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
end
end
Of course, if you have only one of the sorting types enabled, there will only be one layer of folders, and you’ll have to do something like this:
for wordNumber = 1, #frame:GetChildren(), 1 do
print("Word "..wordNumber) -- "Word 1", "Word 2" etc.
local wordFolder = frame[tostring(wordNumber)]
for characterNumber = 1, #wordFolder:GetChildren(), 1 do
print("Character "..characterNumber) -- "Character 1", "Character 2" etc.
local character = wordFolder[tostring(characterNumber)]
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
end
Alternatively, you can use the GetCharacters
function, which will return all of the characters.
You can simply loop through the table like this:
local characters = textPlus.GetCharacters(frame)
for _, character in ipairs(characters) do
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
Specific indexing and looping
You can always access the exact line, word or character number you want by indexing like this:
frame["1"]
With some sorting enabled, you’ll be able to loop through specific lines and words.
Character (requires you to have no sorting)
for _, character in ipairs(frame:GetChildren()) do
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
Word (requires word sorting)
local word = frame["1"] -- Word sorting.
local word = frame["1"]["1"] -- Line and word sorting.
for _, character in ipairs(word:GetChildren()) do
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
Line (requires line sorting)
local line = frame["1"]
-- Line and word sorting:
for _, word in ipairs(word:GetChildren()) do
-- 'word' will be a folder.
for _, character in ipairs(word:GetChildren()) do
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
end
-- Line sorting:
for _, character in ipairs(line:GetChildren()) do
-- For Roblox fonts, 'character' will be a TextLabel.
-- For custom fonts, 'character' will be an ImageLabel.
end
Transform and style
If you want to change the colors of characters, remember that:
-
For Roblox fonts: Use
TextColor3
, because it will be a TextLabel. -
For custom fonts: Use
ImageColor3
, because it will be an ImageLabel.
If you want to change the transparency of characters, remember that:
-
For Roblox fonts: Use
TextTransparency
, because it will be a TextLabel. -
For custom fonts: Use
ImageTransparency
, because it will be an ImageLabel.
And don’t forget to be creative!
🛠️ Custom fonts
Importing custom fonts is slightly complex. Bear with me.
Get and open BMFont app
Download and install the latest version of AngelCode’s BMFont app.
Unzip/extract the .zip
file.
Open the bmfont64.exe
file that is inside of the bmfont
folder.
A window should pop up.
Include characters
Tick the box next to Latin
on the right side:
It will now include the latin alphabet.
You can include more characters if you want, but this is usually all we need.
Install your font
Get a .ttf
or .otf
file (a font file), whether it’s one of your own or one you found online.
Open it and press Install
, or simply right-click and press Install
.
Font settings
In the BMFont app, go to Options
> Font settings
, or simply press F
on your keyboard.
Find your font in the Font
dropdown located at the top, and select it.
You might want to adjust the Size
option.
This basically controls the maximum size you will be able to render this font in before it begins to look awful (due to low quality). Now you might think that you should just set this to a huge number like 1.000, but you’ve got to remember that it’s going to save this as an image. If you’re not going to make the text really large, don’t make this number large. I’d recommend not going further than 100.
Press OK
once done.
Export options
In the BMFont app, go to Options
> Export options
, or simply press T
on your keyboard.
Make sure that the Width
and Height
is large enough to fit all of your characters — it highly depends on the size you put in the font settings.
Set Bit depth
to 32
.
Find the Presets
dropdown, located near the bottom, and choose White text with alpha
. Don’t worry, it will still be colorable!
For Font descriptor
, choose XML
.
For Textures
, choose png
.
Press OK
once done.
Save the image and XML font files
In the BMFont app, go to Options
> Save bitmap font as...
, or simply press CTRL+S
on your keyboard.
Choose a location where you’ll be able to find the files.
It should save a .fnt
and a .png
file.
Convert XML to Lua format
I’ve made this step nice and simple with a program that does this for you.
Download the converter.
Unzip/extract the zip file.
You should get a folder with a convert.exe
file inside.
Drag your .fnt
file, that you exported from the BMFont app, into the folder where the converter.exe
file is.
Then simply open the convert.exe
file.
It might warn you, saying it might be a threat (virus). This is simply because I haven’t registered the file, as it’s extremely expensive to do so.
After a few short seconds, you should see a new .lua
file.
Uploading image and getting its id
Upload the image at the creator hub.
Then go to your images.
Find your image, click the three dots on it, and then click Copy Asset ID
.
Import font data to Text+
Find the TextPlus
module in your explorer.
Open the CustomFonts
module located inside of it.
Custom fonts work like this:
return table.freeze({
-- Fonts.
MyFont = {
-- Weights.
Regular = {
-- Styles.
Normal = {
Image = 0, -- Image id.
-- From XML:
Size = 32,
Characters = {
}
}
}
}
})
Each font can have multiple weights that all can have multiple styles.
One weight is required per font.
One style is required per weight.
All possible font weights (in ascending order):
- Thin
- ExtraLight
- Light
- Regular
- Medium
- SemiBold
- Bold
- ExtraBold
- Heavy
Add your font like this:
MyFont = {
Regular = {
Normal = -- Paste lua file content here.
}
}
If you’re using a different weight or style, change the Regular
and Normal
.
You can always add more weights and styles by repeating the custom font creation process and adding the data here.
Add your image id of the font in the same table as the Size
and Characters
like this:
MyFont = {
Regular = {
Normal = {
Image = 0, -- Image id.
Size = 32,
Characters = {
}
}
}
}
Use the custom font
Using custom fonts is as simple as using any Roblox font.
Just set the Font
customization’s Family
(first argument) to the exact name you gave the font in the CustomFonts
module. Like this:
textPlus.Create(
"Text",
frame,
{
Font = Font.new(
"MyFont",
Enum.FontWeight.Regular,
Enum.FontStyle.Normal
)
}
)
Share your thoughts and creations!
I’d love to see what you guys are able to do with this, so consider sharing your works!
But most importantly:
- Report any bugs or mistakes you find for this asset and post!
- Consider providing feedback to help me and the asset improve!