Animation Issues

Started by Custerly, Mon 15/01/2024 17:25:20

Previous topic - Next topic

Custerly

Hi all,

When animating a sprite, I initially used this code:
Code: ags
        c.Animate(1, 1);
        
        c.LockView (3); 
        c.Animate(3, 1);
        c.Animate(0, 1);
... but I found that the game was paused during the animation (due to eblock being enabled by default). I figured this would become an issue when I want to have multiple animations running simultaneously, so I updated the code like this:
Code: ags
        c.Animate(1, 1, eOnce, eNoBlock);
        
        c.LockView (3); 
        c.Animate(3, 1, eOnce, eNoBlock);
        c.Animate(0, 1, eOnce, eNoBlock);
... which brings about a new issue: the animations now seem to be skipping through all of the frames instantly, as it jumps right from the starting frame to the ending frame with nothing perceptible in between. I slowed this down by inserting [Display ("blah"];] after each animation line, and that showed that each animation is indeed queing up, and then playing instantly without actually appearing to animate from the user's perspective.

Am I doing something wrong?

Crimson Wizard

#1
To clarify, do you animate one character or multiple characters? I'm asking this because you used same "c.Animate" everywhere.

Normally, if all animations run equal amount of time, then you may simply play last animation blocking.

If they have different length, then make a waiting loop:
Code: ags
while (c.Animating)
{
    Wait(1); // let engine update and redraw
}

where you check the longest animation. Or you may check every character:
Code: ags
while (c.Animating || c2.Animating || c3.Animating)
^ this means that either of the characters still animating.

Matti

Quote from: Custerly on Mon 15/01/2024 17:25:20... which brings about a new issue: the animations now seem to be skipping through all of the frames instantly, as it jumps right from the starting frame to the ending frame with nothing perceptible in between.

Where did you put your code? To me it seems you may have put it in repeatedly execute (without any condition), which makes the animations start over again and again (normally 40 times per second), so they don't actually have a chance to play.

eri0o

Quote from: Custerly on Mon 15/01/2024 17:25:20that showed that each animation is indeed queing up

They don't queue, each command runs once it gets to their time. If there's nothing blocking, they will run one after the other, in the same frame, so only the last one should play - or maybe not even that assuming you are properly locking and unlocking the view you want to animate.

If you want to queue animation in a way that is non-blocking, you will have to write your own system for it - I don't know if there is a module for this, if there's someone could suggest.

Custerly

Thanks @Crimson Wizard, @Matti, & @eri0o: Thanks very much for your input.

@Matti: The code I shared was from a function in the global script (not RepEx).

@Crimson Wizard: To clarify, it is one character animating (1 animation in 1 view, then switches to a 2nd view and runs 2 animations). It needs to be done sequentially obviously, so I guess the fact is that all animations need to run with eblocking enabled and I have to accept that the game will be paused during the animations, correct?

That being the case, if I want multiple animations running simultaneously, the way to achieve that is by having the first animation appearing in the script set to enoblock and the final animation in the script set to eblock, as you said. I understand that now.

I have a bonus issue that I'm wondering if you could weigh on on. When I revert to the original code with eblock enabled, and I run said animation chain via scripting triggered during a conversation (with my custom dialogue GUI open) it stutters noticably. When I run the same animation chain outside of dialogue via clicking on a hotspot, it runs butter smooth. After poking around a bit, I noticed that if I set all of the dialogue GUI buttons to invisible during the animations, it runs smoother (though still not as smooth as when the animations are triggered outside of the dialogue GUI). The game res is 4k, the sprite animating is 1024x1024, and those buttons all have needlessly large transparent PNGs as their background images (so I can have invisible buttons), but I can see no reason why those factors should be burdening the system so much as to produce noticable stuttering in a simple 2d animation. I am running this in a 3-year old low end Dell laptop that I'd think should be more than capable of handling it. Any ideas of things I may be doing wrong?

Khris

