Jump to content

[TUTORIAL] How to Add Talking Fonts to the Game


Lucemodok
 Share

Recommended Posts

Hello, I'm Lucemodok and today I learned from @zarklord_klei how to load fonts into DST.

 

So, first you need to download your font, any font will do as long as you can read it.

 

Second, you'll need BMFont, it's a way to convert font files to bitmap fonts, which is what DST uses.

You'll then need to open BMFont and open the font settings to select a font.

 

After that, you need to set your font configurations, this is what I used.

image.png.46b4fc901a1dd54774c7996805bcf097.png

 

Next, open the export options and use this configuration.

image.thumb.png.b768187d6128bfcde068d8410d796093.png

This makes your font work with DST and have an outline.

 

After that, select save bitmap font as... and save it as "font.fnt" in whatever folder you want, a png with the name "font_0.png" should also appear there.

 

Convert the png into a tex with any tex conversion tool you have, rename it "font.tex" and zip it along with the fnt into "talkingfont_yourcharacter.zip" for the game to be able to read it.

 

Create a fonts folder in your mod folder, and put the new zip into the folder.

 

Here comes the coding part.

-- modmain.lua
Assets = {
  Asset("FONT", "fonts/talkingfont_yourcharacter.zip"),
}

GLOBAL.TALKINGFONT_YOURCHARACTER = "talkingfont_yourcharacter"

AddSimPostInit(function()
    GLOBAL.TheSim:LoadFont(GLOBAL.resolvefilepath("fonts/talkingfont_yourcharacter.zip"), GLOBAL.TALKINGFONT_YOURCHARACTER)
end)

Put that in the bottom of your modmain.lua and put the following in your character's common_postinit function.

inst.components.talker.font = TALKINGFONT_YOURCHARACTER

You should be done with your fonts, now you should test for any crashes.

Enjoy!

Captura_de_pantalla_215.png

Edited by Lucemodok
  • Like 5
  • Thanks 1
  • GL Happy 1
  • Potato Cup 1
Link to comment
Share on other sites

The loading solution will crash if you leave the server/reload the current game, because the font needs to be loaded before mod assets are loaded 
My solution:

local env = env
_G.setfenv(1, _G)

TALKINGFONT_WAYNE = "talkingfont_wayne"

env.AddSimPostInit(function()
	TheSim:UnloadFont(TALKINGFONT_WAYNE)
	TheSim:UnloadPrefabs({"wayne_fonts"})

	local Assets = {
		Asset("FONT", resolvefilepath("fonts/talkingfont_wayne.zip")),
	}
	local FontsPrefab = Prefab("wayne_fonts", function() return CreateEntity() end, Assets)
	RegisterPrefabs(FontsPrefab)
	TheSim:LoadPrefabs({"wayne_fonts"})
	TheSim:LoadFont(resolvefilepath("fonts/talkingfont_wayne.zip"), TALKINGFONT_WAYNE)
end)

It's pretty hacky, so maybe there's other way to resolve reload crash? I've tried to add loading/unloading new font to global functions LoadFonts/UnloadFonts (see mainfunctions.lua), but then the font never even gets loaded.
Maybe @zarklord_klei knows a better way of doing it? :spidercowers:

Edited by Cunning fox
  • Like 2
Link to comment
Share on other sites

2 minutes ago, TheSkylarr said:

What exactly does resolvefilepath() do? I've seen it thrown around, along with softresolvefilepath(), and I'm clueless.

Resolves relative file path into absolute path
This is used if you add asset that is not from the game, so you need to tell the engine where it is stored
Example: resolvefilepath("anim/poop.zip") will return "../../mods/workshop-00000/anim/poop.zip"

Edited by Cunning fox
Link to comment
Share on other sites

Yes, I used this font code and my mod crashes the game upon world regen, which is a big problem because me and a friend I play with regenerate our worlds all the time. I reeeally hope someone comes up with a cleaner solution! Also, inserting that "hacky" code (and changing all the names to my character of course) gained this crash upon trying to create a new world:

image.png.1953cb8c0f816e98610e303803b0d828.png

@Cunning fox

Edited by Garamonde
Inserted a few missing words.
Link to comment
Share on other sites

7 hours ago, Garamonde said:

Yes, I used this font code and my mod crashes the game upon world regen, which is a big problem because me and a friend I play with regenerate our worlds all the time. I reeeally hope someone comes up with a cleaner solution! Also, inserting that "hacky" code (and changing all the names to my character of course) gained this crash upon trying to create a new world:

image.png.1953cb8c0f816e98610e303803b0d828.png

@Cunning fox

Add _G = GLOBAL 

7 hours ago, Garamonde said:

Yes, I used this font code and my mod crashes the game upon world regen, which is a big problem because me and a friend I play with regenerate our worlds all the time. I reeeally hope someone comes up with a cleaner solution! Also, inserting that "hacky" code (and changing all the names to my character of course) gained this crash upon trying to create a new world:

image.png.1953cb8c0f816e98610e303803b0d828.png

@Cunning fox

The code I used changes mods's env to a global one, so you shouldn't use it if you're not experienced enough. Solution without changing env is:
 

local _G = GLOBAL
local TheSim = _G.TheSim

_G.TALKINGFONT_WAYNE = "talkingfont_wayne"

AddSimPostInit(function()
	TheSim:UnloadFont(_G.TALKINGFONT_WAYNE)
	TheSim:UnloadPrefabs({"wayne_fonts"})

	local Assets = {
		Asset("FONT", _G.resolvefilepath("fonts/talkingfont_wayne.zip")),
	}
	local FontsPrefab = _G.Prefab("wayne_fonts", function() return _G.CreateEntity() end, Assets)
	_G.RegisterPrefabs(FontsPrefab)
	TheSim:LoadPrefabs({"wayne_fonts"})
	TheSim:LoadFont(_G.resolvefilepath("fonts/talkingfont_wayne.zip"), _G.TALKINGFONT_WAYNE)
end)

 

Edited by Cunning fox
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

On 3/5/2021 at 3:56 AM, Cunning fox said:

Add _G = GLOBAL 

The code I used changes mods's env to a global one, so you shouldn't use it if you're not experienced enough. Solution without changing env is:
 


local _G = GLOBAL
local TheSim = _G.TheSim

_G.TALKINGFONT_WAYNE = "talkingfont_wayne"

AddSimPostInit(function()
	TheSim:UnloadFont(_G.TALKINGFONT_WAYNE)
	TheSim:UnloadPrefabs({"wayne_fonts"})

	local Assets = {
		Asset("FONT", _G.resolvefilepath("fonts/talkingfont_wayne.zip")),
	}
	local FontsPrefab = _G.Prefab("wayne_fonts", function() return _G.CreateEntity() end, Assets)
	_G.RegisterPrefabs(FontsPrefab)
	TheSim:LoadPrefabs({"wayne_fonts"})
	TheSim:LoadFont(_G.resolvefilepath("fonts/talkingfont_wayne.zip"), _G.TALKINGFONT_WAYNE)
end)

 

Is there a certain place it's supposed to go? I tried this and it crashed when going into a cave.

 

Looked into it, the log says that "AddSimPostInit" isn't declared.

Edited by icantevenname
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...