Fonts are used to render text on Label components and GUI text nodes. Defold supports several font file formats:
Both the legacy and full text layout engines support TrueType outlines and OpenType CFF1/CFF2 outlines, including runtime generation from .ttf and .otf resources.
For information about styling individual text spans and working with links and inline sprites, see the Rich text markup manual.
For TrueType and OpenType fonts, the Mode property selects how glyphs are rendered:
Newly created font resources use Vector mode and Dynamic glyph generation. Existing font resources keep their Bitmap or SDF mode. BMFont sources always use their supplied bitmap.
Vector mode requires graphics support for RGBA16F and R32UI textures and is not supported on OpenGL ES 2 or WebGL 1. Use Bitmap or SDF fonts and matching materials when targeting unsupported graphics adapters; there is no automatic fallback from Vector to SDF. See Vector fonts for setup.
The Glyph Generation property selects when each font’s glyph data is generated:
.ttf or .otf file is not bundled for runtime generation..ttf or .otf file and generates glyphs on demand at runtime. Prewarm Text prepares glyphs when the font loads. Other glyphs can be generated later as needed.SDF and Vector fonts support both choices. Bitmap fonts and BMFont sources use Static generation. Each font resource is configured independently, so a project can mix Static and Dynamic fonts.
Dynamic generation can reduce bundle size and runtime memory use, particularly for fonts with large character sets. It requires the full text layout system in the engine; see Enabling Runtime Fonts.
The runtime fonts also have the benefit of supporting full text layout, e.g. right-to-left. We currently use the libraries HarfBuzz, SheenBidi, libunibreak and SkriBidi.
The editor uses the engine’s font renderer for font and scene text previews. Text shaping and right-to-left layout require runtime fonts and the Use full text layout system option in the App Manifest. For offline fonts, the preview respects the font’s Characters and All Chars settings.
The .fontc file format is also known as a font collection. In offline mode, only one font is associated with it.
When using runtime fonts, you can associate more than one font file (.ttf or .otf) with the font collection.
This allows for using the a font collection when rendering multiple texts in different languages, while also keeping the memory footprint low. E.g. loading a collection with the Japanese font, then associate that font with the current main font, followed by unloading the Japanese font collection.
To create a font for use in Defold, create a new Font file by selecting File ▸ New... from the menu, then select Font. You can also right click a location in the Assets browser and select New... ▸ Font.

Give the new font file a name and click Ok. The new font file now opens in the editor.
Drag the font you wish to use into the Assets browser and drop it in a good spot.
Set the Font property to the font file. For a .ttf or .otf source, select Mode and Glyph Generation, then configure the remaining properties as needed. For Dynamic generation, also complete the runtime font setup.

