MODULE: SpeechBubble v0.8.0

Started by Snarky, Sun 03/12/2017 11:28:04

Previous topic - Next topic

Snarky

Here's a module to do comic book-style speech bubbles. It's an alternative to Phylactere, because the older module doesn't work properly with 32-bit color. This module requires AGS 3.4, and for now it only works in 32-bit mode (or rather, transparency only works in 32-bit mode).

Initial development of this module was paid for by bx83, who agreed to allow it to be open-sourced.

To use, you call Character.SayBubble():

Code: ags
  player.SayBubble("This line will be said in a speech bubble.");


To configure, you set the SpeechBubble properties:

Code: ags
  SpeechBubble.BorderColor = Game.GetColorFromRGB(0,128,0);
  SpeechBubble.BackgroundColor = Game.GetColorFromRGB(128,255,128);
  SpeechBubble.BackgroundTransparency = 33;
  SpeechBubble.PaddingTop = 5;
  SpeechBubble.PaddingBottom = 5;
  SpeechBubble.PaddingLeft = 15;
  SpeechBubble.PaddingRight = 15;


(You should probably do this in game_start() in GlobalScript.)

This module is still under development, and is currently missing some functionality (in particular support for background speech). Please report any bugs you experience.

The module is available on GitHub.

Download SpeechBubble v0.8.0

Change Log:
0.8.0
-Implemented Character.SayBackgroundBubble()
-Added SpeechBubble.DefaultGui property
-Fixed crash with characters that don't have a speech view set

0.7.6
-Fixed an issue with lines with speech clips in text-only mode

0.7.5
-Initial pre-release

CaptainD

Thanks Snarky!

Definitely think I will be using this at some point.
 

Bavolis

Awesome! Definitely going to play with this one. Thank you! :)

Crimson Wizard

Finally someone did it :).


Although, Phylactere sounds so much nicer than Bubble, after all French is such a refined language, compared to the barbaric ones.

Snarky

Quote from: Crimson Wizard on Sun 03/12/2017 15:38:10
Although, Phylactere sounds so much nicer than Bubble, after all French is such a refined language, compared to the barbaric ones.

"Phylactere" always makes me think of "prophylactic". This module, in contrast, is 100% condom-free.

Bavolis

Everything's working very smoothly with only a couple of minor hiccups I'm trying to sort out. They may be on my end:

1. I have one cinematic scene where a floating head is in the middle of the screen. For some reason, it keeps shifting the SayBubble between above and below the character. I thought maybe it was a text length thing, but it puts some short ones on the bottom right next to long ones and then go back to the top for the next line. I don't seem to have any other characters with this problem. In the following example, all the SnipShadow lines play above his head, but cWinfillowFace alternates (but not in any kind of pattern) Here's what it looks like:

