Skip to content

feat: add Unity asset export via optional agentdecompile[unity] extra - #154

Closed
bodencrouch wants to merge 1 commit into
docs/ilspycmd-optional-dependencyfrom
feat/unity-asset-export
Closed

feat: add Unity asset export via optional agentdecompile[unity] extra#154
bodencrouch wants to merge 1 commit into
docs/ilspycmd-optional-dependencyfrom
feat/unity-asset-export

Conversation

@bodencrouch

Copy link
Copy Markdown
Contributor

Summary

Depends on #150 (targets that branch, not master, until it merges — this needed the [all] extra it introduces).

New unity-export CLI subcommand and src/agentdecompile_recovery/unity_assets.py, adapted from a bounded-memory UnityPy-based export script proven out on a large real-world Unity title where AssetRipper's whole-graph loading OOM'd on heavy Mesh/BlendShapeData.

  • Exports textures, sprites, audio clips, text assets, and fonts one object at a time (freeing each immediately) — peak memory stays roughly constant regardless of asset file size on disk, unlike full project-reconstruction tools that load the entire asset graph before writing anything.
  • Deliberately does not attempt meshes/materials/scene-prefab structure — that needs fuller project-graph tooling this module isn't trying to replace.
  • UnityPy is optional (pip install agentdecompile[unity], or via [all]) and imported lazily — importing unity_assets never requires it installed; invoking the CLI command without it raises a clear ImportError naming the extra.

Also fixed (discovered running the suite on this branch)

  • tests/test_rewrite_queue.py's two multiprocessing concurrency tests failed under Python 3.14 even on Linux (PicklingError on a locally-nested function target) — Python 3.14 changed the default multiprocessing start method away from fork on Linux too (previously only macOS defaulted away from it). Forced multiprocessing.get_context("fork") explicitly — same fix already shipped for the macOS-only case in fix: macOS multiprocessing failures + unused import in CI #152, now confirmed broader.
  • source_parity_synthesize.py: removed an unused .state.now import (ruff F401) — pre-existing, unrelated, blocking lint CI.

Test plan

  • 9 new tests for unity_assets.py (sanitization, file discovery, data-dir lookup, error paths, lazy-import failure message)
  • 610 total unit tests pass
  • ruff check clean
  • Verified agentdecompile-recover unity-export --help and both [unity]/[all] extras resolve cleanly via uv pip install --dry-run

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ros3797gzvmswnJudQ1Znk

New `unity-export` CLI subcommand (agentdecompile-recover unity-export
--install-root <dir> --out-dir <dir>) and src/agentdecompile_recovery/
unity_assets.py, adapted from a bounded-memory UnityPy-based export script
proven out on a large real-world title where AssetRipper's whole-graph
loading OOM'd (heavy Mesh/BlendShapeData).

Exports textures, sprites, audio clips, text assets, and fonts one object
at a time (freeing each immediately), so peak memory stays roughly
constant regardless of asset file size on disk -- unlike full
project-reconstruction tools that load the entire asset graph before
writing anything out. Deliberately does not attempt meshes/materials/
scene-prefab structure; that needs the fuller project-graph tooling this
module is not trying to replace.

UnityPy is optional (`pip install agentdecompile[unity]`, or via the
`[all]` extra) and imported lazily -- importing unity_assets never
requires it to be installed; a clear ImportError names the extra to
install if the CLI command is invoked without it.

Also fixed, discovered while running the test suite on this branch:
- tests/test_rewrite_queue.py's two multiprocessing concurrency tests
  failed under Python 3.14 even on Linux (PicklingError on a locally-
  nested function target) -- Python 3.14 changed the default
  multiprocessing start method away from fork on Linux too (previously
  only macOS defaulted away from fork). Forced multiprocessing.get_context
  ("fork") explicitly, same fix already shipped for the macOS-only case.
- source_parity_synthesize.py: removed an unused `.state.now` import
  (ruff F401), pre-existing and unrelated, blocking the lint CI step.

610 unit tests pass; ruff clean.
@bodencrouch
bodencrouch deleted the branch docs/ilspycmd-optional-dependency July 30, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant