Need assistance with setting a narrator screen message with voice

Started by Gal Shemesh, Wed 21/06/2023 11:21:46

Previous topic - Next topic

Snarky

Are you running the game with F5 through the editor, or running the exe directly?

Gal Shemesh

Gal Shemesh,
goldeng


Gal Shemesh

Gal Shemesh,
goldeng

Crimson Wizard

I see now, when run from the editor, the AGS game reacts on mere presence of "Speech" folder, because it counts as an alternate clip location. When run from a compiled exe it will look for vox only.

Probably it could test for the presence of any sound files in the folder too.

Gal Shemesh

Yes, that would be great if it could behave that way.

I just checked whether the IsSpeechVoxAvailable() returns 0 when running the game from the EXE file and it actually does. Though I never thought there is a difference which is why I always relayed on running the game with F5 from within the editor.

Another thing I just noted in case the above thing gets fixed/added - if I compile all files once and a VOX file was created in the Compiled folder, when running the game from the editor it ignores the Speech folder completely and relays on the Speech.VOX file in the Compiled folder.

The same thing goes when adding more files to the Speech folder - if a Speech.VOX file was already compiled and I add new speech files to the Speech folder (or replace an existing file name with an alternate version) they don't play in the game until I re-compile all files. If I want the editor to relay on the actual Speech folder, I have to manually go into the Compiled\Windows folder and to delete the Speech.VOX file; I also manually delete the Speech.VOX file from the Compiled\Data folder to be on the safe side that it doesn't get use when testing the game.

I think that as long as the game is in development, testing the game from the editor should not relay and use the compiled VOX files, but rather relay on the presence of the source raw files in the game's folders.

Thanks for looking into this!
Gal Shemesh,
goldeng

Snarky

Yeah, the way running games from the editor works (in terms of which files/folders it references) is complex and confusing. Glad you found the reason for your problem!

Crimson Wizard

Quote from: Gal Shemesh on Mon 10/07/2023 09:03:15I think that as long as the game is in development, testing the game from the editor should not relay and use the compiled VOX files, but rather relay on the presence of the source raw files in the game's folders.

This is how it is supposed to work, but if you say it does not, then it's a bug, and engine got broken somewhere during the development process.

The idea was that Speech folder has a priority over speech.vox, or rather plain files on disk should have a priority over the package. This lets to add new files without recompiling large vox.

Same is true for audio files, and AudioCache folder.

Quote from: Snarky on Mon 10/07/2023 10:11:07Yeah, the way running games from the editor works (in terms of which files/folders it references) is complex and confusing.

Engine registers lookup locations with category filter. There are 3 filters now, called arbitrary "random files", "audio files", "speech files".
Locations may be directories or packages.
When searching for a file, directories are supposed to have priority over a package.

When run from the editor, engine receives instructions for alternate locations via a command line.

Random files:
- Root project dir
- Compiled/Windows dir - looks for random game files (that is mostly in case user added custom files)
- game package (whether attached to exe or *.ags)

Audio files:
- AudioCache dir
- audio.vox

Speech files:
- Speech dir
- speech.vox

Gal Shemesh

Thanks guys for the input! Much appreciated.

I'm glad that at least I know by now how to troubleshoot this if this is a bug - I checked both scenarios when running my game from the EXE file, based on different conditions that I set when the speech VOX file exists and when it is not, so I'm not worried:

I set in the game_start() function a condition to check if the IsSpeechVoxAvailable is false. If so, it changes the default Voice & Text mode and button to Text Only. I also added an else if statement for displaying a text message to the players about the missing sound pack, if they were to click on the Voice button in the settings panel.

And so, if IsSpeechVoxAvailable is true, the game starts in the default Voice & Text mode and players could cycle through the different voice modes using the Voice button.

Now I'm back testing my game from the editor, and just make sure that there is no speech VOX file in the Compiled folder until if and when this is fixed, so when I add / change sound files in the Speech folder I don't have to recompile everything every time.

Again, thanks for looking into this! This is not taken for granted and I much appreciate you participation and help.  :)
Gal Shemesh,
goldeng

Crimson Wizard

@Gal Shemesh

I tried this in 3.6.0, and it works as expected: if I add new files to Speech folder, or replace existing ones, without rebuilding speech.vox, then run the game from the Editor, then the files from the Speech folder are used.

Please tell in detail, how did you test this case in your game?

Gal Shemesh

Quote from: Crimson Wizard on Mon 10/07/2023 16:10:18@Gal Shemesh

I tried this in 3.6.0, and it works as expected: if I add new files to Speech folder, or replace existing ones, without rebuilding speech.vox, then run the game from the Editor, then the files from the Speech folder are used.

Please tell in detail, how did you test this case in your game?

Yes, that works for me too - the actual problem is this:

