LibGDX static AssetManager for Desktop Only Game - libgdx

I know there is a lot of topic on that issue but for my case the only one I found here wasn't answered.
So i'm asking the same question:
Do I need to worry about setting my AssetManager static for a desktop only Game ?
Now just to summarize and clarify the Mobile Game static reference problem, lets say I also wanted to use a static AssetManager on a Mobile Game (because I find it more convenient). I know this will cause the Texture to be disposed on pause() but I can just reload them on resume() right ?
Lets say I have an animation for a player that use the Texture A (previously loaded into a static AssetManager). If the game is paused, the AssetManager reference will most likely be lost. If on the resume() method I recreate this AssetManager (MyGame.asset = new AssetManager()) and I reload the Texture A, what will happend to my animation ? Will I need to reload it again also ?
I found this phrase in the Texture Javadoc : Managed textures get reloaded automatically. I assume this is only valable for non static AssetManager am I right ?
The last questions are only here to summarize the use of a static AssetManager on Mobile Application.

As Abhishek Aryan correctly pointed out: using static variables for your resources is a serious indication of a fundamental design flaw. You should worry about that regardless the platform you are running your application on, so also on desktop. Depending on the rest of your design you might or might not run into issues.
Usually with these kind of design flaws, it seems to be working just fine for you at first. But later on you will run into issues. Unfortunately by that time you are already so far progressed in your development that you can't easily correct the fundamental issue and need to hack around it instead.
Note btw that it technically is perfectly possible to use static resources on any platform as long as you properly manage them (which is harder than just not using them). For example, libgdx itself is build around the Gdx static members.
To answer your other questions:
I know this will cause the Texture to be disposed on pause() but I can just reload them on resume() right ?
That is incorrect. Textures will never be disposed in pause, nor do you need to reload them in resume.
If the game is paused, the AssetManager reference will most likely be lost.
That is incorrect. I'm not sure why you would think that, but that's not the case.
Will I need to reload it again also ?
If you decide to dispose your old texture (which you would have to do yourself, it is not done automatically for you) then any Animation that uses that texture will be invalid. So, indeed if you want your animation to use a different texture then you will have to either update your animation or recreate it.
I assume this is only valable for non static AssetManager am I right ?
No, managed textures don't care whether you are using static resources. They are are always reloaded when the context is loss. Note that it is very unlikely that you will ever run into this situation, so you don't have to care about this.
You might also want to read this post i wrote a while ago on this topic.

Related

AS3 Starling custom shader crash "Error #3600: No valid program set" when computer is locked or put to sleep

I'm working on a Flash game using Starling, and I have started coming across an issue where my render crashes immediately after I put my PC to sleep/lock it and then turn it back on. The error I'm getting is:
Error #3600: No valid program set
I was not able to find any advice online on how to prevent this/re-initialize everything appropriately. I'm assuming this is part of a wider issue with how Flash/Starling handles the computer being put to sleep/locked.
Things I have tried so far:
Catching the error and re-uploading the shader programs.
Setting Starling.handleLostContext to true
Has anyone come across this issue before? Any help/pointers would be greatly appreciated.
It sounds like your game is losing the GPU context.
On context loss, all GPU data is lost. You have to restore textures, vertex buffers, etc. Starling handles some of it for you when you set handleLostContext to true, but you still have to handle the textures.
If you use the AssetManager, it will handle re-uploading textures for you, which is clearly the easiest way to go. It automatically creates a texture.root.onRestore callback function which Starling calls after it re-creates the context, and it will attempt to re-load your textures from wherever you first loaded them from, whether from disk, an embedded asset, or a URL.
You can also manually define the function yourself, though that is more complicated and as the article mentions, some gotchas are involved.
More information: http://wiki.starling-framework.org/manual/context_loss

packager-based asset embedding

