Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: rongel on Wed 10/04/2024 09:38:22

Title: Multiple colors in a line of text to highlight keywords
Post by: rongel on Wed 10/04/2024 09:38:22
Hello!

I looking into using several colors in a line of text, highlighting key words and effects. Is this possible at all?
I'm experimenting with text labels and the dialog system. The point is to do something a bit similar than in Slay the Spire and many other RPG's:

(https://i.imgur.com/nCHxzSj.png)

I'm using abstauber's CustomDialogGui 1.9, which is great, but it doesn't offer that kind of functionality with colors afaik.

When searching the topic, I found SSH's Hypertext module (https://www.adventuregamestudio.co.uk/forums/modules-plugins-tools/module-hypertext-v1-3-change-font-mid-sentence-web-like-pages-speech-bubble/), which is supposed to do this, but the module is very outdated, and doesn't seem to work that well anymore.

Thanks for any help! 
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Matti on Wed 10/04/2024 09:52:01
I was just wondering the same thing. I also experimented with text labels and wasn't able to have different colors within a single label/line. Would be a great functionality.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Snarky on Wed 10/04/2024 11:50:39
To do this you will need to draw the string yourself in multiple steps, each with a different color, using DrawingSurface.DrawString().

That isn't particularly difficult, but the question is how you control which colors to use for the different parts of the text. SSH's module allows you to use markup to modify the appearance, but parsing that takes a bit of work. You could of course hard-code it, but at that point you might as well just use separate labels.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Wed 10/04/2024 14:00:35
Quote from: Snarky on Wed 10/04/2024 11:50:39To do this you will need to draw the string yourself in multiple steps, each with a different color, using DrawingSurface.DrawString().

Thanks Snarky for the advice! I'll look into DrawingSurface, but I have a feeling that path will complicate my current setup too much. Currently I have a custom dialog Gui and a text label for the descriptions. They work together nicely, and it's easy to create and edit similar scenarios as in the screenshot. So I might just try to use separate labels and see if something similar is possible.

Quote from: Matti on Wed 10/04/2024 09:52:01I was just wondering the same thing. I also experimented with text labels and wasn't able to have different colors within a single label/line. Would be a great functionality.

I agree 100%!
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Snarky on Wed 10/04/2024 14:02:54
Quote from: rongel on Wed 10/04/2024 14:00:35
Quote from: Matti on Wed 10/04/2024 09:52:01I was just wondering the same thing. I also experimented with text labels and wasn't able to have different colors within a single label/line. Would be a great functionality.

I agree 100%!

Again it comes back to: how would you configure it?
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Matti on Wed 10/04/2024 15:00:53
Quote from: Snarky on Wed 10/04/2024 14:02:54Again it comes back to: how would you configure it?

Wouldn't it be (theoretically) possible to have a textcolor for a specific String instead of a whole label? That way one could add several strings in a row with different colors each.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Wed 10/04/2024 15:33:51
Quote from: Matti on Wed 10/04/2024 15:00:53Wouldn't it be (theoretically) possible to have a textcolor for a specific String instead of a whole label? That way one could add several strings in a row with different colors each.

Label has a single String Text property and it must be able to return everything that was set. If it has to support multiple strings each with its own color, then Label would need to be redone into having an array of Texts, paired with color values, at least.


A more universal way to do this would be to implement an extended type of Label that supports some kind of a display formatting in a string, using tags.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Wed 10/04/2024 23:15:02
I think tags are a nice way, it could be like there is a DrawStringWrapped it could have a DrawFancyStringWrapped or whatever the name for it that adds such feature - in addition to LabelFancy or whatever, like Winforms has TextBox and RichTextBox.

There's a particular Game Maker plugin/module called Scribble (made by Juju Adams) that has a ton of interesting features for writing text and one of them is this addition of having text using multiple colors. It uses a tag system somewhat similar to the one we have here on the forums: https://www.jujuadams.com/Scribble/#/latest/text-formatting
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Thu 11/04/2024 07:10:54
Quote from: Crimson Wizard on Wed 10/04/2024 15:33:51A more universal way to do this would be to implement an extended type of Label that supports some kind of a display formatting in a string, using tags.

Quote from: eri0o on Wed 10/04/2024 23:15:02I think tags are a nice way, it could be like there is a DrawStringWrapped it could have a DrawFancyStringWrapped or whatever the name for it that adds such feature - in addition to LabelFancy or whatever, like Winforms has TextBox and RichTextBox.

It would be great to have that kind of functionality added to labels. It could be used to emphasize a certain word in a dialog (by changing the font / color), or by making fancy RPG Guis for example.

If that functionality could be added to dialog options as well, everything would be perfect  :=
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Thu 11/04/2024 07:37:45
This may be done with a script module, if it's only colors then this should not be overly complicated imo.

General idea may be following:
1. Parse the input string, write down an array of positions where color changes, and get a pure string without tags.
2. Calculate line splitting for a pure string, as you would with a normal text.
3. Draw parts of lines line by line and colored section by section.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Snarky on Thu 11/04/2024 09:12:53
Yeah, that's part of what SSH's module does, but it also has things like hyperlink support that isn't really needed.

What would we want to be able to support? Of things AGS lets you control, I can think of:

(Also, if you're mixing different fonts, you probably need some way to control the baseline alignment, though that might be more a module configuration thing than something in the markup.)

Some further options would need to be "faked" (using different fonts or drawing tricks), but it might be convenient to make them accessible via a simple markup:

Other possible formatting/markup features:

And something I think will be a very useful general feature:

Things I don't think should be supported by such a module:

I think the biggest decision to make is how to encode the formatting. XML/HTML (+CSS?) or LATEX seem like overkill. Markdown would be a nice choice in a lot of ways, but it doesn't support setting color. BBCode (like on this forum) runs into the problem of AGS interpreting [ as a linebreak.

Quote from: eri0o on Wed 10/04/2024 23:15:02There's a particular Game Maker plugin/module called Scribble (made by Juju Adams) that has a ton of interesting features for writing text and one of them is this addition of having text using multiple colors. It uses a tag system somewhat similar to the one we have here on the forums: https://www.jujuadams.com/Scribble/#/latest/text-formatting

It's an interesting point of comparison, and I like the approach of not having to close tags. The only tags I see as immediately relevant are color and possibly alpha and scale (though with AGS's text rendering I don't think scale will give very good results).
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Thu 11/04/2024 11:19:42
My feature list in mind is very different, lol, as for me typewriter and animation are much more important than bold and italics, which I wouldn't support (they don't work in game UI in my opinion), I also wouldn't support bullet list (again, think if you need you are already with some button system, which doesn't make it useful)... I think if you can have enough to do a system like the one in Zelda Ocarina of Time and Undertale, then it should work.

