Files
OpenMaidEngine/docs/PROJECT-STRUCTURE.md
gamer147 463877773c chore: initialize age-reimpl repo
Reverse-engineering + open reimplementation workspace for Eushully's AGE/SYS4
engine (first target: Himegari). The repo root is age-reimpl/; the original game
install and the extracted ALF data are siblings outside the repo and are never
tracked. build/ (derived corpora) is gitignored and regenerated by the tools.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 12:58:30 -04:00

97 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Project Structure
Layout for the *姫狩りダンジョンマイスター* (Himegari) → open AGE-engine reimplementation.
The guiding rule is **source vs. derived vs. our work**: the shipped game is read-only
input, the extracted archives and everything our tools generate are disposable/reproducible,
and our code + docs live entirely apart from the game install. Nothing we produce is ever
written back into the game folder.
Workspace root: `S:\Game Hacking\Eushully\Himegari\`
```
S:\Game Hacking\Eushully\Himegari\ ← workspace root (three siblings)
├── 姫狩りダンジョンマイスター/ ← SOURCE — pristine game install (read-only)
│ │ Never edit, move, or add to this folder. It holds ORIGINALS ONLY.
│ ├── AGE.EXE, AGERC.DLL, *.dll shipped engine (packed). Stays intact and
│ │ runnable in place — Frida launches it if needed.
│ ├── DATA1-5.ALF, APPEND01.ALF/.AAI shipped archives (~2.3 GB).
│ ├── *.BIN 52 loose patch-override scripts (v1.03) —
│ │ AUTHORITATIVE over their DATA1 copies. Plus
│ │ non-script indices (SYS4INI=S4IC, SYS4AB=S4AB).
│ └── *.exe (uninstallers), SAS0099.OGG … other shipped files.
├── extracted/ ← DERIVED (game-side) — extracted ALF contents,
│ │ ~3.9 GB, regenerable via age-reimpl/bin/BinExtractALF.
│ └── DATA1/ … DATA5/ DATA1 = 481 .BIN scripts (the corpus we parse)
│ + AGF/BMP/WAV in the others.
└── age-reimpl/ ← OUR WORK (everything we made lives here)
├── tools/ Python tooling (parser/disassembler + extractors + VM)
│ ├── paths.py ★ central path anchor — the ONLY place that knows
│ │ where the game / extracted / build dirs are. All
│ │ tools import it; relocatable with no other edits.
│ ├── sys4load.py loader + disassembler (opcode-decoding)
│ ├── age_opcodes.py 548-entry AGE opcode/arg-type table (pristine)
│ ├── age_opcodes_himegari.py inferred Himegari opcode-name overlay
│ ├── vm0.py headless Python VM (Phase A0); `--test` = RECOVER unit test
│ ├── extract_phase2.py batch: disasm + text + data extraction
│ ├── extract_init.py, global_map.py … *INIT parsers, global-var map builder
│ ├── validate_opcode_table*.py decode-coverage validators
│ └── probe_*.py format reverse-engineering probes (historical)
├── bin/ 3rd-party binaries we use (not ours, not the game's)
│ ├── BinExtractALF.exe ALF archive extractor → produces extracted/
│ └── LzssCpp.dll its LZSS codec dependency
├── vm-map/ VM / reverse-engineering reference artifacts
│ ├── opcodes-himegari.json validated opcode table (what this game uses)
│ ├── kelebek1-age-shared.cpp / -disassembler.cpp upstream opcode-table source
│ └── opcode-leads.json, small-script-listings.md, himegari-opcode-notes.md
├── docs/ all documentation
│ ├── PROJECT-STRUCTURE.md this file
│ ├── remake-architecture-and-roadmap.md THE direction doc (phases AE)
│ ├── phase-a-slice-plan.md the current slice (A0/A1/A2)
│ ├── vm-mapping-plan.md the phased decode plan
│ ├── himegari-port-reference.md master reference + engine background
│ ├── name-resolution.md call-script + global-var name recovery
│ ├── sys4-format-notes.md byte-level container format
│ └── script-inventory.md what the 481 scripts are
├── build/ DERIVED (our-work-side) — generated by tools/; disposable
│ ├── disasm/ <NAME>.asm — human-readable disassembly, one per script
│ ├── text/ extracted text:
│ │ ├── <NAME>.strings.txt all inline strings in a script
│ │ ├── dialogue.jsonl show-text lines only (the translation corpus)
│ │ └── strings.jsonl every string, tagged by source opcode
│ ├── data/ parsed data tables (*INIT → JSON)
│ ├── scripts-json/ machine-readable full dumps (on demand via --json)
│ ├── global-var-map.{json,md} partial global-variable name map
│ └── manifest.json, opcode-coverage.md
└── godot/ DELIVERABLE — the Godot/C# engine project (built in Phase A2+)
```
## Conventions
- **Three-way separation.** `姫狩りダンジョンマイスター/` = untouched originals; `extracted/` =
game-derived data (regenerable, game-side); `age-reimpl/` = everything we authored. The first two
are consumed, never modified.
- **Tools never hard-code paths.** `tools/paths.py` derives `GAME_DIR`, `EXTRACTED`, `DATA1`,
`BUILD`, etc. from its own location. To point the tools at a different install, edit that one file.
The whole tree can be relocated without touching any other tool.
- **Path references in docs** are `age-reimpl/`-relative (e.g. `tools/sys4load.py`,
`build/text/dialogue.jsonl`) unless they name a game/extracted path explicitly.
- **Authoritative script copies:** where a script exists both as a loose `.BIN` in the game folder
and under `extracted/DATA1/`, the game-folder copy (patch v1.03) wins. `paths.scripts()` resolves
this automatically (overrides win).
- **`build/` and `extracted/` are disposable.** `build/` regenerates via `tools/extract_phase2.py`
(or `sys4load.py`); `extracted/` regenerates via `bin/BinExtractALF.exe` on the `.ALF` files.
Safe to delete and rebuild; do not hand-edit.
- **Encoding:** all generated text is UTF-8 (source strings are cp932/Shift-JIS, decoded on
extraction). Run Python as `py -3.11 -X utf8`.
- **The game install is a runnable unit** — do not relocate `AGE.EXE`/`*.ALF`/DLLs relative to each
other, or the game (and any Frida work) breaks.