The situation is as follows. Currently i'm developing an AIR game that will contain plenty of bitmap assets. I'd like to target several tablets (iPad, Xoom, others) and, thus, am considering having the assets done in different ppi, so as to have more visual consistency across the devices. I'm not concerned much about the resolution, because i'll be using scrolling for assets that don't fit on the screen; but units, buildings, enemies should look pretty much the same regardless of the device.
The question is:
can this be done and how (packager-based?)
what would be the best way of doing this
should i even bother?
The only thought that comes to my mind so far is to have an application file for each device being targeted (or ppi, actually), that pulls a big bitmap-registry that corresponds to the ppi of the device. The static registry class is essentially the same for all of these applications differing only in the filename that [Embed] points to (and the classname obviously).
I think you are on the right track, if you wanted to have specific sets of assets for each device type. The way that I've done this in the past is to use a rake script, but any make-like/ant-like utility that you are conformable with will do. Essentially, one of the tasks that runs before the project compilation is to dig through the file structure and programmatically build up these helper classes; it helps avoid the monotony of constructing these mappings by hand. Which can be mind-numbing once you get a non-trivial set of assets.
In my project I would have a structure like this:
/ProjectRoot
/src
/imgs
/132dpi
/unit1.jpg
/unit2.jpg
.
/160dpi
/unit1.jpg
/unit2.jpg
.
/264dpi
/unit1.jpg
/unit2.jpg
.
/326dpi
/unit1.jpg
/unit2.jpg
.
I would usually have some interface which all my assets would abide by, something like
public interface IAssetSet {
function get DPI():uint;
function get Unit1():BitmapData;
function get Unit2():BitmapData;
}
The script would run scrape the folders/files and generate actionscript classes in folder like /src/assets. Stuff like
public class AssetSet132dpi implements IAssetSet {
public function get DPI():uint { return 132; }
[Embed("img/132dpi/unit1.jpg")]
private var _unit1Class:Class;
private var _unit1:BitmapData;
public function get Unit1():BitmapData { return _unit1; }
[Embed("img/132dpi/unit2.jpg")]
private var _unit2Class:Class;
private var _unit2:BitmapData;
public function get Unit2():BitmapData { return _unit2; }
...
public function AssetSet132dpi() {
_unit1 = BitmapData(new _unit1Class()).bitmapData;
_unit2 = BitmapData(new _unit2Class()).bitmapData;
....
}
}
In your initialization code, you determine what device you are running on or you precompile only for specific devices, and instantiate the dpi you want. Everywhere else in your code you just pass around references to IAssetSet, and figure out what to do based on IAssetSet.DPI.
That is one approach, but there are others.
Another approach, would be store embed your source images at the highest DPI and then on application load, downscale them in memory to the desired DPI and dispose() the originals.
Another approach, which is more viable these days with Stage3D and frameworks like Starling and nd2d, you can get away with letting the GPU -- which is really good at doing this scaling -- do most of the heavy lifting that really feasible with traditional compositing.
I think, if you are using traditional compositing, then you will probably seem some performance boosts using assets specifically sized to what you need, rather than trying to dynamically size them all the time. Flash can be a little weird sometimes about regenerating internal representations of those assets at strange times and tanking performance. Probably the best approach would be to leverage Stage3D/Starling/nd3d, but if you have a non-trivial codebase built up, it will probably be a non-trivial task to switch rendering engines at this point in the game...
At least, those are my two cents. Maybe somebody else has had a different experience.

Garbage collection - manually wiping EVERYTHING!

I have been building a game for a while (nearly done) - But the game needs a replay button and its a big task.
I know the GC is dreadful in flash, but I wanted to know if there is a way to wipe EVERYTHING as if the flash app has just begun. Clearing memory, game data - I haven't to worry about game loading as its not really heavy on data.
Everything pretty much lives in a DataModel - but I fear if I just clear the all variables, I'll have pockets of orphaned memory.
Any forwarding idea would be great.
cheers guys.
I would do this:
make a class that encapsulates your entire game, called GameContainer or whatever.
Do a search on all your source code, and make sure that in every call to addEventListener, you are passing true for the "use weak references" argument.
In your document class (or frame script), make a single instance of GameContainer and add it to the stage, and do nothing else.
Now when you want to entirely clear your game from memory, remove GameContainer from the stage and null the reference. Memory will not immediately be released, but everything in your game will now be eligible for release. If Flash thinks it needs more memory it will trigger a GC, and the large orphaned GameContainer will be nuked. (Step 2 above will keep your event listeners from counting as references to your objects, and make sure that all self-contained objects are eligible for disposal.
Not sure what you mean about Flash's GC being dreadful though. I can't recall having heard of any bugs in it. It won't nuke your objects unless you are careful with your references, but that's true of all garbage collection.
Not short of refreshing the page. There might be some hack you could do by loading a separate swf and then unloading it, but that would be just as error prone as doing it the proper way.
My advice would be to just buckle down and write your reset function then get something to monitor memory and make sure it works by reiniting/resetting a bunch of times.
The problem with Flash's garbage collector is that as far as I know you cannot FORCE it to "collect". I had this issue with a program in which I would load in various external SWF's, and occasionally Flash would simply not load them. What you may need to do is make a function to set every major variable in your code to null at the end of a game, if you want a true reset.
There is still no guarantee, but unfortunately I'm fairly certain there is no shortcut to force a memory release.
(For me this meant also making sure my event handlers were cleared properly, and my loaders would "unload()" after passing their content off, in the case of my external SWF loader.)

AS3: Faster to use EventListeners or ArrayLoops?

I am writing a game in AS3 and have, as an example, around 40 objects on screen. Let's say they are clouds. I'm wondering which of the two paths would be less a strain on system resources:
a) Put an eventListener on each object and have it update itself, or
b) Loop through the array and manually update each object
Or is the performance difference negligable? Does either solution scale better than the others?
I would expect the performance to be fairly negligable either way. Once you get a lot of objects you might see a difference (with the loop being the winner). From my experience Adobe put a lot of work into optimizing the actionscript event listener path.
This is a tricky one, purists would say to to go with the array looping method, as with this method it would be possible to cut out the 'view' out of the MVC and still have the system working (which is a good test of any system). However, if you are working with the events you can cut some corners with event bubbling and strict typing.
For example if we assume you make a custom event called CloudEvent that has a property called cloud that contains a reference to the dispatching CloudSprite, then as long as the event bubbles by default, you don't need to add an event listener to each one, just to the DisplayObjectContainer which holds them (which I am imaginatively calling CloudContainer). This way the event bubbles up and you only have to add one listener, and don't have to worry about managing listeners on child items.
public function CloudContainer()
{
super();
addEventListener(CloudEvent.CHANGE, cloudChangeHandler);
}
private function cloudChangeHandler(evt:CloudEvent):void
{
var cloud:CloudSprite = evt.cloud;
cloud.update();
}
Hope this helps
I am under the impression that event listeners require more resources so it is better to use an array when performance is required. It would also scale better for that reason. If you are using Flash 10 then use a Vector, I believe it offers better performance than an array (and type saftey).
Use EventListeners! Just make sure you manage them properly ie. remove them when you done, use weak references.
You wont really find much performance from doing things like this. Usually better performance comes from the bigger ticked items, like not using filters, lowering the frame-rate etc. So punishing your code clarity and OO for the sake of a half a millisecond is not worth it in my book.
There are a few really great guides out there that will teach you all about optimizing in AS3. The best one I have found is Grant Skinner's; AS3 Resource Management. And I just found a quicker seven step version. I would definitely recommend everyone doing AS3 should read the Grant Skinner slides though.
Of course don't just take my word (or anyone else answering your question), you can do you own tests and actually see whats up using a profiler. See Lee Brimlow's latest video tutorial for how to do this. It is worth the watch! Check it out here: GotoAndLearn - ActionScript 3 Performance Testing.