Rename your Speech folder to SpeechOld or something, and make a hotkey to see what isSpeedhVoxAvailable() returns to you - run the game from within the editor and it will return the value 1 instead of 0, even if there are no speech files available, which is incorrect. If you re-build all files and check this by running the game (that doesn't have any speech files in it) from the EXE, the hotkey will return to you the value 0, which is what it should have done by running the game from the editor. That's one problem.

The second problem is if you compile all files and then add or change an existing speech file in the Speech folder, when testing the game by hitting F5 from the editor, it won't reflect in the game unless you delete the Speech.VOX file from the Compiled folder.
Gal Shemesh,
goldeng

Crimson Wizard

Quote from: Gal Shemesh on Mon 10/07/2023 17:20:17The second problem is if you compile all files and then add or change an existing speech file in the Speech folder, when testing the game by hitting F5 from the editor, it won't reflect in the game unless you delete the Speech.VOX file from the Compiled folder.

That's what I was referring to:

Quote from: Crimson Wizard on Mon 10/07/2023 16:10:18I tried this in 3.6.0, and it works as expected: if I add new files to Speech folder, or replace existing ones, without rebuilding speech.vox, then run the game from the Editor, then the files from the Speech folder are used.

1. Make a game with sounds in Speech folder (e.g. EGO1, EGO2, EGO3), and few dialog lines that use these.
2. Rebuild all files. Test that everything works.
3. Replace 1 voice file in Speech folder.
4. Press F5 to run a test (dont rebuild all files), the replacement works.

Gal Shemesh

Found the problem. It's quite confusing and hard to spot but I got it - it's not when adding new sound files, which work fine without recompiling. It is when you modify or replace the sound files that were already compiled, if for example you want to re-record a certain file or replace what is said in it while keeping the origianl file numbers.

Steps to reproduce:
1. Create a new game with the Sierra-style template.
2. Put 1 audio file such as Ego1.wav in the Speech folder.
3. Go to the cEgo_Look function and change the "Display()" with player.Say("&1 Damn, I'm looking good!");
4. Rebuild all files.
5. Run the game with F5 and confirm that the Ego1 file is played.
6. Close the game and delete the Ego1.wav from the Speech folder.
7. Copy an different audio file to the Speech folder and rename it to Ego1 as well.
8. Run the game with F5 - the new replaced file won't be heard but the previous one that was originally compiled.
Gal Shemesh,
goldeng

Crimson Wizard

This is the precise situation I was referring to, and it worked for me.
I may test again, but it's quite strange.

Can anybody else try this out?

Does this sound replacement play at all, after you rebuild all files?

Gal Shemesh

Yep, if I rebuild all files then the new file that was replaced plays without any problem when running the game from the editor. Same as if I delete the Speech.vox file altogether from the Compiled folder.

Attached the new test game that I made if it helps - link

I've included in it a "_RESOURCES" folder with 3 speech files that I originally made for the Narrator in my version of the template. The first file is already in the Speech folder. I removed all the pre-compiled files so you could test it from scratch.

* There's also the Enter hotkey in it for the return value of the isSpeechVoxAvailable matter for your convenience. :)

If there's anything else you wish me to test from my side kindly let me know.
Gal Shemesh,
goldeng

Crimson Wizard

I tried this project and it works as supposed to.

1. Rebuilt all files, look at character: it sais "Damn you're looking good".
2. Went to Speech dir and deleted Ego1.wav
3. Copied Ego3.wav into Speech dir, and renamed to Ego1.wav
4. Pressed F5 in the editor, look at character: it sais "Talking to yourself is a sign of madness".

Gal Shemesh

Thanks for the checking. I'm really not sure what's going on - I can swear it didn't work before in more than one project that I tested, but from unknown and awkward reason when I test the game now from the zip file that I shared, the replaced speech file is played correctly. I hope it will remain that way and that we didn't both encounter a temporary scenario that it actually works.

Thanks again for looking into this! So the only issue remains is the isSpeechVoxAvailable matter that keeps returning 1 when the game is begin test from the editor, even when there are no speech files in the Speech folder.
Gal Shemesh,
goldeng

Gal Shemesh

Hi @Khris :)

On the same senario of the Narrate custom function you assisted me with, I'm trying to make the same thing for character.Say (any character) so the '&' with the speech file number will be outside of the actual string and not part of it, like when I call for the Narrate function as you instructed me:
Code: ags
Narrate(1, "Damn, you're looking good!");

However, I'm having some trouble modifiying the function to work.

The current function of yours with a little tuning for all the voice modes looks like this:

