About color text dialogs

Started by Diarandor, July 10, 2015, 04:29:00 PM

Previous topic - Next topic
Hi there!

I have modified Christopho's dialog_box.lua file so that the dialog box allows some commands for colored text.

For this to work correctly it is required that all letters have the same width (which happens for the font I am using, but may not be true for some of the fonts you use), because letters of different colors are drawn in different text surfaces, and to align the letters I use spaces when necessary.

The syntax of the new commands is the following:

${surface_name}: change to other surface. This allows to use several colors at the same time, one for each surface. The original one is "${default}". (These surfaces are destroyed after the dialog and the default one is reseted to white color.)

$[color] or $[(r,g,b)]: name of a color (red, blue,...) predefined in the function dialog_box:set_color(color), or RGB coordinates of some color. These commands only affect to the current surface.

(I was thinking that these surfaces could also be used to program other commands, for example to move letters up and down and make text vibration. I'll try to make this when I have some time.)

I'd like to share the code of the script. Should I post it here? Or maybe in the libsolarus-mudora repository?
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Nice!
Posting this to libsolarus-mudora is probably a good idea, you can make a pull request.

I made the pull request. I put a link to the repository, just in case someone is interested in the script when it is posted there:
https://github.com/Nate-Devv/libsolarus-mudora
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

July 10, 2015, 06:09:20 PM #3 Last Edit: July 10, 2015, 06:11:27 PM by Diarandor
It's already posted. I put an example of how to use the commands:

dialog{
  id = "put_the_dialog_id_here",
  text = [[
$[red]This is an ${g}$[green]example${default} to
show how the script
changes the ${y}$[(200,200,0)]colors.${default}$[white]
${y}Feel free ${g}to use or
modify it as you wish.${default}
=P
]]
}
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Wow, this is really cool! I tried to play around with colored dialogs and didn't get anywhere with it - great work!  8)

Is anyone else getting this repeating error? In on_draw [string "menus/dialog_box.lua"]:564: attempt to index a nil value
The only thing I changed was this section:
  -- Initialize dialog box data.
dialog_box.line_surfaces.default = {}; dialog_box.current_line_surface = dialog_box.line_surfaces.default
  local font, font_size = sol.language.get_dialog_font()
  for i = 1, nb_visible_lines do
    dialog_box.lines[i] = ""
    dialog_box.line_surfaces.default[i] = sol.text_surface.create{
      horizontal_alignment = "left",
      vertical_alignment = "top",
      rendering_mode = "antialiasing",
      font = font,
      font_size = font_size,
    }
  end

to take into account the global dialog font. Did I mess something up? I tried it with the exact dialog that you posted, but I think I'm still a little confused by the syntax.

July 11, 2015, 07:14:24 AM #5 Last Edit: July 11, 2015, 08:40:35 AM by Diarandor
Hi! I don't have this error, and I don't see why it happens, it's very strange. Did you have it before making the changes? (We can discuss this by email if you want.)

I think the error is in the line with "surface:draw(self.dialog_surface, text_x, text_y)", but not sure, isn't it? (This could mean that some of the other surfaces has not been created correctly and is nil.)

In the script there are more text_surfaces, which are created if the commands ${surface_name} is used, so you would need to change the font in that part of the code too. (I would put all the properties of the font above, where the general properties are defined.) I will try to improve a bit the code of the file in the repository.

PS: If you find the syntax terrible, I can change it. Suggestions are welcome. (At present, ${surface_name} changes the current surface and the commands $[color] and $[(r,g,b)] change the color of the current surface. But I can make changes in the file to change the syntax.)

EDIT: I found a mistake on my code. I was using sol.text_surface.create{...} instead of sol.text_surface.create({...}), so the parentheses were missing. This may be the cause of your problem, although it is strange that I did not get an error with this.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Hi wrightmat,

I have modified the script (see the repository) so that the dialog font and font size are set using the custom function sol.language.get_dialog_font(), which is defined on the main script, and also corrected a syntax problem which could be the cause of the error you got. I think this is what you needed. Tell me if you still get some error.

I'll be happy to help with these things, and any suggestion to improve the script is welcome.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Works great now - thanks!

I think the syntax is just fine, but I did go through and simplify things for my game. I wanted to be able to use $r, $g, $b, etc. for the colors just like $0 and $1 are used. If you'd like to check out my edited version, I just committed the change to zbom's github.

I am so excited to start adding colors to my dialogs! Thanks again!

April 13, 2017, 06:32:45 PM #8 Last Edit: April 13, 2017, 06:39:19 PM by Diarandor
Hi! Due to the fact that there was a lot of discussions about the color features of the dialog box (bugs and improvements), we can continue talking about this in this topic.

@llamazing: You said that you made a script that allows to change colors for any type of font (even non-monospaced fonts) and also working with special characters (multi-byte characters, like accents, Japanese characters, etc). Would it be possible for you to share it here? It may help others, including me, to improve our dialog box scripts.

@wrightmat: I think that your syntax is ok for your game, but it is not so good for other games if we plan to add more features that are combined with the color feature; for instance, we could allow to change the font type or size in the middle of a dialog, or even allow to code several "shaking" effects for part of a dialog, so the approach of changing surfaces (and give names to them) may be better in my opinion.

The only think one has to be careful, when using your syntax, is that when you change color before of a word, your syntax may be concatenated in a weird way sometimes. For instance, if the first word of a phrase (say, "Hello world") is in red and the rest in white color, you would have to write "$rHello$w world" without a space between the "r" and "H" because spaces are not ignored (unless we change the code). With my syntax it would be something like this: "${red_surface}$[color_name]Hello ${default}world", which makes slightly easier for translators to detect where the color syntax ends, I think. It is also good to allow choosing color with the "$[(r,g,b)]" syntax too, just in case we don't want to define a color name for a color that is used just once; for colors that are used a lot it is probably better to use the other syntax, "$[color_name]", so allowing both syntaxes seems a good idea to me.

Note that if we try to expand the features of the dialog box, for instance to add a shaking effect, it would be usefult too the change of surface. If we use a LaTeX-like command for the shaking effect, say "$\{shake}text to shake", an example for a shaking word would be: "This ${shaking_surface}$\{shake}word ${default}is shaking". I was thinking that it could be more intuitive if we use a math mode like in LaTeX, where dollar symbols $ are used to start and to end math mode in a way like this "blablabla $\command_name{optional_parameters}$ blablabla", and enviroinments can be started or finished in the same way (maybe we could omit the dollars, or just use the dollars as if they were the "\" symbol as I already did in my syntax).

@everybody: Well, we all should discuss which syntax for the dialog box could be more intuitive, but also versatile for all kind of general purposes, and it would be nice to fix a standard notation compatible between all games. (It could even be added to the Quest Editor if Christopho or someone else programs the Editor to display the text with that kind of features (colors, shaking effects, change of fonts or size, etc), but I guess that this would be too specific and is probably a bad idea for the Editor.)

Our main purpose in this topic would be then to fix an "official" syntax for dialog box features that produces no limitations (i.e., that allows to add more commands and as many of them as we want) and is intended to be used in most games of the community (for compatibility reasons). We could share the code here or in some github repo. We could even open some poll in the forum, if necessary, to make some decissions.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Quote from: Diarandor on April 13, 2017, 06:32:45 PM
@llamazing: You said that you made a script that allows to change colors for any type of font (even non-monospaced fonts) and also working with special characters (multi-byte characters, like accents, Japanese characters, etc). Would it be possible for you to share it here? It may help others, including me, to improve our dialog box scripts.

This script parses the text of dialogs.dat and processes player inputs:
https://github.com/llamaizing/cythera-tech-demo/blob/master/data/scripts/menus/dialogs/conversation_dialog.lua

> Note: dialog_box.text_areas contains the text from dialogs.dat

I wrote a library of UI elements, and this one is for multi-line text, used by the script above for the dialog box. This script handles the drawing to the screen, including making the "hyperlink" text a different color:
https://github.com/llamaizing/cythera-tech-demo/blob/master/data/scripts/lib/uix/controls/multiline.lua

> See lines 151-166 for keeping track of the position(s) of the hyperlink text to be colored differently
> See the ml:refresh() function for drawing of the text (especially lines 301-321)

I provided some details about the syntax I use for the dialogs here (I'm not suggesting syntax to use for this topic, just to be able to make sense of my scripts):
http://forum.solarus-games.org/index.php/topic,873.msg4864.html#msg4864




FYI-- don't be confused by the way I named my scripts. I used 3 types of dialogs in my project:

  • scrips/menus/dialogs/conversation_dialog.lua - to display a text box for when talking with an NPC (this is the one relevant for this topic)
  • scrips/menus/dialogs/question_dialog.lua - for displaying system level pop-up dialogs with buttons (e.g. "Do you want to save?")
  • scrips/menus/dialogs/sleep_dialog.lua - to display a dialog to select how long to sleep when using a bed.

/scripts/dialog_manager.lua - manages the 3 types of dialogs above and processes keyboard/mouse inputs from the player. Ignore this one, it's not relevant to this topic.
/scripts/conversation_manager.lua - maps out the conversation, deciding which text to display next. It has nothing to do with drawing the dialog box and can be ignored for the purposes of this topic.

Thanks a lot @llamazing!
I'm sure your scripts will be useful to others to program similar features.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

My suggestion for syntax is to keep it simple and just use a dollar sign followed by a single letter to specify the command name, e.g. $c{red} for red text. For changing fonts it could be $f{courier} and $s{12} for font size.

I like the idea for having additional options too, such as specifying a color code, e.g. $c{255,0,170}. It might be easier to parse if a hex color code were used, like $c{ff00aa} because then there would always be exactly 6 characters and the commas would not be necessary.

I'd even go a step farther and allow for a third option where up to 9 preset values can be used, as hard-coded somewhere in the script, e.g. $c1 thru $c9. $c0 could be used as shorthand for $c{default}. This has the advantage of being very few characters.

I'd recommend against using the \ character in the syntax. It would make the parsing more difficult for separating out special characters like \n or \t. I also don't see any reason to include a second closing dollar sign. Adds one more character everywhere and potentially confusing for translators.

April 15, 2017, 02:06:03 PM #12 Last Edit: April 15, 2017, 03:58:28 PM by MetalZelda
Oooooo, i like this, i'll try this with different language to see if that works correctly

I also suggest adding a horizontal text alignment thing like $vertical{"center"}
i don't know, maybe centering some text be cool

It would be very useful too to add a feature that manages the change of line of the dialog box if the max lenght of one line is given. I don't have time these days to work on this, though.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

April 16, 2017, 01:54:20 AM #14 Last Edit: April 16, 2017, 02:00:47 AM by MetalZelda
There is still the spacing problem if you use a special characters such as é, è, ç, à and Asian type characters, even with a mono-spaced font, hmmm, this is one tough issue.
There is no problem when texts are in english though, but it is problematic, because, I am translating Book of Mudora in French and some texts overlap depending on if there is a special character before the colored text. This will also happen if you translate in Spanish / Russian / Asian languages.

This is the new surface's space that is problematic, the script already includes special characters it seems, but I can't figure out what is the real issue here ...