Author Topic: [SOLVED] Why this strange 'reset' to height when inclding a .Walk() command?  (Read 835 times)

bx83

  • Get 'Er Doooooone
I've noticed the following weird behaviour.

My sprite has a wide area under him:



...so to make him walk back and forth on the path set out, I need to either:
a) export, change, and re-import all the masks for every room (not happening, too complex, will take 3 months, plus I have to resize paths with continuous scaling, and just editing a mask .bmp is paint.net or paint.exe results in it saving wrong)
OR
b) make his z coords good for "lowering" him to the path

I've already come up with an equation which seems to work 100% of the time depending on his scaling:

cJulius.z = 0 - ( FloatToInt( (Z_FACT / 100.0) * IntToFloat(cJulius.Scaling), eRoundDown ) );

Where cJulius is my sprite
Z_FACT is a floating point constant of 72.0 (about the distance his feet are from the bottom of his frame, 72pixels)

The final result for cJulius.z is always a negative number.

I have a usual interact function: walk to object, face object, say something, pickup object (play an animation of him bending down to get it).
The pickup animation is the same size exactly as the standard walk animations; it goes seemlesly.

HOWEVER

When I have a .Walk() anywhere near to the .PickupUp() animation, it 'resets' itself after I've done this --  in other words, it seems to jump a random amount in height, for no known reason:
https://redrom.ltd/img/julius reset.webm

When I take out the walking line, no reset:
https://redrom.ltd/img/julius no reset.webm

The code is:

Code: [Select]
function oWallet_Interact()
{
cJulius.Walk(587, 396, eBlock, eWalkableAreas);    <-- THIS LINE CAUSES RESET; if I comment it out, no reset occurs.
cJulius.FaceObject(oWallet);
cJulius.SayBubble("My wallet! Something survived the time-travel. Oh... it's got all the money missing.");
cJulius.PickUp(eLow, iWallet, oWallet, false, 8, player.Room);
}


Also, here's the .PickUp() code:

Code: [Select]
function PickUp (this Character*, PickUpHeight height, InventoryItem *i, Object *o, bool visibility, int obj, int room)
{
 
int _loop_down=0;
int _loop_up=0;
 
if (height == eLow) {
_loop_down=138; //low
_loop_up=140;
}
... //other heights, this just sets the view number for the pickup down, pickup up views
 
int cur_loop=this.Loop;

this.LockView(_loop_down);
this.Animate(cur_loop, 1, eOnce, eBlock);
this.UnlockView();

this.AddInventory(i);
o.Visible = visibility;

this.LockView(_loop_up);
this.Animate(cur_loop, 1, eOnce, eBlock);
this.UnlockView();

}


Now - obvious questions:

Have you tried setting Julius' loop to the same each time, even when you don't include the .FaceObject() function call? Yes - still happens.
Have you tried peppering Wait(1); between each line of code, and the .PickUp animation code? Yes - still happens.
Have you created a new room, with all the same objects, paths, masks and scaling, and see if it does this still? Yes - still happens.
Have you tried making a generic room with only the Walk,Speak,Pickup code in it? Yes - still happens.
Have you tried deleting the line to do with the .FaceObject() function, so it's walk,speak,pickup; or for that matter walk,pickup; or walk/wait/speak/wait/pickup; or walk,wait,pickup; or...? Yes - still happens as long as .Walk() is there.
What about when Julius walks to an object by guidance of the mouse, not a Walk() command It works when I send him to a point, but not the command .Walk(). However, don't really see how I can get rid of this.
Is the .z variable the same before, after and during? Yes, tested thoroughly, but .z is miss-set when I pickup something, as opposed to the clone rooms. When set .z based on scaling alone eg. if .scaling=5 then .z=-16 or whatevs -- it sets the .z different to other rooms, and the 'reset' still happens. However, the .z it's set to is always the same mis-set number.
What's the function for the setting Julius' .z variable?

