Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

6 years ago by danicor

I'm developing an application that contains many minigames... I need to load modules dynamically and not statically (module and requires) because the waiting time is getting longer with every new minigame.

I have some idea about this but I need help from someone who knows ImpactJS to make it clean.

Thanks!

6 years ago by Apiheld

Why not make every minigame its own ImpactJS game on different canvases and simply swap canvases in HTML/JS?

6 years ago by danicor

Not valid for my application because i want to have a single canvas and don't do redirects. Any other ideas using the method _loadScript or similar?

Example:

	ig._loadScript('X', 'Y');

	setTimeout(loadGame, 3000);

	function loadGame() {
		var game = Task.getTaskName(get('game'));
		ig.main('#canvas', game, 60, window.innerWidth * scale, window.innerHeight * scale, 1, NptLoader);
	}

6 years ago by danicor

Link to a possible solution:

http://mandarin.no/dynamic-loading-of-assets-entities-and-levels-in-impactjs/

Thx

6 years ago by amadeus

I have a solution in my project that has worked very well, however the downside is that its implementation is very tied into the other existing infrastructure I have written for the project, so it's not like I can just simply send you a couple files so you can be on your way.

I can however explain a bit how I accomplished it, and if more info is required, hit me up on the ImpactJS IRC chat room (same name) and I can provide more specific info.

Basically I needed a system where I would only load the current level that I need to play, and once I move onto another level, I would need to remove/clear out any and all garbage created by that level, and load up the next one.

To accomplish this, I basically abused the current built in module system. Of course I only allow levels to be loaded in a deferred way (after or before a run loop), so consider these steps happening between a run cycle.

1. Stop/Pause the game's run loop

2. Clean out current level garbage if necessary
- All image/font references are nulled out (to enable garbage collection).
- null out the global level variable created and preload references

3. I call my .loadLevel method using a string that references the level to be loaded, since I don't have the level class to specify from. This string is used to dynamically create a ig.module().requires().defines() call sort of like so:

ig.module('preloading-' + this.levelName) // A temporary preload module
  .requires('game.levels.' + this.levelName) // the actual level to load
  .defines(this.levelCallback); // The code to execute once all level requirements are loaded

The .levelCallback of course would then be used to resume the run loop, and actually load the level.

One additional piece I built was an extension of the image and font classes that are considered 'permanent'. They would maintain a different singleton that would safely allow me keep certain permanent assets, and only clear level specific stuff. Also I hacked Weltmeister to allow me to specify arbitrary assets to load on a per level basis that may not be tied to any specific entity (this includes music and sounds, for example).

6 years ago by danicor

Thanks for the reply, very well explained. For now, I have all the information needed to solve my problem.

6 years ago by vincentpiel

Just a thought : the source code is only text, so it is not taking that much space.
To give an example, full jQuery's code -quite a big code base :-) - (not minified) is around 300K, and the minified is below 100K.
So the code is NOT the issue : do not bother with the modules loading/unloading and such. you'll save only a few Kb with this.
The issue will be in your assets obviously : graphics and sound : one single game asset can easily use quite a few Mb.
It is the asset loader that you should investigate to have your resources loaded / unloaded when you switch minigame.
One difficulty here being to be sure to flush out any reference that might be made by you or Impact, so you'll have to watch out for caches, so that the memory recollection is possible.

Basically this is about retriggering the ig.Loader with an new list of assets on each game change.

6 years ago by amadeus

I really only address nulling out level data and assets. These are actually huge potential sources of memory leaks if you are not careful.

For example, any sizable level with good detail will load very large arrays into memory, which, even when gzipped through the wire, will still account for much greater amounts of memory.

One should be weary of conflating file size to size in memory, they are rarely the same.

As an example, I found that on Ejecta, if I didn't properly clear level data, it would take about an hour of loading levels back and forth to crash the app due to memory limitations. This was on the highest end iPhone 5S with the most forgiving memory requirements. It would have been much worse on older generation hardware.

People may be playing your game for periods much greater than one hour. It's very important to manage memory effectively, and because JS is an implicitly GC'ed language, it's not always immediately clear what will and will not be collected.

Remember, all objects and arrays are passed around via reference, so any small little reference in some little closure somewhere can prevent a massive object from being cleared.
Page 1 of 1
« first « previous next › last »