New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endless loop when the first hero is named is \N[1] #1145

Closed
rohkea opened this Issue Apr 17, 2017 · 5 comments

Comments

Projects
None yet
4 participants
@rohkea
Member

rohkea commented Apr 17, 2017

In RPG Maker (tested on RM2k v.1.61), when \N[x] or \V[x] appears in a character name, it’s displayed as [x] in the message.

In EasyRPG, a substitution is performed recursively. If the first character is named \N[1], an attempt to print their name would result in an endless loop.

Judging by how text lines are broken in winning messages (see my comment on #588 (comment)), I think RPG Maker does the code replacement in two passes: first, \N[x] and \V[x] are replaced, and after this, the formatting codes are applied.

@carstene1ns carstene1ns added this to the 0.5.2 milestone Apr 17, 2017

@rohkea

This comment has been minimized.

Show comment
Hide comment
@rohkea

rohkea May 8, 2017

Member

Just checked. If the hero name contains \N[1] or \V[1], it is displayed as [1]. But this [1] is different from normal [1], because it can’t be used with other message commands.

For example.

  • Hero 1's name: \N[1]
  • Message: \C\N[1]Hello
  • Result in RPG_RT: [1]Hello
  • Result in EasyRPG: endless loop

This is different from a case with a hero named [1]:

  • Hero 1's name: [1]
  • Message: \C\N[1]Hello
  • Result in RPG_RT: 'Hello' in colour 1
  • Result in EasyRPG: same as in RPG_RT
Member

rohkea commented May 8, 2017

Just checked. If the hero name contains \N[1] or \V[1], it is displayed as [1]. But this [1] is different from normal [1], because it can’t be used with other message commands.

For example.

  • Hero 1's name: \N[1]
  • Message: \C\N[1]Hello
  • Result in RPG_RT: [1]Hello
  • Result in EasyRPG: endless loop

This is different from a case with a hero named [1]:

  • Hero 1's name: [1]
  • Message: \C\N[1]Hello
  • Result in RPG_RT: 'Hello' in colour 1
  • Result in EasyRPG: same as in RPG_RT
@Ghabry

This comment has been minimized.

Show comment
Hide comment
@Ghabry

Ghabry May 8, 2017

Member

I think recursive replacement is actually a nice feature but we should add some sanity check to prevent endless substitution.

Member

Ghabry commented May 8, 2017

I think recursive replacement is actually a nice feature but we should add some sanity check to prevent endless substitution.

@rohkea

This comment has been minimized.

Show comment
Hide comment
@rohkea

rohkea May 12, 2017

Member

I was wrong about the \N[x] being performed before other codes. Further experiments with word-wrapping seem to suggest that \N[x] codes are not replaced before word-wrapping: at least I was able to have a "word-wrapped" lines that don’t fit into the line, if I use long character names:

hero-name-cropped

Member

rohkea commented May 12, 2017

I was wrong about the \N[x] being performed before other codes. Further experiments with word-wrapping seem to suggest that \N[x] codes are not replaced before word-wrapping: at least I was able to have a "word-wrapped" lines that don’t fit into the line, if I use long character names:

hero-name-cropped

@CherryDT

This comment has been minimized.

Show comment
Hide comment
@CherryDT

CherryDT May 17, 2017

@rohkea #588 (comment)

Strange, you said in the other post linked above that \N is honored in wrapping...

EDIT: Hm actually I think I know what is going on here.

First of all, the \N is not honored for wrapping, you just didn't notice because \N[0] has the exact same number of characters as Daisy has.

There are multiple kinds of message displays:

  1. The full message window, like it is used on the map. It supports everything "Show Message" supports, it handles the typing effect, waits for keypress, and so on. The full message window can take its texts out of a message pool, 4 lines at a time, until the pool is empty (remarkably not used by the "Show Message" command, but used by level-up messages).
  2. The "battle message window" which is basically just a set of 4 lines which can be controlled individually (this allows things like the first line staying and the second line switching through texts).
  3. Lists of messages which can require more than 4 lines but shouldn't use the "typing effect" but instead appear (and be skippable) a line at a time are using the message pool, but displayed in the battle message window (not the full message window).

On the map, everything comes from point 1 of course. Mostly the message pool is kind of redundant because only 4 lines can be used in the "Show Message" event command anyway, so it is not used there at the moment, but level-up messages use it for example (because you may learn tons of skills).

In battle, most of the things you see come from point 2, the battle message window directly. Messages created by events as well as game over and victory messages (including level-up) come from point 1, the full message window. Only the battle start messages ("xxx appears") come from the weird combo in point 3 because they behave like the other in-battle messages (not like the full message window) but can have more than 4 lines.

The RM handles the escape sequences at different places, and this explains the differences and bugs as well:

  1. When text is loaded into a normal message window (taken from the message pool or added manually):
    1. \$ at the start of the first line in the window (opens gold window but is not replaced yet - I think this is done so that the gold window can open simultaneously with the message window even though the first character hasn't been officially processed yet)
    2. \\ (skipped but not yet replaced), \V[X] (replaced), \_ (converted to encoded half-space, 0x01 byte)
    3. \N[X] - since RM2k v1.50 and RM2k3 v1.05, this is done in an extra step (in order to allow \N[\V[X]]), which introduces a bug: \\N[X] is will show the hero name minus the first character (e.g. ack) or do other things (based on the first character) because it will become something like \Zack where \Z is later dropped as invalid, defeating the purpose of the double backslash.
  2. When the message window processes a letter (happens before the letter is actually drawn, think of the typing effect):
    1. \C[X], \S[X], \\, \$, \!, \., \|, \>, \<, \^
    2. \ followed by an unknown character is dropped entirely.
    3. Some special processing of $$ and encoded half-space because the message window has to keep track of the X coordinate because of the typing effect.
  3. When drawing text on the screen (from any source, also inside menus, battle messages, etc.):
    1. $X, $$
    2. Encoded half-space (0x01 byte) - consumes 3 pixels instead of 6. (In non-English RM, any text displayed in "info windows" (those one-line windows with skill names and descriptions for example) has all spaces replaced by half-spaces, and half-spaces are also used in some places in battle messages.)
    3. Japenese-specific special width handling of , , ,

In all cases where \X[X] is expected, the RPG Maker peeks if the third character is [ and if it is, it starts parsing and consuming characters until it encounters ] or the end of the string. If not, it evaluates the "value" to -1 and does not advance the position at all.

Invalid [X] values are handled differently depending on the function:

  • \V[X] with invalid X will become zero (same as a "Change Variable" with an invalid variable pointer)
  • \N[X] with invalid X will crash with "Invalid actor"
  • \C[X] with invalid X will do nothing
  • \S[X] just caps the value to 1..20, so higher numbers become 20 and lower numbers (including the -1 from the invalid third character explained above) will become 1

As for the word wrapping bugs - I do the wrapping at two places: I wrap text before it is pushed into the message pool (and then push multiple lines if needed), and I wrap the lines in the 4-lines buffer of the battle window before actually displaying them (unlike the message pool, this can cause lines to be completely hidden because only 4 actual lines can be shown - but it will very rarely happen so I took that risk). This means that those codes are never taken into account, unfortunately, and that's very hard to fix, so I'll probably leave it.

Also, given this information and the explanations above, it should become clear why \C\N[1]Hello with hero name \N[1] becomes [1]Hello in RPG_RT:

  1. In step 1iii, the string becomes \C\N[1]Hello yet again. The "new" \N[1] is not evaluated again because this step is executed only once.
  2. In step 2i, RPG_RT tries to parse \C but because the next character is not a [ but a \, it is handled like \C[-1] which does nothing. The \C is consumed anyway.
  3. Because \N has no meaning in step 2 (only in step 1), it is dropped in step 2ii. Note that the [1] remains.

This means that a hero named [5] in a message \C\N[1] would actually change the color to 5.

By the way, I realized only now that \N[0] references the current party leader... It's missing in the help file, I need to add it.

CherryDT commented May 17, 2017

@rohkea #588 (comment)

Strange, you said in the other post linked above that \N is honored in wrapping...

EDIT: Hm actually I think I know what is going on here.

First of all, the \N is not honored for wrapping, you just didn't notice because \N[0] has the exact same number of characters as Daisy has.

There are multiple kinds of message displays:

  1. The full message window, like it is used on the map. It supports everything "Show Message" supports, it handles the typing effect, waits for keypress, and so on. The full message window can take its texts out of a message pool, 4 lines at a time, until the pool is empty (remarkably not used by the "Show Message" command, but used by level-up messages).
  2. The "battle message window" which is basically just a set of 4 lines which can be controlled individually (this allows things like the first line staying and the second line switching through texts).
  3. Lists of messages which can require more than 4 lines but shouldn't use the "typing effect" but instead appear (and be skippable) a line at a time are using the message pool, but displayed in the battle message window (not the full message window).

On the map, everything comes from point 1 of course. Mostly the message pool is kind of redundant because only 4 lines can be used in the "Show Message" event command anyway, so it is not used there at the moment, but level-up messages use it for example (because you may learn tons of skills).

In battle, most of the things you see come from point 2, the battle message window directly. Messages created by events as well as game over and victory messages (including level-up) come from point 1, the full message window. Only the battle start messages ("xxx appears") come from the weird combo in point 3 because they behave like the other in-battle messages (not like the full message window) but can have more than 4 lines.

The RM handles the escape sequences at different places, and this explains the differences and bugs as well:

  1. When text is loaded into a normal message window (taken from the message pool or added manually):
    1. \$ at the start of the first line in the window (opens gold window but is not replaced yet - I think this is done so that the gold window can open simultaneously with the message window even though the first character hasn't been officially processed yet)
    2. \\ (skipped but not yet replaced), \V[X] (replaced), \_ (converted to encoded half-space, 0x01 byte)
    3. \N[X] - since RM2k v1.50 and RM2k3 v1.05, this is done in an extra step (in order to allow \N[\V[X]]), which introduces a bug: \\N[X] is will show the hero name minus the first character (e.g. ack) or do other things (based on the first character) because it will become something like \Zack where \Z is later dropped as invalid, defeating the purpose of the double backslash.
  2. When the message window processes a letter (happens before the letter is actually drawn, think of the typing effect):
    1. \C[X], \S[X], \\, \$, \!, \., \|, \>, \<, \^
    2. \ followed by an unknown character is dropped entirely.
    3. Some special processing of $$ and encoded half-space because the message window has to keep track of the X coordinate because of the typing effect.
  3. When drawing text on the screen (from any source, also inside menus, battle messages, etc.):
    1. $X, $$
    2. Encoded half-space (0x01 byte) - consumes 3 pixels instead of 6. (In non-English RM, any text displayed in "info windows" (those one-line windows with skill names and descriptions for example) has all spaces replaced by half-spaces, and half-spaces are also used in some places in battle messages.)
    3. Japenese-specific special width handling of , , ,

In all cases where \X[X] is expected, the RPG Maker peeks if the third character is [ and if it is, it starts parsing and consuming characters until it encounters ] or the end of the string. If not, it evaluates the "value" to -1 and does not advance the position at all.

Invalid [X] values are handled differently depending on the function:

  • \V[X] with invalid X will become zero (same as a "Change Variable" with an invalid variable pointer)
  • \N[X] with invalid X will crash with "Invalid actor"
  • \C[X] with invalid X will do nothing
  • \S[X] just caps the value to 1..20, so higher numbers become 20 and lower numbers (including the -1 from the invalid third character explained above) will become 1

As for the word wrapping bugs - I do the wrapping at two places: I wrap text before it is pushed into the message pool (and then push multiple lines if needed), and I wrap the lines in the 4-lines buffer of the battle window before actually displaying them (unlike the message pool, this can cause lines to be completely hidden because only 4 actual lines can be shown - but it will very rarely happen so I took that risk). This means that those codes are never taken into account, unfortunately, and that's very hard to fix, so I'll probably leave it.

Also, given this information and the explanations above, it should become clear why \C\N[1]Hello with hero name \N[1] becomes [1]Hello in RPG_RT:

  1. In step 1iii, the string becomes \C\N[1]Hello yet again. The "new" \N[1] is not evaluated again because this step is executed only once.
  2. In step 2i, RPG_RT tries to parse \C but because the next character is not a [ but a \, it is handled like \C[-1] which does nothing. The \C is consumed anyway.
  3. Because \N has no meaning in step 2 (only in step 1), it is dropped in step 2ii. Note that the [1] remains.

This means that a hero named [5] in a message \C\N[1] would actually change the color to 5.

By the way, I realized only now that \N[0] references the current party leader... It's missing in the help file, I need to add it.

@Ghabry

This comment has been minimized.

Show comment
Hide comment
@Ghabry

Ghabry May 17, 2017

Member

Wow. Thanks for that very detailed writeup. And EASYRPG has to add \N [0], too :D

Member

Ghabry commented May 17, 2017

Wow. Thanks for that very detailed writeup. And EASYRPG has to add \N [0], too :D

Ghabry added a commit to Ghabry/easyrpg-player that referenced this issue May 28, 2017

Ghabry added a commit to Ghabry/easyrpg-player that referenced this issue May 28, 2017

Ghabry added a commit to Ghabry/easyrpg-player that referenced this issue Jun 6, 2017

Ghabry added a commit to Ghabry/easyrpg-player that referenced this issue Jun 17, 2017

carstene1ns added a commit that referenced this issue Jun 23, 2017

Ghabry added a commit to libretro/easyrpg-libretro that referenced this issue May 22, 2018

Ghabry pushed a commit to libretro/easyrpg-libretro that referenced this issue May 22, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment