Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: jumpjack on Mon 26/12/2022 18:27:15

Title: Intercepting character position
Post by: jumpjack on Mon 26/12/2022 18:27:15
Can I "intercept" character position before it's actually updated, to prevent its updating upon my own conditions?
I see that DestinationX/Y only contain final destination for mouse control, not for keyboard control.
Title: Re: Intercepting character position
Post by: eri0o on Mon 26/12/2022 20:36:10
AGS doesn't provide keyboard controls, so you can do this yourself in your own script, by just updating the position later.

Are you using a script for this? Can you share the script code?

If you want to do this with the pathfinder that is part of the Walk functions, the best way is to use a dummy character and move the character you want to move later based on this dummy character position.
Title: Re: Intercepting character position
Post by: Crimson Wizard on Mon 26/12/2022 20:55:49
I do not understand full situation here, but may mention this article about order of game events and script callbacks:
https://adventuregamestudio.github.io/ags-manual/GameEventsOrder.html

Perhaps it will help to know when to do, after you find out what to do.
Title: Re: Intercepting character position
Post by: eri0o on Mon 26/12/2022 20:58:25
CW, do you think mentioning in that article that rep exec and other calls from script also happens top to bottom from the script list?

Edit: also, I never could understand how the KeyboardControl module should work (it comes with some templates I believe), I have a script module called Controlz (https://www.adventuregamestudio.co.uk/forums/index.php?topic=57427.0), I use it instead.
Title: Re: Intercepting character position
Post by: jumpjack on Tue 27/12/2022 10:48:55
I found that the demo game included in AGS has a keyboard management script which I can edit at wish.

What about the pathfinder algorithm? I need to check not just the final destination, but also the path: the embedded nonwalkable area method is not enough, I need to manually monitor character positions not just by one pixel on his feet, but by an area around his feet, which shall not overlap nonwalkable areas.

In other words, the non walkable area surrounding player's feet, currently used to avoid collisions with other characters, should be used also to avoid collisions with nonwalkable areas.

I wonder if I can build my 10x10 tiles room by "pasting" 100 invisible characters above the 100 tiles I already pasted to build the room, so I can "cheat" and let the engine make the player avoid the forbidden tiles...
Title: Re: Intercepting character position
Post by: eri0o on Tue 27/12/2022 11:36:12
I don't really understand what you are trying to accomplish here. You want the movement to be tiled too? If that's the case you can just "round" the x,y destination points to be in the middle of your tiles and I think it would accomplish what you want.

Do you have a game that you are trying to emulate the movement that you could share a video?
Title: Re: Intercepting character position
Post by: Crimson Wizard on Tue 27/12/2022 11:49:06
Quote from: jumpjack on Tue 27/12/2022 10:48:55In other words, the non walkable area surrounding player's feet, currently used to avoid collisions with other characters, should be used also to avoid collisions with nonwalkable areas.

Cannot you make the non-walkable areas wider, giving them the extra "outline", so that the character walks at certain distance from the forbidden tiles?
Title: Re: Intercepting character position
Post by: jumpjack on Tue 27/12/2022 17:55:51
Player can move freely inside its tile, but can't go to adiacent tile if it contains something.

Click on "start emulator with demo game" to see the game I am trying to implement:
https://jumpjack.github.io/oricutronJS/oricutron.html
Title: Re: Intercepting character position
Post by: Snarky on Tue 27/12/2022 18:31:52
Quote from: jumpjack on Tue 27/12/2022 10:48:55In other words, the non walkable area surrounding player's feet, currently used to avoid collisions with other characters, should be used also to avoid collisions with nonwalkable areas.

That cannot be done.

Quote from: Crimson Wizard on Tue 27/12/2022 11:49:06Cannot you make the non-walkable areas wider, giving them the extra "outline", so that the character walks at certain distance from the forbidden tiles?

... But this could be a workaround.

IOW, instead of extending the character's position coordinate e.g. 10 pixels in each direction, you contract the room's walkable area 10 pixels in each direction, and the end result is (more or less) the same.

None of what you have said provides an argument for why this solution is not workable.
Title: Re: Intercepting character position
Post by: jumpjack on Wed 28/12/2022 06:46:34
I can't find any example or explanation about sprites collisions management, any suggestion? I see I can monitor collision of objects and characters, but nothing specific about sprites (more specifically: dynamic sprites).

Are dynamic sprites the only AGS items I can programmatically create? no objects neither characters?

And, as I already asked above: can I access/customize the pathfinder algorithm from a script?
Title: Re: Intercepting character position
Post by: jumpjack on Wed 28/12/2022 11:00:27
I see these 3 functions in the editor 3.6.0RC3:


But only one is documented both in offline and online help, "AreThingsOverlapping". Maybe the others have been deprecated in 3.6.0? I see that there are Character.IsCollidingWithChar , Character.IsCollidingWithObject, Object.IsCollidingWithObject  , maybe they replace the missing global functions?

But I don't understand if I can create objects and characters at runtime.

Title: Re: Intercepting character position
Post by: Khris on Wed 28/12/2022 12:13:11
Afaik objects and characters cannot be created dynamically, no. A dynamic sprite is just a bunch of pixels, it doesn't have a position for instance. That's why a sprite collision usually only makes sense in the context of assigning the sprite to an object or character.

One way to solve this is to create you own entity instance, an array of struct based objects that have a sprite and a position. Now you can get the surface of the sprite and iterate over its pixels, then add the position and collide the result with another entity.
In a 2.5D Iso game you usually only need to collide the footprint, and it gets even simpler if you only need circle vs. circle or circle vs. line.

Re the pathfinder: no, you cannot customize the algorithm in any way. However direct character control doesn't require pathfinding at all; the character will simply move in a direction until they hit something.
AGS supports this by providing a Character.WalkStraight() function. Keyboard modules usually send off the character like player.WalkStraight(player.x + 10000, player.y);
Title: Re: Intercepting character position
Post by: Crimson Wizard on Wed 28/12/2022 12:18:41
Quote from: jumpjack on Wed 28/12/2022 06:46:34I can't find any example or explanation about sprites collisions management, any suggestion? I see I can monitor collision of objects and characters, but nothing specific about sprites (more specifically: dynamic sprites).

The collisions in AGS may be misleading if not confusing at first; primarily because they were meant to emulate some old adventure games and also assume a side-view game.

1. Characters and Objects have Solid property. If this property is set, they actually paint "holes" inside walkable area mask, and update these "holes" as they move. These are rectangular holes positioned around their "feet", and this is what you may see on a walkable debug overlay. These extra holes prevent other character from walking over, so it looks like a collision test. The sizes of these "holes" are determined by BlockingWidth and BlockingHeight properties.
Painting over a walkable mask yourself (as you already do) would give precisely same result.

2. The "IsColliding" functions. Their behavior depends on the kind of object.

Character.IsCollidingWithChar, Character.IsCollidingWithObject functions are special, because they are testing against some rectangular areas at their feet; but I cannot remember if it's exactly the same area as BlockingWidth/Height or some arbitrary one; knowing AGS it could even be some hardcoded factors.

Object.IsCollidingWithObject tests full bounding rectangles of two object sprites.

AreThingsOverlapping also tests full bounding rectangles of two sprites (characters or objects).



Quote from: jumpjack on Wed 28/12/2022 11:00:27But only one is documented both in offline and online help, "AreThingsOverlapping". Maybe the others have been deprecated in 3.6.0? I see that there are Character.IsCollidingWithChar , Character.IsCollidingWithObject, Object.IsCollidingWithObject  , maybe they replace the missing global functions?

There's a table of deprecated functions and their suggested replacements:
https://adventuregamestudio.github.io/ags-manual/ObsoleteScriptAPI.html
Title: Re: Intercepting character position
Post by: eri0o on Wed 28/12/2022 12:38:05
Here's a way to do isometric movement

- divide the walkable area instead of a tile, in quarters, so a corner gets only a quarter of a tile, a border half tile and inner regions get full tile.

- divide the rest of the map in two layers, background and foreground. Split wall and wall-like tiles in the middle, the upper half goes to the foreground, the bottle half goes to the background.

This way there should be no overlapping - IIRC this is how things were done when sorting was too expensive, or not possible in game consoles.
Title: Re: Intercepting character position
Post by: Snarky on Wed 28/12/2022 17:44:50
I suppose the pathfinder might be relevant for NPCs, but it's still not clear why you would need to customize it.
Title: Re: Intercepting character position
Post by: jumpjack on Wed 28/12/2022 19:14:47
Quote from: Crimson Wizard on Wed 28/12/2022 12:18:41
Quote from: jumpjack on Wed 28/12/2022 06:46:34I can't find any example or explanation about sprites collisions management, any suggestion? I see I can monitor collision of objects and characters, but nothing specific about sprites (more specifically: dynamic sprites).

The collisions in AGS may be misleading if not confusing at first; primarily because they were meant to emulate some old adventure games and also assume a side-view game.

1. Characters and Objects have Solid property. If this property is set, they actually paint "holes" inside walkable area mask, and update these "holes" as they move. These are rectangular holes positioned around their "feet", and this is what you may see on a walkable debug overlay. These extra holes prevent other character from walking over, so it looks like a collision test. The sizes of these "holes" are determined by BlockingWidth and BlockingHeight properties.
Painting over a walkable mask yourself (as you already do) would give precisely same result.[...]

Quote from: Snarky on Wed 28/12/2022 17:44:50I suppose the pathfinder might be relevant for NPCs, but it's still not clear why you would need to customize it.

(https://user-images.githubusercontent.com/1620953/209861232-e5aea13b-5989-45dd-95c9-2d65bf6340f1.png)

Looking at how character move with debug mode enabled to show walkable area, apparently it seems that check is performed on single pixel on foot of the character versus edges of nonwalkable area. In other words, the "nonwalkable hole" around character's feet can overlap the nonwalkable area, as long as the single pixel at (playerwidth/2 , playerheight) is out of the area.

Can this be considered a bug? (I opened an issue (https://github.com/adventuregamestudio/ags/issues/1873), if it's not a bug it will be closed, but it will remain as useful information for posterity).
Title: Re: Intercepting character position
Post by: Crimson Wizard on Wed 28/12/2022 19:28:53
Quote from: jumpjack on Wed 28/12/2022 19:14:47Looking at how character move with debug mode enabled to show walkable area, apparently it seems that check is performed on single pixel on foot of the character versus edges of nonwalkable area. In other words, the "nonwalkable hole" around character's feet can overlap the nonwalkable area, as long as the single pixel at (playerwidth/2 , playerheight) is out of the area.

Can this be considered a bug?

No, this is not a bug, this is an intended behavior of AGS. I tried to explain above, that this "hole" is used only to prevent other characters from walking too close to the "solid" character.

Yes, like you say, when calculating a path, the check is only performed against a single pixel on foot of a character, and not the area around it.
IIRC, this particular character's "hole" is edited out while calculating the path, so it does not block itself.
Title: Re: Intercepting character position
Post by: jumpjack on Wed 28/12/2022 19:35:43
Quote from: Crimson Wizard on Wed 28/12/2022 19:28:53I tried to explain above, that this "hole" is used only to prevent other characters from walking too close to the "solid" character.
Yes, this is why it looks like a bug: because the character nonwalkable area behaves differently depending on what touches it: a solid body can't cross it, a solid wall can cross it.
Anyway I'll disable mouse and use only keyboard control to override this behaviour.
Title: Re: Intercepting character position
Post by: Crimson Wizard on Wed 28/12/2022 19:39:05
I honestly still do not understand why cannot you make the non-walking area further from their tiles to compensate for character's sprite width? I think that would be the first thing I'd try, if I were experimenting with such setup. Would not the result look approximately as if the character's "blocking area" was working the way you implied? Is there anything that prevents using this method?

Quote from: jumpjack on Wed 28/12/2022 19:35:43Anyway I'll disable mouse and use only keyboard control to override this behaviour.

I might mention that mouse or keyboard (as an input method) do not enforce walking behavior. It's all in the script, how the script reacts to the player's input, which functions it uses. It's possible to call same functions in both cases.
Title: Re: Intercepting character position
Post by: Snarky on Wed 28/12/2022 20:50:55
Quote from: jumpjack on Wed 28/12/2022 19:35:43Yes, this is why it looks like a bug: because the character nonwalkable area behaves differently depending on what touches it: a solid body can't cross it, a solid wall can cross it.

It's not a bug, it's perfectly consistent behavior. Characters have a position coordinate. Walkable areas define where characters can walk, i.e. their valid position coordinates. The blocking rectangle has nothing to do with it; it is strictly about how close other characters can get to the character, and this is very clearly documented.

It is not a matter of collisions, as you seem to take it. For example, two characters' blocking rectangles can intersect without problem—no "solid body collision check" is made. It's just that their positions can't enter inside the other character's blocking rectangle (while walking normally).
Title: Re: Intercepting character position
Post by: jumpjack on Tue 03/01/2023 16:34:28
Quote from: Crimson Wizard on Wed 28/12/2022 19:39:05I honestly still do not understand why cannot you make the non-walking area further from their tiles to compensate for character's sprite width? I think that would be the first thing I'd try, if I were experimenting with such setup. Would not the result look approximately as if the character's "blocking area" was working the way you implied? Is there anything that prevents using this method?
Available walking areas are already quite small, anyway I'll give it a try.

Quote
Quote from: jumpjack on Wed 28/12/2022 19:35:43Anyway I'll disable mouse and use only keyboard control to override this behaviour.

I might mention that mouse or keyboard (as an input method) do not enforce walking behavior. It's all in the script, how the script reacts to the player's input, which functions it uses. It's possible to call same functions in both cases.
Isn't pathfinder algorithm hardcoded?
Title: Re: Intercepting character position
Post by: Crimson Wizard on Tue 03/01/2023 17:17:12
Quote from: jumpjack on Tue 03/01/2023 16:34:28
Quote
Quote from: jumpjack on Wed 28/12/2022 19:35:43Anyway I'll disable mouse and use only keyboard control to override this behaviour.

I might mention that mouse or keyboard (as an input method) do not enforce walking behavior. It's all in the script, how the script reacts to the player's input, which functions it uses. It's possible to call same functions in both cases.
Isn't pathfinder algorithm hardcoded?

The pathfinder is hardcoded, but the reaction to player's input is not. Everything that happens on mouse clicks or keyboard presses is in the game script and may be changed.

If there's a difference in how character walks after mouse click and key press, this means that the game script issues different commands depending on the input event. And it should be possible to alter the script, making them both to produce similar behavior.

What I am trying to say, is that you don't have to drop an input device support only because the original game script causes it to do something that you do not like.

At the moment I do not fully know which walking behavior you are trying to achieve, so I am merely speculating.
If I remember correctly, in the default game template keyboard controls call WalkStraight function, passing relative coordinates instead of absolute ones (like, player.x + X, player.y + Y). It is possible, for example, to do similar thing with the mouse, by converting absolute mouse coords into relative ones.

This is only to clarify existing opportunities.
Title: Re: Intercepting character position
Post by: jumpjack on Tue 03/01/2023 20:41:58
Quote from: Crimson Wizard on Tue 03/01/2023 17:17:12At the moment I do not fully know which walking behavior you are trying to achieve,

You can see here the game I wouold like to port to AGS:

https://jumpjack.github.io/oricutronJS/oricutron.html

Click on START button adiacent to "Start emulator with demo disk (to create filesystem)" to load the game in the emulator.

M = Move forward
B = Move Backward
S = turn left
X = turn right
Title: Re: Intercepting character position
Post by: Khris on Tue 03/01/2023 21:24:56
That link doesn't work for me; go here instead: https://jumpjack.github.io/oricutronJS/
Then click the link at the top (space1999-en.dsk).
Title: Re: Intercepting character position
Post by: jumpjack on Wed 04/01/2023 11:30:03
Quote from: jumpjack on Tue 03/01/2023 16:34:28
Quote from: Crimson Wizard on Wed 28/12/2022 19:39:05I honestly still do not understand why cannot you make the non-walking area further from their tiles to compensate for character's sprite width? I think that would be the first thing I'd try, if I were experimenting with such setup. Would not the result look approximately as if the character's "blocking area" was working the way you implied? Is there anything that prevents using this method?
Available walking areas are already quite small, anyway I'll give it a try.
I gave it the try. :-)
I had to reverse the logic: rather than manually drawing walkable tiles, I had to make whole room walkable and "drill" nonwalkable tiles in it; else, by reducing size of walkable tiles resulted in many walkbale areas separated by some pixels...
So, rather than reducing walkable areas I extend non walkable areas.
Note: apparenly it's better, for isometric games, not to extend the nonwalkable areas/tiles in all directions, but only downwards.
Title: Re: Intercepting character position
Post by: Crimson Wizard on Wed 04/01/2023 14:05:47
Quote from: jumpjack on Wed 04/01/2023 11:30:03I had to reverse the logic: rather than manually drawing walkable tiles, I had to make whole room walkable and "drill" nonwalkable tiles in it

Ahh, actually I thought this is what you're doing from the start; I had a wrong idea all this time.

Quote from: jumpjack on Wed 04/01/2023 11:30:03Note: apparenly it's better, for isometric games, not to extend the nonwalkable areas/tiles in all directions, but only downwards.

This makes perfect sense, that amount of "outline" may be different depending on direction. I'm bit concerned about the horizontal corners too, but that's something one may find out by testing.