acdream/docs/research/2026-04-26-chorizite-pr-draft.md
Erik 8db7a9ec28 docs(research): sky/weather investigation handoff + diagnostic tools
Captures everything learned from a long worktree iteration on the
foreground-rain bug (ISSUES.md #1 / #26) plus a new star-rendering
bug observed in the same area. The code work from that worktree
(WeatherDispatcher, EmitterDescLoader.LoadFromDat, WeatherCellRenderer,
GameWindow integration) was reverted because it didn't visibly fix
the rain bug — but the research findings + diagnostic tools are
durable and should not have to be rediscovered.

What's added:
- docs/research/2026-04-26-sky-investigation-handoff.md
  Comprehensive seed prompt for the next session. Covers:
  * Bug A: foreground rain (#26) — what's open, what's confirmed,
    what's been tried
  * Bug B: stars rendering as square in corner (NEW, user-observed)
  * 40-agent decomp scan findings — retail rain is NOT camera-
    particles, NOT server-driven, NOT screen-space; the mesh IS
    a hollow octagonal tube; only 5 weather GfxObjs in Dereth
  * Things ruled out by trial (envelope, scaling, unlit, depth-
    always alone, Setup loading)
  * Things to try next (depth+zfar combined, full render-state
    audit, frame ordering, star UV bug as easier first target)
  * Acceptance criteria for "done"

- docs/research/2026-04-26-chorizite-pr-draft.md
  Upstream PR draft for Chorizite/DatReaderWriter. Five generated
  DBObj source files reference nonexistent enum values and are
  silently excluded from the NuGet build:
  ParticleEmitterInfo, Clothing, PaletteSet, DataIdMapper,
  DualDataIdMapper. Fix: delete the duplicates. Independent of
  the rain work — benefits the AC modding ecosystem broadly.

- docs/research/2026-04-26-datreaderwriter-reference.md
  Developer reference for our DatReaderWriter usage. Version,
  types we consume, known broken types, thread-safety caveats,
  upgrade procedure, NuGet-vs-vendored decision matrix.

- tools/PesChainAudit/
  Recursive PES walker — given a 0x33xxxxxx script id, walks all
  CallPES references and dumps every hook + every referenced
  ParticleEmitter's parameters. Used to prove no weather PES
  emits rain particles.

- tools/TextureDump/
  Dumps texture pixel statistics (alpha histogram, brightness,
  max) and saves as PNG for visual inspection.

- tools/WeatherEnumerator/
  Enumerates every DayGroup in a Region, lists weather SkyObjects
  (Properties & 0x04), dumps GfxObj bounding boxes.

- tools/WeatherSetupProbe/
  Loads a Setup id, dumps each part's GfxObj + frame + scale +
  surface. Used to prove weather Setups are 5cm dummy carriers.

Worktree feature/sky-fixes is being deleted in a follow-up step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 21:40:34 +02:00

3.2 KiB
Raw Blame History

Upstream issue draft — Chorizite/DatReaderWriter

Repo: https://github.com/Chorizite/DatReaderWriter

This draft is for filing as a GitHub issue (or a 1-line-fix PR) against the Chorizite DatReaderWriter project. The duplicate generated file fails to build against its own enum and shadows the correct ParticleEmitter registration for the 0x32xxxxxx ID range.


Title (under 80 chars)

Duplicate ParticleEmitterInfo.generated.cs references missing DBObjType enum value

Summary

DatReaderWriter/Generated/DBObjs/ contains two generated files for the same DB type (DB_TYPE_PARTICLE_EMITTER, ID range 0x320000000x3200FFFF):

  • ParticleEmitter.generated.cs — class ParticleEmitter, uses DBObjType.ParticleEmitter (correct, matches the generated enum)
  • ParticleEmitterInfo.generated.cs — class ParticleEmitterInfo, uses DBObjType.ParticleEmitterInfo (does not exist in Generated/Enums/DBObjType.generated.cs)

The second file is byte-for-byte identical to the first apart from the class name and the enum reference. Only DBObjType.ParticleEmitter is emitted by the source generator (see line 179 of DBObjType.generated.cs), so the duplicate fails to compile and also registers a second [DBObjType(..., 0x32000000, 0x3200FFFF, ...)] attribute for the same ID range, which collides at runtime in PortalDatabase.Get<T>(uint id).

Reproduction

  1. Clone Chorizite/DatReaderWriter at master.
  2. dotnet build DatReaderWriter.sln
  3. Build fails in Generated/DBObjs/ParticleEmitterInfo.generated.cs on the DBObjType.ParticleEmitterInfo reference (CS0117: 'DBObjType' does not contain a definition for 'ParticleEmitterInfo').

If the file is hand-edited to compile (e.g. by switching the enum to ParticleEmitter), two classes are then registered for the same ID range 0x320000000x3200FFFF and Get<ParticleEmitterInfo>(id) / Get<ParticleEmitter>(id) ambiguously dispatch.

Expected behavior

A single generated class for DB_TYPE_PARTICLE_EMITTER. The PortalDatabase.generated.cs reader already exposes only GetParticleEmitter(uint id) returning ParticleEmitter?, so ParticleEmitter is the canonical name.

Actual behavior

ParticleEmitterInfo.generated.cs exists and breaks the build. It appears to be a stale artifact from an earlier pass of the source generator when the type was renamed ParticleEmitterInfo → ParticleEmitter.

Proposed fix (one line)

Delete DatReaderWriter/Generated/DBObjs/ParticleEmitterInfo.generated.cs. If the source generator regenerates it, the generator's type-name map needs the ParticleEmitterInfo entry removed too.

Why this matters to downstream consumers

Downstream consumers (e.g. acdream, an open-source modern AC client that vendors DatReaderWriter) cannot build the library as-is — we have to manually delete the duplicate file in our vendored copy on every update. Anyone trying to load 0x32xxxxxx records and reaching for ParticleEmitterInfo (the historical / decompiled-client name) hits a broken type instead of being directed at the renamed ParticleEmitter. A clean upstream fix removes the per-consumer patch.

Environment

  • Commit: master @ HEAD as of 2026-04-26
  • .NET SDK: 10.0
  • OS: Windows 11