Player persistence between worlds

#1

Hi everyone,

I’m currently trying to achieve something similar to the old zelda or pokemon, where different screens are loaded during the game. I’m using collection proxies for the loading and unloading of the different zones of the game.

I find myself puzzled when it comes to the player that is the only object that “travels” between the collections. Setting the player in an independant collection seems a bad idea as the physics is not shared between collections that are instanciated with proxies.

So my question is : what would be the best way to create a game object that is persistent but still interacting with different worlds ?

Thanks !

2 Likes

Confused about how to load different levels
#2

You can keep player state in a global table or module separately from the actual player go and set any visual cues on a spawned player go at each level load.

0 Likes

#3

I am struggling with an identical problem, there is an ongoing discussion about it, check it out: Go properties and collisions between collections? maybe you’ll find something interesting :wink:

0 Likes

#4

Thanks for your answer !

I was starting to go this way but honestly it feels like a hack. It forces you to place some kind of prefab of player factory in every scene you create. May not seem like a big deal but it would be nicer to have a higher logic that doesn’t forces you to repeat yourself every scene you create.

0 Likes

#5

Ok you seem to have an identical problem which is great as we could exchange solutions :slight_smile:

Another thing I’m struggling with is the connection between the scenes. Imagine a lot of different scenes connected as in a maze. Now the problem is Defold does not allow you to fetch resources dynamically (for what I understand) so you must identify every scene in a collection proxy. But for what I’ve read there is a limitation to the number of collection proxies you can create for one game object !

Are you in the same scenario ?

0 Likes

#6

Yes, I’m trying to connect levels in a maze-like world too :smiley: When you reach the right or left edge you want to go to the next/previous scene/level. My game would be a side-scroller. I was thinking about adding another “dimension” by allowing in some part of the level to go deeper, “inside”, which would create a maze like in Pokemon RPGs, but still side-scrolled (e.g. ICEY). So I was thinking about creating a map of levels, which would be a simple description of connections between levels.
I am making one proxy per game object called "level_X" and all of them are in main collection.

1 Like

#7

Your game looks very nice :+1: ! Your logic of scenes connections seems to fall into the “metroidvania” genre, but really should work in the same way as in old top down RPGs.

Did you increment the maximum count of proxies ?
Maybe there is a way to achieve what we want through collection factories, by loading the collections dynamically ? Sadly, I don’t think it is possible to unload them from the memory afterward.

1 Like

#8

You should track the current game state in a persistent data structure, probably a Lua module but possibly also a global Lua table. Both can be persist their data to file on disk as well.

0 Likes

#9

Thanks for your answer @britzl !

That’s what @sicher suggested me too and as I’m sure this solution will work, I’m concerned about the workaround it implies for such a core functionality in the game mechanics.

It feels kind of wrong to add a prefab player spawner to every level I design, but hey maybe that’s the way it is :grin:

Is there any design you would be aware of, that would not imply doing that ?

And while I’m at it. I understand that collection factories could load the collections dynamically. Could this be reversed ? I mean, once they are loaded they are ready to spawn but would it be possible to unload the collections from the memory ?

0 Likes

#10

I am not sure what would be wrong about that. Being explicit often gives major benefits that otherwise would require workarounds (what happens if a level features a different player character? From where do you get the player character on level load? What if the player is not part of an intro cinematic? Do you teleport it to origo during? Etc etc)

Still, you can make life easier if you put things in common for all levels in a collection and put an instance of that in each level.

1 Like

#11

So basically, if I get you right, you are building a open world game, that’s cool :sunglasses:
There are two things I can recommend you:

  1. Defold has its own RPG Map sample, that teaches you how to create a simple RPG like scene, have a look at it…

  2. I will recommend you using @sicher’s idea, it will be the best way to do things. Spawn the player’ using a factory, store it’s every data in a lua module, even it’s id. And later if you need it’s id, :id: you can get it from there. Then create a simple fader script, which fades in and out, and then spawn your worlds, and let your players explore it. This method is extremely good keeping in mind that suppose the player starts one corner of the ground,and then moves to a shop, the next time he comes out of it, you’re expected to spawn it infront of the shop, since you are respawning the player every time the parent scene changes, you can spawn it at the appropriate place directly.

1 Like

#12

Yes I would completely agree to this way of doing things if there were few big levels, but in my case I will have a lot of small screens connected to each other, so I think I would prefer to implicitly load the player in every screen he visits rather than explicitly.

0 Likes

#13

Thanks for your advices @TheKing009 :slight_smile:

I looked at it and surprisingly they use collection factories and not collection proxies to load and unload the different screens. So the player is not deleted and created at each scene as @sicher, @britzl and you suggested me.

But I guess as the world is growing bigger, this solution could not be used anymore ?

I’m not sure to get the benefit of this. Moving the player to the appropriate position at screen load without destroying it and respawning it would do the trick too ?

0 Likes

#14

As the worlds grow bigger, it is not that efficient to use collection factories(correct me if I’m wrong) and use of collection proxies becomes cheaper. And the easiest way to place players in proxy generated world is by spawning them.
Anyways you now know the two ways that can be used, it is now up to you to decide which one will suit your needs.

1 Like

#15

Sure thing. As long as you delete spawned objects you can use collections factories. That will scale.

0 Likes

#16

Ok thanks that is very interesting ! So if I get it right, the difference between collection proxies and collection factories is that collection proxies allocates the memory dynamically is that so ? That means that if I use collection factories all the memory for all the screens in the world will be allocated when the game starts. So maybe even with deleting the collections there will be a time when the allocated memory will grow too large ? If you think not, then what would be the advantage of using collection proxies over collection factories ?

0 Likes

#17

I don’t think so, but correct me if I’m wrong. Collection factories are supposed to work as just a set of normal factories for its game objects and then appling hierarchy, so you don’t know always how many instantiations there will be at the beggining. You can read more about collection proxies here and collection factory there.

1 Like

#18

Factories set up a static requirement for what’s in the referenced prototype (go or go hierarchy in a collection file). All the resources required for those are allocated and loaded up front. Instances are cheap and created from a pool that is also allocated up front (the max number of game objects as set up in game.project).

3 Likes

#19

I think @sicher explained the situation.

So for what I understand there is two steps for the creation of collections and that is how factories and proxies differ.

  1. Loading of the collections.
  2. Instanciation of the collections.
  • Collection factories load the collections automatically (except with “load dynamically”). This means that if for example you have a hundred of collection factories in your game, the needed memory will be automatically required by those factories, even when no instanciation is done. The advantage of this solution is to be able to instanciate the collections at any moment without loading the resources first, which would result in hiccups.

  • Collection proxies load the collections when they are told to. Which mean they have a smaller memory footprint on your game. You could have a hundred of collection proxies, that would result in a zero memory usage, if the proxies are not told to load. So a great solution to hold whole levels and instanciate them when needed.

This is only what I understand for now so there is certainly misunderstanding of some concepts. If any Defold expert read this I would be happy to be corrected :sweat_smile:

The metroidvania logic of scene switching seems to fall somewhere between those two approaches of managing collections. If the world grows too large, the memory footprint of collection factories may become a problem ? (honestly have no idea about this). So maybe collection proxies are a better approach even if they seem to have been designed more for switching whole levels rather than just exploring some areas of the same level.

2 Likes

#20

How many collection would you have? 5, 10, 50, 100?

What would they consist of? You mention “scene switching” but what does that mean? A single screen of gameplay or something larger, but still smaller than a level?

Perhaps dynamic collection factories for these smaller pieces and collection proxies for the entire levels?

0 Likes