mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-13 04:29:30 -04:00
9c29824f38
Unblocks the rest of the migration. soh.o2r is produced by ZAPD via OTRExporter/extract_assets.py, both of which this migration deletes; its replacement is a small in-tree packer that has to reproduce ZAPD's texture quantisation exactly. Rather than block Phases 2/3/5 on that packer, check the archive in and make GenerateSohOtr a copy. The archive doubles as Phase 4's acceptance oracle -- the packer is correct when its output matches this entry-for-entry -- which is strictly more useful than Gate E's planned manifest of hashes of it. Generation turns out to be content-deterministic but NOT byte- deterministic: two runs give identical payloads for all 1,042 entries but different file hashes, because zip stores per-entry timestamps. So the Phase 4 comparison must be entry-wise; whole-file would fail even on a correct archive. Recorded in prebuilt/README.md. Adds a configure-time guard on the baked-in portVersion. OTRGlobals.cpp :283 requires exact major.minor.patch equality and RunExtract exit(1)s with "soh.o2r is outdated", which is an opaque symptom for a stale checked-in file; verified the guard fires by building against 9.2.4. ExtractAssets, CI and copy-existing-otrs.cmake are deliberately untouched -- ExtractAssets still generates a correct archive while ZAPD exists, and the CI job keeps working since it just builds this target.
88 lines
4.2 KiB
Markdown
88 lines
4.2 KiB
Markdown
# Prebuilt `soh.o2r` — **temporary**
|
|
|
|
This directory exists to unblock the Torch migration and is **meant to be deleted**.
|
|
|
|
`soh.o2r` is the port's own asset archive: fonts, textures, presets, translations, shaders —
|
|
everything under `soh/assets/custom/`, plus a `portVersion` stamp. It is built by
|
|
`GenerateSohOtr`, which today drives ZAPD through `OTRExporter/extract_assets.py`. The migration
|
|
deletes ZAPDTR and OTRExporter, so that producer goes away and its replacement — a small in-tree
|
|
packer (Phase 4 of `torch-migration/PLAN.md`) — has to reproduce it byte-for-byte, including
|
|
ZAPD's specific texture quantisation.
|
|
|
|
Rather than block every other phase on that packer, the archive is checked in here and
|
|
`GenerateSohOtr` just copies it into place. **Phases 2, 3 and 5 become testable without the
|
|
packer existing.**
|
|
|
|
This file also serves as Phase 4's acceptance oracle: the packer is correct when its output
|
|
matches this archive entry-for-entry. That replaces Gate E's planned sha256 manifest — the
|
|
artifact is strictly more useful than a list of hashes of it.
|
|
|
|
## Provenance
|
|
|
|
| | |
|
|
|---|---|
|
|
| Generated | 2026-07-25 |
|
|
| Shipwright branch | `torch-migration` @ `fe2f52248` |
|
|
| `develop` at the time | `c4e92a70f` (inputs verified identical — `git diff develop HEAD -- soh/assets/custom libultraship CMakeLists.txt` was empty) |
|
|
| libultraship submodule | `c57da1b4` |
|
|
| `CMAKE_PROJECT_VERSION` | `9.2.3` |
|
|
| Producer | `cmake --build build --target GenerateSohOtr` (ZAPD `botr -se OTR --norom`) |
|
|
| Size / entries | 4,414,957 bytes / 1,042 entries (1,038 checked-in assets + 3 LUS shaders + `portVersion`) |
|
|
| sha256 | `1d23b582fbc29cebf803b6ee54856089d0978e5496e6d4b1dbcde876e13cf13c` |
|
|
| sha256 of inputs | `de8ba0b5167bec6956258dd0445d01ac0f6daac84aff091c678d951cc72598f6` |
|
|
|
|
The input hash covers every file under `soh/assets/custom/` except `shaders/`, which is not
|
|
checked in — it is copied out of `libultraship/src/fast/shaders/` at generation time. Recompute it
|
|
with:
|
|
|
|
```sh
|
|
find soh/assets/custom -type f -not -path '*/shaders/*' -print0 | sort -z \
|
|
| xargs -0 sha256sum | sha256sum
|
|
```
|
|
|
|
(`-print0`/`sort -z` are required: several preset filenames contain spaces.)
|
|
|
|
## Generation is content-deterministic, not byte-deterministic
|
|
|
|
Two consecutive runs produce archives with **identical payloads for all 1,042 entries** but
|
|
**different whole-file hashes** — the zip stores a modification timestamp per entry. So:
|
|
|
|
- The sha256 above identifies *this* file, not "any correct archive".
|
|
- **Phase 4's acceptance test must compare entry-by-entry**, never whole-file. A byte-identical
|
|
archive is not achievable and not the goal.
|
|
|
|
## What this pins
|
|
|
|
The archive freezes three inputs. If any changes while this workaround is in place, the checked-in
|
|
copy is stale and **nothing will tell you at runtime** except missing or wrong assets:
|
|
|
|
1. **`soh/assets/custom/`** — edit an asset and your change is silently ignored. Compare the input
|
|
hash above.
|
|
2. **libultraship's shaders** — `libultraship/src/fast/shaders/` is copied in at generation time,
|
|
so a LUS submodule bump can drift the three shaders inside this archive.
|
|
3. **The project version.** `portVersion` here is `9.2.3`. `OTRGlobals.cpp:283` requires exact
|
|
`major.minor.patch` equality against the build's version, and `RunExtract` calls `exit(1)` with
|
|
"soh.o2r is outdated" if it fails. A configure-time check in the root `CMakeLists.txt` catches
|
|
this and tells you to regenerate, because the runtime symptom is not obvious.
|
|
|
|
## Regenerating
|
|
|
|
From a tree where ZAPDTR/OTRExporter still build (i.e. `develop`):
|
|
|
|
```sh
|
|
cmake --build build --target GenerateSohOtr
|
|
cp soh.o2r prebuilt/soh.o2r
|
|
```
|
|
|
|
Then update the provenance table above.
|
|
|
|
## Removing this
|
|
|
|
When Phase 4's packer lands and its output matches this archive entry-for-entry, delete this
|
|
directory, drop the `!prebuilt/soh.o2r` negation from `.gitignore`, and restore `GenerateSohOtr`
|
|
to a real build step (including the libultraship shader copy, which the copy-only version skips).
|
|
|
|
**Delete it before the migration PR merges** if at all possible. It is a 4.4 MB binary, and a blob
|
|
that reaches `develop` is in the history permanently; removed in the final tree and squash-merged,
|
|
it never lands there at all.
|