Core: add platforms field to manifest

This commit is contained in:
Berserker
2026-03-05 00:38:16 +01:00
parent b372b02273
commit 41eba5a2f6
5 changed files with 17 additions and 0 deletions

View File

@@ -32,6 +32,8 @@ If the APWorld is a folder, the only required field is "game":
There are also the following optional fields:
* `minimum_ap_version` and `maximum_ap_version` - which if present will each be compared against the current
Archipelago version respectively to filter those files from being loaded.
* `platforms` - a list of strings indicating the `sys.platform`(s) the world can run on.
If empty or not set, it is assumed to be any that python itself can run on.
* `world_version` - an arbitrary version for that world in order to only load the newest valid world.
An APWorld without a world_version is always treated as older than one with a version
(**Must** use exactly the format `"major.minor.build"`, e.g. `1.0.0`)

View File

@@ -409,6 +409,7 @@ class BuildExeCommand(cx_Freeze.command.build_exe.build_exe):
apworld = APWorldContainer(str(zip_path))
apworld.minimum_ap_version = version_tuple
apworld.maximum_ap_version = version_tuple
apworld.platforms = [sys.platform]
apworld.game = worldtype.game
manifest.update(apworld.get_manifest())
apworld.manifest_path = f"{file_name}/archipelago.json"

View File

@@ -353,6 +353,8 @@ class World(metaclass=AutoWorldRegister):
"""path it was loaded from"""
world_version: ClassVar[Version] = Version(0, 0, 0)
"""Optional world version loaded from archipelago.json"""
platforms: ClassVar[List[str]] = []
"""Optional platforms loaded from archipelago.json"""
def __init__(self, multiworld: "MultiWorld", player: int):
assert multiworld is not None

View File

@@ -197,6 +197,7 @@ class APWorldContainer(APContainer):
world_version: "Version | None" = None
minimum_ap_version: "Version | None" = None
maximum_ap_version: "Version | None" = None
platforms: List[str] = []
def read_contents(self, opened_zipfile: zipfile.ZipFile) -> Dict[str, Any]:
from Utils import tuplize_version
@@ -205,6 +206,7 @@ class APWorldContainer(APContainer):
for version_key in ("world_version", "minimum_ap_version", "maximum_ap_version"):
if version_key in manifest:
setattr(self, version_key, tuplize_version(manifest[version_key]))
self.platforms = manifest.get("platforms", [])
return manifest
def get_manifest(self) -> Dict[str, Any]:
@@ -215,6 +217,8 @@ class APWorldContainer(APContainer):
version = getattr(self, version_key)
if version:
manifest[version_key] = version.as_simple_string()
if self.platforms:
manifest["platforms"] = self.platforms
return manifest

View File

@@ -118,6 +118,7 @@ for world_source in world_sources:
game = manifest.get("game")
if game in AutoWorldRegister.world_types:
AutoWorldRegister.world_types[game].world_version = tuplize_version(manifest.get("world_version", "0.0.0"))
AutoWorldRegister.world_types[game].platforms = manifest.get("platforms", [])
if apworlds:
# encapsulation for namespace / gc purposes
@@ -165,6 +166,11 @@ if apworlds:
f"Did not load {apworld_source.path} "
f"as its maximum core version {apworld.maximum_ap_version} "
f"is lower than current core version {version_tuple}.")
elif apworld.platforms and sys.platform not in apworld.platforms:
fail_world(apworld.game,
f"Did not load {apworld_source.path} "
f"as it is not compatible with current platform {sys.platform}. "
f"Supported platforms: {', '.join(apworld.platforms)}")
else:
core_compatible.append((apworld_source, apworld))
# load highest version first
@@ -199,6 +205,8 @@ if apworlds:
# world could fail to load at this point
if apworld.world_version:
AutoWorldRegister.world_types[apworld.game].world_version = apworld.world_version
if apworld.platforms:
AutoWorldRegister.world_types[apworld.game].platforms = apworld.platforms
load_apworlds()
del load_apworlds