Commit Graph

18 Commits

Author SHA1 Message Date
DownloadPizza
5946e0910b docs: item sales value + PlayFab/master-server backend map
- SALES_VALUE.md: price model (PriceDto/ItemDto.SellPrice/PriceDataComponent), server-authoritative
- BACKEND_PLAYFAB.md: backend = PlayFab Economy + ws:// master server (per-region);
  observed no-playtest boot behavior, capture findings, OnRegionsLoadFailed dialog path
- WEAPON_DAMAGE.md: cross-link to backend doc
2026-06-12 01:17:07 +02:00
DownloadPizza
ed951764d5 crafting: resolve workbench->recipe-bundle mapping + Discord recipe tables
- workbench_bundles.py: each crafting press's CraftingWorkbenchDataComponent.recipeBundles
  resolved (full press = Armament T1+T2+Utility; small press = T1+Utility, no T2)
- discord_recipes.py: Discord-formatted Tier1/Tier2 workbench + conveyor recipe tables
2026-06-12 01:17:07 +02:00
DownloadPizza
64c6df119f islands: extract in-game names (Landmark -> Toponym), incl. Wunderinsel = Strudel
Definitive island prefab -> in-game name link: each island_* prefab has a child Landmark
GameObject (LandmarkBehaviour.name) = the Toponym key, localized via i2 Toponyms/<name>.
New bundle/extract_island_names.py -> extracted/island_names.json.

Key results: Demo_Wunderinsel=Strudel, Demo_Marktinsel=Segen, Gartenfreude=Insel St. Clemens,
DeusExMashineSmall=Rauchwolke, and island_Factorio = Sprengstofffabrik (the explosives
factory). The LittleFactory/LittleFactoryArmory prefabs are the Forts.

Updates docs/PRODUCTION_LINES.md with in-game names and corrects the earlier Sprengstofffabrik
note (it IS the explosives factory -> Factorio, not the Armory islands). Supersedes the
name-guesses (e.g. DeusExMashine is Rauchwolke, not Maschineninsel).
2026-06-11 20:03:12 +02:00
DownloadPizza
8abe4bcecf production lines: resolve conveyor -> island placement mapping
The recipe conveyors (game_conveyor_<product>_epb) are placed as named child GameObjects
in the island_* prefabs (islands_assets_all.bundle), NOT via energy_grid (power grid only)
or any config asset. New extractor bundle/extract_conveyor_placements.py walks every island
prefab and cross-references production_lines.json -> extracted/conveyor_placements.json.

Result: Factorio (energyRods, 80mmT3Cannon, contactGrenades, armorPiercingRocket),
Kaiserplatz (energyRods, 40mmT3Cannon), Demo_Wunderinsel (70mmT3Cannon), DeusExMashineSmall
(computingModules, coralDust), testIsland(+Tramplers) (the 4 base test conveyors).

Corrects the earlier "Armory = Sprengstofffabrik hosts explosives" guess: the
LittleFactory/LittleFactoryArmory islands place NO recipe conveyors; grenades/rockets are
on Factorio. Unplaced blueprints: explosiveSmall, mechanicalParts (+ the plural
armorPiercingRockets, whose singular-named instance is on Factorio).
2026-06-11 19:38:13 +02:00
DownloadPizza
e4899b43e7 weapon damage: Ghidra decompile phase — confirms server-authoritative, no static seed
Bulk-decompiled ~17.2k combat/system functions (Ghidra 11.1.2 headless) and confirmed
via a second toolchain what the capstone analysis found:
- GetDamage is a pure component read (returns *(comp+0x10), 0 if absent), no constants.
- PlainDamgeDealerComponent has CopyTo -> it's network-replicated (snapshot from server);
  the client receives damage, never computes it.
- No client producer writes a damage value (GetDamage has no real combat caller; the rich
  calc factory has 0 callers).

Conclusion documented: per-weapon damage numbers are server-authoritative runtime Entitas
component values, assigned via fully-generic dispatch with no static class/index/string
anchor -> not statically extractable from GameAssembly.dll. Trackable static artifacts are
the model + formula RVAs.

Adds reusable pipeline: reverse/ghidra_decomp_targets.py, reverse/find_damage_writes.py.
2026-06-11 19:08:38 +02:00
DownloadPizza
674536936a chore: gitignore Ghidra install/project/output dir 2026-06-11 18:19:08 +02:00
DownloadPizza
afbf79ac26 weapon damage: full static map of the model (values are runtime/server, not statically anchorable)
Mapped the damage system end-to-end statically and documented it for cross-patch
tracking (docs/WEAPON_DAMAGE.md):

- Model: 8 DamageXxxDataComponent (value @+0x10) on item/ammo, read by
  HealthAndDamageExtensions.GetDamage (RVA 0x4BAC520); per-shot formula in
  <GetDamage>d__12.MoveNext (RVA 0x4BB3DB0) = base x range-falloff x headshot,
  melee skips range falloff.
