The uncommitted uTint=AmbientColor-for-alpha-submeshes experiment (from
the 2026-04-22 inference) dimmed the sky dome's baked gradient — a
user-verified visual regression. Reverting to the eeae83a baseline
(uTint=Vector4.One for every submesh) while we execute the proper
retail-verbatim port.
Research: three parallel decompile-hunt agents landed verifying
retail's ground-truth sky pipeline for the first time (prior audits
searched for stripped symbol names; the trail opened via the Region
dat-type-index 0x1c registration at chunk_00410000.c:12952). Key
retail functions now mapped in chunk_00500000.c:1097-7535:
- FUN_00501530: keyframe bracket-picker (with 1.0f wrap denominator)
- FUN_00501600: sun+ambient interpolator (sunVec = DirBright ×
(sin yaw·cos pit, cos yaw·cos pit, sin pit))
- FUN_00501860: fog interpolator
- FUN_00502820: SkyDesc::Unpack (2 doubles + DayGroup list)
- FUN_00502a10: build per-frame sky-object table
- FUN_00505f30: apply light state + per-cell AdjustPlanes relight
- FUN_005062e0: per-frame sky tick (throttled by LightTickSize)
- FUN_00508010: sky-object render loop (enqueues through the NORMAL
mesh pipeline via FUN_00514b90 — not a bespoke path)
Surprise findings:
- D3DRS_AMBIENT is set to 0 once at init and NEVER changes per-frame
(chunk_005A0000.c). The r12-inferred "clouds = texture × D3DRS_
AMBIENT" formula is falsified. Retail instead routes keyframe
AmbColor through per-vertex lighting on non-Luminous sky meshes
via _DAT_008682bc/c0/c4.
- Retail does NOT anchor the sky to the camera or use a separate
sky projection. Sky meshes live in world space and follow the
camera via scene-graph parent.
- FUN_00532440 (AdjustPlanes) re-lights every terrain cell on every
keyframe tick — the "terrain follows the sky" effect we don't yet
reproduce.
Phase 1 code change (this commit):
- src/AcDream.App/Rendering/Sky/SkyRenderer.cs: revert uTint to white
for all submeshes (the per-submesh blend split stays — sun gets
additive, clouds get alpha). Keep the `keyframe` parameter in the
signature for Phase 2 readiness. Comments now cite the retail
functions and reference docs instead of the (disproven) r12 formula.
- src/AcDream.Core/World/SkyDescLoader.cs: ACDREAM_DUMP_SKY=1 logs
the entire Region SkyDesc on load — DayGroups, SkyObjects, every
SkyTimeOfDay keyframe, and every SkyObjectReplace with RAW pre-/100
Transparent/Luminosity/MaxBright values so we can settle the unit
question empirically.
- src/AcDream.App/Rendering/Sky/SkyRenderer.cs: ACDREAM_DUMP_SKY=1
additionally logs each sky GfxObj's Surfaces and their SurfaceType
flags on first load, so we can identify which meshes carry the
Luminous bit (dome? sun? moon? stars?) vs which are lit.
- src/AcDream.App/Rendering/GameWindow.cs: passes the interpolated
keyframe to the sky renderer (kept — needed for Phase 2).
Research docs (pushed as part of this commit):
- docs/research/2026-04-23-sky-retail-verbatim.md: full synthesis
with retail function map, struct layouts, globals, pseudocode, and
a 4-phase port plan.
- docs/research/2026-04-23-sky-decompile-hunt-{A,B,C}.md: raw hunt
outputs.
- docs/research/2026-04-23-sky-references-crossref.md: WorldBuilder/
ACE/ACViewer/holtburger/Chorizite coverage.
- docs/research/2026-04-23-sky-dat-schema.md: full dat schema + unit
analysis.
- docs/research/2026-04-22-sky-lighting-decompile.md: prior agent's
(superseded) inference — kept for provenance.
Phase 2 will port Surface.Luminous-flag-aware per-vertex lighting for
sky submeshes once the dump resolves the open questions (Luminous-flag
distribution per Dereth sky mesh; _DAT_007a1870 scale constant value).
Build + 717 tests green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
20 KiB
Sky DAT Schema — Full Map
Date: 2026-04-23
Scope: Every field in the retail Region→SkyDesc→DayGroup→SkyObject/SkyTimeOfDay tree, with units, comments, and cross-references. Covers SurfaceType flags and the acdream interpretation.
Purpose: Pre-port audit. No code changes.
Sources: DatReaderWriter auto-generated Ghidra-parsed types; ACE; ACViewer; WorldBuilder. Retail decompile (docs/research/decompiled/chunk_*.c) has NO sky-related matches (confirmed in prior audit, 2026-04-21-sky-deep-audit.md:9-15).
1. Structure Tree
Region (DB_TYPE_REGION, 0x13000000–0x1300FFFF)
├── RegionNumber : uint32 // internal ID
├── Version : uint32
├── RegionName : PString
├── LandDefs, GameTime, PartsMask, SoundInfo, SceneInfo, TerrainInfo, RegionMisc
└── SkyInfo : SkyDesc (only if PartsMask has HasSkyInfo)
SkyDesc
├── TickSize : double // seconds per game-tick (day length unit)
├── LightTickSize : double // seconds per lighting update tick
└── DayGroups : List<DayGroup>
DayGroup
├── ChanceOfOccur : float // weight in [0, 1] for PDF rolling
├── DayName : PString // e.g. "Clear", "Sunny" — internal-only label
├── SkyObjects : List<SkyObject> // celestial meshes (sun/moon/clouds/...)
└── SkyTime : List<SkyTimeOfDay> // keyframes through the day
SkyObject // ONE celestial layer
├── BeginTime : float // [0, 1] day-fraction visibility start
├── EndTime : float // [0, 1] day-fraction visibility end; wraps if End<Begin
├── BeginAngle : float // degrees arc-start
├── EndAngle : float // degrees arc-end; lerped across [BeginTime,EndTime]
├── TexVelocityX : float // UV scroll speed along U (per-second)
├── TexVelocityY : float // UV scroll speed along V
├── DefaultGfxObjectId: QualifiedDataId<GfxObj> // the mesh (0 = hidden)
├── DefaultPesObjectId: QualifiedDataId<PhysicsScript> // optional particle emitter
└── Properties : uint32 // flag bits (billboard? follow-camera? — not decoded)
SkyTimeOfDay // ONE keyframe at time T
├── Begin : float // [0, 1] when this keyframe becomes the "active" interpolant
├── DirBright : float // sun intensity multiplier (unit unspecified; typically 0..~1.5)
├── DirHeading : float // sun compass heading (degrees; 0=N, 90=E, …)
├── DirPitch : float // sun elevation above horizon (degrees; -90..+90)
├── DirColor : ColorARGB // sun RGB, bytes 0..255 each
├── AmbBright : float // ambient intensity multiplier
├── AmbColor : ColorARGB // ambient RGB, bytes 0..255 each
├── MinWorldFog : float // meters — fog starts
├── MaxWorldFog : float // meters — fog saturates
├── WorldFogColor : ColorARGB // fog tint, bytes 0..255 each
├── WorldFog : uint32 // mode enum: 0=off, 1=D3DFOG_LINEAR, 2=exp, 3=exp2
└── SkyObjReplace : List<SkyObjectReplace>
SkyObjectReplace // per-keyframe override of one SkyObject
├── ObjectIndex : uint32 // index into owning DayGroup.SkyObjects
├── GfxObjId : QualifiedDataId<GfxObj> // mesh override (0 = keep default)
├── Rotate : float // heading override — **degrees**
├── Transparent : float // UNIT DISPUTED — see §4
├── Luminosity : float // UNIT DISPUTED — see §4
└── MaxBright : float // UNIT DISPUTED — see §4
File citations: references/DatReaderWriter/DatReaderWriter/Generated/DBObjs/Region.generated.cs:27-67, Types/SkyDesc.generated.cs:23-30, Types/DayGroup.generated.cs:23-31, Types/SkyObject.generated.cs:23-41, Types/SkyTimeOfDay.generated.cs:23-47, Types/SkyObjectReplace.generated.cs:23-35.
2. Field Table with Units & Sources
| Field | Type | Unit / Range | Comment source | Example |
|---|---|---|---|---|
SkyDesc.TickSize |
double | seconds? | none in generator | 1.0 in test fixture (tests/AcDream.Core.Tests/World/SkyDescLoaderTests.cs:26) |
SkyDesc.LightTickSize |
double | seconds? | none | 2.0 in test fixture (same) |
DayGroup.ChanceOfOccur |
float | probability weight [0,1]? | none; r12 §11 describes PDF use (docs/research/deepdives/r12-weather-daynight.md:544) |
1.0 |
DayGroup.DayName |
PString | UTF-8 | none | "Sunny" (memory; diag dump referenced in SkyDescLoader.cs:253) |
SkyObject.BeginTime |
float | day-fraction [0,1] | r12 deepdive §2 "normalized day-time" (deepdives/r12-weather-daynight.md:161) |
0.0 (always-visible dome) |
SkyObject.EndTime |
float | day-fraction [0,1]; Begin==End → always visible; Begin>End → wraps midnight | our SkyDescLoader.cs:46-52 encodes this; matches WorldBuilder SkyboxRenderManager.cs:188-197 |
1.0, 0.25 |
SkyObject.BeginAngle |
float | degrees | r12 §2 "where on the sky arc" | 0° |
SkyObject.EndAngle |
float | degrees | r12 §2 lerped linearly | 360° |
SkyObject.TexVelocityX |
float | UV/second | r12 §2.1 "UV scroll rate — cloud drift, star twinkle" | ~0.001 typical |
SkyObject.TexVelocityY |
float | UV/second | same | ~0.001 |
SkyObject.DefaultGfxObjectId |
QualifiedDataId | dat-ID; 0=hidden | none | 0x01000XYZ typical |
SkyObject.DefaultPesObjectId |
QualifiedDataId | dat-ID; 0=none | r12 §2.1 "unused at top" | 0 |
SkyObject.Properties |
uint32 | flag bits | not decoded in references; our code ignores | 0 |
SkyTimeOfDay.Begin |
float | day-fraction [0,1] | our SkyState.cs:45 "day-fraction this keyframe kicks in" |
0.0, 0.25, 0.5, 0.75 typical |
SkyTimeOfDay.DirBright |
float | multiplier, > 1 legal | our SkyState.cs:40-42 "channels above 1.0 and the frag shader clamps" |
1.5 in test |
SkyTimeOfDay.DirHeading |
float | compass degrees, 0=N clockwise | r12 §3 (deepdives/r12-weather-daynight.md:262) |
180° at noon |
SkyTimeOfDay.DirPitch |
float | degrees, -90..+90 from horizontal | r12 §3 | 70° at noon |
SkyTimeOfDay.DirColor |
ColorARGB | 4×byte BGRA-packed in file | ColorARGB.generated.cs:27-45 "0-255" |
{R=255,G=250,B=220} at noon |
SkyTimeOfDay.AmbBright |
float | multiplier | none; same semantics as DirBright | 0.4 in test |
SkyTimeOfDay.AmbColor |
ColorARGB | 4×byte BGRA | same | noon ~(82,82,89) |
SkyTimeOfDay.MinWorldFog |
float | meters | r12 §5.1 (deepdives/r12-weather-daynight.md:346) |
120 |
SkyTimeOfDay.MaxWorldFog |
float | meters | r12 §5.1 | 350 |
SkyTimeOfDay.WorldFogColor |
ColorARGB | 4×byte BGRA | none | similar to horizon band |
SkyTimeOfDay.WorldFog |
uint32 | D3D fog mode: 0 off, 1 linear, 2 exp, 3 exp2 | r12 §5.1 "D3DFOG_LINEAR, etc" (line 349) | 1 (linear) |
SkyObjectReplace.ObjectIndex |
uint32 | index into DayGroup.SkyObjects | none | 0..6 |
SkyObjectReplace.GfxObjId |
QualifiedDataId | dat ID; 0 = keep default | r12 §2.3 "swap mesh" | 0x01000... or 0 |
SkyObjectReplace.Rotate |
float | degrees heading override | tested in SkyDescLoader.cs:260-263: "270° values in the data are genuinely heading-degrees, not percentages" |
270 observed |
SkyObjectReplace.Transparent |
float | UNIT UNCONFIRMED — see §4 | none | values up to 100 observed in acdream diag dump |
SkyObjectReplace.Luminosity |
float | UNIT UNCONFIRMED — see §4 | none | values up to 100 observed |
SkyObjectReplace.MaxBright |
float | UNIT UNCONFIRMED — see §4 | none | values up to 100 observed |
Note on ColorARGB: the wire/byte order is B, G, R, A per ColorARGB.generated.cs:49-52; the member names are semantic (Red=red channel 0..255 regardless of file byte position). Our loader's ColorToVec3 at SkyDescLoader.cs:311-315 uses the semantic .Red/.Green/.Blue / 255f which is correct.
3. SurfaceType Enum (full)
From references/DatReaderWriter/DatReaderWriter/Generated/Enums/SurfaceType.generated.cs:13-41 (cross-checked dats.xml:744-758). Flags, parent uint:
| Name | Value | Notes / inferred meaning |
|---|---|---|
Base1Solid |
0x00000001 |
Surface is a flat color (no texture); Surface.ColorValue field populated |
Base1Image |
0x00000002 |
Surface has a texture (SurfaceTexture DataId) |
Base1ClipMap |
0x00000004 |
Alpha-keyed texture; fragment shader discards low-alpha pixels |
Translucent |
0x00000010 |
Implies standard alpha blending |
Diffuse |
0x00000020 |
Receives diffuse lighting (default state for most surfaces) |
Luminous |
0x00000040 |
Self-illuminated / unshaded — NOT additive blend; see §5 |
Alpha |
0x00000100 |
Explicit alpha blend |
InvAlpha |
0x00000200 |
Inverted alpha blend (rare) |
Additive |
0x00010000 |
Additive blend (sun, glow, particle) |
Detail |
0x00020000 |
Detail texture layer |
Gouraud |
0x10000000 |
Gouraud shading (vs. flat) |
Stippled |
0x40000000 |
Stipple pattern (AC-era hardware dithering) |
Perspective |
0x80000000 |
Perspective-correct texturing |
Our TranslucencyKind.FromSurfaceType at src/AcDream.Core/Meshing/TranslucencyKind.cs:61-74 maps these to blend modes:
Additive(0x10000) →TranslucencyKind.Additive(src,one blend)InvAlpha(0x200) →TranslucencyKind.InvAlphaAlpha | Translucent(0x100 | 0x10) →TranslucencyKind.AlphaBlend(src_alpha, one_minus_src_alpha)Base1ClipMap(0x04) →TranslucencyKind.ClipMap(opaque draw, fragment discard)- else →
Opaque
Luminous (0x40) is not mapped to any translucency category — it's a lighting hint, not a blend mode. The code comment at SkyRenderer.cs:345-350 documents a past bug where we treated Luminous as additive and "blew the whole sky to white." That call is consistent with ACE/ACViewer usage (Luminous sets OrigLuminosity on the PhysicsPart.Surface; see references/ACViewer/ACViewer/Physics/Common/Surface.cs:15-19).
No generator comments in Chorizite.ACProtocol (it has no dat-surface types — it's network-message-only). No explicit "SrcBlend/DestBlend" comments anywhere in the references.
4. acdream SkyDescLoader vs Dat Reality — What's Likely Right / Wrong
Likely correct
ColorARGB→Vector3/255f(SkyDescLoader.cs:311-315) — matches the generator comment "0-255" on each channel.- Sun/Amb color pre-multiplied by bright (
SkyDescLoader.cs:289-291) — matches r12 §4 formula (deepdives/r12-weather-daynight.md:307-309); test pins this (SkyDescLoaderTests.cs:84). WorldFogenum mapping (SkyDescLoader.cs:278-284) — matches r12 §5.1 (D3DFOG_LINEAR = 1, exp = 2, exp2 = 3).- Visibility / arc-progress wrap logic (
SkyDescLoader.cs:46-76) — matches WorldBuilderSkyboxRenderManager.cs:188-240line-by-line. Rotatekept as degrees (SkyDescLoader.cs:260) — confirmed by our own observation that diag values of 270 are headings.
Likely WRONG: the /100 on Transparent / Luminosity / MaxBright
This is the load-bearing speculative decision.
Code: SkyDescLoader.cs:273-275 divides all three by 100. The comment at 249-267 claims "confirmed from live diag dump … have Luminosity=100 and Transparent=100" — but there is NO supporting evidence anywhere else in the references:
- DatReaderWriter generator has no comment on those three fields (
SkyObjectReplace.generated.cs:28-34). UnlikeSurface.Luminositywhich is documented as "Self-illumination / emissive strength" and used as a 0..1 fraction in the test fixture (SurfaceTests.cs:27, value0.3f), theSkyObjectReplacefields have no generator comment. - ACE's
SkyObjectReplace.cs:10-12defines them asfloatwith no unit comment. - ACViewer just displays them raw as
"Transparent: {value}"without transform (references/ACViewer/ACViewer/Entity/SkyObjectReplace.cs:35-48). - WorldBuilder doesn't use them at all —
SkyboxRenderManager.cs:180-264ignoresTransparent/Luminosity/MaxBrightentirely. So WorldBuilder gives us zero evidence either way about units. - No decompile data:
docs/research/decompiled/chunk_*.chas no matches for sky/SkyObject/Luminosity (confirmed in the prior audit2026-04-21-sky-deep-audit.md:9-15). - Our existing Surface.Luminosity uses a fraction (test shows 0.3f), so there's a strong cross-field analogy that
SkyObjectReplace.Luminosityis also a fraction, not a percentage. - Our own commit
eeae83aadded the /100 based on a live diag dump — but we don't have the raw dump file indocs/research/and the prior audit2026-04-22-sky-lighting-decompile.md:130-135observed "Diag shows luminosity values max at 0.78 (not > 1)" — which is already in the 0..1 range before any /100 transform.
Status: SPECULATIVE. Two conflicting claims in our own codebase:
SkyDescLoader.cs:253-257: "noon keyframes have Luminosity=100 and Transparent=100" (said to justify /100).- Prior audit
2026-04-22-sky-lighting-decompile.md:143: "luminosity values max at 0.78".
These cannot both be true for the same dat. At least one of those observation logs is incorrect — or they were looking at different fields.
Recommendation for the next decompile pass: capture a fresh raw-bytes dump of one DayGroup's SkyTimeOfDay.SkyObjReplace list from the live Dereth dat (region 0x13000000), print as hex + parsed float, and pin the unit empirically. Until then, treat the /100 as "best guess based on one diag observation" rather than a confirmed fact.
Fields we IGNORE that the dat has
SkyObject.Properties(uint32 flag bits) — we read it intoSkyObjectData.Propertiesbut never consult it. Retail-faithful rendering probably reads one of these bits for billboard-vs-mesh orientation.SkyObject.DefaultPesObjectId— we never load the PhysicsScript; retail probably attaches it as a rain/snow particle emitter (r12 §6.1,deepdives/r12-weather-daynight.md:423-426).SkyTimeOfDay.WorldFog(currently mapped toFogModebut unused past loading — we don't switch between linear/exp/exp2 per keyframe in our shader).SkyDesc.TickSize/LightTickSize— loaded but not consulted; retail uses these for the lighting-update quantisation rate.
5. The 7 Sky Objects (Dereth DayGroup)
The SkyDescLoader.cs code comment asserts there are 7 sky objects per DayGroup. r12 deepdive (deepdives/r12-weather-daynight.md:235-237) says "roughly 4–6 sky objects (one background, one cloud sheet, one sun, one moon, one star sheet)".
Without a fresh diag dump, we cannot positively assign GfxObjId → role.
What we can say from the primary-day-group pattern and the pipeline:
| Index | Expected role | BeginTime/EndTime pattern | Mesh shape | Blend |
|---|---|---|---|---|
| 0 | Sky dome / gradient background | Begin==End (always visible) | Large hemisphere with baked gradient in V | AlphaBlend or Opaque |
| 1 | Cloud layer (upper) | Begin==End (always) | Large hemisphere with cloud texture, UV-scrolled | AlphaBlend |
| 2 | Cloud layer (lower) | Begin==End (always) | Same shape, different texture | AlphaBlend |
| 3 | Sun | BeginTime ≈ 0.25, EndTime ≈ 0.75 (day) | Small billboard quad with bright body | Additive |
| 4 | Moon | Wraps midnight (Begin > End) | Small billboard quad | Additive |
| 5 | Star dome | Wraps midnight (Begin > End) | Large hemisphere with star texture | Additive |
| 6 | Secondary moon or decoration | varies | billboard | Additive or AlphaBlend |
This is the expected pattern from r12, NOT a verified per-index dump. Verifying requires running the client with ACDREAM_DUMP_SKY=1 or equivalent and logging every SkyObject.
Action to confirm in a future pass: write a one-shot CLI or log-dump in SkyDescLoader.LoadFromRegion that prints [i] GfxObjId=0x… BeginTime=… EndTime=… BeginAngle=… EndAngle=… Properties=… for every sky object in each DayGroup, then capture the output. File it under docs/research/ as the "Dereth sky object table" so future work has ground truth.
What the prior audit found but was lost to memory
2026-04-21-sky-deep-audit.md:128-131 describes a white-sky bug and documents 7 objects but does NOT list their GfxObjIds. The comment at SkyRenderer.cs:214-218 captures typical ambient colors per keyframe (noon, dusk, midnight, dawn) but says nothing specific about which GfxObj is which role.
6. Open Questions / Verify Next
- Unit of Transparent/Luminosity/MaxBright on SkyObjectReplace. Strongest evidence (cross-reference to Surface.Luminosity and ACE/ACViewer silence) suggests it's a 0..1 fraction and our
/100is wrong. Verify with fresh raw-bytes dump. - What is
SkyObject.Properties? Retail probably reads a "billboard" bit here. Decompile needed. - Per-SkyObject blend mode — do we classify it correctly? Current code uses
sm.Translucency == TranslucencyKind.Additivebut only reads theAdditive(0x10000) flag. If the dat ALSO usesLuminousas an additive cue in conjunction withAlpha(a combined "luminous alpha mesh"), we'd miss it. Needs a dat dump of every SkyObject → GfxObj → Surface.Type for the 7 Dereth sky objects. SkyDesc.TickSizeunits. r12 says day length is 7620 game-ticks. IfTickSizeis seconds-per-tick, it gives total day seconds. Need to verify by reading the value out of the live dat.WorldFogmode — linear only, or do keyframes actually switch to exp? Our FogMode mapping accepts 1/2/3 but the shader only implements linear. If any retail keyframe uses 2 or 3, we render wrong fog falloff.
7. References
- DatReaderWriter sky types:
references/DatReaderWriter/DatReaderWriter/Generated/Types/{SkyDesc,SkyObject,SkyTimeOfDay,SkyObjectReplace,DayGroup}.generated.cs - DatReaderWriter Region:
references/DatReaderWriter/DatReaderWriter/Generated/DBObjs/Region.generated.cs:27-120 - DatReaderWriter Surface:
references/DatReaderWriter/DatReaderWriter/Generated/DBObjs/Surface.generated.cs:27-101 - DatReaderWriter SurfaceType:
references/DatReaderWriter/DatReaderWriter/Generated/Enums/SurfaceType.generated.cs:13-41 - DatReaderWriter Polygon:
references/DatReaderWriter/DatReaderWriter/Generated/Types/Polygon.generated.cs:23-87 - DatReaderWriter ColorARGB:
references/DatReaderWriter/DatReaderWriter/Generated/Types/ColorARGB.generated.cs:22-65 - DatReaderWriter Surface test fixture:
references/DatReaderWriter/DatReaderWriter.Tests/DBObjs/SurfaceTests.cs:21-45 - ACE SkyObjectReplace:
references/ACE/Source/ACE.DatLoader/Entity/SkyObjectReplace.cs:5-24 - ACE Physics Surface:
references/ACE/Source/ACE.Server/Physics/Common/Surface.cs:5-35 - ACViewer SkyObjectReplace tree:
references/ACViewer/ACViewer/Entity/SkyObjectReplace.cs:14-52 - WorldBuilder SkyboxRenderManager:
references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/SkyboxRenderManager.cs:180-274 - acdream loader:
src/AcDream.Core/World/SkyDescLoader.cs - acdream renderer:
src/AcDream.App/Rendering/Sky/SkyRenderer.cs - acdream translucency classifier:
src/AcDream.Core/Meshing/TranslucencyKind.cs:59-74 - r12 deep dive:
docs/research/deepdives/r12-weather-daynight.md:135-240, 290-330, 340-400, 430-475 - Prior audits:
docs/research/2026-04-21-sky-deep-audit.md,docs/research/2026-04-22-sky-lighting-decompile.md - dats.xml (protocol definition):
references/DatReaderWriter/DatReaderWriter/dats.xml:744-758