freezes in game

Started by lafouine88, Sat 30/03/2024 23:44:49

Previous topic - Next topic

lafouine88

Hi guys
I'm working on a rpg game, diablo-like, if you want to consider the amount of functions and GUIs involved :)

I'm still working on my basic functions : interface,combat,loot etc. and I'm not halfway through what I hope to achieve. But I'm starting to worry a bit since for a little while now, I have small freezes every now and then. It lasts between 1 and 3 seconds and happens every now and then. It doesn't seem to be related to any particular action since it sometimes happens just when I'm walking around alone(though it seems more frequent when I'm fighting ennemies).
I'm working with 30 characters on the map, and the map is quite large (~7000*5000, actually almost as big as the game allows because I reduced it after having an error message like "memory out" or something), but even when I reduce the size I still have the freezes.
Of course there's a lot of functions running all the time, but I guess for PCs as powerfull as we have nowadays it should be a piece of cake and irrelevant compared to what new games require.

So maybe I missed something, either in my scripting architecture, or game settings? Or maybe (and I hope not) the game engine is not designed for this kind of game and I'm running into a wall here ...-_-

If you have any elements I would really appreciate here since I've worked a lot already on it and if it's bound to fail, I might as well know it now :undecided:

Thanks a lot  :wink:

eri0o

#1
It's hard to tell without having the game project and turning off and on things to narrow down what's causing the performance issue.

You can use Debug(4,1) to show fps on screen and selectively turn pieces of your game system to see what's causing issue.

It can be anything, it can be something that is badly scripted in rep exec for instance by mistake.

What AGS version are you using?

What's your game resolution?

Also if you believe that the map size is the issue you may try breaking the game in smaller maps.

If you think the issue is the pathfinding you may try lowering the room walkable area resolution - you can lower by half to a quarter in it's config I think.

You could also simplify the monsters that are far from the player by making them "sleep" and "awake" on player proximity.

You can even try to load the sections dynamically but it will require scripting a system for it. I made a game with a virtual 8092x8092 map but divided it in an 8x8 grid and loaded it in a 3x3 grid centered on the player as necessary. The issue is when doing so you lose the room editor as you will need to come up with a different way to design your levels.

Crimson Wizard

#2
Quote from: lafouine88 on Sat 30/03/2024 23:44:49I'm working with 30 characters on the map, and the map is quite large (~7000*5000, actually almost as big as the game allows because I reduced it after having an error message like "memory out" or something)

Something I should elaborate, in addition to the comment above: AGS is the engine primarily purposed for point-n-click adventure games, and so the way its "rooms" are configured is best suited for that. For instance, the idea of a "room background" (and walkable area mask, etc), being just one big image, - that is something that you normally have in a p-n-c games.

But games with more open world, such as arcades and RPGs, won't benefit from having whole level/world drawn on a single image. Commonly these games use much smaller image (size of screen, or somewhat more than that) generated dynamically, for example, with tiles, as the player moves around. This reduces the amount of memory that the scene takes too.

Similarly, having all possible objects and characters active at the same time may be not optimal. A common thing in open world games is to activate/deactivate objects as player moves around. Or use a "pool" of objects, which allows to reuse objects for various roles.

Quote from: lafouine88 on Sat 30/03/2024 23:44:49Of course there's a lot of functions running all the time, but I guess for PCs as powerfull as we have nowadays it should be a piece of cake and irrelevant compared to what new games require.

That depends on what do you do in these functions... it's quite possible to write suboptimal script that would make a game crawl on a modern PC too.

lafouine88

Hi guys and first, thanks for the very quick and accurate reply.