Code: ags
function room_AfterFadeIn()
{
cWinfillowFace.SayBubble("&1 You'll have a much bigger name than that.");
cSnipShadow.SayBubble("&10 Gah! Spooky voice has a spooky face. Perfect.");
cWinfillowFace.SayBubble("&2 We have much to discuss.");
cSnipShadow.SayBubble("&11 Who are you? Are you me?");
cWinfillowFace.SayBubble("&3 No. You are me. Now listen...");
cWinfillowFace.SayBubble("&4 You must meet me at the peak of the Knobbly Crook.");
cSnipShadow.SayBubble("&12 Right. Sure.");
cSnipShadow.SayBubble("&13 Um. I'm just going to head back home now.");
cWinfillowFace.SayBubble("&5 O'Sirus the Could Have Been...");
cWinfillowFace.SayBubble("&6 O'Sirus the Never-Was...");
cWinfillowFace.SayBubble("&7 Both are apt names.");


2. The text displays fine when I've got voices turned on, but if I turn them off in the game options, the larger text boxes close way too fast, even if I set my game text speed to 1 (which should be 1 character per second, if I'm not mistaken. The default 15 closes extremely fast. I'm not sure if this is due to AGS 3.4 or this module.

Snarky

Quote from: Bavolis on Mon 04/12/2017 00:28:09
1. I have one cinematic scene where a floating head is in the middle of the screen. For some reason, it keeps shifting the SayBubble between above and below the character.

Thanks! I'll look into it.

It'd be helpful to have some more info:

-What is your game resolution, room resolution, and position of your characters during this dialog?
-In the dialog, which lines display in the wrong location?
-What SpeechBubble settings are you using?
-Have you changed SB_sayImpl() (or any other part of the module)?

Quote2. The text displays fine when I've got voices turned on, but if I turn them off in the game options, the larger text boxes close way too fast, even if I set my game text speed to 1 (which should be 1 character per second, if I'm not mistaken. The default 15 closes extremely fast. I'm not sure if this is due to AGS 3.4 or this module.

Ah yes. This is a known issue that is actually a bit difficult to solve properly. (It's because AGS relies on the speech clip length to determine how long to play spoken lines, so the module sends a line containing just the speech clip code and no text (because we're already displaying the speech bubble and don't want the text to appear twice) to Character.Say(). However, if speech is turned off, it falls back to using String length, and since the String is so short it goes away almost immediately.)

The easiest workaround is to set an invisible font (SpeechBubble.InvisibleFont). Here is one you can use: http://www.angelfire.com/pr/pgpf/if.html

Snarky

I haven't been able to reproduce the first issue with the speech bubble positions. Maybe if I could get those details I asked for.

Quote from: Snarky on Mon 04/12/2017 07:15:10
Quote from: Bavolis on Mon 04/12/2017 00:28:092. The text displays fine when I've got voices turned on, but if I turn them off in the game options, the larger text boxes close way too fast, even if I set my game text speed to 1 (which should be 1 character per second, if I'm not mistaken. The default 15 closes extremely fast. I'm not sure if this is due to AGS 3.4 or this module.

Ah yes. This is a known issue that is actually a bit difficult to solve properly.

This turned out to be embarrassingly easy to fix, and the solution embarrassingly obvious. Updated in first post.

Bavolis

Great news on the first solution! Sorry, I've been at work all day, so just now getting to answer. Here are the details:

1024x768 is my game resolution and the room size.

These are the settings I changed (in the global script):

Code: ags
  SpeechBubble.BorderColor = Game.GetColorFromRGB(255,255,255);
  SpeechBubble.BackgroundColor = Game.GetColorFromRGB(0,0,0);
  SpeechBubble.BackgroundTransparency = 20;
  SpeechBubble.PaddingTop = 8;
  SpeechBubble.PaddingBottom = 5;
  SpeechBubble.PaddingLeft = 15;
  SpeechBubble.PaddingRight = 15;


I didn't change any of the code outside of the global script settings.

The two speaking characters are at:

397, 752 <--working fine
552, 483  <--this is the one having problems. The character's top Y coordinate is at 185.

Line positions (Winfillow only because Snipshadow is working fine):

Code: ags

cWinfillowFace.SayBubble("&1 You'll have a much bigger name than that."); <--BOTTOM
cWinfillowFace.SayBubble("&2 We have much to discuss.");<--TOP
cWinfillowFace.SayBubble("&3 No. You are me. Now listen..."); <--TOP
cWinfillowFace.SayBubble("&4 You must meet me at the peak of the Knobbly Crook."); <--BOTTOM
cWinfillowFace.SayBubble("&5 O'Sirus the Could Have Been...");<--TOP
cWinfillowFace.SayBubble("&6 O'Sirus the Never-Was..."); <--BOTTOM
cWinfillowFace.SayBubble("&7 Both are apt names."); <--BOTTOM
cWinfillowFace.SayBubble("&8 Horse."); <--TOP


I had some problem with the first room being corrupt and had to recreate it. If you don't see any reason for this bug, I can go ahead and redo this one too and see if that fixes it. This is my second oldest room that's gone through a few AGS updates.

Dave Gilbert

This is so cool! Is there any way to make these bubbles non-blocking?

Snarky

#10
Thanks Dave! I haven't implemented non-blocking speech yet, but it's next on my TODO list, after I figure out the bug Bavolis is experiencing.

Bavolis, please don't redo the room: I don't see any legitimate reason why it should screw up the module, and it's better to have a bug that can be reliably reproduced than one that we don't know how to trigger any more. Thanks for the additional details, BTW! I'll see if I can recreate the problem with a similar setup. If all else fails I might ask you to send me your project for me to test (or I could make a special debug version of the module for you that would help me nail down where it goes wrong).

Bavolis

#11
Quote from: Snarky on Tue 05/12/2017 15:39:28
Bavolis, please don't redo the room:

I'll wait to see what you can find out - any way I can help, let me know. I thought maybe it was a screen position thing and tried moving the character all the way to the bottom of the screen and the bubble still appeared below him. It's worth pointing out that there's nothing complex going on in this room, too - it's just a straightforward cinematic with lots of says.

EDIT: Snarky solved my problem - it was due to a normal view being tiny when what was being displayed in the idle view was proper sized. It comes as no surprise that the issue was on my end, but I appreciate the troubleshooting to help me find my mistake!

Snarky

Though it's worth noting that the SpeechBubble module behaves a little differently from AGS Character.Say() in this respect:

With Character.Say(), as near as I can tell, the text positioning is always based on the height of the (first frame in the) NormalView â€" unless it has been Locked to some other view â€" even if speech starts while an Idle view is playing. Character.SayBubble(), on the other hand, uses the current view at the time when speech starts, so if the idle animation is playing at that moment, it goes by the height of the Idle view. (I believe it can also be the SpeechView, if the character it already speaking.)

I can't see any way to determine whether the current view (if different from the NormalView) has been set with LockView() or is playing for some other reason, so I'm not sure it's possible to completely match the AGS behavior here.

Bavolis

Another small hiccup I'm having... if I have an inventory window open and look at an item, the saybubble appears behind the GUI(whereas the say function would appear in front of it). IS there a way to set an always in front priority? I don't see ever wanting to have the speech bubbles behind anything. Maybe it's already there and I missed it.

Snarky

#14
This is an AGS limitation. It renders things in a certain order that cannot be changed, back-to-front:

-The room and Objects and Characters in it
-Overlays, including SayBackground() overlays
-GUIs
-The Say() Overlay (and as of 3.4.1, the speech portrait)
-The cursor

So only by using Say() will text always show up in front of the GUIs. (Personally I think it would be more logical for speech to display behind GUIs by default, but it is what it is. The best thing would be if we could manipulate the Z-order freely.) By default, the SpeechBubble module displays the speech bubbles on Overlays, so they'll appear behind any GUIs.

However, there is a way to work around that limitation: you can pass a GUI to SayBubble() as an optional argument, and the module will display the bubble on that GUI instead of on an overlay. (The GUI should be empty and set to a transparent background and border.) If you set the GUI.ZOrder property higher than any of your other GUIs, it will display on top.

Also, as a pro-tip, if want to always use that GUI and don't want to add the argument every time you call SayBubble(), you can edit the SayBubble() function in the module to add this line at the very top (should be line 967):

Code: ags
  bubbleGui = gSpeechBubble; // Replace gSpeechBubble with the name of the GUI you want to use


(In an upcoming version I'll add a default-GUI property to the module so that you won't have to do this.)

Loslem

Really like that Module!

What would I have to do to make it wqork in the Tumbleweed Dialogues?

Greetings

Loslem

Snarky

Thanks!

You mean this template? I haven't used it, but as far as I can tell it doesn't really change anything to do with speech, so you should be able to use both the Tumbleweed Verbs template and the SpeechBubble module at the same time without issue. So you just import the module into your game project. (Save the scm file to your computer, and from the AGS "Explore Project" pane, right-click on "Scripts" and choose "Import Script...")

To get the speech bubble effect, you have to call Character.SayBubble(). So you should put that wherever you had Character.Say() before (where Character is replaced by the name of some character, or the special player variable).

So instead of this:

Code: ags
  cRoger.Say("It's a blue cup.");


You write this:

Code: ags
  cRoger.SayBubble("It's a blue cup.");


In dialog scripts, you must use the command instead of the simple "name: line" format, and have to indent the line with spaces or tabs. So instead of this:

Code: ags
player: What we have here is a failure to communicate.
Davy: What was that?


Put this (Notice that the lines start with two spaces):

Code: ags
  player.SayBubble("What we have here is a failure to communicate");
  cDavy.SayBubble("What was that?");


There's not much more to it. Hope that answers your question!

Loslem

Ah right it workes! I tried putting the commands in the dialog before and I got an error, but that was because I used the Hologram character from the template, and it had no Talking view. Error was "SetCharacterView: invalid view number (You said 0, max is 10)"

So, Characters seem to need to have a talking view assigned. I don't know if that is of any help :)

Snarky

Yeah, I just came across that issue as well. I've put in a check for it. Thanks!

Bavolis

Quote from: Snarky on Sat 09/12/2017 08:02:38

Also, as a pro-tip, if want to always use that GUI and don't want to add the argument every time you call SayBubble(), you can edit the SayBubble() function in the module to add this line at the very top (should be line 967):

(In an upcoming version I'll add a default-GUI property to the module so that you won't have to do this.)

Thanks for the quick help yet again!

SMF spam blocked by CleanTalk