diff --git a/docs/engine-re.md b/docs/engine-re.md index 59113dc..cc61649 100644 --- a/docs/engine-re.md +++ b/docs/engine-re.md @@ -3048,9 +3048,8 @@ The distinction comes from the reference launch path, not the script preset. `AG hard-coded `MS Gothic` family strings. The comparison screenshots therefore show the patch-wrapper realization of AGE's Mincho request as bold MS Gothic, not true unwrapped native rendering. `windows-gdi-gray4` remains the correct native-default path because it reproduces AGE's authored Mincho -request directly. A future launch/profile parameter may optionally override the realized face to reproduce -wrapper-specific environments, but that is compatibility configuration rather than a native-fidelity -correction and is not current work. +request directly. Wrapper-specific realized-face substitution is outside the native-AGE compatibility target; +no launch/profile override is planned for it. `ImmediateSurfaceTextRenderer` builds the complete CP932 request list before touching the destination, making an unsupported character an atomic fallback rather than a partially rasterized string. It applies diff --git a/docs/platform-portability.md b/docs/platform-portability.md index 7aaa110..07ec0ad 100644 --- a/docs/platform-portability.md +++ b/docs/platform-portability.md @@ -164,6 +164,20 @@ Code signing, an installer, Windows-on-Linux execution, and retroactively modify `v0.1.0` release are outside this effort. A future signing slice can use `osslsigncode` and protected credentials without changing how the unsigned portable ZIP is assembled. +### Deferred Linux font-bundling follow-up (2026-08-11) + +The current Linux package deliberately retains its explicit Japanese-capable system-font prerequisite; no font +binary or package behavior changes in this follow-up record. When this work resumes, the preferred first candidate +is an unmodified, pinned upstream set of four region-specific Noto JP static OTFs: Serif Regular/Bold for authored +Mincho requests and Sans Regular/Bold for Gothic requests. Bundled files should be loaded ahead of the existing +`SystemFont` substitutions while retaining system fallback for additional mod-authored Unicode. + +The implementation slice must pin upstream versions and hashes, include the SIL Open Font License and attribution, +extend package membership/build provenance, and smoke both weights/families plus missing-glyph fallback from the +final archive. Variable fonts remain a size-optimization alternative only after TextServer weight-axis behavior is +validated. Game-corpus-only subsetting is not the default because it would constrain first-class modding and name +entry. The system-font-only policy remains supported until the bundled-font option is deliberately selected. + ## Dependency inventory | Area | Current dependency | Runtime impact | Portability status / future action | @@ -173,7 +187,7 @@ without changing how the unsigned portable ZIP is assembled. | AGE movie decode (`0x236` scene movies; `0x20f` modal LOGO/OP/ED; `0x24d` movie masks) | `FfmpegMovieDecoder` is the sole factory over the project-owned `native/age_movie_ffmpeg` ABI | Windows-x64 and Linux-x64 both pass the complete 213-payload installed video/audio corpus gate. The Linux library bundle is present in a validated Godot export; Windows also passes audible LOGO/OP/CHAPTER playback and real TEST.AGF green-mask decode | Add macOS native builds, distributable source-offer packaging, and real Linux/macOS window/audio movie gates | | Movie integration | Each surface owns a unique playback-instance id; `MovieRuntime` owns `IMovieDecoder` from an injected factory; video-only streams use monotonic pacing while audio-bearing streams use the Godot output clock. Opcode `0x24d` redirects decoded green bytes through the platform-neutral retained rasterizer and exact managed packed-alpha mask helper | Concurrent/restarted uses of one asset have independent frame/audio/completion/teardown state. Ordinary and mask movies share VFS/FFmpeg ownership; the mask result is a backend-neutral dynamic RGBA surface consumed by either Godot renderer. Managed code is no longer Windows-annotated, and target-aware builds stage either the win-x64 or Linux-x64 native bundle | Add macOS native builds and Linux/macOS in-engine smoke gates | | Movie audio | ABI v2 returns timestamped stereo float PCM; bounded managed buffering feeds a per-playback Godot `AudioStreamGenerator` and routes native movie flags to engine buses | All 29 installed audio-bearing streams decode with signal; synchronized LOGO/OP/CHAPTER playback is audibly accepted | Treat absent, distorted, or unsynchronized audio from an audio-bearing movie as a runtime bug | -| ADV font discovery/raster fidelity | `Age.Engine.Text` remains OS-neutral. On compatible ACP-932 Windows, `auto` selects the separate exact-to-request `Age.Engine.Text.Windows` GDI gray-4 backend. Otherwise Godot TextServer supplies Unicode masks and metrics from ordered system-font substitutions in `godot/config/himegari-text-rendering.json`; this policy is explicitly not GDI pixel-exact. Immediate `0x204`/`0x205`, live ADV, retained History, and the wait atlas all enter ordinary RGBA surfaces/retained handles | Three Mincho/Gothic regular/bold samples byte-match an independent Unicode GDI oracle. A live `SC0000@0x869` trace proves that the `AGE Patch.exe`/`jprun.dll` wrapper overrides authored Mincho to MS Gothic: 13 captured masks match Gothic byte-for-byte and Mincho 0/13. This is wrapper behavior, not the true-native default. Forced exact and forced portable self-tests cover immediate, live, and History rasterization, bounded caching, complete-line materialization, retained ordering, alpha/tint/fade, transforms, clipping, capture, HIDEWIN suspension, partial erase/republication, reset, and teardown. Gameplay `Label` pools and overlay projection are gone | Optionally expose realized-face overrides through future launch profiles when wrapper compatibility is desired; independently produce and smoke-test Linux/macOS exports, confirm installed family availability/fallback selection there, and keep the GDI project out of non-Windows deliverables | +| ADV font discovery/raster fidelity | `Age.Engine.Text` remains OS-neutral. On compatible ACP-932 Windows, `auto` selects the separate exact-to-request `Age.Engine.Text.Windows` GDI gray-4 backend. Otherwise Godot TextServer supplies Unicode masks and metrics from ordered system-font substitutions in `godot/config/himegari-text-rendering.json`; this policy is explicitly not GDI pixel-exact. Immediate `0x204`/`0x205`, live ADV, retained History, and the wait atlas all enter ordinary RGBA surfaces/retained handles | Three Mincho/Gothic regular/bold samples byte-match an independent Unicode GDI oracle. A live `SC0000@0x869` trace proves that the `AGE Patch.exe`/`jprun.dll` wrapper overrides authored Mincho to MS Gothic: 13 captured masks match Gothic byte-for-byte and Mincho 0/13. This is wrapper behavior, not the true-native default, and reproducing it is outside the compatibility target. Forced exact and forced portable self-tests cover immediate, live, and History rasterization, bounded caching, complete-line materialization, retained ordering, alpha/tint/fade, transforms, clipping, capture, HIDEWIN suspension, partial erase/republication, reset, and teardown. Gameplay `Label` pools and overlay projection are gone | Select and smoke-test a redistributable Linux font-bundling policy or retain the explicit system-font prerequisite; add macOS runtime coverage and keep the GDI project out of non-Windows deliverables | | Filesystem semantics | Several filename and containment comparisons use `OrdinalIgnoreCase`; installed assets are conventionally uppercase | Needs validation on case-sensitive filesystems; may hide casing or containment mistakes | Add Linux/macOS tests with mixed-case synthetic roots and use filesystem-appropriate containment rules | | Save/profile/settings storage | `Sys4PersistencePaths` models AGE's independent `SAVEPATH` and `REGFILEPATH` resolutions. Godot replaces Himegari's related profile directory with `user://`, yielding `user://SAVE` for native S3SD/S4SD/S3RT files and thumbnails plus `user://SYS4REG.INI` for the BOM-less CP932 options file; the preserving writer changes only its nine `[sound]` keys | Save payloads and engine options are isolated together without changing either native format. Native/drop-in resolution remains available through `USEAPPDATAFOLDER` plus both SYS4INI paths. A single-root override is rejected when `SAVEPATH` is not beneath `REGFILEPATH`, preventing cross-profile guesses | Expose explicit profile/native selection through the future launcher and allow independent overrides for profiles whose two native paths are unrelated. Validate CP932 availability, replace/flush, case, permissions, and interrupted-write behavior on each export target | | Game-install, runtime metadata, and repository discovery | `GameRootSelection` accepts `--game-root`, then probes the executable directory and current working directory for `SYS4INI.BIN`; on Unix the frontend prefers inherited shell `PWD` because Godot may change the process directory during project startup. Godot injects the selected root into its catalog and loose-first ALF store. `Himegari.csproj` embeds generated `build/opcodes.json`, and the frontend loads that assembly resource rather than `Paths.OpcodesJson`. Development/test `Paths.cs` finds the repository by tracked `global.json`, solution, and opcode-map markers rather than a checkout-directory name | Installed game data and packaged VM metadata no longer depend on the workspace sibling layout. The Linux export passed an explicit absolute game root outside the repository and read the installed archives; a source-only core proof also passes from an arbitrary repository directory name. Exported automatic page maps use `user://diagnostics/page-maps`; editor/development runs preserve `build/page-map-.jsonl` | Let the future profile launcher pass `--game-root`, and run executable-directory/CWD plus case/permission smoke gates on Linux and macOS | diff --git a/docs/remake-architecture-and-roadmap.md b/docs/remake-architecture-and-roadmap.md index 9a890eb..8072e05 100644 --- a/docs/remake-architecture-and-roadmap.md +++ b/docs/remake-architecture-and-roadmap.md @@ -1192,8 +1192,8 @@ primitive, which cannot be made equivalent by choosing another embolden constant lighter-weight discrepancy: the `AGE Patch.exe`/`jprun.dll` reference launch realizes AGE's authored 24px bold Mincho request as `MS Gothic`. Thirteen intercepted masks match an independent Gothic request byte-for-byte and Mincho 0/13. That result is specific to the wrapper and does not supersede the true - native Mincho target; a realized-face override is optional launch-profile compatibility, not an - acceptance requirement for the exact backend. + native Mincho target. Reproducing that wrapper substitution is outside the native-AGE compatibility + target and no realized-face override is planned for it. This reference backend remains opt-in and is not yet connected to live presentation; the existing Label path therefore remains the current fallback. 4. **Move immediate surface strings first.** Completed 2026-07-30 for the exact Windows path. Ops @@ -1252,9 +1252,9 @@ primitive, which cannot be made equivalent by choosing another embolden constant neighbors, clipping, alpha, and RGB integer rounding. - On Windows, representative CP932 glyph masks, `GLYPHMETRICS`, and advances match a direct invocation of the decoded GDI request; tests compare returned data, not screenshot histograms. -- If wrapper compatibility is requested, a launch profile may override the realized face ahead of the - raster request. Himegari's `AGE Patch.exe`/`jprun.dll` path realizes 24px authored Mincho as MS Gothic, - but the true-native acceptance target remains the authored Mincho request. +- Himegari's `AGE Patch.exe`/`jprun.dll` path realizes 24px authored Mincho as MS Gothic, but that + third-party wrapper substitution is outside the compatibility target. The exact backend accepts the + authored Mincho request as native AGE does without the wrapper. - Surface-string tests prove text is occluded by later handles and inherits the bound object's alpha, tint, affine transform, source clipping, offscreen capture, and transition behavior in both render backends. - Retained-layout tests prove per-glyph handle order, capacity bounds, partial/full erase, reset/republication, @@ -1452,9 +1452,12 @@ layer's rendering diverges from ADV; save layout. --- ## 8. Immediate next step -The **codebase consolidation** maintenance slice is complete: ownership/layout cleanup, source-only Linux CI, -private-remote backup, binary and Kelebek-source history sanitation, attribution, and the MIT project license are -all established. Resume the planned **AGE-exact retained glyph-mask text renderer** polish slice, starting with -the platform-neutral glyph request/result contract and shared coverage/compositing core. Concrete playthrough -blockers may still preempt that work; do not change remote policy without the user's explicit direction. -The completed consolidation effort does not replace Phase B gameplay validation or the open cross-platform gates. +The **AGE-exact retained glyph-mask text renderer** and its portable TextServer backend are complete. The later +codebase-consolidation, Linux/Windows packaging, and dual-platform release-CI efforts are also complete through +`v0.2.0`. Resume **playthrough-led Phase B polish and native save-compatibility testing**; no decoded effectful +opcode gap remains in the shipped 481-script corpus. Use the next reproducible natural-playthrough discrepancy +to choose the concrete gameplay slice instead of returning to opcode-coverage work. + +The open portability gates remain separate follow-ups: deliberately mixed-case synthetic roots, fresh-profile +save/settings writes, native Linux desktop coverage, shared movie A/V synchronization, and a deliberate Linux +font-bundling policy. Do not change remote or release policy without the user's explicit direction.