How to: Custom voiced sector names that actually play - 9.0

The place to discuss scripting and game modifications for X4: Foundations.

Moderators: Scripting / Modding Moderators, Moderators for English X Forum

Promethor
Posts: 1
Joined: Sun, 5. Apr 20, 07:48

How to: Custom voiced sector names that actually play - 9.0

Post by Promethor »

Disclaimer: This is what worked for me in X4 9.0 while building a total-conversion mod. There may be other valid methods, but this is the first complete end-to-end workflow I found that consistently produced custom Betty sector announcements. This was surely discussed in the past but I wasn't able to find a clear answer myself.

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>
2) Sector macros referencing it the normal way:

Code: Select all

<identification name="{2001001,251}" .../>
3) The voice clips, named by their text id, in a plain "voice" folder inside your extension. Note it's voice, NOT voice-l044:

Code: Select all

extensions/YourMod/voice/2001001/normal/251.ogg
extensions/YourMod/voice/2001001/normal/253.ogg
Match vanilla for the OGGs: mono, Vorbis, 44.1kHz. Nothing exotic if MediaInfo says "1 channel, Vorbis, 44.1kHz" you're fine.

4) 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>
Two things that matter in there:
- 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>
(If you want it to sound like vanilla's radio-filtered location pool, you can copy the <effects> block from vanilla's 20005_normal entry into yours. Plain is3d="0" with no effects works fine too, it just sounds drier.)

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.
DJ Aitch
Posts: 148
Joined: Fri, 6. Feb 04, 19:57
x4

Re: How to: Custom voiced sector names that actually play - 9.0

Post by DJ Aitch »

Very helpful, thank you!
User avatar
ChemODun
Posts: 634
Joined: Mon, 12. Feb 07, 21:58
x4

Re: How to: Custom voiced sector names that actually play - 9.0

Post by ChemODun »

Mane thanks for this HowTo!
Multiply entropy by absolute zero

Freedom in space

Return to “X4: Foundations - Scripts and Modding”