I spent the better part of a week getting Betty to read custom sector names for a total-conversion mod, and at one point I was fully convinced the engine just didn't allow it.
It does. The text side is easy and documented all over the place. The voice side has one step that nothing I could find spells out, so here's the whole thing in one post for the next person who searches "custom sector voice not playing" at 2am.
This is for 9.0. The audio side of the engine hasn't really moved in years, so it should hold up for a good while.
For the record, I only cracked this by unpacking Star Wars Interworlds and reading how they did it. Credit to them and to Taros for the announcement voice work the method below is basically theirs, written down.
The one thing you need to know
X4 does not find voice files just because they exist in a folder. Every voiced text page has to be registered in libraries/sound_library.xml with <sound> entries that point at the folder holding the clips.
If you skip that, your sector names display perfectly and Betty stays dead silent. That's the whole trap everything looks correct, so you go hunting in the wrong places for days.
The setup
1) Custom text page with your names, voice="yes" on the page:
Code: Select all
<page id="2001001" title="Sector Names" voice="yes">
<t id="251">Nexus Core Ruins</t>
<t id="253">Broken Crown</t>
</page>Code: Select all
<identification name="{2001001,251}" .../>Code: Select all
extensions/YourMod/voice/2001001/normal/251.ogg
extensions/YourMod/voice/2001001/normal/253.ogg4) The part everyone misses. Register the page in libraries/sound_library.xml:
Code: Select all
<diff>
<add sel="/soundlibrary">
<sound id="2001001_normal" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
</add>
</diff>- The id has to be <yourpage>_normal. The engine derives the sound id from the text page, so it can't be an arbitrary name.
- The sample start is the full path from the game root into your extension's voice folder, and it points at the folder, not individual files. The engine matches the spoken text id to <id>.ogg inside it automatically.
Register the other context variants too. The announcer asks for different ones depending on situation (comm, NPC, broadcast, etc.), and you want it to always find a match. All of them can point at the same normal folder:
Code: Select all
<diff>
<add sel="/soundlibrary">
<sound id="2001001_normal" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
<sound id="2001001_normal_npc" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
<sound id="2001001_comm" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
<sound id="2001001_comm_signalleak" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
<sound id="2001001_comm_npc" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
<sound id="2001001_comm_broadcast" description="custom sector names" repeat="1" is3d="0" preload="0">
<sample start="extensions\YourMod\voice\2001001\normal"/>
</sound>
</add>
</diff>Pack it
Put the voice files in an ext_01.cat/dat. Loose voice audio was not reliable for me Steam launch options needs -prefersinglefiles and even then custom clips wouldn't play consistently.
Packed just works. The sound_library.xml and text file can live loose or packed, doesn't matter.
Dead ends that ate my week, so they don't eat yours
- Copying the vanilla voice-l044/<page>/normal/ layout for a CUSTOM page does nothing on its own. Custom pages go through the sound_library registration with an explicit sample start. That's the difference.
- Don't add a partial page id="10002". That's vanilla Betty's page, and a partial override there shadows her "Entering system" line, so you lose the prefix before your sector name.
- Hijacking {20005,1001} as a test just plays "Argon Prime". It proves the vanilla pool works, but it's a dead end for custom names.
- The file is sound_library.xml, with the underscore. Easy to fat-finger as soundlibrary.xml, especially because the xml use <soundlibrary>.
- If you're not even sure your packed cat is loading, change a packed text line temporarily and check whether the name changes in game. If the text doesn't change, your cat isn't loading and the voice was never going to play so fix that first.
That's the whole thing. It's a short post for something that took an absurd number of dead ends to land on. If your text shows but she won't speak, it's almost always the sound_library step.
I'm completely new to modding in general, so this was like a boss fight for me, so hopefully this will be helpful to someone else in the future.
Remember : The engine derives the sound lookup from the page ID. If those numbers do not match, the text can display correctly while the voice lookup silently fails. And the path use voice not voice-l044.

