Maploader Plan
This document mixes:
- the shipped experimental
maploaderresource contract - the planned long-term orchestration direction
Goal​
Keep map selection and map transition policy out of engine core.
Instead of hardcoding map package orchestration into the runtime, a Lua maploader resource should coordinate:
- resource lifecycle
- baked map lifecycle
- map transition policy
Current Experimental Resource​
An experimental external resource now exists at:
Server/ExternalResources/mtadm-resources/maploader
Current resource-local request events:
custom:maploader_catalog_requestcustom:maploader_load_requestcustom:maploader_unload_request
Current result events:
custom:maploader_catalog_resultcustom:maploader_load_resultcustom:maploader_unload_result
Current behavior:
- catalog requests return
Map.GetAvailable() - load requests resolve the target map resource, start it with
Resource.Start(...), then callMap.Load(mapId) - unload requests call
Map.Unload(...)for the active map and then stop the owning map resource
This contract is still experimental and may change before it is treated as stable public scripting surface.
Current deployment note:
maploaderexists as an external resource package- it is not automatically a core engine service
- it must be started like any other resource before its request/result events are available
- current local singleplayer launch uses it this way:
- the main menu lists published map packages from the prelaunch local C# catalog
- core starts the local singleplayer server profile
- core waits for the
maploaderclient resource to report ready - core dispatches an internal client-local launch event
maploaderturns that intocustom:maploader_load_request
Intended Responsibilities​
A future maploader resource should:
- choose the active map package
- start the selected
resourceType = "map"package - activate the baked runtime payload with
Map.Load(mapId) - unload the active baked payload with
Map.Unload(mapId) - stop the previous map package resource
Launch Intent Boundary​
maploader should execute gameplay map intents, but it should not own the top-level pending session intent itself.
That boundary stays in core/session flow:
- menu chooses the next action
- local server profile decides which startup resources should run
- core waits for the target resource to be loaded
- core dispatches the pending action to that resource
Current local-session bridge already follows this pattern for both:
map-editorcreate/open package actionsmaploadergameplay published-map load actions
Intended Flow​
Activate:
Resource.Start(mapResourceName)Map.Load(mapId)
Deactivate:
Map.Unload(mapId)Resource.Stop(mapResourceName)
Why This Exists​
This split keeps:
- core runtime responsible for low-level map/resource lifecycle
- gameplay policy in Lua resources
That is important for:
- singleplayer flows
- multiplayer map rotation
- vote systems
- map-specific transitions
Related Shipped APIs​
Map.GetAvailable()SMap.Load(mapId)SMap.Unload(mapId)SResource.Start(resourceName)SResource.Stop(resourceName)S
Current Product Model​
Recommended list split:
- gameplay map browser:
- prelaunch menu browsing may use the local C# catalog for installed published packages
- runtime activation still goes through
maploader, which resolves the target throughMap.GetAvailable()
- map editor load browser:
- use editable drafts, not
Map.GetAvailable()
- use editable drafts, not
Not Shipped Yet​
Not implemented yet:
Maploader.*Lua namespace- standardized engine-owned maploader API
- stable transition events beyond the current resource-local request/result pattern
- gameplay unload/rotation UX above the current minimal load/unload requests