AGS 3.6.2 - Release Candidate (RC 3)

Started by Crimson Wizard, Tue 11/02/2025 18:20:38

Previous topic - Next topic

greg

#20
Hi, I noticed a change in the behavior of Character.SayAt().

I intentionally display the message off-screen, so that I can instead show it as a subtitle in a dedicated UI element:

Code: ags
chr.SayAt(Room.Width + 100, Room.Height + 100, 1024, message);

Before RC1, this displayed off-screen as expected.  Starting with RC1, the text is now displaying at the bottom-center of the screen.

PS: As a workaround, I changed the width argument from 1024 to 0 so that the text doesn't display.

Crimson Wizard

Quote from: greg on Sat 22/02/2025 17:02:35Hi, I noticed a change in the behavior of Character.SayAt().

I intentionally display the message off-screen, so that I can instead show it as a subtitle in a dedicated UI element:

Before RC1, this displayed off-screen as expected.  Starting with RC1, the text is now displaying at the bottom-center of the screen.

I've been fixing an automatic display of LA speech over character's head, which could appear completely under the bottom of the screen. I tried to keep the case when SayAt requires explicit offscreen position, but apparently made a mistake.

greg

I've also observed a change in how the "walks onto region" event is triggered:

Let's say we have the following configuration:

  • The room has region1 where the "walks onto region" event calls region1_WalksOnto().
  • As part of the scripting in region1_WalksOnto(), the player walks off, back onto, and back off of region1.

In previous versions, once region1_WalksOnto() completes, the player regains control of the game.

In RC1, once region1_WalksOnto() completes, "walks onto region" is automatically triggered again.  This results in an infinite loop, and the player never regains control of the game.

(As a workaround, I'm now disabling region[1] at the start of region1_WalksOnto() and re-enabling it at the end.)

greg

#23
Some additional behavior changes I've noticed:

  • Walks are less precise:

    Example A: In one room, I'm directing the character to walk to (723, 534), which is comfortably within a walkable area (i.e. there's a margin on all sides).  When I call cEgo.Walk(723, 534), they end their walk at (721, 533).  When I call cEgo.Walk(723, 534) again, they again end their walk at (721, 533).

    Example B: In another room, I'm directing the character to walk to (945, 270).  This point is on the right-most edge of a walkable area, i.e. (945, 270) is on the walkable area but (946, 270) is not.  When I call cEgo.Walk(945, 270), they end their walk at (944, 272).  When I call cEgo.Walk(945, 270) again, they end their walk at (944, 271).

    This lack of precision has the side effect that, if a character walks twice in a row to the same coordinates, they'll jitter a bit between the two walks since they're not precisely at those coordinates.

  • Characters keep getting stuck in non-walkable areas.

    When walking to coordinates in a room, my player character keeps getting stuck (presumably in a non-walkable area), even though the coordinates are all on walkable areas, all the walk calls use eWalkableAreas, and the walkable area isn't being removed from underneath the character.

    This isn't consistently reproducible (i.e. for the same coordinates, sometimes the cEgo.Walk() call gets the character stuck and sometimes it doesn't), but it happens relatively frequently.

    The coordinates in question are at the very edge of a walkable area, so I suspect #1 and #2 are related, e.g. the lack of walk precision results in the character being slightly off the coordinates in a non-walkable area.

  • AudioChannel.PositionMs isn't refreshing immediately after calling AudioClip.PlayFrom().

    Immediately after calling "channel = clip.PlayFrom(position, eAudioPriorityNormal, eRepeat)", the value of clip.PositionMs is 0 rather than position.

  • When an object and a walkbehind have the same baseline, previous versions rendered the object on top of the walkbehind.  The current version renders the walkbehind on top of the object.

Crimson Wizard

@greg for all the walk issues I would require to have exact walkable mask for a test.

Please clarify, which older version are you comparing with (which worked correctly)?

Crimson Wizard

#25
Quote from: greg on Sat 22/02/2025 17:02:35Hi, I noticed a change in the behavior of Character.SayAt().

I tried older versions, and SayAt behavior was exceptionally inconsistent already.
It allows to position the text below the bottom screen, but refused to position it above the top, or behind left or right borders.
The y position is unclear. The manual sais that "the text is displayed with its top left corner at (X,Y)", but it feels like the text is vertically centered or otherwise adjusted. Because passing screen height as Y will still make the text line partially visible.

If the wanted behavior is to be able to position it precisely where told to, then it has to be fixed in multiple ways.


Quote from: greg on Sat 22/02/2025 17:02:35I intentionally display the message off-screen, so that I can instead show it as a subtitle in a dedicated UI element:

Earlier I missed the fact that you are displaying it completely offscreen (I thought it should only be partially offscreen). This sounds like an unnecessary workaround for something. Why do you need to call SayAt at all?

Quote from: greg on Sun 23/02/2025 20:12:49When an object and a walkbehind have the same baseline, previous versions rendered the object on top of the walkbehind.  The current version renders the walkbehind on top of the object.

