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):
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.)