FLVPlayback component memory issues

My website is entirely flash based, it moves around a 3D model which was given to me as chunks of video that I've converted to FLV files. I'm using the FLVPlayback component to control the video inside of my program. While running memory checks using System.totalMemory I've noticed that whenever a video is loaded, it will eat up a chunk of memory and even when I remove all the event listeners from it(they are all weakly referenced), remove the component from its parent, stop the video and null the component instance, it still will not give that memory back.
This has been bothering me since I started working on this project because of the huge amount of video a user can potentially instantiate and load. Currently every video is loaded into a new FLVPlayback instance whenever it is required, but I have read that perhaps the best way to go about this problem is to simply have a global FLVPlayback instance and just reload the new video into the old instance, that way there would only be one FLVPlayback component in the application's memory.
Has anyone else run into this problem as well? Have you found a better solution than using a global instance that you just re-use for every new video?
I've never really liked the components, they're a bit dodgy. This particular problem seems to be common, and the somewhat annoying solution is, as you're suggesting, to only have one FLVPlayback and reuse that.
Here's a blog post about it
You can't help the memory problems much until Flash adds destructors and explicit object deletion, unfortunately. See this thread:
Unloading a ByteArray in Actionscript 3
There's a limit to how much memory Flash applets can use; the GC seems to fire upon reaching that limit. I've seen my memory-easy applets use as much as ~200MB, just because they run for hours on end and the GC doesn't want to kick in.
Oh, and I don't think using a single instance is an elegant solution, either. Currently I just write a dispose() function for my custom classes, waiting for some day when it can be turned into a proper destructor.
From what I gather after a lot of testing is that flash dynamically loads in libraries and components as needed but never garbage collects that data. For instance, if I have a website or an Air app that uses the FLVPlayback component, the actual component and libraries associated with it aren't loaded until a new FLVPlayback() instance is created. It will then load in the library and component into memory but you will never get that space back until the program / website is closed. That specific instance with the video inside of it will get garbage collected and release some memory as long as you remove listeners from it, take it off the stage, and set it to null.
Also, if you are doing individual videos, the VideoPlayer is much lighter weight, and cleans up nicer.
Thanks for the responses, the links to the other blog questions were helpful as well, I had read all of Grant Skinner's info on garbage collection too, but searching through those links and going back and re-reading what he had originally said about GC helped refresh the old noggin. In addition to nulling and re-instantiating that single FLVPlayback component, I also realized that I wasn't correctly unloading and destroying my Loader instances either, so I got them cleaned up and now the program is running much more efficiently. I would say the memory usage has improved by around 90% for the site.
#aib I will admit the single instance solution isn't elegant, but because flash just won't let go of those FLV files, I'm kind of stuck with it.
#grapefrukt I detest the flash components, they typically cause more grief than time saved, however in this case I had a lot of cue points and navigation stuff going on with the video files and the FLVPlayback component was the best solution I found. Of course I'm still fairly new to the ActionScript world so perhaps I over-looked something.
Unfortuantely, thats just the way flash handles it. Not particularly smart, but it works for most people.