Skip to content

Voice system

inkoalawetrust edited this page Jan 18, 2025 · 6 revisions

For more technical information on the voice system, check here.

The voice pack system is a feature that allows for creating packs that constitute an NPC's "voice", using a custom lump/file format. These packs can then be accessed by NPCs to speak them to say the defined voice lines of the pack, segregated in different types of voices, such as voice lines for being scared of something, voice lines for joining a group, etcetera.

This page is mainly concerned with the non-technical aspects of the voice system, mainly the KAI_VOICES file itself.

KAI_VOICES

Note

If you're here to make a voice pack for an NPC that uses this library, keep in mind that different NPCs will use this data differently, for example, they might only use the See voice type and not also the unique PlayerSee type! That's up to the NPCs' author to specify for you.

This is the special file that voice definitions are parsed and generated from. Each mod can only have ONE KAI_VOICES file, and ONLY in the root directory of the archive, you cannot make additional files like KAI_VOICES.Whatever (Only one file will be parsed out of the whole mod), nor does the format support #include directives. (Though these limitations might be removed in the future.)

Syntax

Below is an example of the basic syntax of a Voice{} block, the primary, and currently only block which KAI_VOICES has.

Voice Example
{
	See = "Sight1", "Sight2"
	Custom NewType = "Custom1"
}

Voice marks the block as being a voice definition. Example is the name of the voice pack. See the voice type (More info below). Custom is used to mark what comes next on that line as a custom, arbitrary voice type on the pack, as opposed to any built-in one, such as See. Followed by NewType which is the name of the custom voice type.

These sound names NEED to be SNDINFO-defined sounds for the voice type to store the properly.

Default voice types

Here is a list of all the existing voice types supported by KAI_Voice:

Type Intended Purpose
See Said when the NPC sees an enemy.
PlayerSee Said when the NPC sees an enemy player specifically.
Fear Said when the NPC is scared of something, i.e a monster over the NPC's ThreatLevelThreshold
Idle Said when the NPC is idling
Hazard Said when the NPC is in range of a hazard
PlayerFear Said when the NPC is specifically scared of a player.
OrderChange Said when the NPCs' order is changed.
GroupJoin Said when the NPC joins an NPC group.
GroupLeave Said when the NPC leaves and NPC group.
Death Said when the NPC dies.
AllyDeath Said when an NPC friendly to the speaking NPC dies.
AllyPlayerDeath Ditto, but for players.
EnemyDeath Said when a hostile NPC or player dies.
AllyVehicleDeath Said when a friendly vehicle dies.
EnemyVehicleDeath Said when an enemy vehicle dies.
AllyRevive Said when a friendly player or NPC resurrects.
EnemyRevive Ditto, but for enemies.
Revive Said when the speaking NPC is resurrected.

Important

If you are a modder, keep in mind that the death and revive voice types for other actors besides the caller, require their own handling to alert your NPCs to comment on those events. Such as using an event handler to find all your nearby NPCs and trigger the appropriate voice type to be uttered.

ZScript API

Of course, the voice system also comes with ZScript functions for using it, the key functions are:

  • SayVoiceLine(): The function that makes the calling KAI NPC actually say a voice line. Main feature entrypoint.
  • GetNPCVoice(): Used for acquiring a loaded voice pack definition by name.
  • GetCustomType(): Check the calling voice pack to see if it has the specified custom voice type in it, custom voice types are identified by name.

Notes

  • The actual ZScript voice data (KAI_Voice) is transient, meaning that it is not saved on game exit, and has to be reparsed every time, allowing voice packs to be modifiable between GZDoom sessions, such as for adding new sounds to a voice definition, or removing and replacing existing ones.

See also

Clone this wiki locally