Code: [Select]
function repeatedly_execute()
{
cJulius.z = 0 - ( FloatToInt( (Z_FACT / 100.0) * IntToFloat(cJulius.Scaling), eRoundDown ) );
....
}

Have you tried writing it walk/say/nothing You mean leave out the PickUp() animation? Or the .SayBubble()? It still does the reset wherever there's a Walk() command.
Is it something to do with the .SpeechBubble() code? Perhaps - I've got 0.8 but made a few minor changes to integrate it. Anyone wanting to see it I'll PM it to.

Am I missing something here? Does walk always do this, reset graphics somehow? Does walk() do something which the standard code for getting a character to walk somewhere based on a mouse-click in eModeWalk doesn't?
Am I insane, or as usual overthinking?

Plz help :(
« Last Edit: 10 Feb 2020, 03:43 by bx83 »

bx83

  • Get 'Er Doooooone
Is there anyone in here who can help?
I'm happy to post code if that helps find a solution?

bx83

  • Get 'Er Doooooone
I used ProcessClick to try and find a function other than Walk():

Room.ProcessClick(580, 404, eModeWalkto);

But Julius doesn't walk to these coordinates. Am I doing something wrong?
« Last Edit: 09 Feb 2020, 04:33 by bx83 »

Gilbert

  • Local Moderator
  • * KILL* * KILL * * KILL *
    • Lifetime Achievement Award Winner
Is there anyone in here who can help?
I'm happy to post code if that helps find a solution?
It's just the usual 'everyone has a life and may not concern much about virtual adventures at weekends' thing. Just be patient as this is a forum, not a chat. It's normal to have people answer to a thread only after hours have passed (not to mention they live in different time zones).

I could not help ATM as I'm not at home and writing this with my phone.

Please don't bump threads unless there really is some new things to add, and don't cross-post in different forums. If you think a thread was not started in the appropiate forum just notify a moderator for them to move it for you. I'll remove tge duplicated thread from the beginners' forum.

bx83

  • Get 'Er Doooooone
Okay. Was just kiling my game, gave it over night, still no replies. It's all good.

In fact if someone could just tell me the ProcessClick() syntax that would be good, currently it does nothing, no walking.

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
I always thought z-coordinates were scaled along with the character by the engine.

bx83

  • Get 'Er Doooooone
I don't think so... having trouble finding answers on this. If it does scale, then it's all been for nothing :/

bx83

  • Get 'Er Doooooone
Doesn't appear to scale.
.z=-72 means its always 72 pixels below floor. If you go into a room where Julius is scaled to like 8% then he's suddenly a huge amount under the floor.
« Last Edit: 09 Feb 2020, 20:06 by bx83 »

The videos are not a fair test because the character is facing forwards when he picks it up in the second video.

I don't know if it's good practice or not but I never use commands like face object because I don't have full control over where the character will face. In this instance I would have used the code for facing left, and if you had done so, then when testing it without the walk command, it would be a fair test. How do we know he doesn't move upwards when facing left without walking when we only see him face forwards (down) in the second video? We don't.

bx83

  • Get 'Er Doooooone
I have a room where he can click objects in any direction, so I've tested extensively. It's just the walk() command; don't know if ProcessClick() because I can't get it to - he doesn't walk (and the coordinate he's walking to is on the walkable area).

TheManInBoots

  • Epically wrote function to declare an int
I had some trouble using the z-layer as well.
But you can simply edit out the space below the character sprites in the original files and re-import the sprites by right clicking all the character sprites in the sprite folder and selecting import from source.
If you don't have a proper tool to cut out the empty space below the character sprites, you can use gimp, which is freeware. It has a plug in that you can look for and download separately which allows you to export layers. So you can add all images in one project file as different layers. Remove the lower space with the "Crop to Selection" tool.
Then export them.
And then import them into the game as described above.
If you know what you're doing this is done in an hour and your game is fixed.
If you do it this way and you have troubles on the way feel free to ask.

