@@ -9,6 +9,9 @@ Stardew Valley.
99* [ Introduction] ( #introduction )
1010* [ Type 1: Voice Data] ( #type-1-voice-data )
1111 * [ Content Patcher Example: Type 1] ( #content-patcher-example-type-1 )
12+ * [ Type 1i: Line Expressions] ( #type-1i-line-expressions )
13+ * [ Dialogue IDs] ( #dialogue-ids )
14+ * [ Content Patcher Example: Type 1i] ( #content-patcher-example-type-1i )
1215 * [ Dialogue Command] ( #dialogue-command )
1316* [ Type 2: Line Readings] ( #type-2-line-readings )
1417 * [ Content Patcher Example - Type 2] ( #content-patcher-example-type-2 )
@@ -20,9 +23,11 @@ Stardew Valley.
2023Vox Box works by providing data assets for other mods to edit. At this time,
2124those mods are expected to use Content Patcher to perform their edits.
2225
23- There are two different ways to define character voices:
26+ There are two and a half different ways to define character voices:
2427
25281 . Voice data, which sets general voice parameters to apply to an NPC.
29+ 1 . Line expressions, to override an NPC's general voice data for specific
30+ lines.
26312 . Line readings, which sets specific audio to apply to specific dialogues.
2732
2833
@@ -46,7 +51,7 @@ Mods/ichortower.VoxBox/VoiceData
4651```
4752
4853The asset is a ` string->object ` dictionary. The ` string ` keys are NPC internal
49- names, and the model ( object) has the following fields:
54+ names, and the ` object ` model has the following fields:
5055
5156<table >
5257
@@ -68,9 +73,9 @@ your cues this way, to provide more character to the speech effect).
6873
6974See [ Modding: Audio on the Stardew Valley
7075Wiki] ( https://stardewvalleywiki.com/Modding:Audio ) for more detail on how to
71- set up your cues in ` Data/AudioChanges ` . But, ** it is strongly advised to set
72- StreamedVorbis to false for any .ogg files you use in your VoiceData cues**
73- (see [ Caveats and Advice] ( #caveats-and-advice ) for more).
76+ set up your cues in ` Data/AudioChanges ` . But, ** you should set StreamedVorbis
77+ to false for any .ogg files you use in your VoiceData cues** (see [ Caveats and
78+ Advice] ( #caveats-and-advice ) for more).
7479
7580* Default:* ` "dialogueCharacter" `
7681
@@ -95,7 +100,7 @@ values here.
95100
96101Note also that the function controlling this is called only once per frame, so
97102it has a minimum resolution of 16.67 milliseconds; therefore, for instance, the
98- value ` 10 ` is no different than the value ` 0 ` .
103+ value ` 10 ` produces the same result as the value ` 0 ` .
99104
100105* Default:* ` [30] `
101106
@@ -141,8 +146,9 @@ Since it is a multiplier, `0.0` will generate complete silence, `1.0` will have
141146no effect, and the player's perception of increased volume will likely depend
142147on where their game volume sliders are set. ** Use this setting with caution** ;
143148in most cases, you should omit this in the general voice data. The reason it is
144- here is to allow [ the special dialogue command] ( #dialogue-command ) to override
145- it to add expression to type 1 voice lines.
149+ here is to allow [ the special dialogue command] ( #dialogue-command ) and [ Line
150+ Expressions] ( #type-1i-line-expressions ) to override it to add expression to
151+ type 1 voice lines.
146152
147153If this field is set to an empty array (` [] ` ), then this mod will use a volume
148154multiplier of ` 1.0 ` for every play, just as if you had specified ` [1.0] ` .
@@ -211,25 +217,204 @@ You can also use your own cues (the intended approach):
211217}
212218```
213219
220+ ## Type 1i: Line Expressions
221+
222+ This type has the same effect as Type 1: creating voices out of
223+ randomly-selected sounds. The difference is that the voice data is applied to a
224+ specific dialogue line instead of broadly to an NPC. This lets you, for
225+ example, make one line louder and higher-pitched to reflect an NPC saying
226+ something angrily.
227+
228+ To add expressions, target the following asset:
229+
230+ ```
231+ Mods/ichortower.VoxBox/LineExpressions
232+ ```
233+
234+ The asset is a ` string->list(object) ` dictionary. The ` string ` keys are
235+ dialogue IDs (see below), and the values are lists (` [] ` ) of objects following
236+ the same model described above for Type 1 voice data. The only difference in
237+ the object model is that in this asset, the default value for every field is
238+ ` null ` , which means not to change that field (since this asset is specifying
239+ * overrides* ).
240+
241+ Within the list, the index of each object determines which segment of the
242+ dialogue line it applies to. A dialogue line might look like this:
243+
244+ ```
245+ "Fall seeds are here! Crops don't grow in winter so this is your last shot until spring.#$b#Better go all out, huh?"
246+ ```
247+
248+ This will be displayed using two dialogue boxes (they are separated by the
249+ ` #$b# ` ). When targeting this line (which happens to be
250+ ` Characters/Dialogue/Pierre:fall_Mon ` ), you can provide two objects in the
251+ list, which will target the first and second pieces, respectively.
252+
253+ Setting an object to ` null ` causes no override to take place, and the mod will
254+ use either the NPC's general Type 1 voice data, or the vanilla sounds.
255+ Likewise, any fields within a provided object that are ` null ` (or not
256+ specified) will cause no change, so you need only provide the fields you wish
257+ to modify.
258+
259+
260+ ### Dialogue IDs
261+
262+ When patching in Line Expressions (or [ Line Readings] ( #type-2-line-readings ) ,
263+ below), your patch will need to use dialogue IDs as keys. When the dialogue
264+ matching the ID is shown, this mod will automatically override the vanilla or
265+ Type 1 dialogue sounds using the data provided.
266+
267+ A dialogue ID for Vox Box's purposes comes in two formats:
268+
269+ 1 . A ** translation key** identifying a dialogue string in a game asset, in the
270+ form ` <asset name>:<key> ` \
271+ (example: ` Characters/Dialogue/Marnie:Fri6 ` ).
272+ 2 . An ** event key** identifying a dialogue line in an event, in the form
273+ ` <event id>:<full text of event command> ` \
274+ (example: ` 45:speak Lewis \"Hey! What do you think you're doing? That's private property!$4\" ` ).
275+
276+ Unfortunately, for infelicitous reasons, you do have to provide the full,
277+ expanded event command as the key when using the second format. This can be
278+ unwieldy, but [ there may be alternatives] ( #caveats-and-advice ) .
279+
280+
281+ ### Content Patcher Example: Type 1i
282+
283+ Here's how you might patch a line expression into the example from Pierre's
284+ dialogue, above:
285+
286+ ``` js
287+ {
288+ " Target" : " Mods/ichortower.VoxBox/LineExpressions" ,
289+ " Action" : " EditData" ,
290+ " Entries" : {
291+ " Characters/Dialogue/Pierre:fall_Mon" : [
292+ null ,
293+ { " Pitch" : [100 ], " Volume" : [1.2 ] }
294+ ]
295+ }
296+ }
297+ ```
298+
299+ This will leave the first line unchanged, and make him say the second one
300+ ("Better go all out, huh?") slightly louder and slightly higher pitched.
301+
302+
303+ ### Dialogue Command
304+
305+ The dialogue command is not currently available for use. Future betas and/or
306+ the 1.0 release will probably include it, pending feedback.
307+
214308
215309## Type 2: Line Readings
216310
217311This type of voice allows you to specify a single audio cue that will play when
218312a particular dialogue line is displayed. When a matching dialogue is shown, all
219313other dialogue sounds are ignored and the given cue is played exactly once. The
220314goal of this feature is to let you include recorded voice acting, foleys, other
221- sound effects, etc., which should take the place of any vanilla or type 1 audio
222- during the text display.
315+ sound effects, etc., which will take the place of any vanilla, type 1, or type
316+ 1i audio during the text display.
317+
318+ To add line readings, target the following asset:
319+
320+ ```
321+ Mods/ichortower.VoxBox/LineReadings
322+ ```
323+
324+ The asset is a ` string->list(object) ` dictionary. The ` string ` keys are
325+ [ dialogue IDs] ( #dialogue-ids ) , just like line expressions, and the values are
326+ lists (` [] ` ) of objects. The ` object ` model has the following fields:
327+
328+ <table >
329+
330+ <tr >
331+ <th >Field</th >
332+ <th >Type</th >
333+ <th >Purpose</th >
334+ </tr >
335+
336+ <tr >
337+ <td ><code >Delay</code ></td >
338+ <td >integer</td >
339+ <td >
340+
341+ How long, in milliseconds, to wait before starting playback of the sound.
342+
343+ * Default:* ` 0 `
344+
345+ </td >
346+ </tr >
347+
348+ <tr >
349+ <td ><code >Sound</code ></td >
350+ <td >string</td >
351+ <td >
352+
353+ An absolute file path of the sound file to play.
354+
355+ This mod expects to read an absolute file path here, and will use it to
356+ construct a cue in the soundback on your behalf. The purpose of doing this is
357+ to save you work; you would normally need to create your own cue for each sound
358+ file, which would require a lot of copy and paste busywork. Instead, you
359+ should use Content Patcher's ` {{AbsoluteFilePath}} ` token here and let Vox Box
360+ make the cue.
361+
362+ This field is required, since it is the purpose of patching in line readings.
363+
364+ If you use an Ogg Vorbis (.ogg) file here, which I recommend in general, this
365+ mod will automatically set StreamedVorbis to ` true ` on the resulting cue. This
366+ can cause major problems if your file is too short (see [ Caveats and
367+ Advice] ( #caveats-and-advice ) ), so either use longer sounds or switch to .wav
368+ for very short ones.
369+
370+ </td >
371+ </tr >
372+
373+ </table >
374+
375+ Just like line expressions, the list of objects corresponds to the indexes in
376+ the dialogue string. Set an object to null to avoid setting a line reading for
377+ that segment.
223378
224- Line readings defined this way are tied to the ID (see below) of the dialogue
225- itself, and take priority over type 1 voice data.
226379
227380### Content Patcher Example: Type 2
228381
382+ Here's what it might look like to add readings for specific lines:
383+
384+ ``` js
385+ {
386+ " Target" : " Mods/ichortower.VoxBox/LineReadings" ,
387+ " Action" : " EditData" ,
388+ " Entries" : {
389+ " Characters/Dialogue/Lewis:GreenRain" : [
390+ {
391+ " Sound" : " {{AbsoluteFilePath: assets/audio/Lewis/Dialogue_GreenRain_0.ogg}}"
392+ },
393+ {
394+ " Sound" : " {{AbsoluteFilePath: assets/audio/Lewis/Dialogue_GreenRain_1.ogg}}"
395+ }
396+ ],
397+ " 14:speak Haley \" Oh! @.$8\" " : [
398+ {
399+ " Sound" : " {{AbsoluteFilePath: assets/audio/Haley/Event14_Line0.ogg}}" ,
400+ " Delay" : 220
401+ }
402+ ],
403+ " 14:speak Haley \" The lighting is so nice right now... I had to come out and take some nature shots.\" " : [
404+ {
405+ " Sound" : " {{AbsoluteFilePath: assets/audio/Haley/Event14_Line1.ogg}}" ,
406+ }
407+ ]
408+ }
409+ },
410+ ```
411+
412+
229413## Caveats and Advice
230414
231- StreamedVorbis not recommended for VoiceData (clips are replayed frequently)
232- StreamedVorbis has minimum length
233- event command matching is a bit unwieldy
234- you can use translation keys in event command ` speak `
235- see the sample pack!
415+ - line readings is highest priority, then expressions, then voice data
416+ - StreamedVorbis not recommended for VoiceData (clips are replayed frequently)
417+ - StreamedVorbis has minimum length
418+ - event command matching is a bit unwieldy
419+ - you can use translation keys in event command ` speak `
420+ - see the sample pack!
0 commit comments