asset loader per level code

Hey all,

Repo here

I have roughed up a system that allows you to load assets per “level”. It could do with loads of improvement but I was hoping to get some feedback if I am heading in the right direction.

Look in the repo at Assets/assets.txt and you will see a simple text format of an asset path along with a name you can identify it by (split by comma). Also some header info of the level name and the type of asset being loaded.

The basic idea is this, when you start a level you can call Load(“levelname”) and it will load all assets it needs for that level, if you load another level then it unloads the previous level etc. You can then access the assets by name/id using the manager classes opposed to the old content way (basically a wrapper). ie var background = GetGraphicsManager.LoadTexture("mainmenubackground"); // use background in draw etc.

I understand you would always have to map your content directories to the assets.txt list but that can be automated and as well the trade off by just referring to a name or id might well be worth it.

Also I understand a large project this may not be the way to go, but something like a 2D platformer with screen transitions etc may suit well.

Some points I am interested in for feedback:

  1. AssetLoader.cs is a static class and keeps a reference to the original Content instance (passed in from game1)

  2. The managers get this reference but then create their own ContentManager from the passed in content.ServiceProvider

  3. The managers keep a list of Assets (struct of 2 strings) at all times

  4. On level load the managers and their contentmanagers are emptied and nulled and recreated.

  5. Would there be a benefit to preload all the text file in a List of level names?

  6. Any more comments :slightly_smiling:

It definitely can be usefull to optimize memory usage on devices.
And I like the idea, as it could be extended to do async load streaming: a chunk of word could be thought of a “level” and loaded when the player gets closer.

Thats an amazing idea, I also thought you could load all adjacent areas. If your screens are somewhat tile based then you could load the 4 screens accessible from the sides.

I wrote the managers as singletons because it might be extendable to easily remove the singleton behaviour and use instances per area or something like that. That was the idea anyway so singleton overruled using a static class here.

I have done continuously loading levels before. Not in MonoGame but on consoles just over ten years ago. It demands a different way of looking at the level design and careful planning of asset usage. It is not an easy task to get right.

I may have mis-understood your point, but I usually load assets between levels… Loading between screen fades is really fast, and the memory impact is huge when using hi-res textures and audio.

I have done this in a few different ways, here’s 2:

One was loading from directories, where to add a level, you just created a folder and dropped in the content… Each level folder would contain files like “backgroundimage.png” or “introtext.txt”.
-A ‘LevelLoader’ class would scan the directories for content,build a level selection screen, and load data from the selected levels folder… (no re-programming to add new content. My game vector ball does this)

Another was having a folder for each enemy, and it would contain several versions of the sprite, for different situations/damage states, but ALSO level appropriate camouflage.
-So for each level-number, for each enemy type featured in the level, the game would load a new texture for the enemies, replacing the static enemy textures between levels… (my game grinder does this)

My “engine” loads contents from folders and I store only one instance of each content in the memory with a counter of references. When this counter reaches zero, I unload it from the memory.
It serves my small games well, although in larger projects I would extend it with:

  1. Dynamic content loading (per content), so even during game I could load content into memory (though because of asynchronous access I’d need to keep track of the state of the loading).

  2. Reference-based loading mixed with the previous dynamic loading, so I would not load everything from a folder, instead I would load only those contents that my objects reference onto.

As long as your engine is well-separated from your games, it will be easy to change anything later.