MasterReDWinD said:
store, loader, cache and proxy concepts… I have gathered some notes so far but I'm still unclear on several points. For example: 1. Whether the ‘store’ is the conceptual replacement of the resource manager class and contains the load() function. 2. How the placeholder/proxy is swapped out with the real object?
Those look like my words (store, loader, cache and proxy) from about a decade ago.
For both of your questions, you can see them in modern games all the time.
Have a look at the life cycle of game objects in Unreal Engine with this documentation from the engine's perspective, and in with Unity with this documentation from the script's perspective.
The store is the thing that owns them. It may be the game world, the simulation, a map, or some other container. Something somewhere controls what it means to have an object in the game, usually having it parented into a world hierarchy. You make a call like AddToWorld or SpawnActor or CreateInstance or Initialize. This can also work for individual components. It gives you back a game object or other which you can do something with. You as the user shouldn't know or care too much about its internal state, if it is displaying something or is loading asynchronously in the background or is at a particular LOD. This could be synchronous (blocking execution of the code until it is ready) or asynchrnous (returning flow control immediately while sub-components are processed) but that's an implementation detail.
The thing I called the proxy is what the script writer sees as the object. The script writer gets back a UE4 Actor or a Unity GameObject and they can use it immediately with no questions asked. From their perspective they received back a fully-formed, fully functional game object. You don't need to know, nor should you generally care, about what details the engine has actually loaded internally. All you need to know is that this object is fully usable for you.
For asynchronous engines the proxy object may have several function calls and events. For example, Unreal exposes PostLoad(), InitializeActorsForPlay(), PreInitializeComponents(), InitializeComponents(), PostInitializeComponents(), and eventually gets to BeginPlay() when proxy object has been fully realized in the game. Unity has fewer exposed elements since it is synchronous with the script, with Awake(), sceneLoaded events, and OnEnable(). But at the same time, you don't typically know details like which LOD or mipmap level is being used, nor do you care. That gets handled by the engine.
From the object script writer's perspective the loader and cache don't exist, or at least aren't something typically touched.
The loader may quietly switch out model LODs for a visual mesh or textures, or even substitute with a billboard, or even cull visibility entirely. When you create an object in the world you don't care where the loader is pulling resources from, if they're loaded from disk or cloned from another object or already held in memory. Similarly the script writer usually doesn't care about the cache. The cache may be quietly making every instance use a shared mesh model, or it might keep the model around in memory even after you've destroyed a game object. The cache might have existing shared copies of data structures, of audio clips, of physics models, and the script writer typically has no need to know about them.
With all that in mind, we can revisit your two items:
1. Whether the ‘store’ is the conceptual replacement of the resource manager class and contains the load() function.
That's a concept, not a specific function call. Something somewhere serves as a container. You may call it a SceneManager, a World, a Simulator, or some other name, but it is a “thing” which serves as the source for all the in-game “things” and controls their individual life cycles.
2. How the placeholder/proxy is swapped out with the real object?
From the scripting side, it doesn't matter. The script doesn't care if it is running at the highest level of detail or the lowest, it doesn't care how audio is being mixed, it doesn't care if the graphics texture is in a DDS format, PVR format, or S3TC format.
From the engine side, this all must happen transparently so it is whatever work the engine must do.
If the engine swaps out a mesh LOD it needs to identify which mesh is required, possibly generate a view-dependent mesh or view-independent mesh, possibly transfer the mesh to the video card, possibly morph between them so they don't pop, possibly unload the other mesh, and more.
The engine may switch over to use GPU instancing for some but not for others, changing the number of GPU draw calls without notifying the script.
The engine may use megatextures or sparse textures (so that only a portion of the texture is in memory at any given time) and this may be invisible to the game object script. That same task may require substantial effort on the engine, a sparse texture means knowing what data needs to be transferred to the graphics card and actually doing that work, even though it is never visible to the game object scripter.
The engine may also unload resources, such as dumping currently-unused textures or meshes or audio to save resource space while keeping the metadata around, and load them back up when they're eventually used. (This is more of an issue in game consoles then the PC, which can use virtual memory to accomplish much of the same.)
In each of these cases, the engine is doing work behind the scenes to make the best behavior, reduce the number of calls, share resources rather than duplicate them, etc., but that work is nearly always kept invisible to the programmers using the system. It is the engine's responsibility to quietly substitute out the concrete items, such as the LODs and the instanced objects, and the conceptual item used by the script writers (the GameObject or Actor or similar) remains available regardless of the actual data.