I’m making a space RPG, and I’m trying to find out what the right approach is for setting the game up. What I’m trying to figure out is:
Is it better to start with a scene that has all of the game objects(locations, NPCs, etc) already there, or is it better to start with an empty scene and instantiate all of the game objects at runtime from a script?
Keep in mind that during the game, new game objects will be spawned from time to time, and their information will have to be serialized. And other game objects that were there at the start of the game will be gone.
Someone else can argue for runtime instantiation better than I can.
I’ve worked on a number of projects that use Unity’s scene model at design time, and it really hasn’t been a problem. The biggest downside is that it’s still difficult-to-impossible for multiple people to work on the same scene simultaneously. But, apart from that, it’s easy to work with, and you don’t need any additional special code to populate your scene at runtime. Also, if you bring on team members who are familiar with Unity, they won’t have an extra learning curve to figure out your custom scene setup solution.
In any case, use prefabs. Ideally everything in your scene will be prefab except for any empty (0,0,0) GameObjects that you use as “folders” to organize your scene.
Also, figure out saving and loading early. This has a big impact on your overall game implementation.
This issue is largely resolved these days if you break it apart into smaller scenes, now that the editor can load and edit multiple scenes simultaneously.
Yeah. I’m basically leaning toward runtime instantiation, but I’m trying to get a sense for how most games normally handle it. I don’t really want to re-invent the wheel.
No doubt. I’ve gotten into the habit of doing that early. It makes life much easier, to be sure.
I figured that was the way to go. I’ve got save/load functionality working okay, and I’m going with .json as a format. It’s not a multi-player game, so security is not an issue. What I’m thinking of doing at the start is loading everything from a pre-made .json file that has all of the starting game objects. Then when I save, it will just save to a new file from there, and save to that file going forward, unless the player chooses “save as”.
The tricky part is figuring out how to repopulate the game variables on load without having to have walls of code. I’m going to try to do it with a system of lists.
Any elements that you know are going to load into the scene exactly the same every time should be built into the scene ahead of time. If there is anything random I would make those loaded at runtime. You may also take a look at Object Pooling and see if that is relevant for any of your objects. There is a nice tutorial on it here: Object Pooling - Unity Learn
I wouldn’t hesitate to use a hybrid solution that works for you. As long as you can keep track of what is what, then you’re gravy. So, you may for example have all your static items (tables, chairs, lights, etc.) done through Unity and set into the scene while the characters are generated runtime through script to reflect their changing location depending on what time the game was last saved or whatever.
Time frame wise items which are always going to load exactly the same will load faster if they are built into the scene.
Building scenes in the editor is the chance to use various optimization techniques that require a “baking process” or at least the knowledge at build time about whether an object will be static or not. (Batching, Occlusion Culling, Light and Reflection Probes, Light Maps, Navigation, Physics…)
Don’t miss the chance to make use of these techniques and don’t underestimate them. It’s quite important to always keep them in mind, even if some may not be of any use all the time. These can improve performance greatly.
Yeah, I was basically thinking the same thing. Have the static stuff be there already, and load the characters at runtime. It sounds like that might be the way to go.
Yeah, I am considering possibly having EVERYTHING in the scene already, even the stuff that isn’t spawned yet, and go the object-pooling route, activating characters from my pool when they spawn, and deactivating characters and storing them in the pool when they die and have them eventually come back as different characters when needed.
You’re not kidding. For an arcade-style game, you maybe have a dozen variables that need to be saved, but for RPGs, thousands of variables need to be saved and loaded back again. Possibly tens of thousands. It hurts just thinking about it.
Tbh, things that appear once in a while won’t need to be in memory from start up and won’t need to stay in memory once no longer used. That’s suboptimal as you’ll most-likely load a huge amount of objects into memory that is not needed most of the time. And this can even have a negative influence on the underlying memory management which is done by 1) GC for the managed side and the 2) the native C++ memory management which the engine uses.
The idea of pooling is mainly used for objects that are frequently requested. Examples may be “physical” projectiles when we speak about gameobjects, or arguments for frequently raised methods and events that would otherwise always require instantiation of a type whereas previous instances could be “re-initialized”.
Guess you have to find a well-balanced mixture of both.
Sure, that makes sense. Probably just instantiate new characters, then. Like you said, that won’t happen frequently enough for it to make a difference.