Forum rules - please read before posting.

[Bug] Multi-line speech with custom tags throws ArgumentOutOfRangeException

Here's the situation.
I have an action "Dialogue:Play Speech" with the following text:

[cam:FaceCam][mood:surprized]Who?
Ataruamterhemutranu?
[mood:normal]Of course not.

A little explanation about the tags. Tag [cam:something] finds the camera "something" and switches to it, while [mood:something] simply changes expression to something. Does exactly the same that [expression:something], only it is faster to type "mood" than "expression].

When the engine gets to this action my little dude speaks an empty line, and the debugger spits out long list of the following error:

ArgumentOutOfRangeException: startIndex + length > this.length
Parameter name: length
System.String.Substring (Int32 startIndex, Int32 length) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/String.cs:356)
AC.Speech.UpdateDisplay () (at Assets/AdventureCreator/Scripts/Speech/Speech.cs:460)
AC.Dialog._LateUpdate () (at Assets/AdventureCreator/Scripts/Speech/Dialog.cs:79)
AC.StateHandler.LateUpdate () (at Assets/AdventureCreator/Scripts/Game engine/StateHandler.cs:451)


So it seems the error is somewhere deep in the AC speech system.

The error seems to appear only when I use custom tags in several lines of text. If there is only one line, there is never a problem.

However, a speech action with following text (two lines), does not throw out exception:

[eyes:down]I'm wrong.
[eyes:straight]It was the cat.

Also, when I split the first example into two separate actions, there is no error, everything works as it supposed to.

Settings in the Speech Manager are as follow:
    Treat carriage returns asa separate speech lines: true
    Subtitles can be skipped: true
    Can skup with mouse clicks: true
    Retain subtitle text buffer once line has ended: true

Everything else is set to false. My AC version is 1.65.0.

Comments

  • edited November 2018
    Sure.



    Also I have a little update, which makes things even more confusing. The problem might not be with multi-line texts after all.

    This single line of text also throws the exception:

    "[cam:TaxCam][mood:surprized]What?!"  -> exception

    However this line of text works fine!

    "[mood:surprized][cam:TaxCam]What?!"  -> no problem


    And here goes the best part: the function I attach (for tests) to AC.EventManager.OnSpeechToken += OnSpeechToken" looks like that:


    private void OnSpeechToken (AC.Char speakingCharacter, int lineID, string tokenKey, string tokenValue)
    {
      return;
    }

    It does nothing! But there is still an exception. So if I do nothing and then nothing, it is ok. But when I switch the order and first do nothing and then nothing, we have an exception.

    Ok, if this doesn't sound crazy, I don't know what does.

    Please help. I'm afraid of developing my game now. I think there might be dark magic involved.
  • I'm having trouble recreating this.

    However, try opening Speech.cs, and find line 444:

    if (gapIndex >= 0 && speechGaps.Count >= gapIndex)

    Replace it with:

    if (gapIndex >= 0 && speechGaps.Count > gapIndex)

    Does that resolve it?
  • No. Still the same exception.
  • Here's a little help with debuging.


    I added the following text in line 460 in Speech.cs

    Debug.Log ("Full: " + log.fullText + ", Index: " + speechGaps[gapIndex].characterIndex);

    When the game got to the speech with this text:

    "[cam:TaxCam][mood:surprized]What?!"

    Here's what the debug said:

    Full: What?!, Index: 0
    Full: What?!, Index: 12
    ArgumentOutOfRangeException: startIndex + length > this.length
    and so on.

  • edited November 2018
    Ok, now I understand where the problem is.
    What I don't understand is why it has worked sometimes.

    I'm sure you figured it out by now, line 460 says:

    displayText = log.fullText.Substring (0, speechGaps[gapIndex].characterIndex);

    And it is supposed to set displayText to, I believe, text ready to be displayed. And it would, if the log.fullText contained the full, original text, with all those custom tags and all. But it contains already the text to display as far as I checked. And the speechGaps[gapIndex].characterIndex contains the index meant for the original text.

    I guess it's easy to see now why this bug survived so long. It was really hard to detect and reproduce: someone would have use more than one custom tag in the speach, but also the text to say had to be shorter than the first tag. Only then the index would go out of range.

    So the question is how to fix it?

    I'm not sure, but at this point in code log.fullText seems to be already processed and ready to display.

    So, Chris, can I replace the line 460:

    displayText = log.fullText.Substring (0, speechGaps[gapIndex].characterIndex);

    with:

    displayText = log.fullText ?


    Will it break something?
    I test it and it seems to work fine, the exception is gone, tags work, text looks exactly as expected. But since I don't understand fully this part of the code, I can't be really sure.
  • That wouldn't be a complete fix, no.  Please leave it to me.  However, I need to be able to reproduce this for myself, and so far I can't.

    Would you be able to share a project or .unitypackage that demonstrates the issue?  I would need your Managers, a test scene, which includes the custom tag code - assets such as graphics and sound can all be omitted.
  • Ok, I'll try to prepare something small.
  • edited November 2018
    Here is quick and dirty example project. I built it from the start, to make sure it is as clean as possible. I just packed it all, I hope it is enough.

    So there is a conversation on the start of the scene. Both characters try to speak and then generate exceptions.

    *REDACTED BY MODERATOR*
  • Link redacted: DO NOT post public to AC's source code - see the forum rules.

    Project downloaded, please leave this with me.
  • I'm sorry, you're right, it was stupid of me. I was tired and my brain refused to work properly.

    Won't happen again.

    I'll leave it with you then and wait for the patch.
  • Recreated.  This is to do with the ordering of custom tags: right now, they're assumed to be placed in the speech text in the same order as they're declared in your custom script.

    This is fixable, but will require a change in algorithm - as opposed to a simple tweak.  Expect a fix in the upcoming 1.66.0 release.
  • Thank you!

    I rely heavily on custom tags, as it saves lots of time, so I'll be waiting happily for 1.66.

    And I really admire the amount of work you put into the Adventure Creator. It saves us, game developers, unbelievable amount of time.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.