Code: ags
void Narrate(int cue, String text)
{
  String cueString = String.Format("&%d",cue);
  {
    if (Speech.VoiceMode == eSpeechVoiceAndText && IsSpeechVoxAvailable())
    {
      AudioChannel* ch = Game.PlayVoiceClip(cNarr, cue);
      Display(text);
      if (ch != null)
      {
        ch.Stop();
      }
    }
    else if (Speech.VoiceMode == eSpeechVoiceOnly && IsSpeechVoxAvailable())
    {
    cNarr.Say(cueString);
    }
    else if (Speech.VoiceMode == eSpeechTextOnly)
    {
      Display(text);
    }
  }
}

I've duplicated the custom function and managed to modify its code to make a specific character to say his cue, the same as the custom Narrate function does, but it's only for a specific character:

Code: ags
void Roger(int cue, String text)
{
  String cueString = String.Format("&%d", cue);
  {
    if (Speech.VoiceMode == eSpeechVoiceAndText && IsSpeechVoxAvailable())
    {
      AudioChannel* ch = Game.PlayVoiceClip(cEgo, cue);
      cEgo.Say(text);
      if (ch != null)
      {
        ch.Stop();
      }
    }
    else if (Speech.VoiceMode == eSpeechVoiceOnly && IsSpeechVoxAvailable())
    {
    cEgo.Say(cueString);
    }
    else if (Speech.VoiceMode == eSpeechTextOnly)
    {
      cEgo.Say(text);
    }
  }
}

Can you help me out making it work for any character?

Thanks

UPDATE:
I've just nailed it! The problem I had is that I declared the name 'character' after Character* which is already in used by AGS, so I changed it to 'myCharacter' instead.

Here's the code if anyone is interested not to include the speech file pointers ('&') in the actual character strings. This is very handy if you don't want to have the '&' pointer along with the strings in your translation file, and so you won't have to copy it for any translated lines below the original line. :)

Code: ags
// this function is used for showing character speech while having a speech file pointer OUTSIDE of the actual string.
// if you don't have a speech file yet just type 0 in its place.
// call for this function as follows where 1 is the first speech file of cCharacter:
// SayNew(cCharacter, 1, "A string for the character to say.");
void SayNew(Character* myCharacter, int cue, String text)
{
  String cueString = String.Format("&%d", cue);
  {
    if (Speech.VoiceMode == eSpeechVoiceAndText && IsSpeechVoxAvailable())
    {
      AudioChannel* ch = Game.PlayVoiceClip(myCharacter, cue);
      myCharacter.Say(text);
      if (ch != null)
      {
        ch.Stop();
      }
    }
    else if (Speech.VoiceMode == eSpeechVoiceOnly && IsSpeechVoxAvailable())
    {
      myCharacter.Say(cueString);
    }      
    else if (Speech.VoiceMode == eSpeechTextOnly)
    {
      myCharacter.Say(text);
    }
  }
}

Put the above in the GlobalScript header. And then call for it from other scripts like this, where cCharacter is your character ScriptName and 1 in the example is its first speech file Char1.ext in the Speech folder:

Code: ags
SayNew(cCharacter, 1, "the text string you wish the character to say"); 

* Note that this does not affect dialogue scripts and per my current knowledge, I'm not sure how to implement this in a way that dialogue scripts could use it with a speech file pointer that is outside of the literal string. So currently is you want to use this in dialogues you will need to use indentation and to use regular scripting method.
Gal Shemesh,
goldeng

Khris

Nice work, just wanted to point out that AGS supports so-called extender functions.

Code: ags
void SayNew(this Character*, int cue, String text)
{
  String cueString = String.Format("&%d", cue);
  {
    if (Speech.VoiceMode == eSpeechVoiceAndText && IsSpeechVoxAvailable())
    {
      AudioChannel* ch = Game.PlayVoiceClip(myCharacter, cue);
      this.Say(text);
      if (ch != null)
      {
        ch.Stop();
      }
    }
    else if (Speech.VoiceMode == eSpeechVoiceOnly && IsSpeechVoxAvailable())
    {
      this.Say(cueString);
    }      
    else if (Speech.VoiceMode == eSpeechTextOnly)
    {
      this.Say(text);
    }
  }
}

Now you can use
Code: ags
cCharacter.SayNew(1, "the text string you wish the character to say");

Gal Shemesh

Quote from: Khris on Tue 25/07/2023 22:14:41Nice work, just wanted to point out that AGS supports so-called extender functions.

Thanks, @Khris! :) I'm learning from the best I guess.

And thanks for pointing this out! I didn't understand at first why I couldn't just use cCharacter along with my new custom function name and make it to work. So that extender you mention is the 'this' word before the Character*?

*By the way, I've just posted my final mini-game "Going Home", which wasn't possible without your, @Crimson Wizard and @Snarky's help. So thank you all! :) You may find it in the Completed Game Announcements section.
Gal Shemesh,
goldeng

SMF spam blocked by CleanTalk