You should turn the buttons invisible instead of assigning transparent sprites to them.

As for the animation, you should be able to put all these frames into a single loop, that way you can have a single non-blocking animation.
It's also possible to run non-blocking commands in sequence but it requires a bunch of additional code (basically implementing a custom queue).

(Also, your game resolution is 4k? Seems excessive.)

Crimson Wizard

#6
4k resolution?... AGS currently runs 1920x1080 games more or less fine without too many simultaneous objects on screen, but they still get issues sometimes (we spent last year improving things there). But 4k sounds like an overkill. Frankly, AGS engine was simply never meant for this, it has a lot of old methods in it in way of it handles resources and graphics, that may not be suitable for this resolution.
There's also a question of how would this run for players whose monitors don't support a resolution that big, as pixel 2D games that AGS produces cannot reliably downscale the game without massive quality loss.

Quote from: Custerly on Mon 15/01/2024 19:27:32I run said animation chain via scripting triggered during a conversation (with my custom dialogue GUI open) it stutters noticably. When I run the same animation chain outside of dialogue via clicking on a hotspot, it runs butter smooth. After poking around a bit, I noticed that if I set all of the dialogue GUI buttons to invisible during the animations, it runs smoother (though still not as smooth as when the animations are triggered outside of the dialogue GUI)

When you say "custom dialogue GUI", do you mean that you script custom dialog options rendering, or something else? Are these actual buttons, or something that you draw using a DrawingSurface?

Custerly

#7
@Khris:
- To clarify, I do make the buttons invisible during animations (as I observed that reduces the stuttering while not toally eliminating it), but the reason for the transparent background is so that I can have dialogue options displayed to the player without a button graphic being seen. So obviously, turning the buttons invisible is not an option during conversations.
- Whether one loop or 100, the animations are not being displayed during runtime unless there is blocking. They just run through instantly and are inperceptible to the user unless there is blocking.
- Perhaps 4k is excessive, I just didn't previously see a reason not to go for the max resolution.

@Crimson Wizard:
- I see. I will then port everything over to 1080p as suggested. When doing so, is there a way that AGS can automate this transition, or do I need to manually resize all game assets, re-load them into the game, and re-place all sprites and redraw all hotspots?
PS. I have been developing this on a 1080p monitor with no perceptible degredation in quality from AGS downsizingh everything from 4k.
- It is a cutom dialogue GUI made from the ground up. You've helped me in the past with several roadblocks I've run into while building it. It has buttons for up to 9 dialogue options, it has a label displaying dialogue, it has labels showing numbers for each dialogue option visible, it has labels for each speaker in sequence, it has labels floating over buttons to get text wrapping on the buttons.
Here's what it looks like in action (please ignore the nonsense dialogue, it is purely for testing):
https://imgur.com/a/sLqtcYp

Bonus question: Can I have AGS automatically re-size a sprite during runtime? I want to have character portraits shrink to half size when they are not the current speaker during a conversation.
- EDIT: After some Googling, it looks like I want DynamicSprite.Resize right? Will I still be able to animate the new dynamic sprite using the same views as the original?


Khris

Resetting a button to displaying text should work by setting its .NormalGraphic to 0, but I haven't tested this.

That is weird, people use non-blocking animations all the time without issue. You do have a frame delay of 1 in your code, but that should still not run the entire animation in a single frame.

One reason would be your game graphics, which I don't think require 4k at all. You have a fairly lowres background, a portrait with visible pixels and even for the font, Full HD should easily suffice.
There is no reason to go for the max resolution unless you actually require that level of detail, especially on a "legacy" engine like AGS.

Custerly

Quote from: Khris on Tue 16/01/2024 17:53:09Resetting a button to displaying text should work by setting its .NormalGraphic to 0, but I haven't tested this.

That is weird, people use non-blocking animations all the time without issue. You do have a frame delay of 1 in your code, but that should still not run the entire animation in a single frame.

