Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / debug difficulties in AGK

Author
Message
nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 3rd Sep 2014 22:40
I have a debug issue where 2 users have reported a complete hang/freeze.

I can't debug this by logging (file logging is extremely slow, even if I was only capturing a tiny amount of information) - even worse that the error is rare and may occur after 90 mins of play!

I can't really even log stuff to the screen, as unless the sync occurs, I won't see the correct information on the screen.

Any ideas how I can catch this?

The freeze btw, is just in the AppGameKit app and not the whole computer.

I suppose this question is really for Paul - is there any kind of extended debug / error mode that could be enabled (it would probably have to be a debugging version of the windows T1 player...)

Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 4th Sep 2014 07:05
After 90 minutes of play? That's a long time
Which AppGameKit version?
I hit some issues with cloning sprites made with load sprite. But that's the only time I've had crashes in Windows.
There are these commands, but I've no clue if they work:
http://www.appgamekit.com/documentation/Reference/Error.htm

Can you replicate the issue?
Have you tried running the code through the v2 compiler? It might catch some stuff that v1 won't. Also you could monitor the memory usage in Windows Task Manager to see if there is a odd leak or something. There are also the benchmarking commands which might help to indicate if you have an excess of unused objects.

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 4th Sep 2014 12:31
If it's after 90 mins it could be down to the timer needing a reset. You might want to occasionally check the value of the timer is not over a certain value. If it is use reset but be sure to adjust any values that also use the timer.
Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 4th Sep 2014 19:45
That's a good point. I didn't think about that one
I'm going to run a general test to see if that happens.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 4th Sep 2014 20:19
90 minutes or longer. Seems pretty random.

This is on 108.21. I have tried to compile through version 2, but ran into a major issue (see here)

Its actually a hang/freeze - not a crash. This makes things decidedly more difficult to sort out. No error management will work - only a low level debugger probably? I've done extensive checks on the memory (no problems) and checked the amount of sprites etc. (all cleared and reset each level).

I do use clonesprite for everything (keep one master set loaded and clone as required).

I will put another debug in to log number of sprites etc. I notice DeleteAllSprites() doesn't mention cloned, but seems to get rid of them anyway?

With regards to the timer - this sounds like a good thing to check. I'll be OK re reset it each level, as I only use it for timer based movement.

Cheers for the idea!

Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 4th Sep 2014 20:35
I'm highly suspicious of the effectiveness of delete all sprites, but unless you think you're accumulating 10,000+ sprites I think you should be OK if it isn't catching everything. No idea if it actually deletes cloned sprites. I'd hope it does! You should be able to tell using GetManagedSpriteCount.

Now when you say it's a hang/freeze does Windows say the program is not responding and force close it? If this is not the case and the program is still running but you just can't do anything then you're getting stuck in a loop.

I've been running a simple timer program for 2500 seconds now without issue. I'll keep it going and see how far it gets before the float flops.

I'm very sorry for you. Bugs like this are a huge pain. I couldn't imagine having one that happens a whopping 90 minutes into a game. That's just killer to debug or diagnose.

Regarding v2: I was just curious if you ran it through the compiler as it will at least be able to check for weird errors like misuse of variables or arrays. If you're just getting jitters then you might want to compile and run through v2 until the freeze happens. Maybe you'll get lucky and it will spit out an error...

fog
21
Years of Service
User Offline
Joined: 5th Oct 2003
Location: Newcastle, England
Posted: 4th Sep 2014 20:52
Having got used to proper debugging tools and error reporting I could never use Tier 1. Good debugging must knock 20% off your development time. I still have sleepless nights about debugging in DBPro.

Anyway something slightly more constructive.

When I had issues like this in the past I sometimes had to approach them backwards. Rather than find out what crashes/freezes the app, find out what the last thing that ran successfully was.

Identify potential problem areas and divide that code into suitable chunks (I find each function is a good start) and at the start of that code output to the screen/file a message saying where you are. When the code freezes the last message should tell you what just ran.

Then starting from that point divide that code/function into smaller chunks and do the same, narrowing the search each time.

It sounds like you would need a lot of "checkpoints" but you can probably discount most of your code immediately as much of it obviously wont be causing the issue.

Not ideal, especially if the crash takes a long time to appear, but in my experience it does work.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 4th Sep 2014 20:54
Well, I've just done some memory checks and it is leaking a couple of mb between levels and a whopping 20mb between games, so I'll have to look into this. I am beginning to distrust deleteallsprites() where cloned sprites are concerned...

I use to have a loop going from 10000 to 12000 and manually deleted existing sprites before deleteallsprites() got added part way through version 1. I'll switch that back on and see.