I cannot reproduce this. When I test this, whether object has an automatic baseline by its position, or manually set baseline, if baseline is equal to walk-behind's, object appears on top. Please clarify how do you setup this scene?

greg

Quote from: Crimson Wizard on Mon 24/02/2025 08:52:12@greg for all the walk issues I would require to have exact walkable mask for a test.

Please clarify, which older version are you comparing with (which worked correctly)?

Sure, here are the masks.  Interestingly, when I export the masks, they're at half the size of the room (e.g. exporting from a 1024x768 room yields a 512x384 mask), even though the default mask resolution is 1:1 in General Settings.

  • Room 13: When I call cEgo.Walk(723, 534), they end their walk at (721, 533).  When I call cEgo.Walk(723, 534) again, they again end their walk at (721, 533).
  • Room 15: When I call cEgo.Walk(945, 270), they end their walk at (944, 272).  When I call cEgo.Walk(945, 270) again, they end their walk at (944, 271).
  • Room 17: When I call cEgo.Walk(765, 450) or cEgo.Walk(855, 555), they sometimes but not always get stuck after the walk.  These points are on but at the edge of the walkable area.

I haven't tested this section of the game in detail for a while.  I think the version with the more precise walks was 3.6.1.

Quote from: Crimson WizardEarlier I missed the fact that you are displaying it completely offscreen (I thought it should only be partially offscreen). This sounds like an unnecessary workaround for something. Why do you need to call SayAt at all?

I'm displaying the character's line in a custom subtitles UI:

Code: ags
// The character says the line, but hide the message string.
chr.SayAt(Room.Width + 100, Room.Height + 100, 0, msg);

// Instead, display the message string in the subtitles UI.
if (Speech.VoiceMode == eSpeechTextOnly || Speech.VoiceMode == eSpeechVoiceAndText) {
  lSubtitlesLabel.Text = msg;
}

Quote from: Crimson WizardWhen I test this, whether object has an automatic baseline by its position, or manually set baseline, if baseline is equal to walk-behind's, object appears on top. Please clarify how do you setup this scene?

Sure, here is the setup with screenshots.

Crimson Wizard

Quote from: greg on Tue 25/02/2025 03:56:57I'm displaying the character's line in a custom subtitles UI:

Code: ags
// The character says the line, but hide the message string.
chr.SayAt(Room.Width + 100, Room.Height + 100, 0, msg);

// Instead, display the message string in the subtitles UI.
if (Speech.VoiceMode == eSpeechTextOnly || Speech.VoiceMode == eSpeechVoiceAndText) {
  lSubtitlesLabel.Text = msg;
}

You don't need to call SayAt for this, since AGS 3.5.0 there's Game.PlayVoice():
https://adventuregamestudio.github.io/ags-manual/Game.html#gameplayvoiceclip
so above can be done by a combination of PlayVoice and WaitInput, for example.

Crimson Wizard

#28
Quote from: greg on Tue 25/02/2025 03:56:57Interestingly, when I export the masks, they're at half the size of the room (e.g. exporting from a 1024x768 room yields a 512x384 mask), even though the default mask resolution is 1:1 in General Settings.

Each Room has a separate Mask Resolution setting. General Settings only set "default" resolution for the new rooms. If you like having 1:1 masks everywhere, then you need to go through all the existing rooms and adjust their settings individually.

If the mask is 1:2, then that usually explains why character cannot reach certain coordinates. Try changing "Mask Resolution" in these rooms to 1:1 and see if that fixes the issue.

Crimson Wizard

Quote from: greg on Tue 25/02/2025 03:56:57
Quote from: Crimson WizardWhen I test this, whether object has an automatic baseline by its position, or manually set baseline, if baseline is equal to walk-behind's, object appears on top. Please clarify how do you setup this scene?

Sure, here is the setup with screenshots.

No, I still cannot reproduce this. I make a room with objects "lying" on walkbehind, use your literal script where it sets equal baselines, and they show up on top.

Is there a way to test this exact room or the compiled game?

Crimson Wizard

Temp build available for download:
https://cirrus-ci.com/task/6353866658152448

Fixes:
- PositionMs not telling real position right after calling PlayFrom().
- Dynamic sprites not appearing on buttons after deleting and creating again.
- Buttons resized when assigning NormalGraphic = 0
(last two were reported for AGS 4, but apply to 3.6.2 too)

greg

Quote from: Crimson Wizard on Tue 25/02/2025 07:48:40No, I still cannot reproduce this. I make a room with objects "lying" on walkbehind, use your literal script where it sets equal baselines, and they show up on top.

Is there a way to test this exact room or the compiled game?

Sure, I'll PM you a link to the game.

Crimson Wizard

#32
@greg ,
Summary of the reports:

1. SayAt getting clamped to the screen, should be able to print below the screen.
Should be fixed now, temp build available for a test:
https://cirrus-ci.com/task/6537096439005184

