SOCOM Legacy Modding
Reference

Bounds

Status: Format onlyOwned by: redotcom/docs/specs/2026-10-25-pack-framework.md, redotcom/packages/viewer/src/packs/registry.ts:527-535, redotcom/packages/creator-contracts/src/packs.ts, redotcom/docs/research/370-the-thunderstore-package-format.md

The pack contract's limits and their values, generated from the code.

Status: Format only. The checker holds a pack to these bounds before it is stored; nothing in the game applies a v2 pack yet (the pack-framework spec, "Import"). Thunderstore's rules are the format only: no tool writes the store zip and nothing installs from the store (research 370; the store team is the owner's question H342).

Each bound is a named constant in the pack contract (*_ADAPTATION: chosen for this project, not taken from the game). A pack over one is refused with the code its description names.

The pack's bounds

constantvaluewhat it bounds
PACK_BYTES_ADAPTATION536870912 (512 MiB)All members together, by their sizes in the manifest (pack.TOO_LARGE). The stored files are first held to this plus the manifest's own bound.
PACK_DEPENDENCIES_ADAPTATION64Entries in dependencies (pack.LIMIT_EXCEEDED).
PACK_DESCRIPTION_CHARS_ADAPTATION400Characters in description (pack.FIELD_INVALID).
PACK_FILES_ADAPTATION8192Files in the pack, and rows in files (pack.TOO_MANY_FILES).
PACK_HANDLERS_ADAPTATION32Claims in handlers (pack.LIMIT_EXCEEDED).
PACK_HANDLER_ACTIONS_ADAPTATION64Action names in one claim's actions (pack.FIELD_INVALID).
PACK_HANDLER_OPTIONS_BYTES_ADAPTATION4096 (4 KiB)Bytes of one claim's options written as JSON (pack.FIELD_INVALID).
PACK_HANDLER_OPTIONS_DEPTH_ADAPTATION2How deep one claim's options nest: the options object is level 1, an object or list inside it level 2 (pack.FIELD_INVALID).
PACK_ID_CHARS_ADAPTATION64Characters in id, not counting an earlier format's prefix (pack.FIELD_INVALID).
PACK_INTENTS_ADAPTATION64Entries in intents (pack.LIMIT_EXCEEDED).
PACK_MANIFEST_BYTES_ADAPTATION1048576 (1 MiB)The size of s2u-pack.json (pack.MANIFEST_TOO_LARGE), and of Thunderstore's manifest.json when the store checker reads it.
PACK_MEMBER_BYTES_ADAPTATION524288000 (500 MiB)One member, other than a rules member (pack.MEMBER_TOO_LARGE).
PACK_NAME_CHARS_ADAPTATION48Characters in name (pack.FIELD_INVALID).
PACK_PATH_CHARS_ADAPTATION240Characters in one member path (pack.PATH_INVALID).
PACK_PATH_DEPTH_ADAPTATION16Folders in one member path (pack.PATH_INVALID).
PACK_RULES_MEMBER_BYTES_ADAPTATION1048576 (1 MiB)One rules member, which is read whole (pack.MEMBER_TOO_LARGE). It is the manifest's bound.

Thunderstore's package rules

Held as data in THUNDERSTORE_PACKAGE_RULES; its source: wiki.thunderstore.io, "Creating a package" (read 2026-10-26; quoted in docs/specs/2026-10-27-creator-rules-contract.md §8). Nothing is fetched from Thunderstore.

rulevaluewhat it is
requiredmanifest.json, icon.png, README.mdThe files a Thunderstore package must hold at its root (not in a folder).
optionalCHANGELOG.mdThe root file a Thunderstore package may also hold.
manifestKeysname, version_number, website_url, description, dependenciesThe keys of Thunderstore's manifest.json, in the order the export writes them.
namepattern ^[A-Za-z0-9_]+$, maxChars 128The store name: letters, digits and underscores, at most 128 characters. Our id becomes it with each . and - written as _.
versionNumberpattern ^\d+\.\d+\.\d+$The store version: strictly Major.Minor.Patch, with no pre-release or build part.
descriptionmaxChars 250The store description's length in characters. The export never cuts a longer one; it refuses it.
websiteUrlpattern ^(?:https?://\S+)?$The store website_url: empty, or an http or https address. This rule is ours, not Thunderstore's; a pack manifest cannot carry an address, so the export takes it as an option.
dependencypattern ^[A-Za-z0-9_]+-[A-Za-z0-9_]+-\d+\.\d+\.\d+$One store dependency: Team-Name-x.y.z, an exact version. The export pins each {id, range} dependency to the highest release it is given inside the range.
iconwidth 256, height 256The size icon.png must be, in pixels. Only the PNG header is read.

On this page