Parsed game data under extracted/ (item/compartment/loot/crafting definitions, hashes, I2 localization terms) plus root JSON artifacts (i2_terms_en, item_defs_full, name_index).
83 lines
5.5 KiB
Markdown
Executable File
83 lines
5.5 KiB
Markdown
Executable File
# SAND extracted game data
|
|
|
|
Extracted from `D:\SteamLibrary\steamapps\common\Sand Playtest` (Addressables bundles) and
|
|
the local walker saves. Tools: UnityPy + TypeTreeGeneratorAPI (in `~/sand_tools/venv`).
|
|
|
|
## Files
|
|
|
|
- **crafting_recipes.json** — all 4 crafting recipe bundles (Utility T1, Armament T1/T2, Test).
|
|
Schema: `{bundleName: [{inputs:[{id,count}], outputs:[{id,count}], craftTime}]}`.
|
|
Source: `craftingrecipes_assets_all.bundle` (4 MonoBehaviours).
|
|
|
|
- **CompartmentsDatabase.json** — the full compartment placement DB (126 parts: cells, sockets,
|
|
groups, pivots). Source: `CompartmentsDatabase` TextAsset in `walkershared_assets_all.bundle`.
|
|
|
|
- **compartment_hashes.json** — `{entityId: {CompartmentHash, placement}}` for all 126 parts.
|
|
`CompartmentHash = MD5(UTF8(JsonConvert.SerializeObject(placement, compact)))` — VERIFIED
|
|
against every part in the local walkers. This is the authoritative current CompartmentHash.
|
|
|
|
- **definition_hashes_known.json** — per-part hashes OBSERVED in the 5 local walker saves
|
|
(18 parts). Has both observed CompartmentHash/DefinitionHash and the computed CompartmentHash.
|
|
|
|
- **item_definitions.json** — the MASTER ITEM LIST: 121 item ids → category (WEAPON, AMMO,
|
|
RESOURCE_T1/2/3, KEY, ARMOR, ENERGY, FOOD, MONEY, …18 categories). Parsed from the
|
|
`CheatItemDefinitionsData` MonoBehaviour in `configuration_assets_all.bundle`.
|
|
|
|
- **epb_catalog.json** — all 1446 entity blueprints (EPBs) by category: walker compartments
|
|
(156), chassis (22), weapons, turret containers, crates, props, spawners, AI, items, etc.
|
|
Source: `epb_assets_all.bundle` container paths. (Walker buildable parts = 126 of the 156
|
|
comp EPBs; see CompartmentsDatabase.json for the placeable set.)
|
|
|
|
- **i2_terms_en.json** — the FULL I2 Localization term table (English), 3440 terms keyed like
|
|
`Items/item_X_name`, `WalkerCompartments/..._name/_description`, `WalkerFirstName/...`, etc.
|
|
Source: the `I2Languages` LanguageSourceAsset baked into `Sand_Data/data.unity3d`.
|
|
|
|
- **item_names.json** — real in-game item names + descriptions: `{itemId: {name, shortDescription,
|
|
description}}` for 642 named entries from the `Items/*` I2 terms. NOTE: this is the WIDE set — it
|
|
includes damage-type name variants (`_Ranged`/`_Melee`) and world objects that merely have a
|
|
display name. For the true item list use items_registry.json.
|
|
|
|
- **items_registry.json** — the AUTHORITATIVE carriable-item list: 121 items, each with `type`
|
|
(ItemType), `storageStack`, real `name`, `shortDescription`, `description`. Source: the game's
|
|
only `List<ItemDefinition>` (`CheatItemDefinitionsData.Items`, read via IL2CPP typetree) merged
|
|
with I2 names. An item is here iff the game defines it as a real inventory item — this is the
|
|
principled "what can be picked up" filter (excludes `_Ranged`/`_Melee` variants + world objects).
|
|
(2 craftable outputs — `ArtefactCrystal`, `item_rifleMusket` — lack an ItemDefinition; likely
|
|
WIP/renamed.) The Items wiki page is built from this.
|
|
|
|
- **loot_tables.json** — the DROP TABLES, decoded from the two Odin-binary `LootTablesConfig`
|
|
assets (`conf_worldLootTablesStormConfig` / `conf_worldLootTablesVoyageConfig`). Schema:
|
|
`{region: {lootTableId: [{itemBlueprint, countMin, countMax}]}}`. 193 tables per region (Storm,
|
|
Voyage), 696 drop rows each. Both regions share the same table ids but 152/193 differ in counts
|
|
(Voyage is leaner). Decoded by `~/sand_tools/odin_read.py` (a from-scratch Sirenix Odin Binary
|
|
reader) + `~/sand_tools/extract_loot.py`. Raw payloads: `conf_worldLootTables*Config.odin.bin`.
|
|
|
|
- **Crafting.mediawiki** — ready-to-paste MediaWiki page for all crafting recipes, using the real
|
|
item names. Generated by `~/sand_tools/make_crafting_wiki.py`.
|
|
|
|
## Crafting / workbench notes
|
|
|
|
- 4 recipe bundles: `Recipes_Utility_Workbench_T1` (fabric/armour/food/valuables), `Recipes_Armament_Workbench_T1`
|
|
and `_T2` (ammo/weapons), `TestRecipesBundle` (debug).
|
|
- Placeable crafting compartments (in CompartmentsDatabase, all enabled): `walker_compCrafting_Open_1x1`
|
|
= "S&H Armaments Workbench", `_Small_Wood_1x1` = "S&H Compact Armaments Workshop", `_Wood_2x1`
|
|
= "S&H Armaments Workshop". The "KF Sewing Workshop" (`walker_compCraftingUtility_Wood_2x1`,
|
|
utility/fabric) is NOT in the buildable list in this build.
|
|
- The compartment→recipe-bundle binding is set at runtime in (obfuscated) game code, NOT in the
|
|
asset data — the EPB CraftingWorkbench components carry no PPtr to the bundles. So which placed
|
|
workbench loads which bundle is inferred, not statically proven.
|
|
|
|
## Hash facts
|
|
|
|
All walker hashes = `MD5(UTF8(JsonConvert.SerializeObject(obj)))`, uppercase hex.
|
|
- `CompartmentHash` (per part): obj = CompartmentPlacementInfo (from CompartmentsDatabase). DONE.
|
|
- `DefinitionHash` (per part): obj = CompartmentDefinitionDto {EpbId, Weight, VisualWeight, HP,
|
|
Properties[{Key,Value}], CrownPrice, T1/T2/T3_MetalPrice}. **SERVER-SOURCED — not reproducible
|
|
offline.** `ClientCompartmentDefinitionsContainer.GetDefinitionsAsync` fetches the DTO list from
|
|
the masterserver (`ClientMasterServerNetwork.GetCompartmentDefinitions`) and hashes the response;
|
|
the stats are not in local assets. Only the 18 values observed in local walkers are known (see
|
|
definition_hashes_known.json). To get more: build the part in-game once (its hash lands in the
|
|
save) or capture the masterserver definitions response.
|
|
- Aggregate `CompartmentsHash`/`DefinitionsHash`/`ConnectionsHash` (per walker): MD5 of a
|
|
Newtonsoft-serialized object; exact input not yet pinned down.
|