2. Walks onto region retriggers during blocking walk.
Did not look into this yet, but plan to do soon.

3. Walks are less precise.
Suggest that this is because of 1:2 Mask Resolution in rooms, should try increasing to 1:1 using a individual room setting (the masks will be resized automatically, keeping areas).

4. Characters keep getting stuck in non-walkable areas.
May be related to p3. It's best to fix p3 first in the game, and then retry.
If that's still a problem, then i will need a proper test case, like a room where I can reproduce this issue.
Note: I've been optimizing a scan for the nearest walkable area recently, so naturally curious if that affected this situation (although my intent was to improve things on contrary).

5. AudioChannel.PositionMs isn't refreshing immediately after calling AudioClip.PlayFrom().
Should be fixed, use the same download link as above.

6. When an object and a walkbehind have the same baseline, previous versions rendered the object on top of the walkbehind.  The current version renders the walkbehind on top of the object.
Still could not reproduce, even after trying the room from your project source.
But I downloaded only a single room and installed it into a dummy project. I may try downloading full project and compiling it awhole and see if that changes anything. (although downloading from OneDrive is unreliable for me for some reason)
EDIT: By the way, just in case, which graphics driver do you use to run this game?

Crimson Wizard

@greg, it looks like I found a silly mistake that was causing the problem with the walkbehinds and baselines.
This mistake only appears after changing a room at least once, that's why I did not see it during my first tests.

Here's a fixed build:
https://cirrus-ci.com/task/4888087794286592
(will be available roughly 30 mins after posting this)

greg

Thanks, CW!

With the build you linked to, I've validated the fixes for #1, #5, and #6.

For #3 and #4, I've updated the masks in all rooms to 1:1, and I have a reproducible case of an imprecise walk that results in ending up off a walkable area and stuck.  I reply to our PM thread with a link to the game sources and the save game.

Crimson Wizard

I found there's a mistake in the latest 3.6.2 build, where engine does not auto-fix the character position after the walk if it got to a non-walkable area, as it was supposed to do. I made a fix, and the fixed build will be available here:
https://cirrus-ci.com/task/4945115942223872

As for imprecise walk, mistakes by 1-2 pixels are likely because of the inaccurate walking logic in AGS, where it uses fixed-point math instead of a floating point. This was causing many kinds of glitches over the years, like characters walking in one place etc. Some of these were fixed in 3.6.1, but there still may be mistakes in final position by a pixel or so.
This was improved in AGS 4 where the character pathing is done using floating point math.

greg

Thanks, CW!

QuoteI found there's a mistake in the latest 3.6.2 build, where engine does not auto-fix the character position after the walk if it got to a non-walkable area, as it was supposed to do. I made a fix, and the fixed build will be available here:
https://cirrus-ci.com/task/4945115942223872

With the linked build, I'm still experiencing the same issue where the character ends up 1 pixel off the walkable area. I've addressed it by adding a check to my Walk() and FaceDirection() wrappers where, if chr isn't on a walkable area, they're moved to Room.NearestWalkableArea(chr.x, chr.y);

QuoteAs for imprecise walk, mistakes by 1-2 pixels are likely because of the inaccurate walking logic in AGS, where it uses fixed-point math instead of a floating point. This was causing many kinds of glitches over the years, like characters walking in one place etc. Some of these were fixed in 3.6.1, but there still may be mistakes in final position by a pixel or so.

Thanks for the explanation!  I've addressed this in my game by adding a check to my Walk(x, y) wrapper where, if the character is within 2 pixels of the (x, y), it skips the walk.

Crimson Wizard

#37
Quote from: greg on Mon 03/03/2025 00:58:37With the linked build, I'm still experiencing the same issue where the character ends up 1 pixel off the walkable area. I've addressed it by adding a check to my Walk() and FaceDirection() wrappers where, if chr isn't on a walkable area, they're moved to Room.NearestWalkableArea(chr.x, chr.y);

Of course, I made another mistake, and did not fix it!

Here's a new build:
https://cirrus-ci.com/task/6277045589639168

greg

Thanks, CW!  That fixes the issue where a character unintentionally walks off the walkable area (a call to chr.Walk() where WalkWhere=eWalkableArea).

However, it's creating a new issue when a character intentionally walks off a walkable area (a call to chr.Walk() where WalkWhere=eAnywhere).

Specifically, when I call chr.Walk(550, 1000, eBlock, eAnywhere) to get the character off-screen, the character snaps back onto the walkable area at the end of their walk.

Crimson Wizard

Quote from: greg on Tue 04/03/2025 03:04:06However, it's creating a new issue when a character intentionally walks off a walkable area (a call to chr.Walk() where WalkWhere=eAnywhere).

Of course I forgot to test the opposite case, and did not notice that this still does not work correctly.

Here's another build:
https://cirrus-ci.com/task/6345292460589056

I would need to update our automatic game tests and include walking test there.

SMF spam blocked by CleanTalk