For Vector fonts, use Font Size on a Label component or GUI text node to change the displayed text size. Outline/Shadow Bitmap Size controls the resolution of the effect bitmaps independently of the displayed text size.
For Bitmap and SDF fonts, set Size in the font resource to choose the generated glyph size. BMFont sizes come from the source .fnt file. To change the displayed size of these fonts, scale the Label component or GUI text node.
.fnt file to use for generating the font data..ttf or .otf source: Bitmap, SDF or Vector. This replaces the former Output Format property. The property is not shown for BMFont sources..ttf and .otf sources. For SDF, Vector and BMFont sources, Defold selects the layer arrangement automatically.
.fnt file and cannot be edited here..ttf and .otf sources.The built-in Bitmap font shader supports shadows in both Single Layer and Multi Layer render modes. For generated Bitmap fonts that use Single Layer rendering and do not need shadows, a custom material can use /builtins/fonts/font-singlelayer.fp. SDF and Vector fonts require shaders matching their mode; see Font materials.
font.prewarm_text().The ASCII printable characters are: space ! “ # $ % & ‘ ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
ERROR:RENDER: Out of available cache cells! Consider increasing cache_width or cache_height for the font.).
If set to 0 the cache size is set automatically, and will grow to 2048x4096 max.
Use a material that matches the font mode. The font resource’s Material is used by GUI text nodes. Label components have a separate Material property that must also match the font:
| Font mode or source | Font material for GUI text | Label component material |
|---|---|---|
| Bitmap | /builtins/fonts/font.material |
/builtins/fonts/label.material |
| SDF | /builtins/fonts/font-df.material |
/builtins/fonts/label-df.material |
| Vector | /builtins/fonts/font-vector.material |
/builtins/fonts/label-vector.material |
BMFont (.fnt) |
/builtins/fonts/font-fnt.material |
/builtins/fonts/label-fnt.material |
Changing Mode in the font editor switches between the corresponding built-in Bitmap, SDF and Vector materials when one of those materials is already assigned to the font. Custom materials are not replaced automatically. Check the Material property on any Label components that use the font as well.
Vector fonts render glyph faces from curves so they remain sharp as the displayed text size changes. To set up a font that generates its glyphs at runtime:
.font resource, for example /fonts/ui.font, and select a TrueType or OpenType source in its Font property. The built-in /builtins/fonts/vera_mo_bd.ttf can be used for ordinary text./builtins/fonts/font-vector.material. These are the defaults for newly created font resources./builtins/fonts/label-vector.material. Set the component or node’s Font Size to the desired display size.Vector glyph faces use curve textures, but enabled outlines and shadows still generate SDF bitmap data and consume glyph-cache texture memory. Outline/Shadow Bitmap Size sets that bitmap resolution independently of the Label or GUI text node’s Font Size. Set Outline Alpha and Shadow Alpha to 0 when those effects are not needed to avoid generating their bitmap data.
Vector fonts can render COLRv1 color emoji, including palette colors and linear and radial gradients. Bitmap and SDF modes do not render COLRv1 colors. Use the Dynamic Vector setup above, then add a COLRv1 emoji font as a fallback to the font collection. Ordinary text continues using the original font.
For example, copy the COLRv1 Noto Color Emoji font into your project as /fonts/NotoColorEmoji-Regular.ttf. Choose the COLRv1 version: other emoji fonts may use a different color format even when their filename ends in .ttf.
Append /fonts/NotoColorEmoji-Regular.ttf to Project ▸ Custom Resources in game.project. With no other custom resources, the setting is:
[project]
custom_resources = /fonts/NotoColorEmoji-Regular.ttf
A font path written in Lua does not cause the font file to be bundled. Custom Resources makes this source font available to font.add_font(), which loads it through the resource system. Pass the source font’s string path when loading it from the bundle.
Add the fallback once per shared font resource. The change affects every Label and GUI text node using that font, and adding the same fallback twice raises an error. If using both the Label example and the GUI example with the same .font, coordinate initialization so the fallback is added once before either example prewarms or displays text. The examples prewarm the complete text after adding the fallback and display it when the callback succeeds.
Distance field fonts store the distance to the edge of the glyph in the texture instead of bitmap data. When the engine renders the font, a special shader is required to interpret the distance data and use that to draw the glyph. Distance field fonts are more resource intensive than bitmap fonts, but allow for greater sizing flexibility.

Select SDF in Mode and choose Static or Dynamic in Glyph Generation. Use /builtins/fonts/font-df.material for the font and /builtins/fonts/label-df.material for Label components, or custom materials that handle distance field data.
In addition to generated bitmaps Defold supports prebaked bitmap “BMFont” format fonts. These fonts consists of a PNG font sheet with all the glyphs. In addition, a .fnt file contains information on where on the sheet each glyph can be found as well as size and kerning information. (Note that Defold does not support the XML version of the .fnt format that is used by Phaser and some other tools)
These types of fonts provide no performance improvement from bitmap fonts generated from TrueType or OpenType font files, but can include arbitrary graphics, coloring and shadows right in the image.
Add the generated .fnt and .png files to your Defold project. These files should reside in the same folder. Create a new font file and set the Font property to the .fnt file. Defold uses the supplied bitmap and reads its size from the .fnt file. Mode and Glyph Generation are not shown for BMFont sources.
To create a BMFont, you need to use a tool that can generate the appropriate files. Several options exist:

Set the font’s Material to /builtins/fonts/font-fnt.material. For Label components, use /builtins/fonts/label-fnt.material.
Generally, bitmap fonts are best when the font is rendered with no scaling. They are faster to render to screen than distance field fonts.
Distance field fonts respond very good to upscaling. Bitmap fonts, on the other hand, being just pixelated images will increase in size so the pixels will grow as the font is scaled, resulting in blocky artifacts. The following is a sample at font size 48 pixels, scaled up 4 times.

When scaling down, bitmap textures can be nicely and efficiently scaled down and antialiased by the GPU. A bitmap font keeps its color better than a distance field font. Here is a zoom of the same sample font at size 48 pixels, scaled down to 1/5 of the size:

Distance field fonts need to be rendered to a target size that is big enough to hold distance information that can express the curves of the font glyphs. This is the same font as above, but at 18 pixels size and scaled up 10 times. It is clear that this is too small to encode the shapes of this typeface:

If you don’t want shadow or outline support, set their respective alpha values to zero. Otherwise, shadow and outline data will still be generated, taking up unnecessary memory. In Vector mode, disabling both effects avoids generating their bitmap data; the glyph faces continue to use curve data.
Bitmap and SDF font resources use a glyph cache texture and font data at runtime. Vector fonts store their glyph faces as curve data and use a bitmap cache for enabled outline and shadow effects. The texture layout described below applies to Bitmap and SDF fonts.
At runtime, when rendering text, the engine will first loop through the glyphs to be rendered to check which glyphs are available in the texture cache. Each glyph that is missing from the glyph texture cache will trigger a texture upload from the bitmap data stored in the font data.
Each glyph is placed internally in the cache according to the font baseline, which enables calculating local texture coordinates of the glyph within its corresponding cache cell in a shader. This means that you can achieve certain text effects such as gradients or texture overlays dynamically. The engine exposes metrics about the cache to the shader via a special shader constant called texture_size_recip, which contains the following information in the vector components:
texture_size_recip.x is the inverse of the cache widthtexture_size_recip.y is the inverse of the cache heighttexture_size_recip.z is the ratio of cache cell width to the cache widthtexture_size_recip.w is the ratio of cache cell height to the cache heightFor example - to generate a gradient in a shader fragment, simply write:
float horizontal_gradient = fract(var_texcoord0.y / texture_size_recip.w);
For more information about shader uniforms, see the Shader manual.
Runtime generation is configured per font resource:
.font resource and select a TrueType (.ttf) or OpenType (.otf) source.font.prewarm_text() and wait for its callback before displaying it.New font resources already use Vector mode and Dynamic generation, but still require the App Manifest configuration above.
Dynamic fonts generate the glyphs needed by Prewarm Text when the font loads. The field is interpreted as text to be laid out, so the cache is prepared for the glyphs that the text needs. All Chars is not available for Dynamic fonts.
You can also call font.prewarm_text(font_collection, text, callback) for a Dynamic font. The callback tells you when all the missing glyphs have been added to the cache and it is safe to display the text. This function cannot be used with Static fonts.
For Dynamic fonts, it’s possible to add or remove source fonts (.ttf or .otf) to a font collection.
This is useful when a large font has been split up into multiple files for different character sets (e.g. CJK)
Adding a font to a font collection doesn’t automatically load or render all the glyphs.
function init(self)
-- Get the target font collection.
self.font_collection = go.get("#label", "font")
-- Get the first font assigned to the selected language collection.
local language_collection = go.get("localization_japanese#label", "font")
local font_info = font.get_info(language_collection)
self.language_ttf_hash = font_info.fonts[1].path_hash
-- Associate it with the target collection and increase its reference count.
font.add_font(self.font_collection, self.language_ttf_hash)
end
function final(self)
-- Remove the association and release the font reference.
font.remove_font(self.font_collection, self.language_ttf_hash)
end
To properly show a text with a runtime font, the glyphs need to be resolved. The font.prewarm_text() does this for you.
It is an asynchronous operation, and once it’s done and you get the callback, it’s safe to progress to show any message containing the glyphs.
If the glyph cache gets full, the oldest glyph in the cache will be evicted.
font.prewarm_text(self.font_collection, info.text, function (self, request_id, result, err)
if result then
print("PREWARMING OK!")
go.set(self.label, "text", info.text)
else
print("Error prewarming text:", err)
end
end)