written with Android 4.0
« Last Edit: 09 Feb 2020, 11:40 by TheManInBoots »

I assumed they wanted to keep the space below for some kind of animations, otherwise why have such a big space?

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
Okay, stupid question, but why exactly do you have so much empty space bellow the character? Is there a reason for it, or just because they were provided like that by your artist? I would suggest you cut all that space, so that your z is like -7 or -10 or so, to start with. Just make sure you cut exactly as many pixels in each sprite and don't cut any part of his feet while walking. Don't know if it'll fix your problem, but at least the gap will be less noticeable.
I never used anything but adjusting the z before, and never noticed I needed to. But maybe when you scaling him so much there's a limit...
There are those who believe that life here began out there...

TheManInBoots

  • Epically wrote function to declare an int
I assumed they wanted to keep the space below for some kind of animations, otherwise why have such a big space?
Let's see what bx83 says but the way the character is animated they don't seem to be.
If there is one moment where the character reaches below I would still cut out the lower space for all sprites, and then find a separate solution for that one animation.
Just talking efficiency here.
« Last Edit: 09 Feb 2020, 12:11 by TheManInBoots »

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
There are lots of reasons to have free space below the character. For example, if you want to draw a shadow under them, or if the down walkcycle has the feet going further down.

Doesn't appear to scale .z=-72 means its always 72 pixels below floor. If you go into a room where Julius is scaled to like 8% then he's suddenly a huge amount under the floor.

This seems like a pretty big oversight/bug in AGS. We've been telling people for years to use Character.z to move the character baseline to line up with the character's feet, and if it doesn't take scale into consideration then that's not a suitable solution.

