# Issue #178 — retail EnvCell shell culling (2026-08-28) ## Outcome The Phase A8 `CullMode.Landblock -> CullMode.None` workaround is removed from both production EnvCell draw paths. Constructed cell-shell batches now use retail's clockwise cull state instead of drawing every ordinary shell face twice. No PAK rebuild is required: the package already contains the authored `sides_type` and the correctly expanded index geometry; this change selects the correct GPU state when that geometry is drawn. The source and installed-DAT gates are complete. The owner visual gate passed 2026-08-28 (“Ok looks good”) at the requested interior matrix; #178 is closed. ## Retail oracle The misleading detail is that `DatReaderWriter.Enums.CullMode` is used for the CellStruct polygon's `sides_type`; its values are not direct GPU cull states. - `D3DPolyRender::ConstructMesh @ 0x0059DFA0` expands `sides_type` 0 as the positive face, type 1 as that face plus a reversed copy, and type 2 as the positive and negative surfaces. Its polygon fan is `[0, i-1, i]`; the reversed copy is `[i, i-1, 0]`. - `D3DPolyRender::RenderMeshSubset @ 0x0059CA10` draws the constructed mesh with `D3DCULL_CW` on the ordinary path. - `RenderDeviceD3D::DrawEnvCell @ 0x0059F170` uses that constructed-mesh route. The immediate-mode exception for a type-1 polygon does not apply to the EnvCell mesh. `MeshExtractor.PrepareCellStructMeshData` already reproduces retail's fan and the required reversed geometry. The render policy therefore must be clockwise culling for every constructed shell batch; mapping DAT value 0 to `None` was the obsolete workaround, while mapping it to the generic `Landblock` render state would cull the opposite side. ## Installed-DAT catalog `A8CellAudit cell-winding-catalog` scanned the installed DATs: - 772 environments and 3,168 CellStructs - 38,189 polygons and 70,091 generated fan triangles - 37,843 `Landblock(0)` polygons and 346 `None(1)` polygons - no unknown or unsupported `sides_type` values - no missing polygon vertices Vertex-normal orientation was recorded as a diagnostic, not treated as a contract: CellStruct vertex normals may be smoothed rather than geometric, and retail submits the identical authored fan. ## Implementation and gates - `EnvCellRenderer.ResolveRetailCellShellCullMode` documents and enforces the constructed-mesh policy in both the main and shadow-receiver draw paths. - Hermetic extraction tests pin the exact type-0 fan and type-1 reversed-face expansion. - Renderer tests pin all four source enum values to the retail clockwise constructed-mesh state. - Installed-DAT audit: passed. - Canonical Release gate: 16,321 passed, 0 skipped, 0 failed across 14 test assemblies; Release build completed with 0 warnings and 0 errors. ## Owner visual acceptance In Holtburg buildings and the Facility Hub, rotate the camera through walls, floors, ceilings, ramps, and stairs from their ordinary playable sides. Nothing should vanish at any camera angle. Acceptance of that matrix closes #178. The owner accepted this matrix on 2026-08-28 (“Ok looks good”).