Collection factory or collection proxy? Which one to use in this case?

Hi all!
I’m implementing a Metroidvania game and I’m wondering about which is the correct architecture to use for game rooms/levels.

The game will have 100+ levels/rooms and, in order to improve loading time from the user’s perspective, I would like to load the current room and the adjacent ones: when the player moves to the next room, the game loop will load the current room and the adjacent ones, and will unload the other pre-loaded rooms.

Each room is a separate collection file with a progressive number (e.g. room-001.collection, room-002.collection, etc.).
These room collections contain all needed game objects (tilemap, enemies, interactable objects, etc.).

I created a first prototype with a main.collection containing all required sub-collections (hero, camera, etc.) + 5 collection proxies (1 for the current room, and 4 slots for the adjacent rooms). The collection proxy slots are used to load and unload all the required rooms from the 100+ rooms set.
I implemented everything and then I discovered that each collection proxy is a “separate world” and physics cannot interact between different proxies (my mistake for not checking this beforehand).

So I’m changing everything and moving to a different solution: collection factory instead of collection proxy.
Currently I created a prototype with just 4 rooms: the main.collection contains 4 different collection factories named after the collections that contain the level: room-001.collection (factory collection), room-002.collection (factory collection), etc.
If I proceed this way, I will have 100+ collection factories (1 per room) in the main.collection (obviously flagged as “load dynamically”).
I think that having 100+ collection factories in the main.collection is not a good strategy…

That said, here are my questions:

  • Can I have just 5-6 collection factories (1 for the current room and the others reserved for the adjacent rooms) using “load dynamically” and “dynamic prototype”?
  • Is this the best way/solution to implement this kind of games?
  • Should I move back to the original solution (collection proxy) and manage the physics by creating everything inside a single room/level? (e.g. when the hero moves to a new room, should I save the hero’s status, destroy it and recreate it inside the new proxy? This approach doesn’t look very efficient either.)

I dont think this is a problem, but never been to this number!
Your strategy seems good to me, if you want one continuous world, that is the way to go I guess.

I do something similar for my game (kind of a scroller but not scrolling), but for each level: I have 1 main collection , and many “level_chunks” with same amount of collection factories in the main collection. they are reusable level parts.

I define my levels as a lua table with a list of level_chunks url (factory url) and the level_manager scripts just load the level list, and spawn level_chunks collections while the player is going right or left in the level.

Basically your setup.

For now I have only about 10 level_chunks but I will have many more…

I think you should go ahead, and if you start having problems, maybe you can split everything into “regions” (proxy collection) (like “forest region”, “cave region” etc..) and split you rooms into big areas. For these region, you will unload and load you player state.

I tried the “dynamic prototype” thing, but you still need to add your collections somewhere statically for the builder to find them, I didnt understand how you use it really, if you need to add all the collection “somewhere”…
Maybe you can add them as a ressource directory?
This was my first attempt, but I couldnt make it work, so I’ve decided to go the static path with many collection factories

And domt forget that with dynamically loading collection, you can preload collection: I do that for my level, since I know all chunks I will use, I preload all of them.
You could do something like load previous and next room, but preload preprevious and next next rooms…
Or have some trigger zone that start preloading things when player touch it, or compute distance to room bounds.

I bet @schlista has some thoughts on this! (Metroidvania Toolkit)

1 Like

thank you for your feedback and hints!

@Mathias I also define my levels as a lua table with all “connections” between levels (I did not mentioned it before, but this is the approach that I used).


Mathias

14h

I tried the “dynamic prototype” thing, but you still need to add your collections somewhere statically for the builder to find them, I didnt understand how you use it really, if you need to add all the collection “somewhere”…

My idea is to use 5-6 collection factory, assign them an initial level (to bypass the mandatory initial assignment) and then swap levels depending on the player map navigation leveraging on “dynamic prototype”. But this is just an idea, I’m not sure that it works correctly and that it is the correct/efficient way to proceed.

I’m really interested about @schlista feedback (I saw the Metroidvania Toolkit topic and it seems very interesting).

2 Likes

I currently have a factory for each collection. But I’m not manually creating them. I’m exporting from Tiled and then using an editor script to build the collection and factory for me :slight_smile:

But to answer your question. It’s one per one. It’s not an issue as far as I know…just more files, but they are all small text files anyway. And yes I do just like you…load the room and the adjacent rooms for no delay between rooms.

However, I haven’t fully tested it on different size rooms. MVs can be made in different ways and many mix extremely big rooms that scroll and some small rooms that fit on screen. So if someone makes 5 extremely large rooms next to each other, I haven’t benchmarked that yet. Plus I need to test it on a weaker PC to see if it will work well.

2 Likes