(Sorry, I can't really help with your problem.)

Arlann

    • Arlann worked on one or more games that won an AGS Award!
    •  
    • Arlann worked on one or more games that was nominated for an AGS Award!
Is this not a blocking function problem?
If z is relative to scaling, you should update z in a function repeatedly_execute_always or late_repeatedly_execute_always, because the scale changes as you walk.

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
Yes, it should definitely go in late_repeatedly_execute_always(). In fact, that function was created for pretty much this exact purpose.

(And with Arlann pointing it out, I now see what the problem is, and why this would fix it.)

TheManInBoots

  • Epically wrote function to declare an int
So true of course the block is causing it.
And I have to correct myself. I watched the animation on the phone before.
But on closer look, bx83 totally uses the empty space below for the feet of the walking animation.
« Last Edit: 09 Feb 2020, 13:50 by TheManInBoots »

If that's the case Snarky, it's interesting to me how complex bx83 made things be, which made the issue seem really complicated and way too advanced for me, but it was something I am familiar with.

The more you know, the less you can see, or something?

What I'm trying to say is, did bx83 make this problem much worse for themselves by over complicating things? Assuming it is this solution.

Maybe a dumb question, but are you 100% sure the sprite images are cut exactly the same?
I know i did that mistake in the beginning, that's why i never cut images inside the actual AGS editor anymore, i just import it "correctly" from photoshop directly.
Just a food for thought.

Edit: What i mean is, is the pickup animation the same as the walking animation in height/width pixels and placementwise?

TheManInBoots

  • Epically wrote function to declare an int
Olleh bx83 mentioned before that they are.

Also when the character does not walk, the animation transition goes seemlessly as you can see in the second video.

Olleh bx83 mentioned before that they are.

Also when the character does not walk, the animation transition goes seemlessly as you can see in the second video.

Aha, but it's two different animations tho ??? a side animation when it doesn't work, and the front pickup version when it does work. Still a change it could be off in the cutting, if  it's been done manually (in the ags editor).
Would be interesting to see if it works for anybody else. If he could share the actual animations only so one can import and try. (roll)

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
I think we have already found the cause of the problem (well, Arlann has), so that should not be necessary.

Sorry, haven't read this thoroughly, but

Is this not a blocking function problem?
If z is relative to scaling, you should update z in a function repeatedly_execute_always or late_repeatedly_execute_always, because the scale changes as you walk.

I believe, this must be remembered, and go into FAQ, that if you need some property, especially visual property, be to kept in sync with another built-in property at all times, then it should always be done in late_repeatedly_execute_always, because this function is called always, and called last before drawing things on screen.

repeatedly_execute is not called during blocking actions, therefore may skip a long period,
repeatedly_execute_always is called before main game update, therefore will always be 1 frame "behind" the game and object values.
« Last Edit: 09 Feb 2020, 16:45 by Crimson Wizard »

bx83

  • Get 'Er Doooooone
SOLUTION

Put the Julius z scaling:

Code: [Select]
cJulius.z = 0 - ( FloatToInt( (Z_FACT / 100.0) * IntToFloat(cJulius.Scaling), eRoundDown ) );
...in repeatedly_execute_always(), and not just repeatedly_execute().

Thank you all!  :grin:

I will test this extensively, but it seems to work.

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
Quote
then it should always be done in late_repeatedly_execute_always, because this function is called always, and called last before drawing things on screen.
There are those who believe that life here began out there...

I realised my character z code was in the game start function, so I moved it late repeatedly execute always and when the game loads, I visually see the character get moved down after fade in. Keeping it in on game start as well seems to fix that.

Although my character z code is just the basic version of the code for the z axis, not the above code that bx83 is using which I don't understand.

bx83

  • Get 'Er Doooooone
Cassiebsg: I know, I read this part, tried repeatedly_execute_always(), and it worked. Maybe later_ would also work, doesn't require testing.

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
The difference is that late run after everything else, but just before it being drawn. putting it on the other might give you a little "hickup" as in, the character is drawn in y 80, and moves to y 81 or 79 after it has been drawn. Might be noticeable, might not.

ManiacMatt, that seems to be odd, since the character should be updated to the new z, before he gets drawn in screen, not afterwards.  ??? But putting the z in game start is what I usually do. Never noticed needing all that code bx83 is using. But then again I don't think I have any game with that much scaling.
There are those who believe that life here began out there...

I realised my character z code was in the game start function, so I moved it late repeatedly execute always and when the game loads, I visually see the character get moved down after fade in. Keeping it in on game start as well seems to fix that.

Although my character z code is just the basic version of the code for the z axis, not the above code that bx83 is using which I don't understand.
If by "basic version" you mean something like  player.z = -20;  you should keep it in game_start because there's absolutely no reason to run that line dozens of times per second. Unlike code that has to constantly update z because it takes the current scaling into account (i.e. shifts the player by 108 pixels instead of 72 if they're scaled to 150%).

You saw the jump because when AGS fades in a room the game is blocked, and a room's RepExec function only runs while the game isn't blocked (this is why repeatedly_execute_always exists).
Fail at Floaty Rog' now!  still having to deal with what games are going through

Oh right! I thought maybe I was doing it wrong by having it i. game start despite not noticing any problems. I'll revert it back to how it was. I'm not using any scaling for this game anyway. Yeah that was the code! Thanks both!

TheManInBoots

  • Epically wrote function to declare an int
Aha, but it's two different animations tho ??? a side animation when it doesn't work, and the front pickup version when it does work.
Lol actually he had mentioned that before that he had the exact same results for all animation directions:
I have a room where he can click objects in any direction, so I've tested extensively. It's just the walk() command

I realised my character z code was in the game start function, so I moved it late repeatedly execute always and when the game loads, I visually see the character get moved down after fade in. Keeping it in on game start as well seems to fix that.