ManagedSprites may not help much, as it only responds the amount of sprites which are being rendered.

The hang/freeze is just the game freezing, not windows. It may not be a stuck loop - it may be a low level bug in the windows player which we can't get access to.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 4th Sep 2014 21:00
Fog: Yes, I get this. However, logging to file is far too slow in AppGameKit (hundreds if file writes per second just to checkpoint 1 thing) and logging to screen is no good, as the code would need to reach sync() for the screen debug to appear.

Freeze/hangs are just the worst thing to debug in AGK.

If I could reproduce it, I would write debug info to a memblock and hack into that memory with a 3rd party tool perhaps?

Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 4th Sep 2014 21:06
Ah I thought the GetManagedSpriteCount would report on all sprites and GetManagedSpriteDrawnCount would only report those which are being drawn. Not sure what the difference is if this isn't true.

Since there were issues a long time ago with DeleteAllSprites and DeleteAllImages I wrote them off as totally unreliable and went with my own methods.

You may also want to check any sound and music usage for leaks.

So, what is the total memory usage during a level?

Also if Windows isn't shutting down the program then in my experience it has been a loop getting stuck. I know it seems weird, but I've have some animation loops where I use frame time to do the movement and the exit condition is a location. 99.99999% of the time it would be fine, but every so often it would get stuck so I wrote in second conditions in my animation loops to check the timer to see if total time is a bit more than the expected animation time. This actually happened a bit in Sudoku In Space with the particles for some reason, putting in a timer check fixed it right up.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 4th Sep 2014 22:03
Right, I've found the leak and it is quite interesting.

The leak was images (my fault in the exemption routine - not deleteallimages() which I am not using)

I don't delete all images, but have to go through a list and check for exemptions (saves reloading the atlases etc.)

In my level initialisation, I use createSprite(LoadImage("aaa.png")

This took up sprite slots and image slots.
At the end of the level, I delete all the sprites (~1200) and selectively delete ~600 images). Both manually, without deleateall etc.

Second time around, there are the usual ~1200 sprites to delete, but no extra images to delete (just the 21 exempt ones).

Weird. The same initialisation code loads the sprites using createSprite(LoadImage("aaa.png")) but doesn't leave a residual image the second time around - I have commented my debug output:



Yes, before, I was generating 600 images each level.

Game normally runs at 75mb. Each level, it climbed 2mb or so.
Probably not run out of memory, but 600 extra images x number of levels (checks what the players got up to) level 245. So, ~147000 images.. hmm.

Also, may even carry over between games, so could have been even more!

Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 4th Sep 2014 23:22
Holy images Batman!

So... let me get this straight...
Are you always using createSprite(LoadImage())?
You're loading 621 images, delete 600 images, then load 600 more images, but when you go to clean those up they aren't there? That doesn't seem right.

How are you deleting these images?
I usually use GetSpriteImageID() then delete that image.
I've never tested the validity of it though.

600 images is sooo many. Do you use sprite sheets? Are there really 600 unique image files you're loading? If not I'd highly suggest optimizing your image loads. In my games I generate a UDT array that contains image atlas ID, image ID after loaded, image file name from all of my atlas subimages.txt files. Then I have an "override" style function for LoadImage (called _LoadImage wooo) that searches through the UDT array and looks to see if the image has already been loaded and if not it will load from the atlas if it was listed in the atlas subimages.txt file or just load it. Then when I delete the image I just set the image ID to 0 in the UDT array so that it works as a flag to indicate the image needs loading if/when I call for that image again.

I'd say you're hitting some weird unknown limit with the GPU's texture handler or something.

Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 5th Sep 2014 00:27
Oh... just realized I've been running the timer for 16,700 seconds now and it is still reporting OK. I thought for sure it would have an issue with the float now. Aren't floats only good for 7 digits? Maybe I heard that wrong.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 5th Sep 2014 02:55
Well, many may be generated with CreateSprite(0) ? I don't think I'm loading 600 images, but a lot could be from the atlases or (0) sprites - there may be an imageID behind the scenes for that?

I generally use createSprite(LoadImage())) at least initially. There's a lot of cloning after that.

The 621 images in this case seem to be a mix of loaded sprites (relatively low) but a LOT of cloned or generated sprites created dynamically throughout the level, which may generate images - I haven't checked..

Believe me, this is super optimised. I made a mistake with the delete images code where I was using a lookup to preserve images which are used in the 3D part of the title sequence (big images 2048x2048 for instance) which affected the inter-level load times - those are the atlases and 3D model textures and they only get loaded once.