So :
-I'm still running AGS 3.5.0, I never changed this version but maybe I should?
-Resolution is 640*400
-As for the map size, I was planning on dividing it into smaller maps and use edges to switch to the next one without pause and give the openworld impression (using mandatory passage points like bridges), but I haven't got into that point yet and am REAALLLY intrigued by the tile system you used eriOo and crimson spekas about. I'll look for that on the forum, might be easier. But I'm not sure this is the issue because I tried lowering to something like 2000*2000 and I still have freezes.
-To me, pathfinding could be the problem, first because, for test purposes (still working on the mechanics, I don't have the final map yet) I painted the whole thing in walkable area, so maybe a 7000*5000 walkable area is not the best "^^plus my characters seem to struggle quite often to walk to my player.character when they're chasing him(making a lot of detours^^). So I definitely believe this is part of the problem.
-Repeatedly execute might be suboptimal since it's certain I used some heavy functions when I could have done simpler, but this basically sums up to running a lot of numbers at the same time, I think there is no loophole or bad interrogations (I guess"^^) or the game would always freeze for the same reasons, which doesn't seem to be the case. I'll use the debug mode to try and see something, thanks for the tip:)
-About characters and items, I do make them asleep and teleport to areas around so that you have the impression there s a lot of them when there is actually "only" 30 (but I felt like if I wanted a good continuity and make the player able to pull multiple mobs at the same time this number would be the minimum. Same goes for invitems that 'transform' into the picked up item and release their properties when destroyed. If I do this correclty, I guess 30 characters (say 10 idle or active) and 20 asleep in the buffer zones and 80 invitems is not too much,right ? (Of course...if I do this correctly, this is the main issue -_-)

I definitely have a lot of things to try and work on so thanks a lot to you. I'll give you feedback when I've change a few things

eri0o

Just so you know if you really think that pathfinding is the problem it should be easy, create a new empty game, add 30 characters and put them all to walk and see if you can reproduce your issue. Don't use your game assets, just throw 30 Rogers walking around.

If you can please post this test game here.

Crimson Wizard

Quote from: lafouine88 on Sun 31/03/2024 08:26:58-I'm still running AGS 3.5.0, I never changed this version but maybe I should?

I cannot tell if this will help your game, but there have been a number of performance optimizations done between 3.5.1 and 3.6.1. 3.6.1 in particular showed the script performance improvement up to 40% in some games.

lafouine88

Quote from: Crimson Wizard on Sun 31/03/2024 11:59:31I cannot tell if this will help your game, but there have been a number of performance optimizations done between 3.5.1 and 3.6.1. 3.6.1 in particular showed the script performance improvement up to 40% in some games.

This is the first thing I did...I don't know why I stuck to the older version,nostalgy has its limits^^ thought you speak of 3.6.1 but on the site it says it's still in development so I guess 3.6.0 should already be a good start.
For the rest, it's goign to take some time. I've tried reducing the size of the map and number of characters but it doesn't change. I've isolated the problem to my "aggro" function that makes the ennemy-characters follow the player when he gets closer and it definitely seems to be the one faulty. Maybe the follow function is too hard to manage with multiple characters(I read in the 3.6.0 log that there used to be a limit to 30 characters following).
I'll keep you advised.

Thanks again <3

eri0o

#7
3.6.1 will probably be marked as stable tomorrow just so you know.

How are using the follow character? There's no flag that indicates that a character is already following someone (and who) and I've seen people set it repeatedly every frame because of that. Can you check how you are doing it? And you can also comment just specifically the following to see if it's that or something else in the system for following.

Edit: here's a workaround (scripted in my phone on Easter, untested, lol)

Header
Code: ags
 import void DoFollow(this Character*, Character* follow, int dist=10, int eagerness=97);

import Character* GetFollowingCharacter(this Character*);

Script
Code: ags
 
int arflw[100];

void DoFollow(this Character*, Character* follow, int dist, int eagerness)
{
  if(follow != null) {
    arflw[this.ID] = follow.ID;
  } else {
    arflw[this.ID] = -1;    
  }
  this.FollowCharacter(follow, dist, eagerness);
}

Character* GetFollowingCharacter(this Character*)
{
  int following_id = arflw [this.ID];
  if(following_id >= 0) return character[following_id];
  return null;
}

CaptainD

Quote from: lafouine88 on Sun 31/03/2024 08:26:58my characters seem to struggle quite often to walk to my player.character when they're chasing him(making a lot of detours^^). So I definitely believe this is part of the problem.

(Note - the below won't work if you're using the Follow command, you would need to add a function to compare the player's and NPCs xy positions.)

Just out of curiosity, how are you moving the enemies? If their movement is causing lag / freezing, the following are worth checking:

- If you are using Walk but they don't need to be animated, you could use Move instead.

- If you are using eBlock you could change this to eNoBlock (unless you actually want the blocking)

- If they can move anywhere you could use eAnywhere instead of eWalkableAreas.

These are just some general things that may be worth trying, from what I've understood of what you're trying to do and without seeing the code. I realise you may already have tried these things but thought it was worth mentioning them just in case!
 

Crimson Wizard

I think it's worth investigating what the new pathfinder is doing when ordered to find a route. Specifically, at which moments does it construct the navigation grid, and if it not doing any redundant work. I have vague memories of seeing something suspicious back when it was first implemented, but forgot to investigate.

eri0o

#10
I don't remember now properly but I remember in big maps there was a point where it copied the entire bitmap of the map, because it needs to draw the "feet" (blocking rectangles of other characters) to then rebuild the nodes from this bitmap. I don't know if it's possible to do this addition/removal of blocking things or even if the performance of that specifically is slow. I also think this copy happens on heap instead of holding a copy and overwriting to not require allocation?

This was quickly notedown here: https://github.com/adventuregamestudio/ags/issues/894

At the time I think I was playing with a game I made to test and profile but lost it.

Ah maybe if no characters that are currently in room are solid this could give a slightly perf improvement? Also if two or more solid characters move, how does the pathfinding works, are they moved and updated in a sequence, to avoid a character being stuck in the feet of the other?

lafouine88

#11
Here goes

https://streamable.com/991ic1

I made you a quick video(low quality but you ll get the main issues). Of course don't pay attention to interface and basically graphics etc. since this is not done yet.

There is a freeze at the end, but also you can see that mobs behave weirdly, they kind of run as erraticly as I do^^ and sometimes they glitch a little when they are close to me. I thoughts I would deal with this later but maybe the whole thing is connected. I'll have a closer look at my whole function tonight but if watching the video gives you ideas of what the problem might be, be my guest :)

I'll also try the debugging program of eriOo, though I did put a variable to prevent repeatedly execute follow. Still I'll cross check.

CaptainD, as you can see I can't use move, I do use Noblock. I would also prefer the mobs to use walkable ares to prevent them from crossing a river or getting through a house, that would make them quite harder to deal with^^

eriOo, I thought about this too and initially my characters were all solid. They are not anymore, and pathfinding is better, but as you can see, still not great.

See you soon

lafouine88

Quote from: eri0o on Sun 31/03/2024 10:38:38Just so you know if you really think that pathfinding is the problem it should be easy, create a new empty game, add 30 characters and put them all to walk and see if you can reproduce your issue. Don't use your game assets, just throw 30 Rogers walking around.

If you can please post this test game here.

I tried that and the good news is that neither pathfinding nor 30 characters on the map are any problem at all "^^ they follow me perfectly if I just use 'follow character' on room load.
So I'll keep investigating with my own aggro function paying attention to possible forgotten loops.

eri0o

Holy shit that video looks amazing!

Oh the idea of the function I did is it's a function that extends the one the character has, in this way you can check if character is already following other, and if it is, you can do nothing instead of telling it to follow again.

One thing, in AGS 3.6.1 there is an additional Debug Log panel in AGS Editor and you can log things to it by using the System.Log() functionality! I think it should be useful for your testing of your game.

lafouine88

#14
Quote from: eri0o on Sun 31/03/2024 22:32:21One thing, in AGS 3.6.1 there is an additional Debug Log panel in AGS Editor and you can log things to it by using the System.Log() functionality! I think it should be useful for your testing of your game.

I have dl 3.6.1 thanks for thé tips and I will have to look into this log functionnality. it looked a little complicated but it s going to be the easiest way because my aggro function is not the one After all😑,it s something in repeatedly execute I Guess.

One small technical question about repeatedly execute (since I have the creators here), if I go sthing like this:
Code: ags
Repeatedly execute{

If(globalint1<10){
gui1.x=0;
}
else{
gui1.x=10;
}
}
:
Does that kind of code take unnecessary ressources? Like, Does it continuously set the gui1.x? Or does it do it once and then gets triggered again once globalint1 gets to 10?
Because I sure did a lot of this,and this could be the kind of suboptimal coding crimson spoke about. In which case this would be preferable :
Code: ags
Repeatedly execute{

If(globalint1>=10&&gui.x==0){
gui1.x=10;
}
If(globalint1<10&&gui.x==10){
gui1.x=0;
}
}
:


Thanks👍

Matti

#15
Quote from: lafouine88 on Mon 01/04/2024 07:57:59Like, Does it continuously set the gui1.x? Or does it do it once and then gets triggered again once globalint1 gets to 10?
Because I sure did a lot of this,and this could be the kind of suboptimal coding crimson spoke about.

Yes, it would set the GUI's position every frame, continuously, so you should definitely use your second code.

[Edit: deleted wrong code]

Oh, and you should really form a habit of giving your GUIs and variables proper names, otherwise your code could become unreadable.

Khris

#16
The second variant will take even longer.
Do this instead:
Code: ags
  gui1.x = (globalint1 >= 10) * 10;

You cannot code a "global int has changed its value" event without checking the variable every frame, so there's no alternative to rep_exe here.

Edit: this was less meant to increase performance and more to increase the readability of the main rep_exe function.

Crimson Wizard

#17
Although learning the optimal way to write code is a good thing, I would not bother too much with the things like setting gui.x above, because these kinds of operations only may slow game down only when they are done over hundreds if not thousands of objects in one game frame.

Another thing, in most cases engine itself checks if the new value is different, and if not, then does not do any unnecessary operations, like, recalculating or redrawing objects, etc.

eri0o

Do you have a list of everything you are doing in your repeatedly execute or repeatedly execute always? Doesn't have to be script, just in general, maybe someone can figure it out what it is that you are doing there.

In general I would say looping through lots of things is slow and you should avoid doing in rep exec, but the lots of things I am thinking of is when going upwards ten thousand.

If you can break your code in different script modules, one strategy that you can use is instead of using rep exec and rep exec always directly in their codes is you create an update or update_always function for each and call all of them in repeatedly_execute and repeatedly_execute_always in your Global Script, that way you can turn off systems by simpling commenting things there and this way you can usually track down issues more easily and also helps to focus on each thing separately.


I've done a few non-adventure stuff in AGS and the challenge is always in organizing your code and naming things. Most my stuff is open source of you want to check it out.

lafouine88

Quote from: eri0o on Mon 01/04/2024 13:41:44I've done a few non-adventure stuff in AGS and the challenge is always in organizing your code and naming things. Most my stuff is open source of you want to check it out.
You're god damn right... XD my thing starts to be a huge mess. Though it's much better than my previous games, so there is always margin for improvement^^

One thing is sure, I do use a lot of rep_exe, but way less than  1000.
So far I have things like buff/debuff/dot display, character's stats,a few display things(aggro),information about items you pick up/stats/spells when mouse gets over the button,a following character to display visual effects,targeting and damage display system,patroling,agro,autoattack,death and repop functions and animations unlocking(which I should remove soon because it's not really a good idea after all). I could give you the whole script but it would be a nightmare to read XD.
At some point I did create modules, just to free some space in my global script which became hard to manage. But I don't know how to use update/update_always. this is something else I should take a look at then^^I thought I would just turn them all my rep_exe functions down and bring them back one after the other until it starts lagging. It pretty much defines the way I'm making my games, not at all the best or the fastest,but eventually it should work "^^

QuoteI've done a few non-adventure stuff in AGS and the challenge is always in organizing your code and naming things. Most my stuff is open source of you want to check it out

Definitely yes!! This should be extremely interesting <3 Could you give me a link or something like that please?

Once again thanks to all for the investment, it's always surprisingly constructive and...patient "^^

SMF spam blocked by CleanTalk