I thought about making such text module in the past but imagining it's output is a sprite, there's not something that could receive it to implement the rest of the dialog system, so you endup to have to go beyond and also do all the dialog boxes in the same module.

Here is a module for love2d called Moan :  https://github.com/elennick/Moan.lua

(https://raw.githubusercontent.com/elennick/Moan.lua/master/preview.gif)

Note it also includes delays when showing typewritten text, I remember Rpg maker 2000 supported that too using a tag system.

Here is SYSL-Text : https://github.com/sysl-dev/SYSL-Text

(https://raw.githubusercontent.com/sysl-dev/SYSL-Text/master/screenshots/02.gif)

I think I probably would do this with one Overlay per letter to be able to be more flexible but the issue is you lose the easyness to share it with some other module, this is why in my head it has to become a big swiss army knife of talking module.

But remember... text rendering hates you (https://faultlore.com/blah/text-hates-you/).
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Snarky on Thu 11/04/2024 11:42:47
The main reason I wouldn't include typewriter text is because there already is a typewriter module, and because then you need some way to update it, keep track of state, etc., which adds a whole other level of complexity. (Though I agree that it should be compatible, so that you could combine formatted text with a typewriter effect or other kinetic typography.)

If we're going to have text formatting, I think things like bold and italics are pretty essential. Don't think just of the UIs, but use-cases like dialog (e.g. to use italics for thoughts, or italics or bold for emphasis or sound effects in conversations), games where you can read books or look at web-pages, or in-game documentation, etc. The use-case I had in mind for lists was for if we could parse markdown documents, so that you could read e.g. a change log from file and display it in-game.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Thu 11/04/2024 12:50:17
I would also separate typewriting from text formatting, as typewriting is more or less step-by-step alteration of "current text" (or "current position"), and this may be done by a higher-level "class", similar to how existing typewriter modules use labels or textual overlays.

In other words,

  Typewriter
            ->  Fancy text drawer
                        -> Drawing surface
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Snarky on Thu 11/04/2024 13:07:12
Quote from: eri0o on Thu 11/04/2024 11:19:42I think I probably would do this with one Overlay per letter to be able to be more flexible but the issue is you lose the easyness to share it with some other module, this is why in my head it has to become a big swiss army knife of talking module.

This is something I would try hard to avoid. When I've been working on the SpeechBubble and Lipsync modules, the architecture and implementation have often pushed in this direction, but the scope just gets so gigantic and unwieldy that it's almost impossible to complete.

What I do agree with is that it would make sense to also control typewriter dynamic text formatting (e.g. speed) with tags in the same way as rich text.

Rather than try to do everything in one big module, would it be possible to have a parser that could be generic enough that it could simply report the tags/commands detected one by one, and then different modules could handle the ones they know about?
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Thu 11/04/2024 13:39:00
By the way, in regards to module communication; it's a fact that AGS script currently does not have a easy method of making "interfaces", as in, abstract classes that declare methods which other classes implement.

It's possible to extend a base class, and upcast a managed pointer to base class. This allows to make a parent class with the most basic commands and properties, which may be then extended by an actual implementor. For example:
Code (ags) Select
managed struct TextDrawer
{
    protected String fullText;
    protected int drawFromChar;
    protected int drawToChar;

    import void SetText(String text);
    import void SetDrawRange(int from, int to);
};

// then elsewhere

managed struct FancyTextDrawer extends TextDrawer
{
    ... do actual stuff
};

/*managed?*/ struct Typewriter
{
     import void SetTextDrawer(TextDrawer *text_drawer);
};

In the above example, a Typewriter class could have a pointer to TextDrawer and assign from/to properties, telling actual FancyTextDrawer which part to draw.

The problem with above is that this imposes a base class restriction on implementing classes. There may be only 1 parent class, and if there's a case where extending something is not convenient, or we need more than 1 interface type implemented by the same class for some reason, then this approach no longer works.


So I've been thinking if there's a workaround in AGS script, and I think that an alternative is a helper managed struct serving a "messenger" between 2 classes.

Consider following example:
Code (ags) Select
managed struct TextDrawerInstruction
{
    int drawFromChar;
    int drawToChar;
};

/*managed?*/ struct FancyTextDrawer
{
    import void SetDrawerInstruction(TextDrawerInstruction *inst);

    protected TextDrawerInstruction *myInst;
};

/*managed?*/ struct Typewriter
{
    import TextDrawerInstruction *GetDrawerInstruction();

    protected TextDrawerInstruction *myInst;
};

Here we do not require the class to extend any parent, but require that it could accept a certain object by pointer, and read that object when deciding what to do. Typewriter in this example has to give this "message" object out and change its parameters over time, thus saying that things should be drawn differently.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Cassiebsg on Thu 11/04/2024 17:52:35
Just meddling a bit.  :-D
I like the tags idea, and while we can't use [ maybe we could use some other character(s) that would be unlikely to show up in text, like ##C123456#B#U## could maybe work (doesn't need to be #, just something unlikely to show up in text labels?

player.Say("This is a ##C123456#B#U## test.");
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Scavenger on Thu 11/04/2024 21:40:30
I've done something similar, though it only works in 8-bit mode.

(https://iili.io/JvngVSV.md.png)

With the markup being:
//That's @j1BILL@n. @c009Bill Beltbusta!@c015 Don't you forget it!It's pretty easy to parse something like this if you have an escape character. For it I don't use labels, just dynamic sprites and buttons. Though it's far from usable outside of the contexts I'm using it for.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Thu 11/04/2024 22:30:44
The reason it would be good to get it in-engine is I believe I can hack down a module that does whatever in a low resolution game. But I don't think I can do the same efficiently for a high resolution game, it's just that raw sprite drawing is slow through the script API right now to do this in there.

But to me anything like markdown feels completely useless in a game context and animation is much more relevant. In a high resolution game if a textbox takes a quarter of the screen, that will be the amount of pixels per frame I will be pushing to texture convertion per frame.

Anyway, I think it's doable for a script context for low resolution... But maybe a plugin would be easier to hack up to demonstrate it going since the plugin API for text already exists.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Fri 12/04/2024 07:02:34
I think this conversation goes somewhat sideways. It started with a very specific user request, but now there's a discussion about a hypothetical functionality which contains a list of features, and everyone has got their own list.

The starting request has 2 conditions, at least from my understanding:
1. Being able to color particular words or sequence of words.
2. The text is static, so "raw" drawn once and then kept displayed without changes.

Is this correct, or was there anything else to it?

I think that above may be easily done by a script module today, and should not cause much trouble in high resolution (latter may be tested for performance to see if I'm right or wrong).

Perhaps it would be proper to focus on this problem in this thread, and find out how to solve this within the existing engine version?



For a more complicated functionality, I believe, it's a matter of deciding the purpose and use cases, then writing specification of a desired behavior. Personally, I can easily see a use case for both an animated text, and a emulation of a markdown or HTML page in game. These may require separate approaches, while having some "base functionality" beyond (there's always ways to pick out common code).

Implementation is always a separate question. Once there's a requirement for behavior, we can think about how to implement this, having performance in mind.

It may turn out that it is not possible to run "something" fast in the current engine, because engine does not support modern fast ways of doing things. Like rendering text glyphs as textures, for example, or similar. That's fine, we may leave that "something" for the better times, or keep it potentially slow, available for users who may live with that, and writing down list of things we'd need in the engine to make it faster.

But please, don't plan on pushing the giant formatting feature into the engine only because it's slow to make in script at the moment. I do not think that this whole text formatting with colors and animations should be inside engine, because engine is meant for "basic logical bricks". Everyone will have their own ideas about the formatting behavior, and should have a chance to implement them. IMO it's better to look at this in opposite way, and figure out what the engine could provide to make things like this formatting easier to do in script. Like, if you remember, there was a suggestion of hardware accelerated drawing: https://github.com/adventuregamestudio/ags/issues/2059



On another hand, there may also be various tricks already available to speed things up, if updating a text made with raw drawing appears slow. I don't know about having each letter as an overlay, but it could be separate overlays for animated parts, for example.
Another thing, for a typewriting, instead of redrawing whole thing after every letter is added, one could draw the full text at once, and then hide the part that should not be visible yet with an overlaying object.
Well, just saying.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Fri 12/04/2024 15:43:06
@Crimson Wizard , that ticket is really something that would be great. Like you would send the commands and some form of accelerated drawing would run like at the release call or in some lazyway, and then yes I agree we could have it done by script.

Quoteone could draw the full text at once, and then hide the part that should not be visible yet with an overlaying object

Yeah, if we have some way to "mask" or use a "stencil" of somehow, then I think this is the best way, because then one can do the drawing before, so the tags for color and whatever are already processed and it can have information on the size of each "token" that is getting typewritten, and in this way it works nicely even for languages that use ligatures and everything. Otherwise the typewriter module has to know about the parsing of the color/formatting tags.

But I do think we could have more nice things in Engine. As an example, there's a whole plugin (the SpriteFont) for drawing text that we maintain and features from it could be in engine itself - although it would need some thoughts on this, it's been there for a few years now.

I mean, we don't even have something to break a string in array of strings to make parsing easier. So some niceties to Strings would be nice to make it easier to parse - right now I can only think about going character by character. We also don't have regular expressions.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Sun 14/04/2024 00:37:36
Spoiler
I am trying to come up with a parser, I can't really think in a good way to structure the code to do it in one go, I am trying the following approach.

  • I am using a small stack per type of tag (for my test I am using only font and color), this is so I can go back to the previous state before the tag, but also support a little nesting
  • I parse all text into an array of text tokens that simply hold the string, color and font type, just the minimum so I can remove all tags and not lose information
  • I now read the text tokens and break in the middle of a text token (or not) per width, and also draw things

I actually don't draw directly and instead do draw commands and next do the drawing. I want to later see if I can come up with either a renderer that doesn't redraw if not needed or that is accelerated based on overlays.

It appears to work somewhat. Need to clear up a few details though before posting it here.
[close]
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Sun 14/04/2024 04:18:46
Spoiler
Here is it a preliminary version that can use c as a tag for color and f as a tag for font, you can pass a value using : which is an int number that is either the AGS color value or the font index.

function room_AfterFadeIn()
{
  DrawingSurface* surf = Room.GetDrawingSurfaceForBackground();
 
  String ft = "[c:48214]test string[/c] hi test [f:1]font [c:64939]different[/c] working[/f] now back.";
 
  surf.DrawFancyTextWrapped(48, 48, 200, 22422, eFontNormal, ft);
}

It has a small issue with spaces which I can't quite figure it out, when the style changes it appears it doesn't properly do the space between words but not sure why yet.

Below is the module header and script


FancyText.ash
// fancy text module header
// by eri0o
import void DrawFancyTextWrapped(this DrawingSurface*, int x, int y, int width, int color, FontType font, const string text);

FancyText.asc
Spoiler
// fancy text module script

#define MAX_TXTTK 1024
#define MAX_TXTST 32

struct TextToken {
  int color;
  FontType font;
  String text;
  int width;
  int height;
};
TextToken _txttk[MAX_TXTTK];
int _txttk_count;

void _AppendTxtTok(String text, int color, FontType font)
{
  int i = _txttk_count;
  _txttk[i].color = color;
  _txttk[i].font = font;
  _txttk[i].text = text;
  _txttk[i].width = GetTextWidth(text, font);
  _txttk[i].height = GetFontHeight(font);
  _txttk_count++;
}
void _ClearTxtTok()
{
  _txttk_count = 0;
}

enum TagType {
  eTagNone = 0,
  eTagColor,
  eTagFont 
};

struct StackOfInt
{
  int items[MAX_TXTST];

  int index;
  import void Push(int number);
  import int Pop();
  import void Clear();
};
void StackOfInt::Push(int number)
{
  this.items[this.index] = number;
  this.index++;
}
int StackOfInt::Pop()
{
  this.index--;
  return this.items[this.index];
}
void StackOfInt::Clear()
{
  this.index = 0;
}

StackOfInt _stk_font;
StackOfInt _stk_color;

TagType _get_tag_type(String tag)
{
  int c = tag.Chars[0];
  switch(c)
  {
    case 'c': // color
      return eTagColor;
    case 'f': // font
      return eTagFont;
  }
  return eTagNone;
}

int _get_tag_data(String tag, TagType tag_type)
{
  if(tag_type == eTagNone) return 0;
  int p = tag.IndexOf(":");
  if(p <= 0) return -1;
  p++;
   
  String data = tag.Substring(p, tag.Length - p);
 
  if(data.Chars[0] >= '0' && data.Chars[0] <= '9') return data.AsInt;
  return 0;
}

void _parse_text(String text, FontType base_font, int base_color)
{
  int len = text.Length;
  bool plain_text = true;
  int color = base_color;
  FontType font = base_font;
  String ttok = "";
 
  // first element is a fake to hold length as color
  _ClearTxtTok();
  _AppendTxtTok("", len, 0);

  for (int i=0; i < len; i++) {
    int c = text.Chars[i];
  // System.Log(eLogInfo, "%c", c);
   
    if(c == '[')
    {
      if(ttok.Length > 0) {
        _AppendTxtTok(ttok, color, font);
        ttok = "";
      }
     
      i++;
      bool is_closing = false;
      if(i < len && text.Chars[i] == '/') {
        is_closing = true;
        i++;
      }
     
      int j = i;
      while (j <= len && text.Chars[j] != ']') j++;
      int delta = j - i;
     
      String strtag = text.Substring(i, delta);
      TagType tag = _get_tag_type(strtag);
      TagType tdata = tag;
      if(is_closing) tdata = eTagNone;
      int data = _get_tag_data(strtag, tdata);
      switch(tag) {
        case eTagColor:
          if(is_closing) color = _stk_color.Pop();
          else {
            _stk_color.Push(color);
            color = data;
          }
          break;
        case eTagFont:
          if(is_closing) font = _stk_font.Pop();
          else {
            _stk_font.Push(font);
            font = data;
          }
          break;
      }
     
      i += delta + is_closing;
    }
    else if(c == ' ')
    {
      ttok = ttok.AppendChar(c);
      _AppendTxtTok(ttok, color, font);
      ttok = "";
    }
    else if(c == '\n')
    {
      _AppendTxtTok(ttok, color, font);
      _AppendTxtTok("\n", color, font);
      ttok = "";
    }
    else
    {
      ttok = ttok.AppendChar(c);
    }
  }
  _AppendTxtTok(ttok, color, font);
}

void _draw_text(DrawingSurface* surf, int x, int y, int color, FontType font, const string text)
{
  surf.DrawingColor = color;
  surf.DrawString(x, y, font, text); 
}

void _write_tokens(DrawingSurface* surf, int x, int y, int width)
{
  int start_i, end_i, p_i;
  int len;
  int r_x = x;
  int r_y = y;
  int w;
  int itk = 0;
  int color;
  int font;
  int word_width;
  int word_height;
  int line_height;
  String word;
 
  // fake initial token encodes as color
  len = _txttk[itk].color;
  itk++;
 
 
  for(; itk < _txttk_count; itk++)
  {
    word = _txttk[itk].text;
    font = _txttk[itk].font;
    color = _txttk[itk].color;
    word_width = _txttk[itk].width;
    word_height = _txttk[itk].height;
   
    int word_len = word.Length;
   
    if(word_len <= 0) continue;
   
    if(w + word_width > width || (word_len == 1 && word == "\n"))
    {
      // line break
      r_x = x;
      r_y += line_height;
      w = 0;     
      line_height = 0;
    }
   
    if(word_height > line_height) line_height = word_height;
    w += word_width;
   
    // do draw command
    _draw_text(surf, r_x, r_y, color, font, word);
   
    r_x += word_width;
  }
}

void DrawFancyTextWrapped(this DrawingSurface*, int x, int y, int width, int color, FontType font, const string text)
{
  _parse_text(text, font, color);
  _write_tokens(this, x, y, width);
}
[close]
[close]
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Sun 14/04/2024 20:49:51
Spoiler
OK, did a ton of more work and set up a repository here: github.com/ericoporto/fancy/blob/main/fancy_demo/fancy.asc (https://github.com/ericoporto/fancy/blob/main/fancy_demo/fancy.asc)

It now can do this

function room_AfterFadeIn()
{
  DrawingSurface* surf = Room.GetDrawingSurfaceForBackground();
 
  surf.DrawingColor = 10565;
  surf.DrawRectangle(48, 48, 248, 108);
 
  String ft = "Hello!\nCan you find me the [c:27647]blue cup [s:2041][/c]?\nI lost it in the [c:64493]dangerous [f:0]planet[/f][/c], somewhere.";
 
  surf.DrawFancyTextWrapped(48, 48, 200, 22422, eFontSpeech, ft);
}

(https://i.imgur.com/gebvAfD.png)

I will try to properly release this as a module in the next days...
[close]
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Matti on Mon 15/04/2024 11:47:47
Nice work so far, eri0o!
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Mon 15/04/2024 12:42:44
Thanks @Matti !

So far I got a minimal typed text added too, in case it's needed. I am experimenting with a new tag for delaying it slightly. The text is only parsed once and the information is used later when typing, so it's not performance intensive.

I also added alignment (in the picture it's bottom left), but won't be adding it per tag, just for the whole box (would complicate the code a lot!)

I want to see if I can materialize an animated version of it - for a bouncy text or something, but I think I won't make it before first release - the animated token knows the line height, so it has an idea of the size of the area it has to move text around, but the actual animation code is a bit complicated when compared to how is everything else so far.

Other than this I haven't had many ideas, not sure what sort of utilities would be useful or not.

Edit:

Erh... Decided to just make a quick small release to see how it goes: https://www.adventuregamestudio.co.uk/forums/index.php?topic=61549.0
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Tue 16/04/2024 09:39:36
Sorry for the abcensce, great to see discussion about this! I'll try @eri0o your module soon, looks very nice!

Quote from: Crimson Wizard on Fri 12/04/2024 07:02:34The starting request has 2 conditions, at least from my understanding:
1. Being able to color particular words or sequence of words.
2. The text is static, so "raw" drawn once and then kept displayed without changes.

Is this correct, or was there anything else to it?

Yes, I wanted to simply highlight a specific word with a different color in a text sentence. And so that it works otherwise normally and can be translated to different language without trouble.

In addition, if that functionality could be added to dialog options (in the dialog editor), it would be even better. The dialog system is very nice and simple to use, but the lack of dialog option customization limits its creative use.

I did an ugly test to get the result I was looking for: this is made with CustomDialogGui module, and with three dialog options available. I left the top dialog option empty (actually it has one empty space) and placed a green text label in the same location. When clicking on the green label, the empty dialog option gets selected and the whole text "puzzle" works from the dialog editor. The green label is there just for the graphics.

(https://i.imgur.com/UdKJjbU.png)

If something like this would be possible, I think it could open up new creative ways to use the dialog system.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Tue 16/04/2024 09:58:59
I don't understand, dialog options are fully cistomizeable...

https://adventuregamestudio.github.io/ags-manual/CustomDialogOptions.html

You can draw them how you want and also control them how you want. :/
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Tue 16/04/2024 10:28:44
Quote from: eri0o on Tue 16/04/2024 09:58:59I don't understand, dialog options are fully cistomizeable...

https://adventuregamestudio.github.io/ags-manual/CustomDialogOptions.html

You can draw them how you want and also control them how you want. :/

So it's possible to change the color of specific dialog option using custom dialog option rendering? Or to change the color of a single word? I have never touched custom dialog options rendering, I fear it's above my skills.

I'm using the CustomDialogGui module which is easy to use, but doesn't have that function. In my example, I was thinking of inserting code to the dialog option, or something similar.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Tue 16/04/2024 13:21:57
I tried to do a write up on custom dialogues once, I think I managed to find it here

https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/about-dialog-options-and-templates/msg636637779/#msg636637779

I think chomba asked more questions on custom dialogues that had more answers at the time but I can't find them now.

I found a few more maybe somewhat relevant or not links here

https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/highlight-buttons-text-and-displayhide-arrows-in-dialog-gui/

https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/custom-dialogue-issue-with-dimensions/msg636621681/#msg636621681

https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/personalizing-dialogs-and-giving-them-a-custom-design/msg636654971/#msg636654971

@rongel

I would suggest first if you can find some screenshot that is exactly what you want or if you can draw in a paint program, to do a mockup of exactly what you want, then it should be easier.

If you play my I Rented a Boat game it has two simple custom dialog with slightly differences (one is meant to be selected and force you to select before advancing the game and the other is meant to let the player still walk around when presented, like in Firewatch), the code for those is here: https://github.com/ericoporto/i_rented_a_boat/blob/main/I_rented_a_boat/CustomSay.asc
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Wed 17/04/2024 08:55:34
Quote from: eri0o on Tue 16/04/2024 13:21:57I would suggest first if you can find some screenshot that is exactly what you want or if you can draw in a paint program, to do a mockup of exactly what you want, then it should be easier.
The thing is that I'm still figuring it out myself, and still testing different mechanics. BUT I do have a working prototype, made with ugly tricks and deceit.

Basically it's a short text-based multiple choice event, made with a custom dialog system. Clicking on the dialog option updates the description label and gives new dialog options. In the end, some results may end up positive or negative. Different coloring will highlight the special dialog options and positive / negative results. A rough example:

(https://i.imgur.com/XZsY7X5.png)        (https://i.imgur.com/yyHSYq3.png)


(https://i.imgur.com/ElUnlqj.png)        (https://i.imgur.com/9LEkQTV.png)

So currently I have two requests:


I think I could do this with cheating (placing color labels under dialog options, like in image 1), or by having multiple labels (like in image 4), but it would be nicer if there was an easier way.

I hope this makes sense!
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Khris on Wed 17/04/2024 10:21:59
My guess is the custom dialog module already uses dialog_options_render() under the hood, so you'd have to dive into that to have colored options.

As for label text, AGS doesn't support more than one color per label. You'd have to use a button instead and draw its NormalGraphic.

In both cases you can use eri0o's module to have multiple colors in your text.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Wed 17/04/2024 16:15:08
Hey, I kinda don't remember, when showing dialog options in AGS, does it already has something to make the "title text"? Like in that screen you show options at the bottom and a text at the top, how do you set that text?

I am trying to think how to enable something like that API wise.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Wed 17/04/2024 17:41:50
Quote from: eri0o on Wed 17/04/2024 16:15:08Hey, I kinda don't remember, when showing dialog options in AGS, does it already has something to make the "title text"? Like in that screen you show options at the bottom and a text at the top, how do you set that text?

I am trying to think how to enable something like that API wise.

In custom dialog options you draw everything yourself using DrawingSurface.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Wed 17/04/2024 18:02:08
Right, I was trying to think about the "Description" text in Rongel's case. I guess I have to create a new function with something like

void FancyStart(this Dialog*, const string description) ...
And then later once the dialog is over I clean it up - I know there's an event to check when a dialog has ended but I think I need to handle in rep exec always anyway to be able to detect end of dialog even if something that is blocking is running.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Wed 17/04/2024 19:20:51
Quote from: eri0o on Wed 17/04/2024 16:15:08Hey, I kinda don't remember, when showing dialog options in AGS, does it already has something to make the "title text"? Like in that screen you show options at the bottom and a text at the top, how do you set that text?

That is made with a GUI with a label on top. The custom dialog gui is placed at the bottom. When player selects a dialog option from the bottom, it updates the text label at the top. So there is no actual speech or dialog, just a label.Text command inside the dialog editor.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: eri0o on Thu 18/04/2024 01:36:19
I added a new functionality to my module that lets you "Fancify" a button. I explained in my last post. But essentially you can do something like

Button1.Fancify(Fancy9Piece.CreateFromTextWindowGui(gTextBorder));
And it will adjust the button by feeding the text in the module to parse, generate a sprite and can optionally puts this text inside a 9-piece box - you can also pass three of these 9-piece if the button is meant to be interacted (the normal, mouse over and pushed graphics).

If no such textbox around the text is desired you can pass null too.

@rongel maybe this is helpful, let me know. The custom dialog though I think it's better if you read on and make your own version of it.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: rongel on Thu 18/04/2024 08:37:33
Quote from: eri0o on Thu 18/04/2024 01:36:19@rongel maybe this is helpful, let me know. The custom dialog though I think it's better if you read on and make your own version of it.
Thanks, I really appreciate your work on this, hopefully your module will help others as well. I'm currently working on something else, but I'll delve into your module more closely next week.
Title: Re: Multiple colors in a line of text to highlight keywords
Post by: Crimson Wizard on Thu 18/04/2024 08:48:37
Quote from: eri0o on Thu 18/04/2024 01:36:19@rongel maybe this is helpful, let me know. The custom dialog though I think it's better if you read on and make your own version of it.

I also think it's a right thing if users implement options rendering on their own, using only basic elements from your module (single text drawing, etc). Because each game needs its own look, the arrangement of elements, extra elements (not related to option text) etc, - that's unlimited combinations impossible to predict.

Another thing, potentially, if there are 2 implementations of "fancy text", one of which draws upon a raw drawing surface, and another generates everything using overlays, I suppose (cautiously) that this may still work even with the dialog options, because they should not prevent extra elements created or turned on/off during their display. But there will be a problem of z-sorting, or rather receiving information of what z coordinate does the "main surface" have; this has to be passed somehow...