Although my character z code is just the basic version of the code for the z axis, not the above code that bx83 is using which I don't understand.
Both the late repeatedly execute always and repeatedly execute always start running only AFTER the very first room has loaded. Nobody seemed to have noticed that.
So of course you have to write it both in game start (or room before fade in) AND repeatedly execute always, if you have the constantly changing z-factor.
You saw the jump because when AGS fades in a room the game is blocked, and a room's RepExec function only runs while the game isn't blocked (this is why repeatedly_execute_always exists).
.
Again, that's not correct. Even repeatedly execute always (AND late rep. always )is blocked before the very first room is loaded.
After the first room is loaded the repeatedly always function works during fade ins for other rooms but NOT before the first room is loaded.


I believe, this must be remembered, and go into FAQ, that if you need some property, especially visual property, be to kept in sync with another built-in property
And if you add the FAQ it might be very useful to also explain exactly what you mean with "visual property" and "built-in property", because people who are new to AGS (which are the ones who have FAQs) won't understand it otherwise.

bx83, would you mind sharing a sprite frame of the "walk up animation" of your character? One where the leg is stretched down to the very bottom of the sprite?
Because the question came up several times and I believe not everyone understood why that space below the character was necessary in the first place. And it's just a brilliant example for efficient walk animation (by stretching limbs).
« Last Edit: 10 Feb 2020, 03:00 by TheManInBoots »

bx83

  • Get 'Er Doooooone
Quote
bx83, would you mind sharing a sprite frame of the "walk up animation" of your character? One where the leg is stretched down to the very bottom of the sprite?
Because the question came up several times and I believe not everyone understood why that space below the character was necessary in the first place. And it's just a brilliant example for efficient walk animation (by stretching limbs).

     

All frames are the same size. All frames work seamlessly.

ps Sorry for colours, just to show where the frame begins and ends.

You saw the jump because when AGS fades in a room the game is blocked, and a room's RepExec function only runs while the game isn't blocked (this is why repeatedly_execute_always exists).
.
Again, that's not correct. Even repeatedly execute always (AND late rep. always )is blocked before the very first room is loaded.
After the first room is loaded the repeatedly always function works during fade ins for other rooms but NOT before the first room is loaded.

Yeah, what I meant by that was "in general, repeatedly_execute code doesn't run while the game is blocked (this is why repeatedly_execute_always exists)". The first fade in seems to block everything though, yes.
Fail at Floaty Rog' now!  still having to deal with what games are going through

You saw the jump because when AGS fades in a room the game is blocked, and a room's RepExec function only runs while the game isn't blocked (this is why repeatedly_execute_always exists).
.
Again, that's not correct. Even repeatedly execute always (AND late rep. always )is blocked before the very first room is loaded.
After the first room is loaded the repeatedly always function works during fade ins for other rooms but NOT before the first room is loaded.

Yeah, what I meant by that was "in general, repeatedly_execute code doesn't run while the game is blocked (this is why repeatedly_execute_always exists)". The first fade in seems to block everything though, yes.


Hmmm, this seems like a engine flaw. Fade-in should always be same fade-in, regardless of whether it's first time room is entered or not.
Probably it was explicitly coded to run an all-blocking fade-in at the start.
« Last Edit: 10 Feb 2020, 11:54 by Crimson Wizard »

TheManInBoots

  • Epically wrote function to declare an int
     
ps Sorry for colours, just to show where the frame begins and ends.
It's nice. Thanks for sharing.

TheManInBoots

  • Epically wrote function to declare an int
I had only experimented a little with z-axis and it seemed that only during the first room load the repeatedly_execute_always function is switched off.
After reading this post I felt like experimenting more with it in another project, and actually repeatedly_execute_always (also the late_r...) are paused during room transitions.
It makes sense coming to think about it, because the repeatedly execute functions are all blocked while the game is paused. You don't want  part of the game to continue which is defined in repeatedly_execute_always while the rest of the game pauses. So of course, while the game is paused during room transitions, so are all repeatedly executes.
So I want to correct what I said: during all room changes you need to set the proper scaled z-value in the room before load function in order to avoid the sudden little jump after fade in.
« Last Edit: 05 Mar 2020, 13:25 by TheManInBoots »