- Delivery: PlainDamgeDealerComponent{damageAmount,damageType,isMelee} -> HitEventInfo
  -> reduces HealthDataComponent.value; networked via DamageEvent.

Verified the base numbers are in NO asset (blueprints/ammo/projectiles/CheatItemDefs/all
bundles UTF-16). Established WHY the literal constants aren't statically anchorable: this
build accesses every component via fully-generic Entitas dispatch (no static class/index/
string reference in producing code; typed setters all dead build-wide; item-id strings
have 0 refs, verified via a calibrated string-xref) and damage resolution is server-
authoritative. So the value is a runtime component, not a reachable static constant.

Corrects the earlier draft that overstated "no value exists".

Tools: reverse/il2cpp_re.py (+find_rip_refs_batch, scan_movss_consts),
bundle/component_census.py, bundle/dump_blueprint.py.
2026-06-11 18:08:03 +02:00
DownloadPizza
b61b2526fc docs: reword game_conveyor_base* note to state only what the files show 2026-06-11 16:06:29 +02:00
DownloadPizza
a69f479301 docs+tool: locate & extract world factory production-line recipes
The fixed single-recipe world structures (conveyors, e.g. 1 Raw Aurogen
Crystal -> 10 Energy Rods) are a separate mechanic from workbench recipes.
Document where they live and how to read them, with a reproducible extractor.

- docs/PRODUCTION_LINES.md: the 'where to find it' record — ECS classes
  (ProductionLineRecipeComponent -> CraftingRecipe), the epb_assets_all
  game_conveyor_*_epb prefabs, EntityBlueprint/Odin serialization, the
  extraction path, and the open energy_grid_*/island-placement lead.
- bundle/extract_production_lines.py: UnityPy + odin_read extractor ->
  extracted/production_lines.json (14 conveyor recipes).
- BUNDLES.md: add production_lines.json to the data-source map.
2026-06-11 15:41:54 +02:00
DownloadPizza
7387078423 docs: add BUNDLES.md cataloguing all 35 game asset bundles
Probed every bundle under the bundles/ symlink with UnityPy (object-type
histograms + addressable container paths) and wrote a clean reference:
a summary table (size / asset count / contents), a map from extracted/
outputs back to their source bundles, and per-bundle detail with dominant
object types and example assets.
2026-06-11 15:22:53 +02:00
DownloadPizza
d2d3aeb868 chore: ignore bundles symlink to game asset dir 2026-06-11 14:50:27 +02:00
DownloadPizza
1f23f2c8bc data: refresh harvested part hashes (18 -> 19 known)
Re-running walker/harvest_hashes.py over the current 6 saves picks up
walker_compCrew_Medium_Wood_1x2_epb, which the previously committed
table predated.
2026-06-11 14:49:33 +02:00
DownloadPizza
a44e4db1c3 refactor: group scripts into walker/ wikigen/ bundle/
Organize the 16 loose scripts by concern:
  walker/  -- .wbt save tooling (sand, build_wbt, walker_hashes,
              harvest_hashes, recover_key)
  wikigen/ -- MediaWiki page generators (make_*_wiki, render_wiki)
  bundle/  -- Unity/Odin asset extraction (unitybundle, odin_read,
              extract_*, loot_probe, dump_loot_bytes)

The only cross-script imports (build_wbt->walker_hashes,
extract_loot->odin_read) live within the same folder, so each
script's dir on sys.path[0] keeps them resolving with no code
changes. All data paths are absolute, so the moves don't affect
I/O. Named the code dir wikigen/ to avoid colliding with the
generated wiki/ output dir; ignore the regenerable wiki_site/ render.
2026-06-11 14:49:33 +02:00
DownloadPizza
2e886f31f0 docs: .wbt save-format write-up
TASK.md — the solved .wbt format (BSON+XOR+gzip), recovered key, and
the one remaining open item (name-index -> word mapping).
2026-06-11 14:43:57 +02:00
DownloadPizza
7e0a1d9cdf wiki: generated MediaWiki pages
Crafting, Items, and Loot pages generated from the extracted data.
2026-06-11 14:43:57 +02:00
DownloadPizza
4134b7d986 data: extracted game data and parsed artifacts
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).
2026-06-11 14:43:57 +02:00
DownloadPizza
e2a2984925 tools: SAND .wbt + game-data extraction scripts
Python tooling for decoding walker saves and mining game data:
sand.py / build_wbt.py / walker_hashes.py / harvest_hashes.py (.wbt
codec + hashes), extract_*/loot_probe/odin_read/unitybundle (asset
parsing), make_*_wiki + render_wiki (wiki generation), recover_key.
Paths point at the local extracted/, wiki/, and Walkers symlink.
2026-06-11 14:43:57 +02:00
DownloadPizza
3d5f03c50f chore: repo scaffolding — gitignore and .claude settings
Ignore the Walkers symlink (live game saves), snapshots/, the large
regenerable il2cpp/ dumps, and Python cruft. Carry over the project
permission allowlist in .claude/settings.local.json.
2026-06-11 14:43:57 +02:00