E.g. I generate an explosion with 512 sprites using createSprite(0) - perhaps that also has 512 images behind it? These seem to be cleared by deleting the sprite.

Honestly, I deliberately load all image assets (apart from the resident atlases) between levels as there was no overhead and the idea was to keep things tidy. I think the 621 images is false (why would they be not there on subsequent levels?) so ~600 images are being created somehow which I don't know about but only get cleared on the first cycle and never recreated? I don't know. The same initialisation is called each time.

I think I will do another test and export the alleged images and see what they are

I really don't think I'm creating them per-se, rather that they seem to be created abstractedly by some method I'm using. 21 permanent images seems right (regarding the amount of image files I load in) so the 600 are being created by some (as yet) unknown method - I suspected the createSprite(0) at first, as I do loads of that.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 5th Sep 2014 03:03
The delete image I use is not related to the sprite; I did have that code in there once (I saw I'd remmed it out some time ago).

Now, I scan from 10,000 to 12,000 and delete any sprites/images in that range.

Rough I know, but my memory says using GetSpriteImage() didn't pick them up before (hence the remmed out code).

There's also the issue of cloning - I know there has been cloning bugs in the past, so right now it seems like my new "scan 10,000 to 12,000" thing is picking up images which weren't picked up by GetSpriteImage() before.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 5th Sep 2014 03:09
I tried using GetManagedSpriteCount when I was debugging why I saw 0 sprites compiling this in V2. Turned out it's a setAspectRatio() thing anyway for the V2 problem, but it didn't return me the amount of EXISTING sprites, only the ones set up for drawing (e.g. didn't count invisible) - even with a forced sync()

Naphier
14
Years of Service
User Offline
Joined: 2nd Oct 2010
Location: St Petersburg, Florida
Posted: 5th Sep 2014 03:34
Yeah, you'd think that createSprite(0)wouldn't really load any image, but maybe it does. Also I wonder if you have mipmapping on and that reserves some image areas? No clue...

Have you considered using particles for your explosions instead of sprites? It might not have the same overhead. But you might lose some control and tinkering to get the particle systems correct takes a bit of time.

This is all pretty interesting and I wonder what's in there that GetSpriteImage isn't picking up, maybe you have some sprites in there that are being deleted before the image. Maybe it is a bad garbage collection issue with AGK.

I've had some issues with using particle systems where every so often it will affect some sprites on screen. Those were cloned sprites and it was visible so easy to track and work around. I don't think I've had any other issues other than cloning sprites that were made from LoadSprite (which I'm not sure why I was using it in the first place, must have been tinkering around).

I think you should let Paul know that GetManagedSpriteCount is only returning drawn sprites, that's not what the command is for. Maybe something got switched around in one of the builds and he never noticed because they are rarely used commands.

Anyway, I'm very curious to see what those mystery images are.

nz0
AGK Developer
17
Years of Service
User Offline
Joined: 13th Jun 2007
Location: Cheshire,UK
Posted: 5th Sep 2014 04:09
Can't use particles as the origin couldn't be moved (until v2).
The source had to be in game world and I think particle stuff has also been crippled regarding single color sprites (can't remember the exact details).

MipMapping might be worth a look (noticed that some sorting/ordering commands have also been deprecated/removed).

The garbage collection is a valid point. AGk is still at a point where you can't fully trust some of the behind the scenes functions, if you are pushing the engine hard.

The getManagedSpriteCount returned the amount of sprites set up for drawing (not drawn) as I found, but in my V2 tinkering trying to make this work in V2.

Not very used commands I agree, but as I'm at release point for this game, I didn't want to explore fundamental issues in V2 for this (I did post about the aspect ratio stuff in the V2 thread, but in all honesty I don't think it will get any effort, as I doubt anyone is switching aspect ratio in game like I am for that issue)

I feel sometimes that it's a miracle that I've managed to produce this game with AppGameKit in the state that it is (what with workarounds and endless optimisation) and still find problems which seem so low-level that I'm still debugging AppGameKit and not my game!)

I have gleaned a little knowledge of how AppGameKit works under the hood so to speak, so I'd totally expect that a sprite created with createsprite(0) still has an image related to it somewhere in the mix. I don't feel up to making a proof of concept at the moment, so I've put a new beta out using the forced manual clear of images and see if that solved the problem.

I've reached the point of get it out and move on I think.. next projects will have to bear this situation in mind I think!

(I'll still ID those 600 images at some point tho!)

Login to post a reply

Server time is: 2024-11-25 09:58:47
Your offset time is: 2024-11-25 09:58:47