One reason would be your game graphics, which I don't think require 4k at all. You have a fairly lowres background, a portrait with visible pixels and even for the font, Full HD should easily suffice.
There is no reason to go for the max resolution unless you actually require that level of detail, especially on a "legacy" engine like AGS.

@Khris: Above, eri0o said "If there's nothing blocking, they will run one after the other, in the same frame, so only the last one should play - or maybe not even that assuming you are properly locking and unlocking the view you want to animate." and that has been my experience when using animations without blocking. Are you sure it can work without blocking?

Crimson Wizard

#10
Quote from: Custerly on Tue 16/01/2024 17:31:30- Perhaps 4k is excessive, I just didn't previously see a reason not to go for the max resolution.

The logic of selecting game resolution for 2D games should be opposite: choose the lowest resolution that suits your requirements, as AGS itself can easily scale the game up to any monitor, and that should not cause any performance issues.

The reason to NOT go to max game and asset resolution is simple: the higher resolution, the
- more disk space the assets require
- the longer assets load and prepare for display.
- more RAM and GPU memory they require while being displayed on screen; and if there's not enough of that, they will keep getting reloaded all the time, slowing game down.
So you may be making your game unnecessarily big on disk, and introduce potential performance problems for the players who do not have powerful computers, while not gaining any actual benefit.

This is also why I don't suggest to go to 1080p, but rather recommend finding a resolution which matches the asset looks. That is a resolution where your sprites, fonts, etc can be displayed 1:1 without quality loss. Even if that's 720p or less.

Quote from: Custerly on Tue 16/01/2024 17:31:30I have been developing this on a 1080p monitor with no perceptible degredation in quality from AGS downsizingh everything from 4k.

I suppose that may be because 4k is evenly divided on 1080p.

Custerly

@Crimson Wizard:

I will take your advice (and that of others here) and lower the res. Will I need to manually resize all assets, replace the current assets with the smaller ones, redraw all hotspots, re-place all sprites, etc. or is there a way to automate this within AGS?

Also, I want to have character portraits shrink to half size when they are not the current speaker during a conversation, but I want these miniature sprites to retain the ability to animate. Do I need to make new, smaller sprites and also make new views for animations, or is it possible to have AGS shrink down the existing sprites on the fly and thereby utilize the same graphics and animation views directly? I see that I can use DynamicSprite.Resize, but I assume that I won't be able to animate that.

Crimson Wizard

#12
Quote from: Custerly on Tue 16/01/2024 20:30:15I will take your advice (and that of others here) and lower the res. Will I need to manually resize all assets, replace the current assets with the smaller ones, redraw all hotspots, re-place all sprites, etc. or is there a way to automate this within AGS?

There's no way to automate this in AGS, but there must be a way to automate this using some graphics tool. Unfortunately, I do not have much knowledge of this, but maybe someone else can give an advice on which to use.

Quote from: Custerly on Tue 16/01/2024 20:30:15Also, I want to have character portraits shrink to half size when they are not the current speaker during a conversation, but I want these miniature sprites to retain the ability to animate.

Using Overlays will let you display sprites on screen with any scaling, but you will have to script animation yourself, changing overlay's graphic in periods of time. But I think you would have to do that yourself anyway, as AGS does not have a feature for displaying second portrait on screen.

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

EDIT: Alternatively, you could try using a dummy Character for that, which can be animated using a Animate function, and manually scaled too.
But keep in mind that characters are drawn on a "room layer" behind all GUIs, so that might be tricky (depends on situation).

Khris

@Custerly Well, properly unlocking the view means after the animation is done, so if you do it right after running a non-blocking animate command then it will indeed produce what you described (i.e. nix the animation).

Animating characters non-blocking during a dialog should work fine in principle; locking the view means that AGS will no longer switch to the appropriate view itself based on what's happening with the character (walking, talking, etc), so as long as it's the same view for all character frames, it's probably safe to call UnlockView() only after the dialog ends.

Custerly

Quote from: Khris on Tue 16/01/2024 22:28:52@Custerly Well, properly unlocking the view means after the animation is done, so if you do it right after running a non-blocking animate command then it will indeed produce what you described (i.e. nix the animation).

Animating characters non-blocking during a dialog should work fine in principle; locking the view means that AGS will no longer switch to the appropriate view itself based on what's happening with the character (walking, talking, etc), so as long as it's the same view for all character frames, it's probably safe to call UnlockView() only after the dialog ends.

@Khris:
Here's the code I used:
Code: ags
        c.Animate(1, 1, eOnce, eNoBlock);
        
        c.LockView (3); 
        c.Animate(3, 1, eOnce, eNoBlock);
        c.Animate(0, 1, eOnce, eNoBlock);
I originally did not unlock the view after (this is for a dummy character serving as a charatcer portrait during dialogues, so I don't need AGS to automatically animate this 'character' ever). Using the above code, I see no animation, just the switch from the former view over to view 3 (via [c.LockView (3);]).

If I add in [c.UnlockView (3);] afterwards, the issue remains.

If I enable eblocking, the animations play out, but the game pauses, which I'd hoped to avoid.

Custerly

@Crimson Wizard:

I actually have already been using a dummy character for these portraits. I wasn't aware that AGS has a built-in system for character portraits as you implied. I will continue with this method, I just thought I'd check and see if there was a more automated route I could take.

Thanks once again for sharing your knowledge and insights.

Custerly

@Crimson Wizard:

I updated everything to 1080p from 4k, and the animation stutter is persisting. Again, it is only choppy if my dialogue GUI is open while the animation is playing (if I set the GUI to invisible, the animation plays butter smooth).

I was wondering if this is the fault of my dialogue GUI specifically, or if this is an issue AGS has running animations while a GUI is open, so I tested this by making a new and very small GUI consisting of just one button to trigger the animation (the lightest GUI possible). The animation stuttered. Therefor, this is an inherent issue AGS has running animations while any GUI is open.

This seems beyond me to troubleshoot, but I did think of a potential workaround: Is it possible to copy the appearancy of my GUI (buttons, labels, and all), write that onto the background, make the actual GUI invisible, run the animation, then revert the background to its former appearance and make the GUI visible again?

Snarky

Quote from: Custerly on Wed 17/01/2024 04:26:13I was wondering if this is the fault of my dialogue GUI specifically, or if this is an issue AGS has running animations while a GUI is open, so I tested this by making a new and very small GUI consisting of just one button to trigger the animation (the lightest GUI possible). The animation stuttered. Therefor, this is an inherent issue AGS has running animations while any GUI is open.

May we see this GUI? It seems likely that you're doing something non-optimal.

Crimson Wizard

#18
Quote from: Custerly on Wed 17/01/2024 04:26:13I was wondering if this is the fault of my dialogue GUI specifically, or if this is an issue AGS has running animations while a GUI is open, so I tested this by making a new and very small GUI consisting of just one button to trigger the animation (the lightest GUI possible). The animation stuttered. Therefor, this is an inherent issue AGS has running animations while any GUI is open.

This is unexpected, a lot of AGS games have some GUI on screen at all times. In the past there have been issues with GUIs slowing down high-res games because they redraw unnecessarily on some actions, but that has been fixed.
I'd need to investigate, and know some details about GUI, and how animation is run, how is it started in script, etc.
Do only animations stutter, or the rest of the game too? For example, does cursor slow down or jitter at the sametime?
Please also tell which version of AGS are you using, and which graphics driver do you use to run the game, because that may matter.

EDIT: in Default Setup pane there's "Display FPS on screen" option that enables a FPS counter useful for noticing performance problems. If you could turn that on and test this case, you would see if the whole game slows down or not. If not, then there's something incorrect in how animation is run.

eri0o

Also, if you can reproduce this slow down in a small one room game, that you could share with us, this would be super helpful for debugging too.

SMF spam blocked by CleanTalk