Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 747fae8e2e | |||
| 24ddc99a7b | |||
| 52b6fa2ebb | |||
| 3933dbfc47 | |||
| a07a487368 | |||
| 47dec6c32c | |||
| c8e62acf4c | |||
| 7c64e8d60a | |||
| c1dc07c705 | |||
| d68786355c | |||
| 77cd17a5bc | |||
| 7815385b3b | |||
| fbef131bcb | |||
| 52e1b2ba67 | |||
| ce4f7ec0e2 | |||
| 758b375e7e | |||
| b55bfca2a7 | |||
| a7072e3d14 | |||
| f9c467b71f | |||
| 1c0dfc761d | |||
| f45695c26a | |||
| c2be8ae95e | |||
| 8636427234 |
@@ -830,6 +830,49 @@ $exe = Join-Path $env:TEMP 'godot-4.6.1-openwc\Godot_v4.6.1-stable_win64.exe'
|
||||
- A focused 8-second GUI checkpoint and a seven-checkpoint single-pass GUI run finish without Node, renderer resource or RID leak diagnostics. A timing-dependent anonymous zero-reference `RefCounted` ObjectDB warning can remain at engine teardown; it is tracked separately and is not suppressed.
|
||||
- This is shutdown-only ownership behavior and does not alter checkpoint rendering, cache formats or the `Blizzlike335` compatibility profile.
|
||||
|
||||
## 2026-07-13 Explicit Streaming Focus
|
||||
|
||||
- `StreamingWorldLoader` consumes an immutable `StreamingFocus` containing a
|
||||
typed `GodotWorldPosition`; runtime streaming no longer discovers the active
|
||||
`Camera3D` from the viewport or child nodes.
|
||||
- Eastern Kingdoms and Kalimdor runtime scenes explicitly use the player as the
|
||||
streaming source. Checkpoint capture and terrain/occluder probes explicitly
|
||||
use their dedicated camera through the same public refresh path.
|
||||
- The editor viewport camera remains behind a dedicated editor-only adapter.
|
||||
`camera_path` is retained solely for optional automatic overview positioning.
|
||||
- Streaming radii, LOD decisions, cache formats and renderer quality profiles
|
||||
are unchanged by this migration.
|
||||
|
||||
## 2026-07-13 Coordinate Conversion Boundary Gate
|
||||
|
||||
- Sky/area lookup, streaming tile ownership, player spawn/terrain sampling and
|
||||
terrain diagnostics now cross world-coordinate spaces through typed
|
||||
`CoordinateMapper` methods.
|
||||
- Renderer distance, LOD, ray and model-local M2/WMO calculations remain in
|
||||
their existing Godot/local spaces; they are not axis conversions.
|
||||
- The repository gate rejects new manual world-center, WoW/Godot and
|
||||
Godot-position-to-ADT formulas. The unified renderer baseline runs this gate.
|
||||
- Native ADT/WDT parsers keep one shared world conversion in
|
||||
`wow_chunk_reader.h`; the independent M00 calibration formula remains a test oracle.
|
||||
- Coordinate contract version 2, renderer radii, cache formats and visual
|
||||
quality profiles are unchanged.
|
||||
|
||||
## 2026-07-13 Golden Server Spawn Renderer Evidence
|
||||
|
||||
- The pinned AzerothCore Human Warrior start at server position
|
||||
`(-8949.95, -132.493, 83.5312)` maps through `CoordinateMapper` to Godot
|
||||
`(17199.159666667, 83.5312, 26016.616666667)`, ADT `(32,48)` and MCNK `(3,12)`.
|
||||
- `server_spawn_render_manifest.json` drives the ordinary Eastern Kingdoms
|
||||
checkpoint capture pipeline at that location; no live database or production
|
||||
spawn entity is introduced.
|
||||
- A renderer-native emissive marker starts at the exact mapped origin and keeps
|
||||
depth testing enabled so GUI evidence exposes its relationship to terrain.
|
||||
- `verify_server_spawn_renderer.gd` rejects drift between the pinned fixture,
|
||||
manifest target/player coordinates and expected ADT ownership. The unified
|
||||
renderer baseline runs this contract check before capture.
|
||||
- This closes a coordinate/renderer integration criterion only. It does not
|
||||
claim TrinityCore row equivalence or visual parity with the original client.
|
||||
|
||||
## Practical Rule For Future Work
|
||||
|
||||
If something improves quality but creates visible hitch, it is not done. Move it to bake/cache/background work, split finalization over frames, or prewarm it before the player can see it.
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
# M01-FND-COORD-BOUNDARY-GATE-001 — Coordinate conversion boundary gate
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-FND-COORD-BOUNDARY-GATE-001:sindo-main-codex:2026-07-15 -->
|
||||
<!-- OPENWC_HANDOFF:READY:M01-FND-COORD-BOUNDARY-GATE-001:47dec6c -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: FND/QAR
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-boundary-gate`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Route remaining GDScript world/tile axis conversions through `CoordinateMapper`
|
||||
and add a repository-wide gate that rejects new manual world-center, axis-swap
|
||||
or world-to-ADT tile formulas outside explicit contract/native-oracle boundaries.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Rewriting model-local M2/WMO vertex or placement orientation transforms.
|
||||
- Moving renderer distance/LOD geometry out of Godot space.
|
||||
- Replacing the native parser boundary with GDScript calls from worker threads.
|
||||
- Changing coordinate contract semantics, renderer radii or cache formats.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/tools/verify_coordinate_conversion_boundaries.gd`
|
||||
- Shared/hotspots: `src/domain/coordinates/coordinate_mapper.gd`, coordinate
|
||||
tests/docs/ADR, streamer/player/sky/terrain-probe consumers,
|
||||
`docs/CODING_STANDARD.md`, this claim
|
||||
- Generated/ignored: Godot import metadata, extracted assets and renderer caches
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- Additive mapper methods: Godot position to ADT tile/local and ADT tile/local
|
||||
to Godot position
|
||||
- Native exception: one formula definition in `src/native/src/wow_chunk_reader.h`;
|
||||
ADT/WDT loaders may call it but may not define copies
|
||||
- Oracle exception: `verify_render_coordinate_calibration.gd` retains one
|
||||
independent M00 formula to detect common-mode mapper regressions
|
||||
- Model-local transforms are outside the world-coordinate gate
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: coordinate contract v2 and M01 seams through `7c64e8d`
|
||||
- Blocks: M01 coordinate-centralization exit criterion and milestone evidence audit
|
||||
- External state: no dependency or proprietary input
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: conversion-boundary gate, mapper/golden fixtures, streaming focus,
|
||||
identities, renderer calibration/manifest and repository gates
|
||||
- Fixtures: Godot/ADT tile center, local offsets and exact boundaries
|
||||
- Fidelity evidence: existing build-12340 points and raw ADT/server fixture remain unchanged
|
||||
- Performance budget: mapper allocations occur only at adapter/update boundaries;
|
||||
renderer distance/LOD math remains in Godot scalars
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline public API docs: new mapper methods
|
||||
- Module specification/ADR: boundary APIs, allowed exceptions and gate behavior
|
||||
- Coding standard: mandatory review rule for cross-space conversions
|
||||
- Data-flow diagram: existing coordinate module diagram updated for direct adapters
|
||||
- State/sequence diagrams: unchanged; pure synchronous mapping
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced: `godot_to_adt_tile`, `godot_to_adt_tile_local`,
|
||||
`adt_tile_local_to_godot`, `verify_coordinate_conversion_boundaries`
|
||||
- Simplest considered solution: extend the existing mapper and scan source text
|
||||
for narrow high-signal formula signatures
|
||||
- Rejected complexity/abstractions: generic coordinate algebra framework,
|
||||
native-to-GDScript calls on parser workers and a broad numeric-literal ban
|
||||
- Unavoidable complexity and justification: one native boundary and one
|
||||
independent test oracle must remain explicit to avoid worker coupling and common-mode tests
|
||||
- Measured optimization evidence: existing renderer distance/LOD scalar math is unchanged
|
||||
|
||||
## Status
|
||||
|
||||
- State: ready-for-review
|
||||
- Done: mapper extensions, consumer migration, repository gate, review rule,
|
||||
integrated renderer gate, regression fixtures and documentation
|
||||
- Next: integrator review, merge and M01 completion-evidence audit
|
||||
- Blocked by:
|
||||
|
||||
## Handoff
|
||||
|
||||
- Commit: `47dec6c`
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-boundary-gate`
|
||||
- Outcome: all audited GDScript world/tile conversions in sky, streaming,
|
||||
player spawn/ground sampling and terrain probes route through typed
|
||||
`CoordinateMapper` boundaries. A repository scan rejects new manual
|
||||
world-center, legacy axis-conversion, world-to-tile, tile-local and
|
||||
tile-center formulas.
|
||||
- Contract/schema: additive `godot_to_adt_tile`,
|
||||
`godot_to_adt_tile_local` and `adt_tile_local_to_godot` APIs; no persisted
|
||||
format, cache version or renderer radius changes.
|
||||
- Verification: CoordinateConversionBoundaries PASS (`83` files, one native
|
||||
boundary, one independent oracle, four consumers, six classifier guards);
|
||||
CoordinateMapper PASS (`5` golden points, `8` tile boundaries, `2` raw MCNK,
|
||||
`5` yaw cases); renderer calibration PASS (`5` points, maximum error
|
||||
`0.000015`); renderer manifest PASS (`7/7/7`); unified render baseline dry-run,
|
||||
headless project load, runtime cache shutdown, coordination, documentation
|
||||
and whitespace gates passed.
|
||||
- GUI regression: final ADT-boundary capture compared `2/2`, missing `0`,
|
||||
failed `0` (cold mean `0.0002324`, changed ratio `0.0013741`; warm mean
|
||||
`0.0000226`, changed ratio `0.0001285`). Earlier full capture produced all
|
||||
`14` images; `11/14` met the strict changed-pixel threshold. The three
|
||||
threshold-only differences retained low mean error (`<= 0.00622`) and were
|
||||
visually classified as cold M2 readiness and liquid animation phase, with
|
||||
unchanged camera, geometry alignment, area and streaming focus.
|
||||
- Fidelity: existing build-12340 calibrated points, raw ADT fixture and server
|
||||
spawn fixture remain unchanged. Native parser workers retain exactly one
|
||||
formula in `wow_chunk_reader.h`; the calibration verifier retains exactly one
|
||||
independent formula so mapper and oracle cannot share a common-mode defect.
|
||||
- Rebuild: none. Local ignored extracted assets/native binary/cache junctions
|
||||
were used for runtime checks and are not part of the commit.
|
||||
- Remaining risks: source scanning intentionally recognizes narrow high-signal
|
||||
formula signatures rather than parsing arbitrary algebra; native formula
|
||||
parity still relies on calibration/raw fixtures. Model-local M2/WMO basis
|
||||
transforms and Godot-space LOD distance math are intentionally outside scope.
|
||||
- Recommended merge order: after `7c64e8d`; this package closes the remaining
|
||||
M01 manual axis-conversion checklist item, but only the milestone integrator
|
||||
may update target Evidence/status or set `OPENWC_TARGET_DONE`.
|
||||
- Documentation: coding review rule, coordinate-mapping module API/input-output/
|
||||
data-flow/capability/risk/source-map sections, ADR 0001 and `RENDER.md` were
|
||||
updated. Existing pure synchronous data-flow diagram remains authoritative;
|
||||
no state/sequence diagram changed.
|
||||
@@ -0,0 +1,104 @@
|
||||
# M01-FND-COORD-TILE-AXIS-002 — ADT filename axis correction
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-FND-COORD-TILE-AXIS-002:sindo-main-codex:2026-07-15 -->
|
||||
<!-- OPENWC_HANDOFF:READY:M01-FND-COORD-TILE-AXIS-002:a7072e3 -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: FND
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-tile-axis-fix`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Correct the additive coordinate contract so `AdtTileCoordinate(tile_x, tile_y)`
|
||||
matches actual `Map_tileX_tileY.adt` filenames and MCNK `indexX/indexY` axes.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Migrating renderer/native consumers.
|
||||
- Changing canonical, server, Godot or ADT placement position arithmetic.
|
||||
- Adding server-spawn fixtures or `StreamingFocus`.
|
||||
- Committing proprietary ADT bytes.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/domain/coordinates/coordinate_mapper.gd`,
|
||||
`src/domain/coordinates/adt_chunk_coordinate.gd`,
|
||||
`src/tools/verify_coordinate_mapper.gd`
|
||||
- Shared/hotspots: `docs/adr/0001-canonical-world-coordinates.md`,
|
||||
`docs/modules/coordinate-mapping.md`, this claim
|
||||
- Generated/ignored: local extracted ADT and Godot import metadata
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- Public API/events: method names unchanged; corrected tile/chunk axis semantics
|
||||
- Schema/format version: coordinate contract version increments from 1 to 2
|
||||
- Migration/compatibility: no released consumer exists; contract was merged but
|
||||
not yet consumed, so correction precedes consumer rollout
|
||||
- Consumers: future renderer, network, gameplay and server-data adapters
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: merged `M01-FND-COORDS-001` at `1c0dfc7`
|
||||
- Blocks: coordinate golden fixtures and all coordinate consumers
|
||||
- External state: private `Azeroth_31_49.adt` used read-only for evidence
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: coordinate mapper probe, M00 calibration, manifest, documentation
|
||||
and coordination gates
|
||||
- Fixtures: build 12340 Elwynn point must resolve to `Azeroth_31_49.adt`;
|
||||
MCNK `(0,0)` and `(15,15)` establish chunk-axis direction
|
||||
- Fidelity evidence: local ADT SHA-256
|
||||
`18185B5FAC9566D9C57A9C19ABD75F108370D1795639B6077167C0EFD3672FAE`;
|
||||
OpenRealm independently indexes filename X from world Y and filename Y from world X
|
||||
- Performance budget: unchanged constant-time scalar arithmetic
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline public API docs: corrected tile/chunk direction comments
|
||||
- Module specification: contract version, formulas, capability evidence and risk
|
||||
- Data-flow diagram: corrected filename/chunk axes
|
||||
- ADR: corrected decision and evidence
|
||||
- Sequence/state diagrams: not applicable; pure synchronous mapper
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced: none
|
||||
- Simplest considered solution: swap the two filename formulas and corresponding
|
||||
local/chunk ownership calculations
|
||||
- Rejected complexity/abstractions: compatibility flag for a contract with no consumers
|
||||
- Unavoidable complexity and justification: ADT filename axes differ from client X/Y order
|
||||
- Measured optimization evidence: not applicable
|
||||
|
||||
## Status
|
||||
|
||||
- State: ready-for-review
|
||||
- Done: raw-corpus diagnosis, filename/local/chunk axis correction, contract
|
||||
version 2 documentation and regression fixtures
|
||||
- Next: integrator review and merge before coordinate consumer work
|
||||
- Blocked by:
|
||||
|
||||
## Handoff
|
||||
|
||||
- Commit: `a7072e3`
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-tile-axis-fix`
|
||||
- Outcome: `tile_x/chunk_x` now grow east from canonical Y and
|
||||
`tile_y/chunk_y` grow south from canonical X; public method names unchanged
|
||||
- Contract/schema: coordinate contract version 2; no persisted format, cache or migration
|
||||
- Verification: coordinate mapper PASS (5 build-12340 points, 8 boundaries,
|
||||
2 recorded raw MCNK origins, 5 yaw cases); M00 calibration PASS with maximum
|
||||
error `0.000015`; renderer manifest, coordination, documentation, dependency
|
||||
and whitespace checks passed
|
||||
- Fidelity: private `Azeroth_31_49.adt` hash and raw MCNK origins recorded in
|
||||
ADR 0001; OpenRealm independently uses the same filename-axis ordering
|
||||
- Rebuild: none; private/generated prerequisites remain outside Git
|
||||
- Remaining risks: server spawn fixture, native placement conversion and
|
||||
MDDF/MODF Euler semantics remain subsequent M01 packages
|
||||
- Recommended merge order: merge this correction before golden fixture or consumer migration
|
||||
- Documentation: ADR 0001 and coordinate-mapping module data flow, contract
|
||||
version, capability evidence and known risks updated
|
||||
@@ -0,0 +1,111 @@
|
||||
# M01-FND-COORDS-001 — Canonical coordinate contracts
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-FND-COORDS-001:sindo-main-codex:2026-07-15 -->
|
||||
<!-- OPENWC_HANDOFF:READY:M01-FND-COORDS-001:f45695c -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: FND
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-mapper`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Introduce scene-free value objects for canonical WoW, server, ADT placement,
|
||||
ADT tile/chunk/local and Godot world coordinate spaces, plus the single pure
|
||||
`CoordinateMapper` contract for position and world-yaw conversions.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Migrating `StreamingWorldLoader`, native parsers, sky, player or renderer code.
|
||||
- Defining model-specific MDDF/MODF Euler rotation corrections.
|
||||
- Introducing `StreamingFocus`, typed IDs or a test framework dependency.
|
||||
- Claiming visual parity from arithmetic round trips.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/domain/coordinates/**`, `src/tools/verify_coordinate_mapper.gd`,
|
||||
`docs/modules/coordinate-mapping.md`, `docs/adr/0001-canonical-world-coordinates.md`
|
||||
- Shared/hotspots: `docs/modules/README.md`, this claim
|
||||
- Generated/ignored: Godot import metadata and local test output
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- Public API/events: immutable coordinate value objects and pure mapper methods
|
||||
- Schema/format version: no persisted format; contract version 1 in module docs
|
||||
- Migration/compatibility: additive contract; existing renderer conversions remain
|
||||
unchanged until a later consumer migration package
|
||||
- Consumers: future renderer, network, gameplay and server-data adapters
|
||||
- Rollout order: contract and fixtures first, then native/parser and renderer consumers
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: merged M00 build 12340 coordinate calibration evidence
|
||||
- Blocks: M01 renderer coordinate migration and `StreamingFocus`
|
||||
- External state: no proprietary inputs; reference formulas are source-only evidence
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: headless coordinate contract probe, headless project load,
|
||||
coordination and documentation gates
|
||||
- Fixtures: five build 12340 camera points, ADT map center/edge/boundary points,
|
||||
server/ADT/Godot round trips and yaw normalization cases
|
||||
- Fidelity evidence: M00 observed build 12340 positions plus independent
|
||||
OpenRealm/WoWee and TrinityCore grid formulas
|
||||
- Performance budget: constant-time scalar arithmetic with no allocation beyond result values
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline public API docs: every public value object and mapper method
|
||||
- Module specification: purpose, public API, inputs/outputs, ownership, errors and source map
|
||||
- Data-flow diagram: server/ADT/canonical/Godot mappings
|
||||
- Dependency diagram: canonical contract consumers and forbidden scene dependency
|
||||
- Sequence/state diagrams: not applicable; mapper is synchronous and stateless
|
||||
- ADR: coordinate axes, units, tile indexing and compatibility rollout
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced: `CanonicalWowWorldPosition`, `ServerWorldPosition`,
|
||||
`AdtPlacementPosition`, `AdtTileCoordinate`, `AdtChunkCoordinate`,
|
||||
`AdtTileLocalPosition`, `GodotWorldPosition`, `WorldYaw`, `CoordinateMapper`
|
||||
- Simplest considered solution: scalar immutable value objects and one pure mapper
|
||||
- Rejected complexity/abstractions: generic vector-space framework, matrices,
|
||||
dependency injection and a third-party test framework
|
||||
- Unavoidable complexity and justification: distinct source spaces prevent silent axis swaps
|
||||
- Measured optimization evidence: not applicable
|
||||
|
||||
## Status
|
||||
|
||||
- State: ready-for-review
|
||||
- Done: repository/reference audit, ADR, immutable value objects, pure mapper,
|
||||
build 12340/boundary/yaw fixtures, module specification and repository gates
|
||||
- Next: integrator review and merge before renderer/native consumer migration
|
||||
- Blocked by:
|
||||
|
||||
## Handoff
|
||||
|
||||
- Commit: `f45695c`
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-mapper`
|
||||
- Outcome: additive contract for canonical/server/ADT/Godot positions, ADT
|
||||
tile/chunk/local ownership and world-facing yaw; no existing consumer changed
|
||||
- Public contracts: contract version 1 documented in
|
||||
`docs/modules/coordinate-mapping.md`; no persisted schema or cache change
|
||||
- Verification: coordinate mapper PASS (5 golden points, 8 tile boundaries,
|
||||
5 yaw cases); M00 coordinate calibration PASS (5 points, maximum error
|
||||
`0.000015`); renderer manifest, coordination, documentation, dependency and
|
||||
whitespace checks passed; headless project load completed with expected
|
||||
missing proprietary-data diagnostics in the isolated worktree
|
||||
- Fidelity: observed build 12340 positions match within `0.002` yard; formulas
|
||||
cross-checked against TrinityCore, OpenRealm and WoWee; visual parity is not claimed
|
||||
- Migration/rebuild: none for this additive package; consumers migrate only
|
||||
after merge and must preserve renderer checkpoints
|
||||
- Remaining risks: native loaders and renderer still use manual conversions;
|
||||
MDDF/MODF Euler mapping is intentionally unresolved; server-spawn integration
|
||||
and finite-value adapter validation remain later M01 packages
|
||||
- Recommended merge order: this contract first, coordinate fixtures/server-spawn
|
||||
audit second, renderer/native consumers third, manual-conversion search gate last
|
||||
- Documentation: ADR 0001; coordinate-mapping module spec with data-flow and
|
||||
dependency diagrams; inline API documentation on all public symbols
|
||||
@@ -0,0 +1,112 @@
|
||||
# M01-FND-DOMAIN-IDENTITIES-001 — Stable domain identity namespaces
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-FND-DOMAIN-IDENTITIES-001:sindo-main-codex:2026-07-15 -->
|
||||
<!-- OPENWC_HANDOFF:READY:M01-FND-DOMAIN-IDENTITIES-001:c1dc07c -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: FND
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-domain-identities`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Add scene-free, immutable identity values for stable authored content,
|
||||
session-local entities, opaque WoW wire GUIDs and namespaced server entries so
|
||||
callers cannot silently interchange their numeric/string representations.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Allocating Content IDs, Entity IDs or server entries.
|
||||
- Decoding WoW GUID high types before the build-12340 protocol package.
|
||||
- Defining map/spell/item/quest/display/sound IDs in this package.
|
||||
- Migrating gameplay, network or Content Project consumers that do not exist yet.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/domain/identity/`, `src/tools/verify_domain_identities.gd`,
|
||||
`docs/modules/domain-identities.md`, `docs/adr/0002-domain-identity-namespaces.md`
|
||||
- Shared/hotspots: `docs/ARCHITECTURE.md`, this claim
|
||||
- Generated/ignored: Godot import metadata
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- `ContentId`: canonical lowercase UUID text persisted with schema-owned content
|
||||
- `EntityId`: positive session-local integer, never a persisted content/server identity
|
||||
- `WowGuid`: opaque high/low unsigned 32-bit words preserving wire bits
|
||||
- `ServerEntryId`: positive integer plus non-empty adapter/table namespace
|
||||
- Migration: additive types only; no existing persisted data changes
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: M01 coordinate/focus seams through `77cd17a`
|
||||
- Blocks: Content Project schemas, server adapters, network entity mapping and gameplay registry
|
||||
- External state: no dependency or proprietary input
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: identity contract/boundary verifier, dependency search,
|
||||
coordination/documentation gates and headless project load
|
||||
- Fixtures: valid/invalid UUIDs, session IDs, full unsigned GUID words and
|
||||
duplicate numeric server entries in different namespaces
|
||||
- Fidelity evidence: GUID words remain opaque and lossless until build-12340
|
||||
packet fixtures establish semantic decomposition
|
||||
- Performance budget: constant-time scalar/string validation outside frame loops
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline public API docs: every value and validation/equality method
|
||||
- Module specification: persistence, ownership, namespace mapping and recovery
|
||||
- Data-flow diagram: authored/runtime/wire/server identities into adapters
|
||||
- State/sequence diagrams: lifecycle diagram for content/session/wire/server identity
|
||||
- ADR: namespace separation and UUID persistence decision
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced: `ContentId`, `EntityId`, `WowGuid`, `ServerEntryId`
|
||||
- Simplest considered solution: four independent values with explicit fields
|
||||
- Rejected complexity/abstractions: generic ID base class, registry service,
|
||||
UUID generator and speculative GUID high-type enum
|
||||
- Unavoidable complexity and justification: server entry namespace and split GUID
|
||||
words prevent collisions and signed 64-bit loss
|
||||
- Measured optimization evidence: not applicable
|
||||
|
||||
## Status
|
||||
|
||||
- State: ready-for-review
|
||||
- Done: four identity values, boundary verifier, ADR, module specification,
|
||||
architecture mapping and repository gates
|
||||
- Next: integrator review and merge before the manual axis-conversion gate
|
||||
- Blocked by:
|
||||
|
||||
## Handoff
|
||||
|
||||
- Commit: `c1dc07c`
|
||||
- Branch: `work/sindo-main-codex/m01-domain-identities`
|
||||
- Outcome: authored content, runtime entities, WoW wire GUIDs and namespaced
|
||||
server entries now have separate immutable scene-free value objects
|
||||
- Contract/schema: identity contract version 1; `ContentId` uses canonical
|
||||
lowercase UUID text. No existing schema/cache is migrated; containing future
|
||||
schemas still require their own version and duplicate/reference policy
|
||||
- Verification: DomainIdentities PASS (`5` ContentId, `5` EntityId, `6` WowGuid,
|
||||
`5` ServerEntryId cases); StreamingFocus, coordinate golden fixtures and
|
||||
CoordinateMapper PASS; M00 calibration PASS with maximum error `0.000015`;
|
||||
renderer manifest PASS (`7` checkpoints); headless project load exit `0`;
|
||||
coordination, documentation, naming/dependency and whitespace checks passed
|
||||
- Fidelity: `WowGuid` preserves two complete unsigned 32-bit wire words and
|
||||
explicitly does not claim build-12340 high-type semantics without packet
|
||||
fixtures; zero GUID remains an uninterpreted observable sentinel
|
||||
- Rebuild: none; no dependency or proprietary input. Clean-worktree project
|
||||
load reports expected missing ignored extracted assets/character resources
|
||||
- Remaining risks: no ID allocator, mapping registry or server namespace
|
||||
vocabulary exists yet; UUID shape does not enforce generator version/variant;
|
||||
GDScript callers must use domain `equals` or canonical keys rather than
|
||||
reference `==`
|
||||
- Recommended merge order: after StreamingFocus at `77cd17a`, before the M01
|
||||
manual axis-conversion rule/search gate
|
||||
- Documentation: ADR 0002, domain-identities module API/input-output/data-flow/
|
||||
lifecycle/persistence/recovery/capability/source-map sections, module registry
|
||||
and architecture Domain mapping added or updated
|
||||
@@ -0,0 +1,109 @@
|
||||
# M01-QAR-COORD-FIXTURES-001 — Coordinate golden fixtures
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-QAR-COORD-FIXTURES-001:sindo-main-codex:2026-07-15 -->
|
||||
<!-- OPENWC_HANDOFF:READY:M01-QAR-COORD-FIXTURES-001:ce4f7ec -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: QAR
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-fixtures`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Add a versioned, non-proprietary fixture and headless validator joining one
|
||||
pinned AzerothCore player spawn, raw ADT/MCNK metadata and the five M00
|
||||
original-client coordinate observations through coordinate contract version 2.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Committing ADT files, SQL dumps or original-client screenshots.
|
||||
- Claiming TrinityCore spawn equivalence without a pinned populated TDB source.
|
||||
- Migrating renderer/native consumers or rendering a live server spawn.
|
||||
- Changing coordinate formulas, IDs or `StreamingFocus`.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/tests/fixtures/coordinate_golden_points.json`,
|
||||
`src/tools/verify_coordinate_golden_fixtures.gd`
|
||||
- Shared/hotspots: `docs/modules/coordinate-mapping.md`, this claim
|
||||
- Generated/ignored: extracted ADT data, server database downloads and Godot metadata
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- Public API/events: no new production API; fixture schema version 1
|
||||
- Coordinate contract: version 2, unchanged
|
||||
- Migration/compatibility: additive test data; fixture consumers reject unknown schema versions
|
||||
- Consumers: M01 coordinate mapper, future native/renderer/server adapter migrations
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: merged coordinate contract version 2 at `b55bfca`
|
||||
- Blocks: coordinate consumer migration and golden server-spawn renderer integration
|
||||
- External state: source evidence reduced to pinned revision, numeric rows and SHA-256 hashes
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: fixture validator, coordinate mapper probe, M00 calibration,
|
||||
manifest, coordination and documentation gates
|
||||
- Fixtures: AzerothCore Human Warrior start; raw `Azeroth_32_48.adt` MCNK
|
||||
`(3,12)`; five build 12340 camera points
|
||||
- Fidelity evidence: exact source provenance and mapper outputs with bounded tolerances
|
||||
- Performance budget: negligible headless JSON and scalar arithmetic
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline public API docs: fixture-validator header and field validation functions
|
||||
- Module specification: fixture schema, provenance, verification and source map
|
||||
- Data-flow diagram: server/raw/client fixtures into mapper assertions
|
||||
- State/sequence/dependency diagrams: unchanged; synchronous stateless validation
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced: `coordinate_golden_points`,
|
||||
`verify_coordinate_golden_fixtures`
|
||||
- Simplest considered solution: one JSON fixture and one existing-style headless script
|
||||
- Rejected complexity/abstractions: test framework dependency, SQL parser, ADT bytes in Git
|
||||
- Unavoidable complexity and justification: three independent source categories need explicit provenance
|
||||
- Measured optimization evidence: not applicable
|
||||
|
||||
## Status
|
||||
|
||||
- State: ready-for-review
|
||||
- Done: pinned source research, schema 1 fixture, headless validator, module
|
||||
documentation and all package gates
|
||||
- Next: integrator review and merge before coordinate consumer migration
|
||||
- Blocked by:
|
||||
|
||||
## Handoff
|
||||
|
||||
- Commit: `ce4f7ec`
|
||||
- Branch: `work/sindo-main-codex/m01-coordinate-fixtures`
|
||||
- Outcome: one versioned fixture now joins a pinned AzerothCore Human Warrior
|
||||
spawn, private raw MCNK metadata and five original-client build 12340 points
|
||||
through coordinate contract version 2
|
||||
- Contract/schema: additive test fixture schema 1; production coordinate API and
|
||||
contract version 2 are unchanged; proprietary bytes remain outside Git
|
||||
- Verification: golden fixture PASS (`1` server spawn, `1` raw ADT chunk, `5`
|
||||
original-client points); CoordinateMapper PASS (`5` golden points, `8` tile
|
||||
boundaries, `2` raw MCNK cases, `5` yaw cases); M00 calibration PASS with
|
||||
maximum error `0.000015`; renderer manifest PASS (`7` checkpoints); coordination,
|
||||
documentation, dependency and whitespace checks passed
|
||||
- Fidelity: AzerothCore source pinned at revision
|
||||
`68fcf0098b16388093989627f37be530fc91f07d`; private
|
||||
`Azeroth_32_48.adt` SHA-256
|
||||
`D66E27FD82B461AE38B78562952AED428E619777A3F3E35DD8FF97444644770A`;
|
||||
server and raw data independently resolve tile `(32,48)` and chunk `(3,12)`
|
||||
- Rebuild: no proprietary input is required to rerun the committed fixture;
|
||||
local ignored renderer resources are still required by the inherited M00
|
||||
manifest probe
|
||||
- Remaining risks: TrinityCore equivalence needs a pinned populated TDB snapshot;
|
||||
live server adapter, renderer integration and MDDF/MODF Euler semantics remain
|
||||
subsequent M01 work
|
||||
- Recommended merge order: after coordinate contract version 2 (`b55bfca`) and
|
||||
before live coordinate consumer migration
|
||||
- Documentation: coordinate-mapping module inputs/outputs, persistence, data-flow
|
||||
diagram, verification, capability matrix, risks and source map updated
|
||||
@@ -0,0 +1,85 @@
|
||||
# M01-QAR-SERVER-SPAWN-RENDERER-001 — Golden server spawn renderer evidence
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-QAR-SERVER-SPAWN-RENDERER-001:sindo-main-codex:2026-07-15 -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: QAR/RND
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-server-spawn-renderer`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Route the pinned AzerothCore Human Warrior spawn fixture through
|
||||
`CoordinateMapper` into the live Eastern Kingdoms renderer and produce
|
||||
repeatable headless contract checks plus GUI screenshot evidence at the mapped
|
||||
ADT tile/chunk.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Connecting to a live AzerothCore or TrinityCore database.
|
||||
- Claiming TrinityCore spawn equivalence without a pinned populated TDB row.
|
||||
- Changing coordinate formulas, streaming radii, terrain, player movement or
|
||||
production character presentation.
|
||||
- Adding proprietary assets or screenshots to Git.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/tools/server_spawn_render_manifest.json`,
|
||||
`src/tools/verify_server_spawn_renderer.gd`
|
||||
- Shared/hotspots: `src/tools/capture_render_checkpoints.gd`, renderer runner,
|
||||
coordinate/world-renderer module documentation, `RENDER.md`, this claim
|
||||
- Generated/ignored: Godot UIDs/import metadata and `user://` PNG/JSON evidence
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- Fixture schema and coordinate contract version remain unchanged.
|
||||
- Additive diagnostic checkpoint metadata may request a renderer-native marker;
|
||||
existing M00 checkpoints remain byte-for-byte compatible.
|
||||
- The spawn remains sourced from pinned AzerothCore revision
|
||||
`68fcf0098b16388093989627f37be530fc91f07d`.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: merged M01 packages through `a07a487`
|
||||
- Blocks: M01 golden server-spawn renderer criterion and milestone closeout
|
||||
- External state: GUI capture requires the existing local extracted/cached
|
||||
renderer corpus; headless contract verification remains non-proprietary
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: dedicated spawn verifier, coordinate fixture/mapper/boundary gates,
|
||||
renderer baseline dry-run, GUI checkpoint capture and human inspection
|
||||
- Fixture: AzerothCore race `1`, class `1`, map `0`, server position
|
||||
`(-8949.95, -132.493, 83.5312)`
|
||||
- Expected renderer result: Godot position
|
||||
`(17199.159666667, 83.5312, 26016.616666667)`, ADT `(32,48)`, MCNK `(3,12)`
|
||||
- Fidelity classification: server/coordinate integration evidence only; it does
|
||||
not establish full original-client visual parity
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline API/tool documentation for new verifier and marker metadata
|
||||
- Coordinate-mapping module capability/evidence update
|
||||
- World-renderer checkpoint input/output/source-map update when marker support is added
|
||||
- Existing synchronous coordinate data-flow diagram updated only if flow changes
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names: `server_spawn_render_manifest`,
|
||||
`verify_server_spawn_renderer`, `diagnostic_spawn_marker`
|
||||
- Simplest approach: reuse the existing checkpoint capture pipeline with one
|
||||
dedicated manifest and a renderer-native diagnostic marker
|
||||
- Rejected complexity: live DB adapter, new scene-test framework and production
|
||||
spawn entity implementation before the network/gameplay milestones
|
||||
- Performance: one diagnostic checkpoint outside production runtime
|
||||
|
||||
## Status
|
||||
|
||||
- State: active
|
||||
- Done: merged-package and target evidence audit
|
||||
- Next: implement manifest/verifier/marker, capture GUI evidence and hand off
|
||||
- Blocked by:
|
||||
@@ -0,0 +1,120 @@
|
||||
# M01-RND-STREAMING-FOCUS-001 — Explicit streaming focus contract
|
||||
|
||||
<!-- OPENWC_CLAIM:M01-RND-STREAMING-FOCUS-001:sindo-main-codex:2026-07-15 -->
|
||||
<!-- OPENWC_HANDOFF:READY:M01-RND-STREAMING-FOCUS-001:7815385 -->
|
||||
|
||||
## Ownership
|
||||
|
||||
- Target: M01
|
||||
- Program: RND/FND
|
||||
- Owner/Agent ID: sindo-main-codex
|
||||
- Branch: `work/sindo-main-codex/m01-streaming-focus`
|
||||
- Lease expires UTC: 2026-07-15
|
||||
- Integrator: M01 milestone integrator
|
||||
|
||||
## Outcome
|
||||
|
||||
Introduce a scene-free `StreamingFocus` value and make runtime/test streaming
|
||||
consume it through an explicit source or public setter instead of discovering
|
||||
the active `Camera3D` from a viewport.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Extracting `WorldRenderFacade` or `StreamingTargetPlanner` from the monolithic loader.
|
||||
- Adding direction, velocity, frustum or multi-focus planning.
|
||||
- Decomposing the player controller before M02.
|
||||
- Changing terrain, M2, WMO, liquid, cache or LOD formulas.
|
||||
|
||||
## Paths
|
||||
|
||||
- Exclusive: `src/domain/streaming/`, `src/tools/verify_streaming_focus.gd`
|
||||
- Shared/hotspots: `src/scenes/streaming/streaming_world_loader.gd`,
|
||||
`src/scenes/streaming/eastern_kingdoms_streaming.tscn`,
|
||||
`src/scenes/streaming/kalimdor_streaming.tscn`, renderer diagnostic tools,
|
||||
`docs/modules/world-renderer.md`, this claim
|
||||
- Generated/ignored: local extracted assets, renderer caches and Godot import metadata
|
||||
|
||||
## Contracts and data
|
||||
|
||||
- Public API: immutable `StreamingFocus`; loader `set_streaming_focus` and
|
||||
`refresh_streaming_focus`
|
||||
- Source adapter: explicit `streaming_focus_source_path` may reference any `Node3D`
|
||||
- Migration: runtime scenes use player focus; capture/probe tools explicitly use
|
||||
their dedicated camera as the source
|
||||
- Compatibility: streaming radii/LOD/cache behavior and coordinate contract v2 unchanged
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Requires: coordinate contract version 2 and golden fixtures at `52e1b2b`
|
||||
- Blocks: M01 renderer/test focus exit criterion and later renderer facade extraction
|
||||
- External state: no new dependency or proprietary input
|
||||
|
||||
## Verification
|
||||
|
||||
- Commands: streaming focus contract/integration verifier, renderer baseline
|
||||
manifest/calibration, headless scene smoke, coordination/documentation gates
|
||||
- Fixtures: Node3D player-style source and explicit capture-style setter
|
||||
- Fidelity evidence: existing seven renderer checkpoints and build-12340 coordinate
|
||||
calibration must remain unchanged
|
||||
- Performance budget: one scalar focus snapshot per configured streaming interval;
|
||||
no new per-tile or per-chunk work
|
||||
|
||||
## Documentation deliverables
|
||||
|
||||
- Inline public API docs: focus value and loader public methods
|
||||
- Module specification: inputs/outputs, ownership, lifecycle, failure/recovery and source map
|
||||
- Data-flow diagram: player/editor/capture source to focus contract to loader
|
||||
- State/sequence diagram: focus sampling and refresh threshold sequence
|
||||
|
||||
## Simplicity and naming
|
||||
|
||||
- Important names introduced: `StreamingFocus`, `streaming_focus_source_path`,
|
||||
`set_streaming_focus`, `refresh_streaming_focus`
|
||||
- Simplest considered solution: one immutable value plus one explicit scene adapter path
|
||||
- Rejected complexity/abstractions: provider interface hierarchy, service locator,
|
||||
multi-focus registry and predictive motion fields
|
||||
- Unavoidable complexity and justification: editor viewport remains a separate
|
||||
adapter because its camera is owned by `EditorInterface`
|
||||
- Measured optimization evidence: not applicable
|
||||
|
||||
## Status
|
||||
|
||||
- State: ready-for-review
|
||||
- Done: contract, runtime/editor/capture migration, headless regression,
|
||||
module diagrams, renderer documentation and cold/warm GUI capture
|
||||
- Next: integrator review and merge before typed identity work
|
||||
- Blocked by:
|
||||
|
||||
## Handoff
|
||||
|
||||
- Commit: `7815385`
|
||||
- Branch: `work/sindo-main-codex/m01-streaming-focus`
|
||||
- Outcome: runtime streaming consumes immutable `StreamingFocus`; Eastern
|
||||
Kingdoms and Kalimdor scenes explicitly follow the player, while capture and
|
||||
terrain/occluder probes explicitly follow their dedicated camera
|
||||
- Contract/API: new scene-free `StreamingFocus(GodotWorldPosition)` plus loader
|
||||
`set_streaming_focus`, `refresh_streaming_focus` and
|
||||
`streaming_focus_source_path`; `camera_path` remains only for optional overview positioning
|
||||
- Verification: StreamingFocus PASS (`1` contract, `2` runtime scenes, `3`
|
||||
capture tools); coordinate golden fixtures and CoordinateMapper PASS; M00
|
||||
calibration PASS with maximum error `0.000015`; manifest PASS (`7`
|
||||
checkpoints); runtime-cache shutdown PASS; headless runtime scene exit `0`;
|
||||
coordination, documentation, dependency and whitespace checks passed
|
||||
- Renderer checkpoint: standard 8-second GUI capture completed `14` images
|
||||
(`7` cold + `7` warm) and wrote schema-1 `report.json`; focus tiles changed
|
||||
through the public contract; no Node/resource/RID leak diagnostic appeared
|
||||
- Fidelity: checkpoint camera positions, coordinate contract v2, streaming radii,
|
||||
LOD formulas, cache formats and quality profiles are unchanged; this is
|
||||
regression evidence, not a new `1:1` parity claim
|
||||
- Rebuild: none; GUI verification used local ignored extracted assets/cache
|
||||
junctions. Missing worktree `.godot/imported` copies for several incidental M2
|
||||
GLBs produced existing cache-load fallback diagnostics only
|
||||
- Remaining risks: the monolithic loader still owns planning/jobs/presentation;
|
||||
direction, velocity, frustum and multiple foci remain M03 planner work. The
|
||||
known timing-dependent zero-reference `ObjectDB` shutdown warning occurred,
|
||||
without Node/resource/RID leak diagnostics
|
||||
- Recommended merge order: after coordinate fixtures at `52e1b2b`, before typed
|
||||
identity and renderer-facade extraction
|
||||
- Documentation: `world-renderer.md` inputs/outputs, public API, lifecycle,
|
||||
data-flow and sequence diagrams, ownership, recovery, verification,
|
||||
capability matrix, risks and source map updated; `RENDER.md` updated
|
||||
@@ -36,7 +36,12 @@ TrinityCore/AzerothCore ◄── Network Adapter ◄── Runtime Client
|
||||
|
||||
### Domain
|
||||
|
||||
Содержит идентификаторы, value objects, команды и события: `EntityId`, `WowGuid`, `MapPosition`, `SpellId`, `MoveIntent`, `EntityMoved`. Не содержит side effects.
|
||||
Содержит идентификаторы, value objects, команды и события: stable authored
|
||||
`ContentId`, session-local `EntityId`, opaque wire `WowGuid`, namespaced
|
||||
`ServerEntryId`, typed coordinates, `SpellId`, `MoveIntent`, `EntityMoved`.
|
||||
Эти identity namespaces не конвертируются неявно и не содержат side effects;
|
||||
их lifecycle и mapping определены в
|
||||
[`modules/domain-identities.md`](modules/domain-identities.md).
|
||||
|
||||
### Gameplay
|
||||
|
||||
|
||||
@@ -237,6 +237,23 @@ TODO/FIXME обязан содержать target/work-package ID или diagnos
|
||||
- Медленный понятный reference implementation полезен как oracle для optimized implementation.
|
||||
- Сложная оптимизация удаляется или упрощается, если она не даёт измеримого результата.
|
||||
|
||||
## Coordinate conversion boundary
|
||||
|
||||
- Cross-space world conversions выполняются только через typed API
|
||||
`CoordinateMapper`; ручные world-center offsets, swaps осей и вычисление ADT
|
||||
filename indices из Godot position запрещены.
|
||||
- Scene/render adapter МОЖЕТ создать `Vector3` только после получения
|
||||
`GodotWorldPosition` или перевести engine vector в typed scalar value на своей границе.
|
||||
- Единственная native world-position формула находится в
|
||||
`src/native/src/wow_chunk_reader.h`, поскольку parser workers не вызывают
|
||||
GDScript. Новая native копия требует отдельного boundary decision и parity fixture.
|
||||
- `verify_render_coordinate_calibration.gd` остаётся независимым test oracle;
|
||||
production code не копирует его формулы.
|
||||
- Model-local M2/WMO vertex basis и placement orientation не являются world
|
||||
coordinate conversion. Они документируются и тестируются своим format adapter.
|
||||
- `verify_coordinate_conversion_boundaries.gd` обязателен при изменении
|
||||
coordinates, native parsers, sky, player, streaming или renderer diagnostics.
|
||||
|
||||
## Review checklist
|
||||
|
||||
- Можно ли понять назначение сущности по имени?
|
||||
@@ -245,6 +262,8 @@ TODO/FIXME обязан содержать target/work-package ID или diagnos
|
||||
- Можно ли убрать abstraction без потери correctness/boundary?
|
||||
- Есть ли скрытый mutable state или side effect?
|
||||
- Не появился ли второй источник истины?
|
||||
- Все ли cross-space world coordinates проходят через `CoordinateMapper` или
|
||||
документированную native boundary?
|
||||
- Измерена ли сложная optimization?
|
||||
- Изолирована и документирована ли неизбежная сложность?
|
||||
- Соответствуют ли API docs и diagrams фактическому коду?
|
||||
|
||||
+19
-1
@@ -10,7 +10,10 @@
|
||||
.\tools\run_render_baseline.ps1
|
||||
```
|
||||
|
||||
Скрипт последовательно проверяет headless-загрузку проекта, renderer materials, M2 unique-id dedupe, regression manifest и затем снимает checkpoint-ы. Для CI или быстрой проверки контракта без PNG:
|
||||
Скрипт последовательно проверяет headless-загрузку проекта, renderer materials,
|
||||
M2 unique-id dedupe, regression manifest, coordinate boundaries и dedicated
|
||||
server-spawn renderer contract, затем снимает checkpoint-ы. Для CI или быстрой
|
||||
проверки контракта без PNG:
|
||||
|
||||
```powershell
|
||||
.\tools\run_render_baseline.ps1 -DryRun -WaitSeconds 0.1 -MeasureSeconds 0.1
|
||||
@@ -18,6 +21,21 @@
|
||||
|
||||
Если `godot` отсутствует в `PATH`, скрипт использует локальный executable, указанный в `RENDER.md`. Другой executable задаётся через `-GodotPath`.
|
||||
|
||||
Отдельный M01 server-spawn checkpoint использует тот же capture pipeline, но не
|
||||
расширяет семичастный M00 visual baseline:
|
||||
|
||||
```powershell
|
||||
godot --headless --path . --script res://src/tools/verify_server_spawn_renderer.gd
|
||||
godot --path . --script res://src/tools/capture_render_checkpoints.gd -- `
|
||||
--manifest res://src/tools/server_spawn_render_manifest.json `
|
||||
--output user://server_spawn_renderer
|
||||
```
|
||||
|
||||
Manifest связывает pinned AzerothCore Human Warrior spawn с Godot position,
|
||||
ADT tile/chunk и renderer-native diagnostic marker. Маркер начинается точно в
|
||||
spawn origin и проходит обычный depth test, поэтому screenshot показывает его
|
||||
отношение к terrain; это integration evidence, а не заявление visual parity.
|
||||
|
||||
Результат по умолчанию находится в `user://render_baseline`:
|
||||
|
||||
- `report.json` — Godot, OS, CPU, GPU/backend, viewport, revision, cache inventory, cache versions, параметры checkpoint-ов и результаты;
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
# ADR 0001: Canonical world coordinate contract
|
||||
|
||||
- Status: Accepted for M01 contract implementation
|
||||
- Date: 2026-07-13
|
||||
- Work packages: `M01-FND-COORDS-001`, corrected by `M01-FND-COORD-TILE-AXIS-002`
|
||||
- Decision owners: M01 foundation/integration owners
|
||||
|
||||
## Context
|
||||
|
||||
OpenWC currently performs coordinate conversion in native ADT/WDT loaders,
|
||||
`StreamingWorldLoader`, sky, player and renderer diagnostic scripts. The same
|
||||
numbers are frequently carried in `Vector3` or dictionaries, so the coordinate
|
||||
space is implicit. Existing names also mix ADT filename indices, renderer X/Z
|
||||
indices and MDDF/MODF placement fields.
|
||||
|
||||
M00 recorded five positions observed in WoW 3.3.5a build 12340. They verify the
|
||||
current client-position to Godot-position arithmetic within `0.002` yard, but
|
||||
they do not define a cross-layer contract and do not prove camera composition
|
||||
or visual parity.
|
||||
|
||||
Independent references agree on a 64 by 64 ADT grid and an approximately
|
||||
`533.3333` yard tile size. They do not all use the word “canonical” for the same
|
||||
axis order. OpenWC therefore needs names tied to observable formats instead of
|
||||
adopting an internal convention from one reference project.
|
||||
|
||||
## Decision
|
||||
|
||||
### Canonical position
|
||||
|
||||
`CanonicalWowWorldPosition(X, Y, Z)` preserves the numeric X/Y/Z order used by
|
||||
the WoW client, movement protocol and TrinityCore/AzerothCore world positions.
|
||||
X and Y are horizontal; Z is height. Units are WoW yards.
|
||||
|
||||
`ServerWorldPosition` is a distinct type but converts component-for-component
|
||||
to canonical. The type boundary prevents a server record from being passed
|
||||
directly to renderer code and leaves room for adapter validation without a
|
||||
silent axis swap.
|
||||
|
||||
### World extent and ADT indices
|
||||
|
||||
The contract uses:
|
||||
|
||||
```text
|
||||
ADT_TILE_SIZE_YARDS = 1600 / 3
|
||||
ADT_TILES_PER_MAP_AXIS = 64
|
||||
WOW_WORLD_HALF_EXTENT_YARDS = 32 * ADT_TILE_SIZE_YARDS
|
||||
|
||||
tileX = floor(32 - canonical.Y / ADT_TILE_SIZE_YARDS)
|
||||
tileY = floor(32 - canonical.X / ADT_TILE_SIZE_YARDS)
|
||||
```
|
||||
|
||||
`AdtTileCoordinate(tile_x, tile_y)` always means the indices in
|
||||
`Map_tileX_tileY.adt`. Results are intentionally not clamped: the exact
|
||||
south-east extent produces index 64 and remains diagnosable as out of bounds.
|
||||
Normal valid indices are 0 through 63.
|
||||
|
||||
An `AdtTileLocalPosition` is measured east and south from the tile's
|
||||
north-west corner. Filename `tile_x` and MCNK `chunk_x` grow east; filename
|
||||
`tile_y` and MCNK `chunk_y` grow south, with valid indices 0 through 15. These
|
||||
direction names avoid pretending that ADT file axes are Godot X/Z axes.
|
||||
|
||||
### ADT placement fields
|
||||
|
||||
MDDF/MODF position fields are represented in on-disk X/height/Z order:
|
||||
|
||||
```text
|
||||
adt.X = halfExtent - canonical.X
|
||||
adt.height = canonical.Z
|
||||
adt.Z = halfExtent - canonical.Y
|
||||
```
|
||||
|
||||
Model-local MDDF/MODF Euler corrections are not world orientation. They remain
|
||||
outside this contract until a placement-orientation package has format- and
|
||||
model-specific fixtures.
|
||||
|
||||
### Godot renderer basis
|
||||
|
||||
The compatibility renderer keeps one Godot unit equal to one WoW yard and uses
|
||||
Y-up coordinates from the north-west map extent:
|
||||
|
||||
```text
|
||||
godot.X = halfExtent - canonical.Y # east
|
||||
godot.Y = canonical.Z # up
|
||||
godot.Z = halfExtent - canonical.X # south
|
||||
```
|
||||
|
||||
`GodotWorldPosition` contains scalars rather than `Vector3`. A scene/render
|
||||
adapter may construct `Vector3` only at its boundary.
|
||||
|
||||
### World yaw
|
||||
|
||||
Server/canonical yaw zero faces increasing WoW X; positive yaw turns toward
|
||||
increasing WoW Y. In the mapped Godot basis, Godot forward `-Z` and positive
|
||||
Y-axis yaw produce the same numeric world angle. Mapper conversions therefore
|
||||
normalize the value to `[-PI, PI)` without adding an offset.
|
||||
|
||||
This identity applies to world-facing yaw only. It does not apply to M2/WMO
|
||||
asset axes or placement Euler triples.
|
||||
|
||||
### Contract version 2 correction evidence
|
||||
|
||||
Contract version 1 incorrectly calculated filename `tile_x` from canonical X
|
||||
and `tile_y` from canonical Y. The private WotLK corpus contains the observed
|
||||
Elwynn point in `Azeroth_31_49.adt`, SHA-256
|
||||
`18185B5FAC9566D9C57A9C19ABD75F108370D1795639B6077167C0EFD3672FAE`; the
|
||||
transposed `Azeroth_49_31.adt` does not exist. Raw MCNK headers in that file
|
||||
show `indexX` decreasing world Y (east) and `indexY` decreasing world X (south).
|
||||
OpenRealm independently calculates filename X from world Y and filename Y from
|
||||
world X. Contract version 2 corrects the formulas before any consumer migration.
|
||||
|
||||
### Enforced conversion boundaries
|
||||
|
||||
GDScript production consumers use `CoordinateMapper` for canonical/Godot and
|
||||
Godot/ADT tile-local conversion. `StreamingWorldLoader`, player spawn/terrain
|
||||
sampling, sky/area lookup and terrain diagnostics may construct `Vector3` only
|
||||
at their scene/tool boundary.
|
||||
|
||||
The native ADT/WDT parser path retains one equivalent formula definition in
|
||||
`src/native/src/wow_chunk_reader.h`; worker parsers cannot call GDScript. The
|
||||
M00 renderer calibration keeps one independent formula as a test oracle so a
|
||||
shared mapper defect cannot make both implementation and evidence agree.
|
||||
Repository verification rejects additional world-center, world/tile or named
|
||||
WoW/Godot formulas outside those explicit exceptions. Model-local M2/WMO basis
|
||||
transforms are separate format contracts and are not classified as world-space mapping.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
### Make renderer coordinates canonical
|
||||
|
||||
Rejected because protocol, database and ADT adapters would silently inherit a
|
||||
presentation-specific offset and Y-up basis.
|
||||
|
||||
### Adopt WoWee's internal canonical axis names unchanged
|
||||
|
||||
Rejected because that reference swaps server X/Y into its chosen north/west
|
||||
ordering. OpenWC preserves observable client/server field names and makes the
|
||||
render/ADT transformations explicit instead.
|
||||
|
||||
### Use `Vector3` plus comments
|
||||
|
||||
Rejected because comments cannot prevent server, ADT and Godot values from
|
||||
being passed across the wrong boundary.
|
||||
|
||||
### Generic vector-space or matrix framework
|
||||
|
||||
Rejected as unnecessary complexity for fixed affine transforms and integer
|
||||
grid ownership rules.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Network and server-data adapters can expose typed positions without knowing
|
||||
Godot.
|
||||
- Renderer consumers must explicitly map and then create Godot vectors at their
|
||||
own boundary.
|
||||
- ADT filename indices can no longer be confused with renderer X/Z tile names.
|
||||
- GDScript world/tile consumers use mapper APIs; renderer distance and LOD math
|
||||
remains ordinary Godot-space geometry.
|
||||
- Native ADT/WDT loaders share one boundary formula and the M00 calibration
|
||||
keeps one independent non-production oracle.
|
||||
- New manual axis conversions are review/test violations enforced by the
|
||||
repository-wide source gate.
|
||||
- Persisted schemas are unchanged. Future serialized positions must include an
|
||||
explicit coordinate-space/version discriminator.
|
||||
|
||||
## Verification
|
||||
|
||||
- Five M00 build-12340 client camera positions map to the recorded Godot
|
||||
checkpoints within `0.002` yard.
|
||||
- Server, ADT placement, Godot and tile-local conversions round-trip.
|
||||
- Exact center, tile, chunk and world-extent boundaries have explicit tests.
|
||||
- The observed Elwynn position resolves to the real `Azeroth_31_49.adt` file;
|
||||
MCNK `(0,0)` to `(15,15)` origins confirm X-east and Y-south chunk growth.
|
||||
- World-yaw normalization and round-trip cases cover cardinal angles and wrap.
|
||||
- Direct Godot/ADT tile-local conversions round-trip and production consumers
|
||||
are checked by `verify_coordinate_conversion_boundaries.gd`.
|
||||
|
||||
## References
|
||||
|
||||
- [TrinityCore GridDefines](https://github.com/TrinityCore/TrinityCore/blob/master/src/server/game/Grids/GridDefines.h)
|
||||
- `reference/open-realm/games/world-of-warcraft/renderer/wow/r_wowmap_adt.c`
|
||||
- `reference/open-realm/games/world-of-warcraft/renderer/wow/r_wowmap_objects.c`
|
||||
- `reference/WoWee/include/core/coordinates.hpp`
|
||||
- [`../M00_FINAL_PAIRED_EVIDENCE.md`](../M00_FINAL_PAIRED_EVIDENCE.md)
|
||||
@@ -0,0 +1,122 @@
|
||||
# ADR 0002: Separate domain identity namespaces
|
||||
|
||||
- Status: Accepted for M01 contract implementation
|
||||
- Date: 2026-07-13
|
||||
- Work package: `M01-FND-DOMAIN-IDENTITIES-001`
|
||||
- Decision owners: M01 foundation/integration owners
|
||||
|
||||
## Context
|
||||
|
||||
OpenWC must relate authored content, runtime objects, WoW protocol objects and
|
||||
TrinityCore/AzerothCore rows. All four domains can expose an integer or string,
|
||||
but their identity lifetimes and collision rules are different. A raw `int`, a
|
||||
generic `id` field or one universal ID class would allow an entity sequence to
|
||||
be persisted as content identity, a database entry to be sent as a wire GUID,
|
||||
or equal entry numbers from different tables to collide.
|
||||
|
||||
The Content Project requires stable references before server entries are
|
||||
allocated. Runtime entities require cheap session-local identity even when no
|
||||
server object exists. WoW 3.3.5a GUIDs carry opaque 64 wire bits whose semantic
|
||||
decomposition must be established by protocol fixtures. Server templates use
|
||||
numeric entries scoped by an adapter/table namespace.
|
||||
|
||||
## Decision
|
||||
|
||||
### ContentId
|
||||
|
||||
`ContentId` stores canonical lowercase UUID text in the `8-4-4-4-12` shape.
|
||||
It is the only identity in this decision intended for stable authored-content
|
||||
references and serialization. Construction normalizes whitespace and letter
|
||||
case; `is_valid()` reports malformed input without crashing an import.
|
||||
|
||||
The value validates text shape, not UUID version or variant bits. A future
|
||||
Content Project allocator chooses the UUID generation policy and owns duplicate
|
||||
detection. Every persisted schema that contains a `ContentId` still declares
|
||||
its own schema version and field migration.
|
||||
|
||||
### EntityId
|
||||
|
||||
`EntityId` stores a positive integer allocated by one runtime session owner.
|
||||
It is valid only inside that session and must not be persisted as content,
|
||||
protocol or server identity. Sequence reuse policy belongs to the future entity
|
||||
registry, not the value object.
|
||||
|
||||
### WowGuid
|
||||
|
||||
`WowGuid` stores opaque `high_32_bits` and `low_32_bits` integers. Each word is
|
||||
validated against `0..0xffffffff`, preserving every unsigned wire bit without
|
||||
combining it into GDScript's signed 64-bit integer. The all-zero value remains
|
||||
an observable protocol sentinel and receives no gameplay interpretation here.
|
||||
|
||||
High-type masks, packed-GUID codecs and object-kind extraction are explicitly
|
||||
deferred to the build-12340 protocol package and require packet fixtures.
|
||||
|
||||
### ServerEntryId
|
||||
|
||||
`ServerEntryId` stores a positive numeric entry together with a normalized,
|
||||
non-empty adapter/table namespace. Equal numbers in different namespaces are
|
||||
different identities. Mapping a server entry to a `ContentId` is explicit
|
||||
adapter/snapshot data; neither value derives the other.
|
||||
|
||||
### Equality and keys
|
||||
|
||||
The types expose domain-named `equals` methods because `RefCounted` `==`
|
||||
compares object references. Stable keys are available only where their lifetime
|
||||
allows them: `ContentId.to_key()`, `WowGuid.to_hex_string()` and
|
||||
`ServerEntryId.to_key()`. `EntityId` exposes only `to_debug_key()` to discourage
|
||||
persistence.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
### One generic `Id<T>` abstraction
|
||||
|
||||
Rejected because GDScript has no compile-time generic type distinction and the
|
||||
shared API would obscure different validation, lifetime and persistence rules.
|
||||
|
||||
### Use strings everywhere
|
||||
|
||||
Rejected because prefixes are a convention rather than a type boundary and
|
||||
would still permit accidental cross-layer assignment.
|
||||
|
||||
### Store WowGuid in one integer
|
||||
|
||||
Rejected because unsigned 64-bit GUIDs can exceed GDScript's positive signed
|
||||
integer range. Split words preserve the wire representation losslessly.
|
||||
|
||||
### Use server entries as ContentId
|
||||
|
||||
Rejected because entries are allocated by a particular backend/table, can
|
||||
collide between namespaces and do not exist while authoring offline content.
|
||||
|
||||
### Generate UUIDs inside ContentId
|
||||
|
||||
Rejected because randomness/allocation is a side effect requiring duplicate,
|
||||
fixture and deterministic-build policy. This value object only normalizes and
|
||||
validates an allocator-provided value.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Cross-layer contracts must name the identity type they accept.
|
||||
- Content references remain stable before and after server deployment.
|
||||
- Runtime entity registries need explicit mappings to wire GUIDs/content IDs.
|
||||
- Server adapters must supply a namespace and maintain entry-to-content maps.
|
||||
- Malformed external values remain representable long enough for adapters to
|
||||
produce diagnostics, but consumers must call the relevant validation method.
|
||||
- Additional typed IDs such as map, spell, item and quest remain separate
|
||||
follow-up contracts rather than aliases of these four values.
|
||||
|
||||
## Verification
|
||||
|
||||
- UUID normalization, shape validation and value equality are fixture-tested.
|
||||
- Zero/positive session sequences establish `EntityId` validity boundaries.
|
||||
- Maximum unsigned GUID words round-trip to exactly sixteen hexadecimal digits;
|
||||
overflow is rejected and zero remains detectable.
|
||||
- Equal server entry numbers in creature/gameobject namespaces do not compare equal.
|
||||
- Dependency search verifies that identity values do not inherit Node/Resource
|
||||
or expose `Vector3`.
|
||||
|
||||
## References
|
||||
|
||||
- [RFC 9562: Universally Unique IDentifiers](https://www.rfc-editor.org/rfc/rfc9562.html)
|
||||
- [`../ARCHITECTURE.md`](../ARCHITECTURE.md)
|
||||
- [`../../targets/roadmap/01-foundation-and-data.md`](../../targets/roadmap/01-foundation-and-data.md)
|
||||
@@ -7,6 +7,8 @@
|
||||
| Module | Current status | Primary specification |
|
||||
|---|---|---|
|
||||
| Foundation/data | Planned/Partial | [`../../targets/roadmap/01-foundation-and-data.md`](../../targets/roadmap/01-foundation-and-data.md) |
|
||||
| Coordinate mapping | Implemented | [`coordinate-mapping.md`](coordinate-mapping.md) |
|
||||
| Domain identities | Implemented contract | [`domain-identities.md`](domain-identities.md) |
|
||||
| Renderer | Partial | [`world-renderer.md`](world-renderer.md), [`../../RENDER.md`](../../RENDER.md) |
|
||||
| Network/session | Planned | [`../../targets/roadmap/03-network-and-session.md`](../../targets/roadmap/03-network-and-session.md) |
|
||||
| Gameplay | Prototype/Planned | [`../../targets/roadmap/04-gameplay-systems.md`](../../targets/roadmap/04-gameplay-systems.md) |
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
# Coordinate Mapping
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Status | Implemented |
|
||||
| Target/work package | `M01-FND-COORDS-001`, `M01-FND-COORD-TILE-AXIS-002`, `M01-QAR-COORD-FIXTURES-001`, `M01-FND-COORD-BOUNDARY-GATE-001`, `M01-QAR-SERVER-SPAWN-RENDERER-001` |
|
||||
| Owners | Foundation/domain |
|
||||
| Last verified | Worktree `work/sindo-main-codex/m01-server-spawn-renderer`, 2026-07-13 |
|
||||
| Profiles/capabilities | All profiles; contract version 2 |
|
||||
|
||||
## Purpose
|
||||
|
||||
Provide scene-free value objects and one pure `CoordinateMapper` for positions,
|
||||
ADT grid ownership and world-facing yaw. The module makes every source space
|
||||
explicit before renderer, network, gameplay and authoring consumers migrate.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Reading ADT, packet, SQL or scene data.
|
||||
- Constructing `Vector3`, `Transform3D`, Node or Resource values.
|
||||
- Correcting M2/WMO local axes or MDDF/MODF Euler rotations.
|
||||
- Selecting maps, validating terrain height or owning streaming focus.
|
||||
- Persisting coordinate values in this work package.
|
||||
|
||||
## Context and boundaries
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Server[Server / movement X,Y,Z] --> ServerPosition[ServerWorldPosition]
|
||||
ADT[MDDF/MODF X,height,Z] --> AdtPosition[AdtPlacementPosition]
|
||||
ServerPosition --> Mapper[CoordinateMapper]
|
||||
AdtPosition --> Mapper
|
||||
Mapper --> Canonical[CanonicalWowWorldPosition]
|
||||
Canonical --> Tile[AdtTileCoordinate + AdtTileLocalPosition]
|
||||
Canonical --> GodotPosition[GodotWorldPosition]
|
||||
GodotPosition --> Adapter[Future scene/render adapter]
|
||||
Adapter --> Vector[Vector3 at boundary]
|
||||
Scene[Node / Camera3D / scene lookup] -. forbidden .-> Mapper
|
||||
```
|
||||
|
||||
Allowed dependencies:
|
||||
|
||||
- GDScript scalar math and `RefCounted` lifetime;
|
||||
- other value objects in `src/domain/coordinates`;
|
||||
- callers in network, gameplay, render and server-data adapters.
|
||||
|
||||
Forbidden dependencies:
|
||||
|
||||
- `Node`, `Resource`, SceneTree, Camera3D and global scene lookup;
|
||||
- packet buffers, SQL rows, asset parsers and renderer state;
|
||||
- `Vector3` as a public mapper input or output;
|
||||
- model-specific placement corrections.
|
||||
|
||||
## Public API
|
||||
|
||||
| Symbol | Kind | Purpose | Thread/lifetime | Errors |
|
||||
|---|---|---|---|---|
|
||||
| `CanonicalWowWorldPosition` | Immutable value | Client/server X/Y/Z in yards | Any thread; caller-owned reference | No bounds validation |
|
||||
| `ServerWorldPosition` | Immutable value | Server/wire X/Y/Z in yards | Any thread; caller-owned reference | No adapter validation |
|
||||
| `AdtPlacementPosition` | Immutable value | MDDF/MODF X/height/Z fields | Any thread; caller-owned reference | No file validation |
|
||||
| `GodotWorldPosition` | Immutable value | Godot east/up/south scalars | Any thread; caller-owned reference | Does not create `Vector3` |
|
||||
| `AdtTileCoordinate` | Immutable value | `Map_tileX_tileY.adt` indices | Any thread; caller-owned reference | `is_within_map_grid()` reports invalid indices |
|
||||
| `AdtTileLocalPosition` | Immutable value | East/height/south offsets from tile north-west corner | Any thread; caller-owned reference | Values are intentionally unclamped |
|
||||
| `AdtChunkCoordinate` | Immutable value | MCNK X-east/Y-south indices inside one tile | Any thread; caller-owned reference | `is_within_map_grid()` reports invalid indices |
|
||||
| `CanonicalWowWorldYaw` | Immutable value | Canonical world yaw in radians | Any thread; caller-owned reference | Constructor does not normalize |
|
||||
| `ServerWorldYaw` | Immutable value | Movement orientation in radians | Any thread; caller-owned reference | Constructor does not normalize |
|
||||
| `GodotWorldYaw` | Immutable value | Godot Y-axis world yaw in radians | Any thread; caller-owned reference | Constructor does not normalize |
|
||||
| `CoordinateMapper.server_to_canonical` / inverse | Pure static methods | Preserve server X/Y/Z as canonical | Synchronous; new result value | Null input is a caller contract violation |
|
||||
| `CoordinateMapper.canonical_to_godot` / inverse | Pure static methods | Apply Y-up renderer basis and map offset | Synchronous; new result value | Non-finite scalars propagate |
|
||||
| `CoordinateMapper.godot_to_adt_tile` | Pure static method | Resolve filename indices from typed renderer position | Synchronous; new result value | Result remains unclamped |
|
||||
| `CoordinateMapper.godot_to_adt_tile_local` | Pure static method | Resolve east/height/south offsets from typed renderer position | Synchronous; new result value | Caller validates ownership/range |
|
||||
| `CoordinateMapper.adt_tile_local_to_godot` | Pure static method | Compose typed renderer position from tile/local values | Synchronous; new result value | Non-finite scalars propagate |
|
||||
| `CoordinateMapper.canonical_to_adt_placement` / inverse | Pure static methods | Convert ADT placement field basis | Synchronous; new result value | Non-finite scalars propagate |
|
||||
| `CoordinateMapper.canonical_to_adt_tile` | Pure static method | Compute unclamped filename indices | Synchronous; new result value | Out-of-map result remains invalid |
|
||||
| `CoordinateMapper.canonical_to_adt_tile_local` / inverse | Pure static methods | Split/reconstruct tile-local position | Synchronous; new result value | Caller validates tile ownership |
|
||||
| `CoordinateMapper.adt_tile_local_to_chunk` | Pure static method | Compute unclamped MCNK indices | Synchronous; new result value | Boundary/out-of-range remains diagnosable |
|
||||
| World-yaw mapper methods | Pure static methods | Normalize and cross the world-basis boundary | Synchronous; new result value | Non-finite input is unsupported |
|
||||
|
||||
## Inputs and outputs
|
||||
|
||||
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|
||||
|---|---|---|---|---|---|
|
||||
| Input | `ServerWorldPosition`, `ServerWorldYaw` | Future protocol/server adapter | `CoordinateMapper` | Immutable caller value | Any thread, call duration |
|
||||
| Input | `AdtPlacementPosition` | Future ADT adapter | `CoordinateMapper` | Immutable caller value | Any thread, call duration |
|
||||
| Input | `CanonicalWowWorldPosition`, `CanonicalWowWorldYaw` | Gameplay/content/domain | `CoordinateMapper` | Immutable caller value | Any thread, call duration |
|
||||
| Output | `CanonicalWowWorldPosition` | `CoordinateMapper` | Gameplay/content/adapters | New immutable value | Caller-owned reference |
|
||||
| Output | `AdtTileCoordinate`, `AdtTileLocalPosition`, `AdtChunkCoordinate` | `CoordinateMapper` | Streaming/content adapters | New immutable values | Caller-owned references |
|
||||
| Output | `GodotWorldPosition`, `GodotWorldYaw` | `CoordinateMapper` | Future render/scene adapter | New immutable values | Caller-owned references |
|
||||
| Test input | `coordinate_golden_points.json` schema 1 | Pinned public server row plus private numeric observations | Headless fixture verifier | Versioned repository fixture | Test-process lifetime |
|
||||
|
||||
Side effects:
|
||||
|
||||
- none;
|
||||
- no scene mutation, file/cache write, network send, database access or logging.
|
||||
|
||||
## Data flow
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
ServerFixture[Pinned AzerothCore spawn] --> FixtureVerifier[Golden fixture verifier]
|
||||
RawADTFixture[Raw ADT numeric metadata] --> FixtureVerifier
|
||||
ClientFixture[Build 12340 observations] --> FixtureVerifier
|
||||
FixtureVerifier --> Mapper
|
||||
ServerFixture --> SpawnManifest[Server spawn render manifest]
|
||||
SpawnManifest --> SpawnVerifier[Renderer checkpoint verifier]
|
||||
SpawnVerifier --> Capture[Live renderer capture]
|
||||
Capture --> Marker[Diagnostic marker at mapped spawn]
|
||||
Server[ServerWorldPosition X,Y,Z] -->|identity components| Canonical[CanonicalWowWorldPosition]
|
||||
ADT[AdtPlacementPosition X,height,Z] -->|half extent - horizontal| Canonical
|
||||
Canonical -->|tileX from Y; tileY from X| Tile[AdtTileCoordinate]
|
||||
Canonical -->|north-west edge offsets| Local[AdtTileLocalPosition]
|
||||
Local -->|floor offset / chunk size| Chunk[AdtChunkCoordinate]
|
||||
Canonical -->|half extent - Y; Z; half extent - X| Godot[GodotWorldPosition]
|
||||
Godot -->|typed direct adapter| Tile
|
||||
Godot -->|typed direct adapter| Local
|
||||
Tile -->|tile plus local| Godot
|
||||
ServerYaw[ServerWorldYaw] -->|normalize only| CanonicalYaw[CanonicalWowWorldYaw]
|
||||
CanonicalYaw -->|same numeric world angle| GodotYaw[GodotWorldYaw]
|
||||
```
|
||||
|
||||
## Lifecycle/state
|
||||
|
||||
The module is stateless. Each call reads immutable scalar inputs and returns a
|
||||
new value object. There is no initialization, shutdown, cancellation or retry
|
||||
state machine.
|
||||
|
||||
## Main sequence
|
||||
|
||||
No cross-layer asynchronous sequence occurs inside this module. Producers parse
|
||||
or validate their external format first, call the mapper synchronously, and
|
||||
then pass only typed results across the next boundary.
|
||||
|
||||
## Ownership, threading and resources
|
||||
|
||||
- Value objects own only scalar fields and, for chunks, one immutable tile reference.
|
||||
- Callers own returned `RefCounted` references.
|
||||
- Methods do not mutate inputs or shared state and are safe for worker use.
|
||||
- No Node, RID, file, socket, database or cache resource is acquired.
|
||||
|
||||
## Errors, cancellation and recovery
|
||||
|
||||
| Failure | Detection | Behavior | Diagnostic | Recovery |
|
||||
|---|---|---|---|---|
|
||||
| Tile/chunk outside standard grid | `is_within_map_grid()` | Unclamped indices are preserved | Caller reports source and map context | Reject or apply explicit map policy |
|
||||
| Tile-local value outside half-open tile | Consumer boundary validation | Value is preserved | Caller reports source coordinate | Recompute ownership or reject malformed input |
|
||||
| Null value object | Static typing/call failure | Programming contract violation | GDScript error with call site | Fix producer; no fallback value |
|
||||
| NaN/infinite scalar | Adapter validation | Arithmetic propagates invalid value | Adapter must report source field | Reject malformed external input |
|
||||
|
||||
There is no cancellation because every conversion is constant-time scalar math.
|
||||
|
||||
## Configuration and capabilities
|
||||
|
||||
| Setting/capability | Default | Profile | Runtime mutable | Effect |
|
||||
|---|---|---|---|---|
|
||||
| Contract version | 2 | All | No | Corrected filename/chunk axes in ADR 0001 |
|
||||
| Godot units per WoW yard | 1 | `Blizzlike335` and current tools | No | Preserves current renderer scale |
|
||||
| ADT grid | 64 tiles/axis, 16 chunks/tile | WotLK 3.3.5a | No | Defines index and boundary math |
|
||||
|
||||
## Persistence, cache and migration
|
||||
|
||||
Production code adds no persisted format, cache or migration. Test schema 1 in
|
||||
`coordinate_golden_points.json` persists explicit source provenance, coordinate
|
||||
contract version 2, tolerances, source-space values and expected outputs. It
|
||||
contains no proprietary bytes, database dump or original-client image. Existing
|
||||
dictionaries, native `Vector3` payloads and renderer conversion helpers remain compatible.
|
||||
Consumer migration is ordered after this contract and must remove old manual
|
||||
conversions only after its producer/consumer tests pass.
|
||||
|
||||
Any future serialized coordinate must store a schema version and explicit space;
|
||||
raw three-number arrays are not an accepted new persistence contract.
|
||||
|
||||
## Diagnostics and observability
|
||||
|
||||
- Logs: none in production mapper.
|
||||
- Metrics: none; conversion cost is constant and outside frame-budget concern.
|
||||
- Debug views: headless contract probe prints one PASS summary.
|
||||
- Correlation IDs: supplied by external adapters if an invalid source is reported.
|
||||
|
||||
## Verification
|
||||
|
||||
- Unit/contract tests: `src/tools/verify_coordinate_mapper.gd`.
|
||||
- Cross-source golden test: `src/tools/verify_coordinate_golden_fixtures.gd`.
|
||||
- Boundary enforcement: `src/tools/verify_coordinate_conversion_boundaries.gd`.
|
||||
- Server-spawn renderer contract: `src/tools/verify_server_spawn_renderer.gd`
|
||||
validates the dedicated manifest against the same pinned fixture before GUI capture.
|
||||
- Integration/E2E: sky, player, streamer and terrain probe use mapper boundaries;
|
||||
`StreamingFocus` provides typed renderer focus, and the pinned AzerothCore
|
||||
Human Warrior spawn is captured in the Eastern Kingdoms renderer at ADT
|
||||
`(32,48)`, chunk `(3,12)`.
|
||||
- Fidelity evidence: five build-12340 camera positions from the M00 manifest map
|
||||
within `0.002` yard; a pinned AzerothCore human-warrior spawn and one raw MCNK
|
||||
header observation independently confirm tile `(32,48)` and chunk `(3,12)`;
|
||||
independent reference formulas are recorded in ADR 0001.
|
||||
- Performance budgets: constant-time arithmetic; no scene or file access.
|
||||
- Manual diagnostics: not required for the pure contract; renderer checkpoints
|
||||
are required when consumers migrate.
|
||||
|
||||
## Extension points
|
||||
|
||||
- Add typed map IDs around positions without changing axis semantics.
|
||||
- Add a format-specific placement-orientation adapter with its own fixtures.
|
||||
- Add serialization only with explicit space/version fields and migrations.
|
||||
- Add consumer adapters that construct engine-native vectors at their boundary.
|
||||
|
||||
## Capability status
|
||||
|
||||
| Capability | Status | Evidence | Gap/next step |
|
||||
|---|---|---|---|
|
||||
| Canonical/server/Godot position mapping | Implemented | Headless round-trip, five M00 golden points and migrated GDScript consumers | Network/server adapters remain future consumers |
|
||||
| ADT placement mapping | Implemented | Synthetic/direct round-trip fixtures | Compare native parsed placements during migration |
|
||||
| ADT tile/local/chunk ownership | Implemented | Center/extent boundaries, raw `Azeroth_31_49.adt` evidence and direct Godot adapter round-trip | Native parser remains explicit boundary |
|
||||
| World-facing yaw mapping | Implemented | Cardinal/wrap round-trip fixtures | Placement Euler remains separate |
|
||||
| Scene-free production contract | Implemented | Source boundary, headless tests and repository-wide conversion gate | Maintain gate with new consumers |
|
||||
| Cross-source coordinate fixture | Implemented | Pinned AzerothCore spawn, raw ADT MCNK metadata and five build-12340 points pass one headless verifier | Add live adapter/renderer integration |
|
||||
| TrinityCore populated spawn equivalence | Not verified | The base development schema has no pinned populated row used by this fixture | Pin and verify a TDB snapshot before claiming parity |
|
||||
| Visual/server-spawn integration | Implemented | Dedicated manifest/verifier plus cold/warm GUI capture of the mapped AzerothCore spawn | This is coordinate/renderer integration evidence, not original-client visual parity |
|
||||
|
||||
## Known gaps and risks
|
||||
|
||||
- Native ADT/WDT parsing retains one shared boundary formula because worker
|
||||
parsers cannot call GDScript; the gate prevents additional definitions.
|
||||
- Contract version 1 briefly transposed ADT filename/chunk axes; version 2 fixes
|
||||
the defect before any consumer migration.
|
||||
- MDDF/MODF rotation comments and implementations disagree across existing paths;
|
||||
this package deliberately does not generalize them into world yaw.
|
||||
- Finite-number validation belongs to external format adapters and is not yet implemented.
|
||||
- Arithmetic agreement does not prove terrain, placement, camera direction or visual parity.
|
||||
- The golden server row is verified against pinned AzerothCore data only; no
|
||||
TrinityCore equivalence claim is made without a pinned populated TDB snapshot.
|
||||
|
||||
## Source map
|
||||
|
||||
| Path | Responsibility |
|
||||
|---|---|
|
||||
| `src/domain/coordinates/coordinate_mapper.gd` | Constants and all coordinate-axis conversions |
|
||||
| `src/domain/coordinates/*_position.gd` | Immutable typed position values |
|
||||
| `src/domain/coordinates/adt_tile_coordinate.gd` | ADT filename tile indices and bounds |
|
||||
| `src/domain/coordinates/adt_chunk_coordinate.gd` | MCNK indices and bounds |
|
||||
| `src/domain/coordinates/*_yaw.gd` | Immutable typed world-facing yaw values |
|
||||
| `src/tools/verify_coordinate_mapper.gd` | Headless fixtures and boundary regressions |
|
||||
| `src/tests/fixtures/coordinate_golden_points.json` | Versioned cross-source values, provenance and tolerances |
|
||||
| `src/tools/verify_coordinate_golden_fixtures.gd` | Cross-source fixture schema and mapper validation |
|
||||
| `src/tools/verify_coordinate_conversion_boundaries.gd` | Repository-wide manual conversion and required-consumer gate |
|
||||
| `src/tools/server_spawn_render_manifest.json` | Pinned server-spawn camera, player, marker and expected ADT ownership |
|
||||
| `src/tools/verify_server_spawn_renderer.gd` | Fixture-to-renderer manifest contract verifier |
|
||||
| `docs/adr/0001-canonical-world-coordinates.md` | Normative axes, units, boundaries and rollout decision |
|
||||
|
||||
## Related decisions and references
|
||||
|
||||
- ADR: [`../adr/0001-canonical-world-coordinates.md`](../adr/0001-canonical-world-coordinates.md)
|
||||
- M00 evidence: [`../M00_FINAL_PAIRED_EVIDENCE.md`](../M00_FINAL_PAIRED_EVIDENCE.md)
|
||||
- Architecture: [`../ARCHITECTURE.md`](../ARCHITECTURE.md)
|
||||
- Testing rules: [`../TESTING.md`](../TESTING.md)
|
||||
@@ -0,0 +1,232 @@
|
||||
# Domain Identities
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Status | Implemented |
|
||||
| Target/work package | `M01-FND-DOMAIN-IDENTITIES-001` |
|
||||
| Owners | Foundation/domain |
|
||||
| Last verified | Worktree `work/sindo-main-codex/m01-domain-identities`, 2026-07-13 |
|
||||
| Profiles/capabilities | All profiles; identity contract version 1 |
|
||||
|
||||
## Purpose
|
||||
|
||||
Provide non-interchangeable, scene-free identity values for authored content,
|
||||
runtime entities, WoW wire objects and namespaced server entries. Each value
|
||||
states its lifetime and serialization rules instead of exposing a generic `id`.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Allocating, reserving or globally registering IDs.
|
||||
- Parsing packet bytes or server database rows.
|
||||
- Mapping GUID high types or server entries to gameplay object kinds.
|
||||
- Defining Content Project, snapshot or replay schemas.
|
||||
- Replacing future typed map/spell/item/quest/display/sound IDs.
|
||||
|
||||
## Context and boundaries
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Authoring[Content Project allocator] --> ContentId[ContentId]
|
||||
Session[Entity registry] --> EntityId[EntityId]
|
||||
Wire[Build 12340 packet adapter] --> WowGuid[WowGuid]
|
||||
Server[Core snapshot adapter] --> ServerEntry[ServerEntryId]
|
||||
ContentId --> Mapping[Explicit identity mapping records]
|
||||
EntityId --> Mapping
|
||||
WowGuid --> Mapping
|
||||
ServerEntry --> Mapping
|
||||
Mapping --> Consumers[Gameplay / network / authoring consumers]
|
||||
Raw[Raw int or string] -. forbidden across boundary .-> Consumers
|
||||
```
|
||||
|
||||
Allowed dependencies:
|
||||
|
||||
- GDScript scalar/string operations and `RefCounted` lifetime;
|
||||
- callers in content, gameplay, network and server adapter layers.
|
||||
|
||||
Forbidden dependencies:
|
||||
|
||||
- Node, Resource, SceneTree, renderer and UI state;
|
||||
- packet buffers, SQL connections or database table implementations;
|
||||
- implicit conversion between identity namespaces;
|
||||
- random/global allocation inside the value objects.
|
||||
|
||||
## Public API
|
||||
|
||||
| Symbol | Kind | Purpose | Thread/lifetime | Errors |
|
||||
|---|---|---|---|---|
|
||||
| `ContentId` | Immutable value | Stable authored identity as canonical lowercase UUID text | Any thread; persisted content lifetime | `is_valid()` reports malformed shape |
|
||||
| `ContentId.equals` | Pure method | Value equality across references | Call duration | Null compares false |
|
||||
| `ContentId.to_key` | Pure method | Canonical serialization/dictionary key | Stable across schema lifetime | Caller must validate first |
|
||||
| `EntityId` | Immutable value | Positive session-local runtime sequence | One runtime session | `is_valid()` rejects zero/negative |
|
||||
| `EntityId.equals` | Pure method | Equality within an explicitly shared session | Call duration | Cross-session comparison is a caller error |
|
||||
| `EntityId.to_debug_key` | Pure method | Non-persistent diagnostic label | Session/log lifetime | Must not be serialized as content |
|
||||
| `WowGuid` | Immutable value | Opaque unsigned high/low wire words | Packet/replay/entity mapping lifetime | `has_valid_word_ranges()` reports overflow |
|
||||
| `WowGuid.is_empty` | Pure method | Detect all-zero wire sentinel | Call duration | Does not assign semantic meaning |
|
||||
| `WowGuid.to_hex_string` | Pure method | Sixteen-digit diagnostic/replay key | Wire/replay lifetime | Caller validates ranges first |
|
||||
| `ServerEntryId` | Immutable value | Adapter/table namespace plus positive entry | Snapshot/deployment mapping lifetime | `is_valid()` rejects missing namespace/non-positive entry |
|
||||
| `ServerEntryId.to_key` | Pure method | Namespaced mapping key | Snapshot/schema lifetime | Caller validates first |
|
||||
|
||||
## Inputs and outputs
|
||||
|
||||
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|
||||
|---|---|---|---|---|---|
|
||||
| Input | UUID text | Future Content Project allocator/parser | `ContentId` | Copied normalized string | Build/content lifetime |
|
||||
| Input | Session sequence | Future entity registry | `EntityId` | Copied integer | One runtime session |
|
||||
| Input | Two unsigned 32-bit words | Future build-12340 packet codec | `WowGuid` | Copied integers | Packet/replay/entity lifetime |
|
||||
| Input | Namespace and numeric entry | Future core snapshot adapter | `ServerEntryId` | Copied normalized string/integer | Snapshot/deployment lifetime |
|
||||
| Output | Validation/equality/key results | Identity values | Adapters/registries/schemas | Returned scalar/string | Call duration |
|
||||
|
||||
Side effects:
|
||||
|
||||
- none;
|
||||
- no allocation registry, random generation, file/cache write, packet read,
|
||||
database query, scene mutation or logging.
|
||||
|
||||
## Data flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
ContentSource[Authored document] -->|UUID text| ContentId
|
||||
ServerRow[Backend table row] -->|adapter + table + entry| ServerEntryId
|
||||
Packet[World packet] -->|high/low wire words| WowGuid
|
||||
Registry[Session entity allocator] -->|positive sequence| EntityId
|
||||
ServerEntryId --> DeployMap[Explicit deployment mapping]
|
||||
ContentId --> DeployMap
|
||||
WowGuid --> RuntimeMap[Explicit runtime mapping]
|
||||
EntityId --> RuntimeMap
|
||||
DeployMap --> Snapshot[Versioned snapshot/change set]
|
||||
RuntimeMap --> WorldState[Session world state]
|
||||
```
|
||||
|
||||
## Lifecycle/state
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
state ContentIdentity {
|
||||
[*] --> Parsed
|
||||
Parsed --> Persisted: valid ContentId
|
||||
Persisted --> Referenced
|
||||
}
|
||||
state RuntimeIdentity {
|
||||
[*] --> Allocated
|
||||
Allocated --> Active
|
||||
Active --> Released: session owner removes entity
|
||||
Released --> [*]
|
||||
}
|
||||
state ExternalIdentity {
|
||||
[*] --> Observed
|
||||
Observed --> Mapped: WowGuid or ServerEntryId
|
||||
Mapped --> Stale: disconnect or snapshot replacement
|
||||
Stale --> [*]
|
||||
}
|
||||
```
|
||||
|
||||
The values themselves are stateless and immutable. Allocation, release,
|
||||
mapping and stale-state ownership belong to future registries/adapters.
|
||||
|
||||
## Main sequence
|
||||
|
||||
Identity construction and validation are synchronous. An external adapter reads
|
||||
its format, constructs the matching value, validates it, then publishes an
|
||||
explicit mapping or typed domain event. No value object performs I/O or retries.
|
||||
|
||||
## Ownership, threading and resources
|
||||
|
||||
- Values own only copied strings/integers and are caller-owned `RefCounted` references.
|
||||
- Public methods do not mutate values or shared state and are worker-safe.
|
||||
- Content/session/wire/server mapping records are owned by their future layer,
|
||||
not by these values.
|
||||
- No Node, RID, file, socket, database, lock or cache resource is acquired.
|
||||
|
||||
## Errors, cancellation and recovery
|
||||
|
||||
| Failure | Detection | Behavior | Diagnostic | Recovery |
|
||||
|---|---|---|---|---|
|
||||
| Malformed ContentId | `is_valid()` | Invalid value remains inspectable | Source field/path supplied by parser | Regenerate or repair authored ID |
|
||||
| Invalid EntityId sequence | `is_valid()` | Registry must reject publication | Session/correlation context | Fix allocator/session mapping |
|
||||
| GUID word overflow | `has_valid_word_ranges()` | Codec must reject packet/replay value | Packet offset/opcode context | Reject malformed input; do not truncate |
|
||||
| Empty GUID | `is_empty()` | Preserved as protocol sentinel | Adapter decides whether field permits empty | Apply opcode/field-specific rule |
|
||||
| Missing server namespace/entry | `is_valid()` | Snapshot adapter rejects mapping | Backend/table/row context | Correct adapter schema mapping |
|
||||
| Unknown/stale mapping | Registry/snapshot lookup | No implicit numeric fallback | Typed IDs in diagnostic | Refresh snapshot/session or reject event |
|
||||
|
||||
There is no cancellation inside constant-time value operations.
|
||||
|
||||
## Configuration and capabilities
|
||||
|
||||
| Setting/capability | Default | Profile | Runtime mutable | Effect |
|
||||
|---|---|---|---|---|
|
||||
| Identity contract version | 1 | All | No | Four separate namespaces and validation rules |
|
||||
| ContentId text form | Lowercase `8-4-4-4-12` UUID | Authoring/runtime/tools | No | Stable persisted key |
|
||||
| GUID decomposition | Opaque two-word storage | `wotlk_335a_build_12340` | No | Prevents unverified high-type assumptions |
|
||||
|
||||
## Persistence, cache and migration
|
||||
|
||||
- `ContentId.uuid_text` is the only stable persisted identity introduced here.
|
||||
- Containing schemas must store their own schema version and duplicate/reference policy.
|
||||
- `EntityId` must never be persisted across sessions.
|
||||
- `WowGuid` may appear in versioned packet replays as explicit high/low words or
|
||||
the exact sixteen-digit hex form; a replay schema owns that choice.
|
||||
- `ServerEntryId` may appear in snapshots only with both namespace and entry.
|
||||
- This package is additive and migrates no existing data or cache.
|
||||
|
||||
## Diagnostics and observability
|
||||
|
||||
- Stable diagnostics use `ContentId.to_key`, `WowGuid.to_hex_string` and
|
||||
`ServerEntryId.to_key`.
|
||||
- Runtime diagnostics may use `EntityId.to_debug_key` with a session correlation ID.
|
||||
- Production metrics/logging belong to registries and adapters; values emit none.
|
||||
|
||||
## Verification
|
||||
|
||||
- Contract test: `src/tools/verify_domain_identities.gd`.
|
||||
- Fixtures cover UUID normalization/malformed shape, positive/zero session IDs,
|
||||
maximum/overflow GUID words, zero GUID and cross-table server entry collisions.
|
||||
- Dependency gate confirms no Node/Resource/Vector3 exposure.
|
||||
- Fidelity boundary: GUID bit meaning remains unclaimed until build-12340 packet fixtures.
|
||||
- Performance: constant-time integer checks and a bounded 36-character UUID scan.
|
||||
|
||||
## Extension points
|
||||
|
||||
- Content Project allocator and duplicate/reference validation.
|
||||
- Session-owned entity registry and explicit `WowGuid ↔ EntityId` mappings.
|
||||
- Backend capability adapters that define server entry namespaces.
|
||||
- Separate typed map/spell/item/quest/display/sound values.
|
||||
- Fixture-backed build-12340 GUID high-type decoding in the protocol layer.
|
||||
|
||||
## Capability status
|
||||
|
||||
| Capability | Status | Evidence | Gap/next step |
|
||||
|---|---|---|---|
|
||||
| Stable authored ContentId | Implemented contract | UUID normalization/validation fixtures | Allocator and schema arrive with Content Project |
|
||||
| Session-local EntityId | Implemented contract | Positive/zero/equality fixtures | Registry lifecycle arrives with gameplay world state |
|
||||
| Lossless opaque WowGuid | Implemented contract | Full unsigned words and hex fixture | Packet codec/high-type semantics need build-12340 fixtures |
|
||||
| Namespaced ServerEntryId | Implemented contract | Cross-table collision fixture | Backend namespace capability mapping arrives with server adapters |
|
||||
| Cross-namespace mappings | Planned | Architecture/ADR boundary | Implement only in owning registries/adapters |
|
||||
|
||||
## Known gaps and risks
|
||||
|
||||
- No allocator or duplicate registry exists yet.
|
||||
- GDScript `==` compares references; consumers must use domain `equals` methods
|
||||
or canonical keys until a registry owns keying.
|
||||
- UUID shape validation deliberately does not enforce generation version/variant.
|
||||
- Server namespace vocabulary is adapter-owned and not yet centrally catalogued.
|
||||
- GUID high-type/object-kind semantics remain unverified rather than guessed.
|
||||
|
||||
## Source map
|
||||
|
||||
| Path | Responsibility |
|
||||
|---|---|
|
||||
| `src/domain/identity/content_id.gd` | Stable canonical UUID content identity |
|
||||
| `src/domain/identity/entity_id.gd` | Session-local runtime identity |
|
||||
| `src/domain/identity/wow_guid.gd` | Opaque unsigned WoW wire identity |
|
||||
| `src/domain/identity/server_entry_id.gd` | Namespaced backend entry identity |
|
||||
| `src/tools/verify_domain_identities.gd` | Headless value/boundary regression |
|
||||
| `docs/adr/0002-domain-identity-namespaces.md` | Normative namespace/lifetime decision |
|
||||
|
||||
## Related decisions and references
|
||||
|
||||
- ADR: [`../adr/0002-domain-identity-namespaces.md`](../adr/0002-domain-identity-namespaces.md)
|
||||
- Architecture: [`../ARCHITECTURE.md`](../ARCHITECTURE.md)
|
||||
- Foundation plan: [`../../targets/roadmap/01-foundation-and-data.md`](../../targets/roadmap/01-foundation-and-data.md)
|
||||
@@ -5,9 +5,9 @@
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Status | Partial |
|
||||
| Target/work package | M00 active; декомпозиция M01–M03 |
|
||||
| Target/work package | M00 baseline; `M01-RND-STREAMING-FOCUS-001`; `M01-QAR-SERVER-SPAWN-RENDERER-001`; декомпозиция M02–M03 |
|
||||
| Owners | Renderer workstream / milestone integrator |
|
||||
| Last verified | M00 visual-diff worktree, 2026-07-11 |
|
||||
| Last verified | Worktree `work/sindo-main-codex/m01-server-spawn-renderer`, 2026-07-13 |
|
||||
| Profiles/capabilities | `Performance`, `Balanced`, `High`, `Custom`; Blizzlike fidelity incomplete |
|
||||
|
||||
## Purpose
|
||||
@@ -26,7 +26,13 @@
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Focus[Camera/player/editor focus] --> Loader[StreamingWorldLoader]
|
||||
Player[Player or spectator Node3D] --> Adapter[Explicit source adapter]
|
||||
Editor[Editor viewport adapter] --> Focus[StreamingFocus]
|
||||
Capture[Capture tool] --> Adapter
|
||||
SpawnFixture[Pinned server spawn fixture] --> SpawnManifest[Spawn render manifest]
|
||||
SpawnManifest --> Capture
|
||||
Adapter --> Focus
|
||||
Focus --> Loader[StreamingWorldLoader]
|
||||
Assets[Extracted WDT/ADT/M2/WMO/BLP] --> Native[Native loaders]
|
||||
Cache[Baked terrain/M2/WMO caches] --> Loader
|
||||
Native --> Parsed[Parsed tile/model data]
|
||||
@@ -60,7 +66,11 @@ Forbidden dependencies:
|
||||
|---|---|---|---|---|
|
||||
| `map_name` | Exported property | WDT/map directory name | Set before world load | Missing WDT produces diagnostic/empty world |
|
||||
| `extracted_dir` | Exported property | Root of legally extracted client data | Session lifetime | Missing files reported per loader path |
|
||||
| `camera_path` | Exported property | Current streaming focus compatibility path | Main thread, scene lifetime | Missing camera prevents normal focus update |
|
||||
| `StreamingFocus` | Immutable value | Typed Godot-basis position without Node/Camera dependency | Any thread; caller-owned reference | Null position is a caller contract violation |
|
||||
| `streaming_focus_source_path` | Exported adapter property | Samples any explicit `Node3D` source into `StreamingFocus` | Main thread, scene lifetime | Missing/wrong node warns once and retains prior focus |
|
||||
| `set_streaming_focus` | Public method | Accepts focus from app/editor/tool composition | Main thread/session | Null focus is ignored by refresh until replaced |
|
||||
| `refresh_streaming_focus` | Public method | Samples configured source and applies refresh thresholds | Main thread/session | Returns `false` when no valid focus exists |
|
||||
| `camera_path` | Exported property | Camera used only by optional automatic overview positioning | Main thread, scene lifetime | Missing camera skips automatic positioning |
|
||||
| `quality_preset` | Exported property | Applies renderer budgets/radii | Before/at runtime depending property | Invalid combination should be diagnosed |
|
||||
| `runtime_stats_enabled` | Exported property | Enables periodic performance snapshot | Runtime mutable | Logging overhead only |
|
||||
| `hitch_profiler_enabled` | Exported property | Enables named hitch sections | Runtime mutable | Logging overhead only |
|
||||
@@ -71,12 +81,16 @@ Forbidden dependencies:
|
||||
|
||||
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|
||||
|---|---|---|---|---|---|
|
||||
| Input | Map/focus/configuration | Scene/app/editor | `StreamingWorldLoader` | Caller config, copied/read | Main thread/session |
|
||||
| Input | `StreamingFocus` | Player/spectator/editor/capture adapter | `StreamingWorldLoader` | Immutable caller value | Main thread/session |
|
||||
| Input | Focus-source `NodePath` | Runtime/test scene composition | Loader source adapter | Scene-owned node, sampled position | Main thread/scene lifetime |
|
||||
| Input | Map/configuration | Scene/app/editor | `StreamingWorldLoader` | Caller config, copied/read | Main thread/session |
|
||||
| Input | WDT/ADT/M2/WMO/BLP bytes | Extracted asset repository | Native loaders/builders | Loader result owns parsed data | Worker or controlled load |
|
||||
| Input | Baked resources | Cache build tools | Streamer/builders | Shared immutable resource/cache entry | Session/cache lifetime |
|
||||
| Test input | Server-spawn render manifest | Coordinate fixture/verifier | Checkpoint capture tool | Repository-owned diagnostic data | Test-process lifetime |
|
||||
| Output | Desired tile/detail operations | Streaming planner inside loader | Finalize queues | Loader-owned | Cross-frame |
|
||||
| Output | Terrain/M2/WMO/liquid instances | Loader/builders | Godot world/renderer | Loader/world owner | Main-thread attach |
|
||||
| Output | Metrics/diagnostics | Hitch/stat instrumentation | Logs/baseline tools | Immutable records | Periodic/frame |
|
||||
| Test output | Diagnostic spawn marker and cold/warm PNGs | Checkpoint capture tool | Human/integrator review | SceneTree marker; `user://` files | One capture process |
|
||||
|
||||
Side effects:
|
||||
|
||||
@@ -90,7 +104,15 @@ Side effects:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
F[Streaming focus] --> T[Compute desired ADT tiles]
|
||||
P[Player/spectator Node3D] --> A[Explicit scene adapter]
|
||||
C[Capture camera] --> A
|
||||
SF[Pinned server spawn] --> SM[Validated spawn manifest]
|
||||
SM --> C
|
||||
SM --> Marker[Renderer-native origin marker]
|
||||
E[Editor viewport] --> EA[Editor adapter]
|
||||
A --> F[StreamingFocus]
|
||||
EA --> F
|
||||
F --> T[Compute desired ADT tiles]
|
||||
WDT[WDT tile catalog] --> T
|
||||
T --> Q[Tile load queue]
|
||||
Q --> P[Worker parse/cache load]
|
||||
@@ -104,6 +126,7 @@ flowchart TD
|
||||
M2 --> World
|
||||
WMO --> World
|
||||
Liquid --> World
|
||||
Marker --> World
|
||||
F --> E[Eviction/retention decisions]
|
||||
E --> World
|
||||
```
|
||||
@@ -113,13 +136,14 @@ flowchart TD
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Initializing
|
||||
Initializing --> Ready: WDT/catalog/config ready
|
||||
Initializing --> WaitingForFocus: WDT/catalog/config ready
|
||||
Initializing --> Degraded: missing loaders/data/cache
|
||||
Ready --> Streaming: focus update
|
||||
WaitingForFocus --> Streaming: valid StreamingFocus
|
||||
Streaming --> Streaming: load/finalize/evict ticks
|
||||
Streaming --> WaitingForFocus: world reset without replacement focus
|
||||
Streaming --> SwitchingMap: map/focus reset
|
||||
SwitchingMap --> Initializing
|
||||
Ready --> ShuttingDown
|
||||
WaitingForFocus --> ShuttingDown
|
||||
Degraded --> ShuttingDown
|
||||
Streaming --> ShuttingDown
|
||||
ShuttingDown --> [*]
|
||||
@@ -129,12 +153,14 @@ stateDiagram-v2
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Focus as Camera/Player/Editor
|
||||
participant Source as Player/Editor/Capture source
|
||||
participant Focus as StreamingFocus adapter
|
||||
participant Stream as StreamingWorldLoader
|
||||
participant Worker as Worker task
|
||||
participant Budget as Main-thread budget
|
||||
participant Render as SceneTree/RenderingServer
|
||||
Focus->>Stream: focus position changed
|
||||
Source->>Focus: sample explicit Godot position
|
||||
Focus->>Stream: set/refresh typed focus
|
||||
Stream->>Stream: desired tiles and priorities
|
||||
Stream->>Worker: parse/load tile and detail data
|
||||
Worker-->>Stream: immutable result
|
||||
@@ -150,6 +176,8 @@ sequenceDiagram
|
||||
## Ownership, threading and resources
|
||||
|
||||
- `StreamingWorldLoader` владеет tile states, queues, task registries, active world instances и render caches session scope.
|
||||
- Focus producers own the immutable `StreamingFocus` reference; the loader retains
|
||||
the latest reference and converts it to `Vector3` only inside the render boundary.
|
||||
- Worker tasks не должны менять SceneTree и shared Resource concurrently.
|
||||
- Parsed/grouped results передаются обратно через guarded result queues.
|
||||
- Mesh/material/node/RID finalization выполняется main thread и ограничивается exported budgets.
|
||||
@@ -163,6 +191,8 @@ sequenceDiagram
|
||||
| Failure | Detection | Behavior | Diagnostic | Recovery |
|
||||
|---|---|---|---|---|
|
||||
| Missing WDT/ADT | File/catalog check | Tile/map unavailable | Loader warning/error | Fix extraction/profile, reload |
|
||||
| Missing focus source | Explicit NodePath resolution | Retain current streamed content and prior valid focus | One warning until source recovers | Fix composition path or call `set_streaming_focus` |
|
||||
| No focus supplied | Refresh contract | No target recomputation; queues continue draining | `refresh_streaming_focus()` returns `false` | Supply player/editor/capture focus |
|
||||
| Cache version mismatch | Required format constant | Reject stale cache/fallback | Version diagnostic | Rebuild matching cache |
|
||||
| Worker failure | Task result/empty data | Skip/degrade affected asset | Queue/task warning | Retry/rebuild source |
|
||||
| Main-thread hitch | Named section timing | Frame spike, work remains queued | `HITCH` log | Lower budget/fix finalize path |
|
||||
@@ -184,6 +214,9 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
||||
|
||||
## Persistence, cache and migration
|
||||
|
||||
- `StreamingFocus` is runtime-only and is not serialized. Scene migration adds
|
||||
`streaming_focus_source_path`; existing `camera_path` remains valid only for
|
||||
optional automatic overview positioning.
|
||||
- Renderer reads caches under `data/cache`; caches are not committed.
|
||||
- Format changes require `FORMAT_VERSION`/required-version bump and rebuild instructions.
|
||||
- Atomic cache publication and unified manifest are target-state work from FND/M03.
|
||||
@@ -198,8 +231,9 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
||||
|
||||
## Verification
|
||||
|
||||
- Unit/contract tests: material mapping, unique-ID dedupe, placement probes, baseline manifest, five-point coordinate calibration, synthetic perceptual checkpoint diff, camera-pose grid plan.
|
||||
- Integration/E2E: Eastern Kingdoms/Kalimdor streaming scenes and seven cold/warm checkpoints.
|
||||
- Unit/contract tests: streaming-focus contract/wiring, material mapping, unique-ID dedupe, placement probes, baseline manifest, five-point coordinate calibration, synthetic perceptual checkpoint diff, camera-pose grid plan.
|
||||
- Integration/E2E: Eastern Kingdoms/Kalimdor streaming scenes, seven M00
|
||||
cold/warm checkpoints and one dedicated mapped server-spawn checkpoint.
|
||||
- Fidelity evidence: семь локальных build 12340 reference JPG покрывают terrain/ADT/M2/WMO/liquid/sky и реальный `GryphonRoost01`; automated cold/warm metrics имеют `compared=14`, `missing=0`. Sky использует приблизительно paired camera, а animated-M2 остаётся asset-paired/placement-unpaired из-за synthetic probe.
|
||||
- Performance budgets: M00 report records cold/warm p95 and max hitch; no final acceptance threshold yet.
|
||||
- Manual diagnostics: [`../RENDER_BASELINE.md`](../RENDER_BASELINE.md) and [`../../RENDER.md`](../../RENDER.md).
|
||||
@@ -207,7 +241,7 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
||||
## Extension points
|
||||
|
||||
- Target `WorldRenderFacade` for runtime/editor/capture callers.
|
||||
- Target `StreamingFocus` independent of Camera3D.
|
||||
- Extend `StreamingFocus` with measured direction/velocity needs when the pure planner is extracted.
|
||||
- Extracted planner, budget scheduler, terrain, M2, WMO, liquid, sky and character services.
|
||||
- Separate Blizzlike/Enhanced material and quality profiles.
|
||||
|
||||
@@ -221,12 +255,15 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
||||
| Liquids | Partial | MH2O/MLIQ paths | LiquidType/depth/shore fidelity |
|
||||
| Sky/light | Partial | DBC controller/logs | Zone transition paired validation |
|
||||
| Character presentation | Prototype | Character creator/player experiment | Full customization/equipment states |
|
||||
| Camera-independent streaming focus | Implemented | Typed contract, two player-focused runtime scenes and three explicitly camera-focused diagnostic tools | Multi-focus/direction/velocity belong to planner extraction |
|
||||
| Golden server-spawn visualization | Implemented | Pinned AzerothCore fixture, validated renderer manifest and diagnostic origin-marker capture at ADT `(32,48)`/MCNK `(3,12)` | No TrinityCore row or original-client visual-parity claim |
|
||||
| Stable renderer facade | Planned | M03 | Current caller uses monolithic Node API |
|
||||
|
||||
## Known gaps and risks
|
||||
|
||||
- Monolithic streamer mixes planning, jobs, caches and presentation.
|
||||
- Direct camera path remains until M01/M03.
|
||||
- `camera_path` remains only for optional automatic overview positioning; it no
|
||||
longer drives runtime streaming or discovers the active viewport camera.
|
||||
- Original-client paired fidelity evidence incomplete.
|
||||
- Первый paired run выявил coordinate/placement mismatch: несколько совпадающих server-derived camera positions оказываются под terrain или внутри WMO/rocks OpenWC.
|
||||
- Terrain-height probe исключил under-terrain состояние для всех пяти точек; waterfall exact-XZ miss классифицирован как TriangleMesh seam/edge и подтверждён nearby sample в 2 units.
|
||||
@@ -247,6 +284,8 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
||||
| Path | Responsibility |
|
||||
|---|---|
|
||||
| `src/scenes/streaming/streaming_world_loader.gd` | Current runtime orchestration, queues, caches and attachment |
|
||||
| `src/domain/streaming/streaming_focus.gd` | Immutable camera-independent streaming position contract |
|
||||
| `src/tools/verify_streaming_focus.gd` | Headless contract, dependency and runtime/tool wiring regression |
|
||||
| `addons/mpq_extractor/loaders/adt_builder.gd` | Terrain/material/liquid construction |
|
||||
| `addons/mpq_extractor/loaders/m2_builder.gd` | Static M2 mesh/material construction |
|
||||
| `addons/mpq_extractor/loaders/m2_native_animated_builder.gd` | Native animated M2 experiment |
|
||||
@@ -258,6 +297,8 @@ Exact exported settings and cache versions remain documented in [`../../RENDER.m
|
||||
| `src/tools/compare_render_checkpoints.gd` | Offline JPG/PNG paired-image perceptual metrics and JSON pass/fail report |
|
||||
| `src/tools/verify_render_runtime_cache_shutdown.gd` | Headless ownership regression for detached runtime prototypes, resource caches and empty liquid roots |
|
||||
| `src/tools/capture_render_checkpoints.gd` | Deterministic no-roll checkpoint camera, performance and visual capture |
|
||||
| `src/tools/server_spawn_render_manifest.json` | Dedicated mapped AzerothCore spawn checkpoint and diagnostic marker configuration |
|
||||
| `src/tools/verify_server_spawn_renderer.gd` | Fixture-to-renderer checkpoint contract verification |
|
||||
| `tools/sweep_render_checkpoint_camera_pose.ps1` | Offline yaw/pitch capture grid and paired-error ranking |
|
||||
| `src/tools/verify_render_coordinate_calibration.gd` | Build 12340 camera-coordinate golden point round-trip diagnostic |
|
||||
| `src/tools/probe_render_terrain_height.gd` | Offline active-mesh terrain height and camera-clearance report |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,676 @@
|
||||
Godot Engine v4.6.1.stable.official.14d19694e - https://godotengine.org
|
||||
Vulkan 1.4.341 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5070
|
||||
|
||||
WowSkyController: loaded 850 LightParams profiles, 2307 area records and 81 Azeroth light volumes
|
||||
SKY_LIGHT time=13.00 map=0 area=12:Элвиннский лес zone=12:Элвиннский лес wow=(-9333.3,266.7,67.2) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 12, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded 687 ADT tiles from WDT for Azeroth
|
||||
StreamingWorld: focus_tile=(32, 48) wanted=276 queued=276
|
||||
StreamingWorld: focus_tile=(32, 48) wanted=276 queued=275
|
||||
StreamingWorld: loaded tile 32,48
|
||||
HITCH 267.98ms refresh=true queues[tile=274 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=0 wmobuild=1 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=10.75 terrainq=254.39 details=2.73
|
||||
StreamingWorld: loaded tile 31,48
|
||||
WMOLoader: loaded 12 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_spidermine/md_spidermine.wmo
|
||||
HITCH 631.67ms refresh=true queues[tile=273 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=1 wmobuild=2 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.12 terrainq=112.75 m2results=0.08 m2build=0.35 wmobuild=515.68 details=0.57
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded tile 32,49
|
||||
WMOLoader: loaded 286 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/stormwind.wmo
|
||||
HITCH 5842.59ms refresh=true queues[tile=272 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=2 wmobuild=3 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=5.00 terrainq=101.38 m2results=0.07 wmobuild=5729.42 details=6.53 refresh=0.08
|
||||
StreamingWorld: loaded tile 31,49
|
||||
WMOLoader: loaded 10 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_goldmine/md_goldmine.wmo
|
||||
HITCH 216.94ms refresh=true queues[tile=271 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=3 wmobuild=4 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.00 terrainq=101.58 m2results=0.09 wmobuild=107.46 details=5.59 refresh=0.11
|
||||
StreamingWorld: loaded tile 32,47
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/redridge_stable/redridge_stable.wmo
|
||||
HITCH 142.16ms refresh=true queues[tile=270 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=4 wmobuild=5 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.73 terrainq=119.08 m2results=0.10 wmobuild=18.56 details=0.45 refresh=0.14
|
||||
StreamingWorld: loaded tile 33,48
|
||||
WMOLoader: loaded 14 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/nsabbey/nsabbey.wmo
|
||||
HITCH 206.43ms refresh=true queues[tile=269 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=5 wmobuild=6 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=1.75 terrainq=93.29 m2results=0.08 m2build=0.39 wmobuild=109.28 details=1.45 refresh=0.13
|
||||
StreamingWorld: loaded tile 31,47
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/elwynn/widebridge/elwynnwidebridge.wmo
|
||||
HITCH 116.63ms refresh=true queues[tile=268 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=6 wmobuild=7 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=1.18 terrainq=100.00 m2results=0.09 m2build=0.38 wmobuild=14.70 details=0.09 refresh=0.12
|
||||
StreamingWorld: loaded tile 33,49
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/elwynn/abbeygate/abbeygate01.wmo
|
||||
TERRAIN_QUALITY target=8 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=8 queue=0 focus=32_48:stream done=false
|
||||
HITCH 145.09ms refresh=true queues[tile=267 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=6 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.12 terrainq=104.05 m2build=0.40 wmobuild=32.40 details=2.44 refresh=2.61
|
||||
StreamingWorld: loaded tile 30,48
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/elwynn/abbeygate02/abbeygate02.wmo
|
||||
HITCH 148.60ms refresh=true queues[tile=266 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=7 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.55 terrainq=120.53 m2results=0.10 m2build=0.37 wmobuild=24.71 details=0.16 refresh=0.12
|
||||
StreamingWorld: loaded tile 33,47
|
||||
HITCH 124.33ms refresh=true queues[tile=265 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=8 wmobuild=9 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.29 terrainq=121.22 m2results=0.07 m2build=0.42 details=0.11 refresh=0.12
|
||||
StreamingWorld: loaded tile 32,50
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/keepwall/wallpost01.wmo
|
||||
HITCH 146.34ms refresh=true queues[tile=264 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=9 wmobuild=10 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.37 terrainq=119.65 m2results=0.07 m2build=0.40 wmobuild=18.19 details=4.45 refresh=0.14
|
||||
StreamingWorld: loaded tile 30,49
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/keepwall/wallpiece01.wmo
|
||||
HITCH 146.33ms refresh=true queues[tile=263 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=10 wmobuild=11 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.99 terrainq=122.59 m2results=0.09 m2build=0.38 wmobuild=19.46 details=0.62 refresh=0.13
|
||||
StreamingWorld: loaded tile 31,50
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/human_farm/farm.wmo
|
||||
HITCH 154.25ms refresh=true queues[tile=262 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=11 wmobuild=12 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.83 terrainq=112.99 m2results=0.08 m2build=0.43 wmobuild=29.62 details=7.09 refresh=0.14
|
||||
StreamingWorld: loaded tile 30,47
|
||||
HITCH 121.05ms refresh=true queues[tile=261 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=12 wmobuild=12 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.52 terrainq=117.75 m2results=0.09 m2build=0.36 details=0.11 refresh=0.14
|
||||
StreamingWorld: loaded tile 33,50
|
||||
DBG QUEUES tiles_load=260 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=15
|
||||
PERF fps=6.0 tiles=15 wanted=15 retained=15 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=15 lod_rid=15 lod_node=0 lod_hidden=0 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=260 detail=0 m2_task=1 m2_anim=0 m2_mesh=0 m2_build=13 wmo_build=13 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=13 m2_mm=0 m2_inst=0 wmo=11
|
||||
HITCH 117.47ms refresh=true queues[tile=260 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=13 wmobuild=13 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.42 terrainq=107.04 m2results=0.08 details=4.80 refresh=2.01
|
||||
StreamingWorld: loaded tile 32,46
|
||||
TERRAIN_QUALITY target=16 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=16 queue=0 focus=32_48:stream done=false
|
||||
HITCH 103.23ms refresh=true queues[tile=259 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=14 wmobuild=14 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.33 terrainq=96.01 m2results=0.09 m2build=0.47 refresh=4.19
|
||||
StreamingWorld: loaded tile 34,48
|
||||
HITCH 97.18ms refresh=true queues[tile=258 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=14 wmobuild=15 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.64 terrainq=91.08 m2build=0.38 wmobuild=1.83 details=1.06 refresh=0.13
|
||||
StreamingWorld: loaded tile 31,46
|
||||
WMOLoader: loaded 12 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/goldshireinn/goldshireinn.wmo
|
||||
HITCH 179.81ms refresh=true queues[tile=257 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=15 wmobuild=16 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=1.13 terrainq=94.46 m2results=0.08 m2build=0.39 wmobuild=83.48 details=0.07 refresh=0.13
|
||||
StreamingWorld: loaded tile 34,49
|
||||
HITCH 113.35ms refresh=true queues[tile=256 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=15 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=1.99 terrainq=105.96 m2build=0.39 details=4.77 refresh=0.14
|
||||
StreamingWorld: loaded tile 30,50
|
||||
HITCH 213.78ms refresh=true queues[tile=255 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=16 wmobuild=18 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.50 terrainq=201.63 m2results=0.16 m2build=0.61 wmobuild=0.06 details=8.50 refresh=0.23
|
||||
StreamingWorld: loaded tile 33,46
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/humantwostory/humantwostory.wmo
|
||||
HITCH 189.71ms refresh=true queues[tile=254 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=17 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=5.34 terrainq=120.10 m2results=0.12 m2build=0.53 wmobuild=62.78 details=0.52 refresh=0.21
|
||||
StreamingWorld: loaded tile 34,47
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_animalden/animalden.wmo
|
||||
HITCH 204.90ms refresh=true queues[tile=253 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=18 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.70 terrainq=177.62 m2results=0.08 m2build=0.38 wmobuild=23.52 details=0.36 refresh=0.15
|
||||
StreamingWorld: loaded tile 29,48
|
||||
HITCH 168.79ms refresh=true queues[tile=252 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=19 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=8.66 terrainq=158.61 m2results=0.09 m2build=0.53 wmobuild=0.05 details=0.58 refresh=0.18
|
||||
StreamingWorld: loaded tile 30,46
|
||||
HITCH 118.54ms refresh=true queues[tile=251 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=20 wmobuild=21 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=1.42 terrainq=116.43 m2results=0.08 m2build=0.35 refresh=0.13
|
||||
StreamingWorld: loaded tile 32,51
|
||||
TERRAIN_QUALITY target=25 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=25 queue=0 focus=32_48:stream done=false
|
||||
HITCH 142.71ms refresh=true queues[tile=250 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=20 wmobuild=22 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.29 terrainq=134.68 m2build=0.38 details=1.40 refresh=3.84
|
||||
StreamingWorld: loaded tile 29,49
|
||||
HITCH 111.03ms refresh=true queues[tile=249 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=21 wmobuild=23 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=9.63 terrainq=97.87 m2results=0.09 m2build=0.41 wmobuild=2.68 details=0.17 refresh=0.13
|
||||
StreamingWorld: loaded tile 31,51
|
||||
HITCH 150.85ms refresh=true queues[tile=248 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=22 wmobuild=24 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.22 terrainq=136.81 m2results=0.07 m2build=0.35 wmobuild=2.37 details=7.82 refresh=0.14
|
||||
StreamingWorld: loaded tile 34,50
|
||||
HITCH 112.68ms refresh=true queues[tile=247 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=23 wmobuild=25 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.58 terrainq=101.24 m2results=0.09 m2build=0.35 wmobuild=2.31 details=5.92 refresh=0.13
|
||||
StreamingWorld: loaded tile 29,47
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/goldshireblacksmith/goldshireblacksmith.wmo
|
||||
HITCH 155.75ms refresh=true queues[tile=246 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=24 wmobuild=26 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=6.22 terrainq=96.94 m2results=0.13 m2build=0.42 wmobuild=49.94 details=1.87 refresh=0.16
|
||||
StreamingWorld: loaded tile 33,51
|
||||
HITCH 121.17ms refresh=true queues[tile=245 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=25 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.39 terrainq=116.68 m2results=0.10 m2build=0.42 details=1.25 refresh=0.22
|
||||
StreamingWorld: loaded tile 34,46
|
||||
DBG QUEUES tiles_load=244 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=31
|
||||
PERF fps=5.0 tiles=31 wanted=31 retained=31 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=31 lod_rid=31 lod_node=0 lod_hidden=0 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=244 detail=0 m2_task=1 m2_anim=0 m2_mesh=0 m2_build=26 wmo_build=27 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=26 m2_mm=0 m2_inst=0 wmo=19
|
||||
HITCH 106.72ms refresh=true queues[tile=244 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=26 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.55 terrainq=102.04 m2results=0.13 m2build=0.42 wmobuild=0.05 details=0.36 refresh=1.07
|
||||
StreamingWorld: loaded tile 29,50
|
||||
StreamingWorld: loaded tile 32,45
|
||||
HITCH 125.49ms refresh=false queues[tile=242 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=29 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=4.19 terrainq=116.70 m2results=0.13 m2build=0.56 wmobuild=3.73 details=0.06
|
||||
StreamingWorld: loaded tile 30,51
|
||||
TERRAIN_QUALITY target=34 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=34 queue=0 focus=32_48:stream done=false
|
||||
HITCH 25.58ms refresh=true queues[tile=241 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=28 wmobuild=29 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=4.24 terrainq=10.25 m2build=0.58 wmobuild=0.06 details=5.00 refresh=5.33
|
||||
StreamingWorld: loaded tile 31,45
|
||||
HITCH 157.95ms refresh=false queues[tile=240 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=29 wmobuild=29 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=1.65 terrainq=151.68 m2results=0.10 m2build=0.40 wmobuild=4.05
|
||||
StreamingWorld: loaded tile 35,48
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_human_farm_burnt/westfallfarmhouseburnt.wmo
|
||||
HITCH 34.69ms refresh=true queues[tile=239 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=29 wmobuild=30 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=1.47 terrainq=15.32 m2build=0.42 wmobuild=17.07 details=0.16 refresh=0.16
|
||||
StreamingWorld: loaded tile 35,49
|
||||
HITCH 108.19ms refresh=false queues[tile=238 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=30 wmobuild=30 wmogroups=0 lod+=3 lod-=0 chunk+=0 chunk-=0] finalize=2.21 terrainq=104.15 m2results=0.08 m2build=0.38 details=1.26
|
||||
StreamingWorld: loaded tile 33,45
|
||||
StreamingWorld: loaded tile 29,46
|
||||
HITCH 92.67ms refresh=false queues[tile=236 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=31 wmogroups=0 lod+=4 lod-=0 chunk+=0 chunk-=0] finalize=2.82 terrainq=89.23 m2results=0.08 m2build=0.41
|
||||
StreamingWorld: loaded tile 35,47
|
||||
StreamingWorld: loaded tile 34,51
|
||||
HITCH 123.59ms refresh=false queues[tile=234 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=33 wmobuild=33 wmogroups=0 lod+=5 lod-=0 chunk+=0 chunk-=0] finalize=2.68 terrainq=110.27 m2results=0.09 m2build=0.43 wmobuild=2.81 details=7.20
|
||||
StreamingWorld: loaded tile 30,45
|
||||
HITCH 31.27ms refresh=true queues[tile=233 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=33 wmogroups=0 lod+=5 lod-=0 chunk+=0 chunk-=0] finalize=1.53 terrainq=28.61 m2results=0.10 m2build=0.41 wmobuild=0.39 refresh=0.17
|
||||
StreamingWorld: loaded tile 28,48
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/magetower/magetower.wmo
|
||||
HITCH 163.22ms refresh=false queues[tile=232 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=32 wmogroups=0 lod+=6 lod-=0 chunk+=0 chunk-=0] finalize=10.85 terrainq=101.97 m2build=0.50 wmobuild=49.81
|
||||
StreamingWorld: loaded tile 35,50
|
||||
StreamingWorld: loaded tile 28,49
|
||||
WMOLoader: loaded 45 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/az_blackrock/blackrock.wmo
|
||||
HITCH 1822.26ms refresh=false queues[tile=230 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=31 wmogroups=0 lod+=7 lod-=0 chunk+=0 chunk-=0] finalize=14.63 terrainq=116.23 m2build=0.43 wmobuild=1690.89
|
||||
StreamingWorld: loaded tile 32,52
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/human_barn_silo/barn.wmo
|
||||
TERRAIN_QUALITY target=46 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=46 queue=0 focus=32_48:stream done=false
|
||||
HITCH 43.10ms refresh=true queues[tile=229 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=32 wmogroups=0 lod+=7 lod-=0 chunk+=0 chunk-=0] finalize=1.53 terrainq=7.63 m2build=0.44 wmobuild=28.24 details=0.07 refresh=5.09
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded tile 31,52
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/human_barn_silo/silo.wmo
|
||||
HITCH 119.84ms refresh=false queues[tile=228 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=33 wmogroups=0 lod+=8 lod-=0 chunk+=0 chunk-=0] finalize=3.21 terrainq=97.72 m2build=0.51 wmobuild=18.25 details=0.06
|
||||
StreamingWorld: loaded tile 29,51
|
||||
StreamingWorld: loaded tile 28,47
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/redridge/redridgedocks02/redridgedocks02.wmo
|
||||
HITCH 130.26ms refresh=false queues[tile=226 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=35 wmogroups=0 lod+=9 lod-=0 chunk+=0 chunk-=0] finalize=11.15 terrainq=100.96 m2build=0.42 wmobuild=17.56 details=0.06
|
||||
StreamingWorld: loaded tile 34,45
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/worldtree/duskworldtree.wmo
|
||||
HITCH 48.19ms refresh=true queues[tile=225 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=35 wmogroups=0 lod+=9 lod-=0 chunk+=0 chunk-=0] finalize=1.54 terrainq=7.12 m2build=0.39 wmobuild=38.80 details=0.09 refresh=0.19
|
||||
StreamingWorld: loaded tile 35,46
|
||||
HITCH 134.74ms refresh=false queues[tile=224 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=35 wmogroups=0 lod+=10 lod-=0 chunk+=0 chunk-=0] finalize=2.88 terrainq=131.29 m2build=0.45
|
||||
StreamingWorld: loaded tile 33,52
|
||||
StreamingWorld: loaded tile 28,50
|
||||
WMOLoader: loaded 28 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/human_barracks/human_barracks.wmo
|
||||
HITCH 288.28ms refresh=false queues[tile=222 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=36 wmogroups=0 lod+=11 lod-=0 chunk+=0 chunk-=0] finalize=12.86 terrainq=88.93 m2build=0.47 wmobuild=185.86 details=0.06
|
||||
StreamingWorld: loaded tile 30,52
|
||||
StreamingWorld: loaded tile 29,45
|
||||
DBG QUEUES tiles_load=220 tile_lod_create=12 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=55
|
||||
PERF fps=2.0 tiles=55 wanted=55 retained=55 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=43 lod_node=0 lod_hidden=0 lod_prepared=12 chunk_rid=0 chunk_node=0 queues[tile=220 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=34 wmo_build=37 wmo_groups=0 lod+=12 lod-=0 chunk+=0 chunk-=0] m2_tiles=34 m2_mm=0 m2_inst=0 wmo=36
|
||||
HITCH 117.55ms refresh=false queues[tile=220 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=37 wmogroups=0 lod+=12 lod-=0 chunk+=0 chunk-=0] finalize=2.70 terrainq=110.05 m2build=0.53 wmobuild=3.09
|
||||
StreamingWorld: loaded tile 32,44
|
||||
StreamingWorld: loaded tile 31,44
|
||||
WMOLoader: loaded 22 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_goldmine/md_goldmine_varianta.wmo
|
||||
HITCH 271.13ms refresh=false queues[tile=218 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=38 wmogroups=0 lod+=13 lod-=0 chunk+=0 chunk-=0] finalize=2.83 terrainq=99.62 m2build=0.49 wmobuild=168.01 details=0.08
|
||||
StreamingWorld: loaded tile 28,46
|
||||
TERRAIN_QUALITY target=58 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=58 queue=0 focus=32_48:stream done=false
|
||||
HITCH 22.82ms refresh=true queues[tile=217 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=38 wmogroups=0 lod+=13 lod-=0 chunk+=0 chunk-=0] finalize=9.31 terrainq=7.97 m2build=0.38 wmobuild=0.59 refresh=4.49
|
||||
StreamingWorld: loaded tile 36,48
|
||||
HITCH 94.48ms refresh=false queues[tile=216 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=39 wmogroups=0 lod+=14 lod-=0 chunk+=0 chunk-=0] finalize=1.55 terrainq=92.36 m2build=0.42
|
||||
StreamingWorld: loaded tile 35,51
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stable/stable.wmo
|
||||
HITCH 25.35ms refresh=true queues[tile=215 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=39 wmogroups=0 lod+=14 lod-=0 chunk+=0 chunk-=0] finalize=2.06 terrainq=8.04 m2build=0.41 wmobuild=14.54 refresh=0.22
|
||||
StreamingWorld: loaded tile 36,49
|
||||
HITCH 106.11ms refresh=false queues[tile=214 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=40 wmogroups=0 lod+=15 lod-=0 chunk+=0 chunk-=0] finalize=6.62 terrainq=98.80 m2build=0.53
|
||||
StreamingWorld: loaded tile 33,44
|
||||
StreamingWorld: loaded tile 34,52
|
||||
WMOLoader: loaded 13 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_crypt/md_crypt_c.wmo
|
||||
HITCH 1166.42ms refresh=false queues[tile=212 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=41 wmogroups=0 lod+=16 lod-=0 chunk+=0 chunk-=0] finalize=2.58 terrainq=101.20 m2build=0.41 wmobuild=1062.05 details=0.09
|
||||
StreamingWorld: loaded tile 36,47
|
||||
StreamingWorld: loaded tile 30,44
|
||||
HITCH 95.39ms refresh=false queues[tile=210 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=43 wmogroups=0 lod+=17 lod-=0 chunk+=0 chunk-=0] finalize=1.61 terrainq=91.60 m2build=0.42 wmobuild=1.60
|
||||
StreamingWorld: loaded tile 35,45
|
||||
StreamingWorld: loaded tile 28,51
|
||||
HITCH 105.01ms refresh=false queues[tile=208 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=45 wmogroups=0 lod+=18 lod-=0 chunk+=0 chunk-=0] finalize=2.57 terrainq=98.89 m2build=0.52 wmobuild=2.86 details=0.08
|
||||
StreamingWorld: loaded tile 29,52
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/stormwindhangar.wmo
|
||||
HITCH 45.41ms refresh=true queues[tile=207 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=46 wmogroups=0 lod+=18 lod-=0 chunk+=0 chunk-=0] finalize=1.86 terrainq=7.11 m2build=0.39 wmobuild=35.69 details=0.06 refresh=0.22
|
||||
StreamingWorld: loaded tile 36,50
|
||||
HITCH 105.53ms refresh=false queues[tile=206 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=47 wmogroups=0 lod+=19 lod-=0 chunk+=0 chunk-=0] finalize=3.17 terrainq=98.93 m2build=0.48 wmobuild=2.82 details=0.05
|
||||
StreamingWorld: loaded tile 27,48
|
||||
StreamingWorld: loaded tile 27,49
|
||||
HITCH 115.65ms refresh=false queues[tile=204 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=47 wmogroups=0 lod+=20 lod-=0 chunk+=0 chunk-=0] finalize=11.92 terrainq=100.20 m2build=0.43 wmobuild=3.00
|
||||
StreamingWorld: loaded tile 32,53
|
||||
TERRAIN_QUALITY target=72 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=72 queue=0 focus=32_48:stream done=false
|
||||
StreamingWorld: loaded tile 34,44
|
||||
HITCH 105.00ms refresh=false queues[tile=202 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=48 wmogroups=0 lod+=21 lod-=0 chunk+=0 chunk-=0] finalize=1.73 terrainq=102.62 m2build=0.45 wmobuild=0.06 details=0.05
|
||||
StreamingWorld: loaded tile 31,53
|
||||
StreamingWorld: loaded tile 27,47
|
||||
HITCH 115.77ms refresh=false queues[tile=200 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=49 wmogroups=0 lod+=22 lod-=0 chunk+=0 chunk-=0] finalize=11.73 terrainq=100.67 m2build=0.41 wmobuild=2.87
|
||||
StreamingWorld: loaded tile 36,46
|
||||
StreamingWorld: loaded tile 28,45
|
||||
HITCH 115.99ms refresh=false queues[tile=198 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=50 wmogroups=0 lod+=23 lod-=0 chunk+=0 chunk-=0] finalize=12.05 terrainq=100.26 m2build=0.46 wmobuild=3.14
|
||||
StreamingWorld: loaded tile 33,53
|
||||
StreamingWorld: loaded tile 29,44
|
||||
HITCH 108.98ms refresh=false queues[tile=196 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=50 wmogroups=0 lod+=24 lod-=0 chunk+=0 chunk-=0] finalize=14.07 terrainq=94.19 m2build=0.52
|
||||
StreamingWorld: loaded tile 27,50
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_caveden/md_mushroomden.wmo
|
||||
HITCH 92.63ms refresh=true queues[tile=195 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=50 wmogroups=0 lod+=24 lod-=0 chunk+=0 chunk-=0] finalize=11.34 terrainq=7.19 m2build=0.48 wmobuild=73.23 details=0.06 refresh=0.25
|
||||
StreamingWorld: loaded tile 35,52
|
||||
HITCH 117.26ms refresh=true queues[tile=194 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=50 wmogroups=0 lod+=25 lod-=0 chunk+=0 chunk-=0] finalize=2.42 terrainq=114.32 m2build=0.08 details=0.05 refresh=0.29
|
||||
StreamingWorld: loaded tile 30,53
|
||||
DBG QUEUES tiles_load=193 tile_lod_create=25 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=82
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/lumbermill/lumbermill.wmo
|
||||
PERF fps=5.0 tiles=82 wanted=82 retained=82 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=57 lod_node=0 lod_hidden=0 lod_prepared=25 chunk_rid=0 chunk_node=0 queues[tile=193 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=33 wmo_build=51 wmo_groups=0 lod+=25 lod-=0 chunk+=0 chunk-=0] m2_tiles=33 m2_mm=0 m2_inst=0 wmo=56
|
||||
HITCH 50.36ms refresh=true queues[tile=193 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=51 wmogroups=0 lod+=25 lod-=0 chunk+=0 chunk-=0] finalize=2.13 terrainq=8.18 m2build=0.06 wmobuild=37.13 details=0.10 refresh=2.64
|
||||
StreamingWorld: loaded tile 36,51
|
||||
HITCH 108.96ms refresh=false queues[tile=192 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=52 wmogroups=0 lod+=26 lod-=0 chunk+=0 chunk-=0] finalize=3.46 terrainq=103.24 m2build=0.06 wmobuild=2.07 details=0.05
|
||||
StreamingWorld: loaded tile 27,46
|
||||
HITCH 21.02ms refresh=true queues[tile=191 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=52 wmogroups=0 lod+=26 lod-=0 chunk+=0 chunk-=0] finalize=12.22 terrainq=7.83 m2build=0.06 wmobuild=0.53 refresh=0.30
|
||||
StreamingWorld: loaded tile 32,43
|
||||
TERRAIN_QUALITY target=85 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=85 queue=0 focus=32_48:stream done=false
|
||||
HITCH 97.40ms refresh=false queues[tile=190 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=53 wmogroups=0 lod+=27 lod-=0 chunk+=0 chunk-=0] finalize=2.83 terrainq=85.79 m2build=0.08 wmobuild=0.53 details=0.05
|
||||
StreamingWorld: loaded tile 31,43
|
||||
StreamingWorld: loaded tile 28,52
|
||||
HITCH 120.33ms refresh=false queues[tile=188 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=54 wmogroups=0 lod+=28 lod-=0 chunk+=0 chunk-=0] finalize=9.23 terrainq=109.50 m2build=0.07 wmobuild=1.40 details=0.05
|
||||
StreamingWorld: loaded tile 34,53
|
||||
StreamingWorld: loaded tile 37,48
|
||||
HITCH 99.29ms refresh=false queues[tile=186 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=56 wmogroups=0 lod+=29 lod-=0 chunk+=0 chunk-=0] finalize=1.75 terrainq=97.34 m2build=0.07
|
||||
StreamingWorld: loaded tile 35,44
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/guardtower/guardtower.wmo
|
||||
HITCH 56.40ms refresh=true queues[tile=185 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=57 wmogroups=0 lod+=29 lod-=0 chunk+=0 chunk-=0] finalize=1.74 terrainq=7.31 m2build=0.07 wmobuild=46.88 details=0.09 refresh=0.24
|
||||
StreamingWorld: loaded tile 37,49
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/elwynn/lionbridge/elwynnlionbridge.wmo
|
||||
HITCH 119.77ms refresh=false queues[tile=184 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=58 wmogroups=0 lod+=30 lod-=0 chunk+=0 chunk-=0] finalize=3.60 terrainq=99.15 m2build=0.06 wmobuild=16.81 details=0.06
|
||||
StreamingWorld: loaded tile 36,45
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/moonbrook_human_farm/moonbrook_human_farm.wmo
|
||||
HITCH 33.69ms refresh=true queues[tile=183 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=59 wmogroups=0 lod+=30 lod-=0 chunk+=0 chunk-=0] finalize=1.78 terrainq=7.29 m2build=0.07 wmobuild=24.15 details=0.07 refresh=0.23
|
||||
StreamingWorld: loaded tile 33,43
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_humantwostory/westfall_humantwostory.wmo
|
||||
HITCH 154.81ms refresh=false queues[tile=182 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=59 wmogroups=0 lod+=31 lod-=0 chunk+=0 chunk-=0] finalize=2.97 terrainq=98.54 m2build=0.48 wmobuild=52.68 details=0.06
|
||||
StreamingWorld: loaded tile 37,47
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/altarofstorms/altarofstorms.wmo
|
||||
HITCH 73.71ms refresh=true queues[tile=181 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=60 wmogroups=0 lod+=31 lod-=0 chunk+=0 chunk-=0] finalize=2.88 terrainq=6.97 m2build=0.34 wmobuild=63.06 details=0.09 refresh=0.26
|
||||
StreamingWorld: loaded tile 27,51
|
||||
HITCH 115.23ms refresh=false queues[tile=180 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=60 wmogroups=0 lod+=32 lod-=0 chunk+=0 chunk-=0] finalize=10.65 terrainq=104.38 m2build=0.06
|
||||
StreamingWorld: loaded tile 29,53
|
||||
StreamingWorld: loaded tile 30,43
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/trollburrow/trollburrow.wmo
|
||||
TERRAIN_QUALITY target=97 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=97 queue=0 focus=32_48:stream done=false
|
||||
HITCH 139.79ms refresh=false queues[tile=178 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=62 wmogroups=0 lod+=33 lod-=0 chunk+=0 chunk-=0] finalize=3.04 terrainq=100.88 m2build=0.07 wmobuild=28.77 details=0.07
|
||||
StreamingWorld: loaded tile 37,50
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orcblacksmith/orcblacksmith.wmo
|
||||
HITCH 41.75ms refresh=true queues[tile=177 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=63 wmogroups=0 lod+=33 lod-=0 chunk+=0 chunk-=0] finalize=2.31 terrainq=7.38 m2build=0.06 wmobuild=31.61 details=0.06 refresh=0.23
|
||||
StreamingWorld: loaded tile 28,44
|
||||
HITCH 108.28ms refresh=false queues[tile=176 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=63 wmogroups=0 lod+=34 lod-=0 chunk+=0 chunk-=0] finalize=10.72 terrainq=95.61 m2build=0.06 wmobuild=1.80
|
||||
StreamingWorld: loaded tile 27,45
|
||||
StreamingWorld: loaded tile 26,48
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_docks.wmo
|
||||
HITCH 246.89ms refresh=false queues[tile=174 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=62 wmogroups=0 lod+=35 lod-=0 chunk+=0 chunk-=0] finalize=12.27 terrainq=105.58 m2build=0.06 wmobuild=128.89
|
||||
StreamingWorld: loaded tile 34,43
|
||||
WMOLoader: loaded 4 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/transports/transport_ship/transportship.wmo
|
||||
HITCH 344.09ms refresh=true queues[tile=173 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=62 wmogroups=0 lod+=35 lod-=0 chunk+=0 chunk-=0] finalize=1.88 terrainq=7.72 m2build=0.40 wmobuild=333.61 refresh=0.38
|
||||
StreamingWorld: loaded tile 36,52
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_lowmain.wmo
|
||||
HITCH 124.59ms refresh=true queues[tile=172 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=62 wmogroups=0 lod+=36 lod-=0 chunk+=0 chunk-=0] finalize=2.10 terrainq=101.32 m2build=0.54 wmobuild=20.30 refresh=0.26
|
||||
StreamingWorld: loaded tile 26,49
|
||||
StreamingWorld: loaded tile 37,46
|
||||
HITCH 103.09ms refresh=false queues[tile=170 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=60 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.04 terrainq=100.86 m2build=0.09
|
||||
StreamingWorld: loaded tile 32,54
|
||||
DBG QUEUES tiles_load=169 tile_lod_create=37 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=106
|
||||
PERF fps=9.0 tiles=106 wanted=106 retained=106 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=69 lod_node=0 lod_hidden=0 lod_prepared=37 chunk_rid=0 chunk_node=0 queues[tile=169 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=32 wmo_build=60 wmo_groups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] m2_tiles=32 m2_mm=0 m2_inst=0 wmo=73
|
||||
StreamingWorld: loaded tile 35,53
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/nightelfmoonwell/dsnightelfmoonwellornate.wmo
|
||||
HITCH 42.52ms refresh=false queues[tile=168 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=59 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.42 terrainq=7.09 m2build=0.06 wmobuild=32.86
|
||||
StreamingWorld: loaded tile 26,47
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/collidabledoodads/darkshore/wreckedelvendestroyer/elvendestroyerwreckback.wmo
|
||||
HITCH 55.79ms refresh=false queues[tile=167 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=59 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=11.66 terrainq=7.57 m2build=0.06 wmobuild=36.42
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded tile 31,54
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 21.08ms refresh=true queues[tile=166 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=58 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=4.79 terrainq=7.34 m2build=0.08 refresh=8.75
|
||||
StreamingWorld: loaded tile 29,43
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/duskwood/opengrave/duskwoodopengrave.wmo
|
||||
HITCH 27.04ms refresh=false queues[tile=165 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=58 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=5.53 terrainq=7.64 m2build=0.09 wmobuild=13.68
|
||||
StreamingWorld: loaded tile 33,54
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_humantwostory/duskwood_humantwostory.wmo
|
||||
HITCH 58.93ms refresh=false queues[tile=164 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=58 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=1.89 terrainq=7.39 m2build=0.06 wmobuild=49.51
|
||||
StreamingWorld: loaded tile 26,50
|
||||
StreamingWorld: loaded tile 37,51
|
||||
HITCH 35.11ms refresh=false queues[tile=162 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=57 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=3.52 terrainq=31.42 m2build=0.06
|
||||
StreamingWorld: loaded tile 30,54
|
||||
HITCH 22.07ms refresh=false queues[tile=161 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=57 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=7.34 terrainq=14.15 m2build=0.07 wmobuild=0.43
|
||||
StreamingWorld: loaded tile 27,52
|
||||
StreamingWorld: loaded tile 36,44
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/collidabledoodads/wetlandsfootbridge/wetlandsfootbridge01.wmo
|
||||
HITCH 22.78ms refresh=false queues[tile=159 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=1.88 terrainq=7.33 m2build=0.06 wmobuild=13.43
|
||||
StreamingWorld: loaded tile 28,53
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/northrend/buildings/human/icebreaker/transport_icebreaker_ship_nomasts.wmo
|
||||
HITCH 49.88ms refresh=false queues[tile=158 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=7.95 terrainq=13.66 m2build=0.07 wmobuild=28.13
|
||||
StreamingWorld: loaded tile 26,46
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_shipshelter.wmo
|
||||
HITCH 35.34ms refresh=true queues[tile=157 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.66 terrainq=7.39 m2build=0.06 wmobuild=14.85 refresh=0.30
|
||||
StreamingWorld: loaded tile 35,43
|
||||
StreamingWorld: loaded tile 37,45
|
||||
StreamingWorld: loaded tile 34,54
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_lowtwr.wmo
|
||||
HITCH 26.09ms refresh=false queues[tile=154 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=4.85 terrainq=7.57 m2build=0.08 wmobuild=13.50
|
||||
StreamingWorld: loaded tile 32,42
|
||||
StreamingWorld: loaded tile 31,42
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_lowstr.wmo
|
||||
HITCH 37.22ms refresh=false queues[tile=152 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.96 terrainq=20.71 m2build=0.07 wmobuild=13.37
|
||||
StreamingWorld: loaded tile 27,44
|
||||
HITCH 24.69ms refresh=false queues[tile=151 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=10.93 terrainq=13.25 m2build=0.41
|
||||
StreamingWorld: loaded tile 38,48
|
||||
StreamingWorld: loaded tile 26,51
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_lowstair.wmo
|
||||
HITCH 37.62ms refresh=true queues[tile=149 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=15.06 terrainq=7.23 m2build=0.38 wmobuild=14.51 refresh=0.36
|
||||
StreamingWorld: loaded tile 33,42
|
||||
StreamingWorld: loaded tile 38,49
|
||||
StreamingWorld: loaded tile 29,54
|
||||
StreamingWorld: loaded tile 28,43
|
||||
HITCH 20.82ms refresh=true queues[tile=145 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=56 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.59 terrainq=7.21 m2build=0.39 wmobuild=0.30 refresh=0.26
|
||||
StreamingWorld: loaded tile 38,47
|
||||
RENDER_CHECKPOINT saved C:/Users/sindo/AppData/Roaming/Godot/app_userdata/OpenWC/server_spawn_renderer_m01_gui/azerothcore_human_warrior_start__cold_process.png sha256=9aaa04f1c836fb9aff7387a8d2f10dc69e379778309b0b1013a668e5b3ee9eaa
|
||||
StreamingWorld: focus_tile=(32, 48) wanted=276 queued=144
|
||||
StreamingWorld: loaded tile 36,53
|
||||
StreamingWorld: loaded tile 30,42
|
||||
StreamingWorld: loaded tile 37,52
|
||||
HITCH 27.24ms refresh=false queues[tile=141 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=55 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=3.52 terrainq=23.46 m2build=0.10
|
||||
StreamingWorld: loaded tile 26,45
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/collidabledoodads/mulgore/taurentent01/taurentent01.wmo
|
||||
HITCH 58.92ms refresh=true queues[tile=140 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=55 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=23.05 terrainq=13.01 m2build=0.10 wmobuild=22.19 refresh=0.43
|
||||
StreamingWorld: loaded tile 38,50
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 29.89ms refresh=false queues[tile=139 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=55 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=4.20 terrainq=12.34 m2build=0.09 wmobuild=0.52
|
||||
StreamingWorld: loaded tile 34,42
|
||||
StreamingWorld: loaded tile 35,54
|
||||
HITCH 31.42ms refresh=false queues[tile=137 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=54 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=4.43 terrainq=26.82 m2build=0.06
|
||||
StreamingWorld: loaded tile 38,46
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/buildings/greatwall/greatwall_tower_01.wmo
|
||||
HITCH 26.40ms refresh=false queues[tile=136 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=54 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.19 terrainq=9.13 m2build=0.40 wmobuild=14.59
|
||||
StreamingWorld: loaded tile 25,48
|
||||
WMOLoader: loaded 4 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/az_blackrock/blackrock2.wmo
|
||||
HITCH 185.62ms refresh=true queues[tile=135 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=54 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=11.09 terrainq=7.34 m2build=0.41 wmobuild=166.30 refresh=0.39
|
||||
StreamingWorld: loaded tile 27,53
|
||||
WMOLoader: loaded 4 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_cavetunnels/md_cavetunnel01.wmo
|
||||
HITCH 60.02ms refresh=true queues[tile=134 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=54 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=18.12 terrainq=7.11 m2build=0.37 wmobuild=33.97 refresh=0.36
|
||||
StreamingWorld: loaded tile 25,49
|
||||
WMOLoader: loaded 21 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orcfortress/blackrockorcfortress.wmo
|
||||
HITCH 162.51ms refresh=false queues[tile=133 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=53 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=10.86 terrainq=7.09 m2build=0.06 wmobuild=144.43
|
||||
StreamingWorld: loaded tile 36,43
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_human_farm/westfall_human_farm.wmo
|
||||
HITCH 33.14ms refresh=true queues[tile=132 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=53 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=3.32 terrainq=7.30 m2build=0.06 wmobuild=21.81 refresh=0.56
|
||||
StreamingWorld: loaded tile 29,42
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_barn/westfall_barn.wmo
|
||||
HITCH 39.86ms refresh=false queues[tile=131 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=53 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.70 terrainq=7.30 m2build=0.06 wmobuild=29.73
|
||||
StreamingWorld: loaded tile 37,44
|
||||
StreamingWorld: loaded tile 32,55
|
||||
StreamingWorld: loaded tile 25,47
|
||||
WMOLoader: loaded 7 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_mountaincave/md_mushroomcave02.wmo
|
||||
HITCH 145.03ms refresh=false queues[tile=128 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=51 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=13.17 terrainq=15.22 m2build=0.41 wmobuild=116.14
|
||||
StreamingWorld: loaded tile 31,55
|
||||
DBG QUEUES tiles_load=127 tile_lod_create=37 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=148
|
||||
PERF fps=21.0 tiles=148 wanted=148 retained=148 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=111 lod_node=0 lod_hidden=11 lod_prepared=37 chunk_rid=0 chunk_node=0 queues[tile=127 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=32 wmo_build=51 wmo_groups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] m2_tiles=32 m2_mm=0 m2_inst=0 wmo=102
|
||||
HITCH 21.23ms refresh=true queues[tile=127 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=51 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=9.67 terrainq=8.94 m2build=0.07 refresh=2.44
|
||||
StreamingWorld: loaded tile 26,52
|
||||
HITCH 22.14ms refresh=false queues[tile=126 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=50 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.50 terrainq=8.37 m2build=0.58 wmobuild=0.59
|
||||
StreamingWorld: loaded tile 28,54
|
||||
WMOLoader: loaded 13 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_mountaincave/md_mushroomcave.wmo
|
||||
HITCH 146.61ms refresh=false queues[tile=125 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=50 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=13.42 terrainq=7.96 m2build=0.46 wmobuild=124.69
|
||||
StreamingWorld: loaded tile 38,51
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 22.00ms refresh=true queues[tile=124 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=49 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=5.09 terrainq=7.14 m2build=0.38 wmobuild=0.68 refresh=8.62
|
||||
StreamingWorld: loaded tile 33,55
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/redridge_human_farm/redridge_human_farm.wmo
|
||||
HITCH 32.30ms refresh=false queues[tile=123 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=49 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.52 terrainq=7.51 m2build=0.42 wmobuild=21.77
|
||||
StreamingWorld: loaded tile 25,50
|
||||
HITCH 23.78ms refresh=false queues[tile=122 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=49 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=15.65 terrainq=7.42 m2build=0.06 wmobuild=0.57
|
||||
StreamingWorld: loaded tile 30,55
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/redridge_humantwostory/redridge_humantwostory.wmo
|
||||
HITCH 70.89ms refresh=true queues[tile=121 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=49 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=11.80 terrainq=7.28 m2build=0.50 wmobuild=50.88 refresh=0.35
|
||||
StreamingWorld: loaded tile 27,43
|
||||
HITCH 27.95ms refresh=false queues[tile=120 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=48 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.56 terrainq=14.19 m2build=0.57 wmobuild=0.54
|
||||
StreamingWorld: loaded tile 35,42
|
||||
StreamingWorld: loaded tile 26,44
|
||||
HITCH 21.03ms refresh=false queues[tile=118 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=47 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=13.30 terrainq=7.58 m2build=0.06
|
||||
StreamingWorld: loaded tile 38,45
|
||||
StreamingWorld: loaded tile 37,53
|
||||
StreamingWorld: loaded tile 34,55
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orcmagetower/orcmagetower.wmo
|
||||
HITCH 199.26ms refresh=false queues[tile=115 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=46 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=3.32 terrainq=7.13 m2build=0.06 wmobuild=188.68
|
||||
StreamingWorld: loaded tile 36,54
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orckennel/orckennel.wmo
|
||||
HITCH 28.78ms refresh=true queues[tile=114 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.27 terrainq=7.17 m2build=0.44 wmobuild=18.41 refresh=0.39
|
||||
StreamingWorld: loaded tile 32,41
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/guardtower_ruined/ruinedhumanguardtower01.wmo
|
||||
HITCH 25.85ms refresh=false queues[tile=113 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.31 terrainq=7.07 m2build=0.39 wmobuild=15.99
|
||||
StreamingWorld: loaded tile 28,42
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwoodabandoned_human_farm/duskwoodabandoned_human_farm.wmo
|
||||
HITCH 53.35ms refresh=false queues[tile=112 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=11.94 terrainq=8.97 m2build=0.48 wmobuild=31.87
|
||||
StreamingWorld: loaded tile 25,51
|
||||
WMOLoader: loaded 11 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_inn/duskwood_inn.wmo
|
||||
HITCH 107.21ms refresh=true queues[tile=111 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.76 terrainq=7.37 m2build=0.47 wmobuild=86.07 refresh=0.46
|
||||
StreamingWorld: loaded tile 31,41
|
||||
StreamingWorld: loaded tile 29,55
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_human_farm/duskwood_human_farm.wmo
|
||||
HITCH 40.35ms refresh=false queues[tile=109 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.71 terrainq=7.33 m2build=0.06 wmobuild=20.17
|
||||
StreamingWorld: loaded tile 39,48
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_townhall_nowall/duskwood_townhall_nowall.wmo
|
||||
HITCH 50.82ms refresh=false queues[tile=108 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.44 terrainq=7.30 m2build=0.09 wmobuild=40.91
|
||||
StreamingWorld: loaded tile 33,41
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_blacksmith/duskwood_blacksmith.wmo
|
||||
HITCH 36.71ms refresh=true queues[tile=107 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=45 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.38 terrainq=7.87 m2build=0.07 wmobuild=25.97 refresh=0.35
|
||||
StreamingWorld: loaded tile 39,49
|
||||
StreamingWorld: loaded tile 38,52
|
||||
StreamingWorld: loaded tile 39,47
|
||||
StreamingWorld: loaded tile 30,41
|
||||
StreamingWorld: loaded tile 26,53
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 31.21ms refresh=false queues[tile=102 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=44 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=13.90 terrainq=8.40 m2build=0.53 wmobuild=0.44
|
||||
StreamingWorld: loaded tile 27,54
|
||||
HITCH 23.11ms refresh=false queues[tile=101 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=43 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=14.97 terrainq=7.31 m2build=0.42 wmobuild=0.33
|
||||
StreamingWorld: loaded tile 37,43
|
||||
StreamingWorld: loaded tile 39,50
|
||||
WMOLoader: loaded 9 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_ogremound/md_ogremound.wmo
|
||||
HITCH 217.74ms refresh=true queues[tile=99 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=43 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=7.87 terrainq=8.63 m2build=0.41 wmobuild=200.40 refresh=0.35
|
||||
StreamingWorld: loaded tile 35,55
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_stable/duskwood_stable.wmo
|
||||
HITCH 25.15ms refresh=true queues[tile=98 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.49 terrainq=7.58 m2build=0.50 wmobuild=14.02 refresh=0.48
|
||||
StreamingWorld: loaded tile 36,42
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_magetower/westfall_magetower.wmo
|
||||
HITCH 70.28ms refresh=false queues[tile=97 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.46 terrainq=21.05 m2build=0.46 wmobuild=46.24
|
||||
StreamingWorld: loaded tile 34,41
|
||||
StreamingWorld: loaded tile 38,44
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwoodabandoned_humantwostory/duskwoodabandoned_humantwostory.wmo
|
||||
HITCH 58.98ms refresh=false queues[tile=95 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=3.67 terrainq=7.56 m2build=0.06 wmobuild=47.61
|
||||
StreamingWorld: loaded tile 39,46
|
||||
WMOLoader: loaded 11 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwoodabandoned_inn/duskwoodabandoned_inn.wmo
|
||||
HITCH 146.85ms refresh=false queues[tile=94 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.51 terrainq=9.56 m2build=0.08 wmobuild=134.61
|
||||
StreamingWorld: loaded tile 25,52
|
||||
HITCH 23.89ms refresh=true queues[tile=93 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=15.26 terrainq=7.42 m2build=0.07 wmobuild=0.71 refresh=0.36
|
||||
StreamingWorld: loaded tile 29,41
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwoodabandoned_barn/duskwoodabandoned_barn.wmo
|
||||
HITCH 46.24ms refresh=false queues[tile=92 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.69 terrainq=7.17 m2build=0.06 wmobuild=36.24
|
||||
StreamingWorld: loaded tile 28,55
|
||||
HITCH 22.17ms refresh=false queues[tile=91 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=42 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=13.56 terrainq=7.81 m2build=0.06 wmobuild=0.66
|
||||
StreamingWorld: loaded tile 32,56
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/collidabledoodads/darkshore/darkshoredocks/darkshoredocks01.wmo
|
||||
HITCH 23.02ms refresh=true queues[tile=90 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=41 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.80 terrainq=7.13 m2build=0.06 wmobuild=12.57 refresh=0.35
|
||||
StreamingWorld: loaded tile 27,42
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_stable/westfall_stable.wmo
|
||||
HITCH 47.56ms refresh=false queues[tile=89 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=41 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=17.14 terrainq=14.46 m2build=0.08 wmobuild=15.80
|
||||
StreamingWorld: loaded tile 31,56
|
||||
DBG QUEUES tiles_load=88 tile_lod_create=37 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=187
|
||||
PERF fps=18.0 tiles=187 wanted=187 retained=187 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=150 lod_node=0 lod_hidden=50 lod_prepared=37 chunk_rid=0 chunk_node=0 queues[tile=88 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=31 wmo_build=41 wmo_groups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] m2_tiles=31 m2_mm=0 m2_inst=0 wmo=138
|
||||
StreamingWorld: loaded tile 39,51
|
||||
HITCH 21.91ms refresh=true queues[tile=87 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=41 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=7.49 terrainq=13.35 m2build=0.06 wmobuild=0.52 refresh=0.41
|
||||
StreamingWorld: loaded tile 37,54
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/prison_camp/prisonlonghouse.wmo
|
||||
HITCH 34.89ms refresh=false queues[tile=86 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=41 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.13 terrainq=7.32 m2build=0.08 wmobuild=15.28
|
||||
StreamingWorld: loaded tile 33,56
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/westfall_lumbermill/westfall_lumbermill.wmo
|
||||
HITCH 29.00ms refresh=false queues[tile=85 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=41 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=4.13 terrainq=7.25 m2build=0.09 wmobuild=17.44
|
||||
StreamingWorld: loaded tile 38,53
|
||||
StreamingWorld: loaded tile 35,41
|
||||
StreamingWorld: loaded tile 30,56
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stormwind/sw_harbor_lighthouse.wmo
|
||||
HITCH 53.47ms refresh=false queues[tile=82 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=39 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=11.74 terrainq=7.09 m2build=0.08 wmobuild=34.48
|
||||
StreamingWorld: loaded tile 39,45
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
StreamingWorld: loaded tile 36,55
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/collidable doodads/searinggorge/searinggorgescaffold/searinggorgescaffold.wmo
|
||||
HITCH 28.87ms refresh=true queues[tile=80 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=39 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=3.85 terrainq=7.46 m2build=0.06 wmobuild=17.06 refresh=0.38
|
||||
StreamingWorld: loaded tile 28,41
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/buildings/searinggorge/darkirontower.wmo
|
||||
HITCH 28.94ms refresh=false queues[tile=79 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=39 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=5.55 terrainq=7.37 m2build=0.06 wmobuild=15.89
|
||||
StreamingWorld: loaded tile 26,54
|
||||
HITCH 21.86ms refresh=false queues[tile=78 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=39 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=13.26 terrainq=8.08 m2build=0.06 wmobuild=0.39
|
||||
StreamingWorld: loaded tile 34,56
|
||||
StreamingWorld: loaded tile 37,42
|
||||
StreamingWorld: loaded tile 38,43
|
||||
StreamingWorld: loaded tile 25,53
|
||||
HITCH 20.83ms refresh=false queues[tile=74 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=38 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=12.93 terrainq=7.05 m2build=0.06 wmobuild=0.72
|
||||
StreamingWorld: loaded tile 32,40
|
||||
StreamingWorld: loaded tile 39,52
|
||||
StreamingWorld: loaded tile 29,56
|
||||
HITCH 24.21ms refresh=false queues[tile=71 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=38 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=15.63 terrainq=8.42 m2build=0.06
|
||||
StreamingWorld: loaded tile 27,55
|
||||
HITCH 24.28ms refresh=false queues[tile=70 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=38 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=16.08 terrainq=7.61 m2build=0.07 wmobuild=0.44
|
||||
StreamingWorld: loaded tile 31,40
|
||||
StreamingWorld: loaded tile 40,48
|
||||
StreamingWorld: loaded tile 33,40
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_shipwreck/shipwreck_b.wmo
|
||||
HITCH 57.12ms refresh=false queues[tile=67 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=37 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.64 terrainq=7.69 m2build=0.06 wmobuild=46.65
|
||||
StreamingWorld: loaded tile 40,49
|
||||
StreamingWorld: loaded tile 30,40
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/collidabledoodads/darkshore/wreckedelvendestroyer/elvendestroyerwreckfront.wmo
|
||||
HITCH 32.00ms refresh=false queues[tile=65 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=36 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=7.90 terrainq=7.81 m2build=0.50 wmobuild=15.70
|
||||
StreamingWorld: loaded tile 40,47
|
||||
StreamingWorld: loaded tile 36,41
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/westfall/westfallgrainsilo01/westfallgrainsilo01.wmo
|
||||
HITCH 25.30ms refresh=false queues[tile=63 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=36 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.87 terrainq=7.11 m2build=0.06 wmobuild=15.18
|
||||
StreamingWorld: loaded tile 39,44
|
||||
StreamingWorld: loaded tile 35,56
|
||||
WMOLoader: loaded 13 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_mountaincave/md_icecave.wmo
|
||||
HITCH 122.62ms refresh=false queues[tile=61 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=34 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=11.09 terrainq=8.08 m2build=0.10 wmobuild=103.25
|
||||
StreamingWorld: loaded tile 40,50
|
||||
HITCH 23.01ms refresh=true queues[tile=60 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=34 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=15.05 terrainq=7.25 m2build=0.09 refresh=0.49
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded tile 34,40
|
||||
StreamingWorld: loaded tile 38,54
|
||||
StreamingWorld: loaded tile 40,46
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orctower/blackrockorctower.wmo
|
||||
HITCH 84.15ms refresh=false queues[tile=57 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=34 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=2.90 terrainq=7.05 m2build=0.50 wmobuild=73.61
|
||||
StreamingWorld: loaded tile 27,41
|
||||
HITCH 24.43ms refresh=true queues[tile=56 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=33 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=16.30 terrainq=7.08 m2build=0.44 refresh=0.51
|
||||
StreamingWorld: loaded tile 28,56
|
||||
WMOLoader: loaded 11 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/redridge_inn/redridge_inn.wmo
|
||||
HITCH 106.06ms refresh=false queues[tile=55 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=33 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=15.27 terrainq=7.19 m2build=0.07 wmobuild=83.43
|
||||
StreamingWorld: loaded tile 37,55
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 23.49ms refresh=true queues[tile=54 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=33 wmogroups=0 lod+=37 lod-=0 chunk+=0 chunk-=0] finalize=4.39 terrainq=8.27 m2build=0.11 wmobuild=0.84 refresh=9.79
|
||||
StreamingWorld: loaded tile 29,40
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/redridge_townhall_nowall/redridge_townhall_nowall.wmo
|
||||
HITCH 53.24ms refresh=false queues[tile=53 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=33 wmogroups=0 lod+=36 lod-=0 chunk+=0 chunk-=0] finalize=4.65 terrainq=7.25 m2build=0.08 wmobuild=41.16
|
||||
StreamingWorld: loaded tile 39,53
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/redridge/redridgedocks/redridgesmalldock01.wmo
|
||||
HITCH 37.59ms refresh=true queues[tile=52 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=33 wmogroups=0 lod+=35 lod-=0 chunk+=0 chunk-=0] finalize=11.79 terrainq=8.20 m2build=0.42 wmobuild=16.60 refresh=0.47
|
||||
StreamingWorld: loaded tile 40,51
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/redridge/redridgedocks/redridgesmalldock02.wmo
|
||||
HITCH 34.41ms refresh=false queues[tile=51 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=33 wmogroups=0 lod+=34 lod-=0 chunk+=0 chunk-=0] finalize=11.72 terrainq=7.63 m2build=0.07 wmobuild=14.92
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/redridge/redridgedamagedbridge/redridgedamagedbridge.wmo
|
||||
HITCH 85.96ms refresh=false queues[tile=50 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=32 wmogroups=0 lod+=33 lod-=0 chunk+=0 chunk-=0] finalize=2.17 terrainq=7.63 m2build=0.42 wmobuild=75.63
|
||||
WMOLoader: loaded 7 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_mountaincave/md_mushroomcave03.wmo
|
||||
HITCH 88.86ms refresh=true queues[tile=49 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=32 wmogroups=0 lod+=32 lod-=0 chunk+=0 chunk-=0] finalize=3.13 terrainq=7.68 m2build=0.06 wmobuild=77.36 refresh=0.53
|
||||
StreamingWorld: loaded tile 25,54
|
||||
WMOLoader: loaded 13 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_goldmine/md_goldmine_variante.wmo
|
||||
HITCH 279.25ms refresh=true queues[tile=48 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=32 wmogroups=0 lod+=31 lod-=0 chunk+=0 chunk-=0] finalize=14.32 terrainq=7.78 m2build=0.48 wmobuild=256.13 refresh=0.44
|
||||
StreamingWorld: loaded tile 26,55
|
||||
HITCH 23.93ms refresh=true queues[tile=47 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=31 wmogroups=0 lod+=30 lod-=0 chunk+=0 chunk-=0] finalize=13.79 terrainq=9.08 m2build=0.09 wmobuild=0.49 refresh=0.39
|
||||
StreamingWorld: loaded tile 38,42
|
||||
StreamingWorld: loaded tile 35,40
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_barn/duskwood_barn.wmo
|
||||
HITCH 37.37ms refresh=false queues[tile=45 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=31 wmogroups=0 lod+=28 lod-=0 chunk+=0 chunk-=0] finalize=2.96 terrainq=7.30 m2build=0.41 wmobuild=26.61
|
||||
StreamingWorld: loaded tile 36,56
|
||||
DBG QUEUES tiles_load=43 tile_lod_create=26 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=229
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/chapel/duskwoodchapel.wmo
|
||||
PERF fps=13.0 tiles=229 wanted=229 retained=229 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=195 lod_node=0 lod_hidden=95 lod_prepared=37 chunk_rid=0 chunk_node=0 queues[tile=43 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=31 wmo_build=31 wmo_groups=0 lod+=26 lod-=0 chunk+=0 chunk-=0] m2_tiles=31 m2_mm=0 m2_inst=0 wmo=174
|
||||
HITCH 45.02ms refresh=false queues[tile=43 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=31 wmogroups=0 lod+=26 lod-=0 chunk+=0 chunk-=0] finalize=10.78 terrainq=8.03 m2build=0.08 wmobuild=24.58
|
||||
StreamingWorld: loaded tile 40,45
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_goldmine/md_goldmine_1room.wmo
|
||||
HITCH 50.82ms refresh=false queues[tile=42 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=31 wmogroups=0 lod+=25 lod-=0 chunk+=0 chunk-=0] finalize=2.76 terrainq=7.08 m2build=0.42 wmobuild=40.46
|
||||
WMOLoader: loaded 19 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_crypt/md_crypt_d.wmo
|
||||
HITCH 432.91ms refresh=true queues[tile=41 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=30 wmogroups=0 lod+=24 lod-=0 chunk+=0 chunk-=0] finalize=1.90 terrainq=7.38 m2build=0.50 wmobuild=422.48 refresh=0.58
|
||||
StreamingWorld: loaded tile 37,41
|
||||
HITCH 30.06ms refresh=true queues[tile=40 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=30 wmogroups=0 lod+=23 lod-=0 chunk+=0 chunk-=0] finalize=4.72 terrainq=23.70 m2build=0.07 wmobuild=1.09 refresh=0.40
|
||||
StreamingWorld: loaded tile 39,43
|
||||
StreamingWorld: loaded tile 28,40
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/collidabledoodads/tanaris/trolltent/trolltentsand01.wmo
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 41.54ms refresh=false queues[tile=38 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=29 wmogroups=0 lod+=21 lod-=0 chunk+=0 chunk-=0] finalize=9.28 terrainq=7.80 m2build=0.45 wmobuild=14.99
|
||||
StreamingWorld: loaded tile 24,53
|
||||
HITCH 21.15ms refresh=true queues[tile=37 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=28 wmogroups=0 lod+=20 lod-=0 chunk+=0 chunk-=0] finalize=12.93 terrainq=7.34 m2build=0.06 wmobuild=0.35 refresh=0.41
|
||||
StreamingWorld: loaded tile 27,56
|
||||
HITCH 28.64ms refresh=false queues[tile=35 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=27 wmogroups=0 lod+=18 lod-=0 chunk+=0 chunk-=0] finalize=19.68 terrainq=8.05 m2build=0.43 wmobuild=0.39
|
||||
StreamingWorld: loaded tile 40,52
|
||||
WMOLoader: loaded 8 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_mountaincave/md_mountaincave_medium.wmo
|
||||
HITCH 78.34ms refresh=false queues[tile=34 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=27 wmogroups=0 lod+=17 lod-=0 chunk+=0 chunk-=0] finalize=15.98 terrainq=7.21 m2build=0.06 wmobuild=54.99
|
||||
StreamingWorld: loaded tile 38,55
|
||||
StreamingWorld: loaded tile 36,40
|
||||
StreamingWorld: loaded tile 39,54
|
||||
StreamingWorld: loaded tile 40,44
|
||||
WMOLoader: loaded 5 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/moonbrook_townhall_nowall/moonbrook_townhall_nowall.wmo
|
||||
HITCH 49.11ms refresh=true queues[tile=29 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=26 wmogroups=0 lod+=12 lod-=0 chunk+=0 chunk-=0] finalize=3.79 terrainq=7.64 m2build=0.49 wmobuild=36.65 refresh=0.44
|
||||
WMOLoader: loaded 11 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/moonbrook_inn/moonbrook_inn.wmo
|
||||
HITCH 93.32ms refresh=false queues[tile=28 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=26 wmogroups=0 lod+=11 lod-=0 chunk+=0 chunk-=0] finalize=1.27 terrainq=6.97 m2build=0.05 wmobuild=84.95
|
||||
StreamingWorld: loaded tile 37,56
|
||||
HITCH 24.19ms refresh=true queues[tile=27 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=26 wmogroups=0 lod+=10 lod-=0 chunk+=0 chunk-=0] finalize=15.39 terrainq=7.30 m2build=0.42 wmobuild=0.53 refresh=0.47
|
||||
StreamingWorld: loaded tile 27,40
|
||||
HITCH 20.87ms refresh=false queues[tile=26 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=26 wmogroups=0 lod+=9 lod-=0 chunk+=0 chunk-=0] finalize=12.50 terrainq=7.72 m2build=0.06 wmobuild=0.53
|
||||
StreamingWorld: loaded tile 25,55
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/moonbrook_humantwostory/moonbrook_humantwostory.wmo
|
||||
HITCH 66.94ms refresh=false queues[tile=24 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=26 wmogroups=0 lod+=7 lod-=0 chunk+=0 chunk-=0] finalize=13.73 terrainq=7.25 m2build=0.07 wmobuild=45.80
|
||||
StreamingWorld: loaded tile 40,53
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/moonbrook_blacksmith/moonbrook_blacksmith.wmo
|
||||
HITCH 45.57ms refresh=true queues[tile=23 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=26 wmogroups=0 lod+=6 lod-=0 chunk+=0 chunk-=0] finalize=14.01 terrainq=7.81 m2build=0.06 wmobuild=23.02 refresh=0.56
|
||||
StreamingWorld: loaded tile 38,41
|
||||
StreamingWorld: loaded tile 39,42
|
||||
WMOLoader: loaded 38 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/az_deadmines/az_deadmines_a.wmo
|
||||
HITCH 444.17ms refresh=false queues[tile=21 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=25 wmogroups=0 lod+=4 lod-=0 chunk+=0 chunk-=0] finalize=6.34 terrainq=7.02 m2build=0.06 wmobuild=430.68
|
||||
StreamingWorld: loaded tile 24,54
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_ogremound/md_grogremound1room.wmo
|
||||
HITCH 77.71ms refresh=true queues[tile=20 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=24 wmogroups=0 lod+=3 lod-=0 chunk+=0 chunk-=0] finalize=13.07 terrainq=7.21 m2build=0.49 wmobuild=56.35 refresh=0.51
|
||||
StreamingWorld: loaded tile 26,56
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 29.29ms refresh=false queues[tile=19 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=24 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=13.43 terrainq=7.19 m2build=0.39
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/stranglethorn/stranglethornruins16/stranglethornruins16.wmo
|
||||
HITCH 24.38ms refresh=true queues[tile=18 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=24 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=1.18 terrainq=7.18 m2build=0.56 wmobuild=14.88 refresh=0.49
|
||||
StreamingWorld: loaded tile 37,40
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/stranglethorn/stranglethornruins11/stranglethornruins11.wmo
|
||||
HITCH 25.97ms refresh=false queues[tile=17 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=24 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=4.85 terrainq=7.06 m2build=0.40 wmobuild=13.56
|
||||
StreamingWorld: loaded tile 40,43
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stranglethorn_bootybay/bootybay_railing.wmo
|
||||
StreamingWorld: loaded tile 39,55
|
||||
StreamingWorld: loaded tile 38,56
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/stranglethorn/stranglethornruins12/stranglethornruins12.wmo
|
||||
HITCH 25.66ms refresh=false queues[tile=13 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=24 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=13.02 terrainq=0.28 m2build=0.05 wmobuild=12.24
|
||||
StreamingWorld: loaded tile 40,54
|
||||
StreamingWorld: loaded tile 24,55
|
||||
StreamingWorld: loaded tile 25,56
|
||||
StreamingWorld: loaded tile 39,41
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/swampofsorrows/swampdock01/swampdock01.wmo
|
||||
HITCH 20.21ms refresh=false queues[tile=9 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=24 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.94 terrainq=0.31 wmobuild=16.82
|
||||
StreamingWorld: loaded tile 38,40
|
||||
StreamingWorld: loaded tile 40,42
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/stranglethorn/stranglethornruins04/stranglethornruins04.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/stranglethorn/ropebridge/ropebridge.wmo
|
||||
StreamingWorld: loaded tile 39,56
|
||||
StreamingWorld: loaded tile 40,55
|
||||
StreamingWorld: loaded tile 39,40
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/buildings/searinggorge/darkironcrane.wmo
|
||||
StreamingWorld: loaded tile 40,41
|
||||
StreamingWorld: loaded tile 40,56
|
||||
StreamingWorld: loaded tile 40,40
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_caveden/md_trollden.wmo
|
||||
HITCH 27.07ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=31 wmobuild=23 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=4.83 m2build=0.06 wmobuild=22.09
|
||||
DBG QUEUES tiles_load=0 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=264
|
||||
PERF fps=15.0 tiles=264 wanted=264 retained=264 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=37 chunk_rid=0 chunk_node=0 queues[tile=0 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=30 wmo_build=22 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=31 m2_mm=0 m2_inst=0 wmo=217
|
||||
WMOLoader: loaded 9 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_ogremound/md_brogremound.wmo
|
||||
HITCH 85.87ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=21 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.43 wmobuild=84.84 refresh=0.52
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_ogremound/md_ogremound1room.wmo
|
||||
HITCH 22.11ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=21 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.09 wmobuild=21.93
|
||||
WMOLoader: loaded 9 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_mountaincave/md_mushroomcave05.wmo
|
||||
HITCH 67.81ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.08 wmobuild=67.64
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/stranglethorn/holdingpen/holdingpenbamboo.wmo
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 23.39ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.08 wmobuild=15.11
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_lumbermill/duskwood_lumbermill.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/wetlands/wetlandshumandock01/wetlandshumandock01.wmo
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_shipwreck/transport_shipwreck.wmo
|
||||
HITCH 46.59ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.49 wmobuild=46.00
|
||||
WMOLoader: loaded 12 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/az_karazahn/kharazan.wmo
|
||||
HITCH 185.26ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmobuild=185.11
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/lorderon/collidabledoodads/arathihighlands/humanruinedbuildings/huruinedbuildingssmall01.wmo
|
||||
HITCH 20.60ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.06 wmobuild=20.48
|
||||
WMOLoader: loaded 4 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/lorderon/collidabledoodads/arathihighlands/humanruinedbuildings/huruinedbuilding_collapsed.wmo
|
||||
HITCH 138.29ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=30 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.06 wmobuild=138.17
|
||||
WMOLoader: loaded 7 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/lorderon/collidabledoodads/arathihighlands/humanruinedbuildings/huruinedbuildingssm01_winecellar.wmo
|
||||
HITCH 77.52ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=29 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmobuild=77.38
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orctower/swamporctower.wmo
|
||||
WMOLoader: loaded 13 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_anvilmarpass/anvilmarpass.wmo
|
||||
HITCH 152.38ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=13 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.05 wmobuild=152.26
|
||||
WMOLoader: loaded 6 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/buildings/anvilmar/anvilmar.wmo
|
||||
HITCH 343.07ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=13 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmobuild=342.42 refresh=0.51
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/trollhut/trollhutsmall01.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/trollhut/trollhut01.wmo
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/zulgurub/zulgurubcity.wmo
|
||||
HITCH 41.64ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=11 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.06 wmobuild=41.52
|
||||
DBG QUEUES tiles_load=0 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=264
|
||||
WMOLoader: loaded 4 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/stranglethorn_ruins/stranglethorn_ruins02.wmo
|
||||
PERF fps=59.0 tiles=264 wanted=264 retained=264 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=0 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=37 chunk_rid=0 chunk_node=0 queues[tile=0 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=28 wmo_build=11 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=28 m2_mm=0 m2_inst=0 wmo=317
|
||||
HITCH 232.24ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=11 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainq=1.99 m2build=0.06 wmobuild=227.42
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/ziggurat/trollziggurat.wmo
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/kalimdor/buildings/orcmedium/orcmedium.wmo
|
||||
HITCH 34.15ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.43 wmobuild=33.64
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/redridge_lumbermill/redridge_lumbermill.wmo
|
||||
HITCH 21.85ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.44 wmobuild=20.76 refresh=0.58
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/keepwall/wallpostruined01.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/keepwall/wallpieceruin02.wmo
|
||||
WMOLoader: loaded 16 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/md_ruinedkeep/ruinedkeep.wmo
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
HITCH 120.37ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.06 wmobuild=110.76
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/keepwall/gateruined01.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/collidable doodads/redridge/redridgefootbridge/redridgefootbridge.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/azeroth/buildings/duskwood_human_farm_burnt/duskwoodfarmhouseburnt.wmo
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/outland/humanbuildings/outlandruinedmagetower.wmo
|
||||
HITCH 29.83ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=27 wmobuild=4 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.05 wmobuild=29.72
|
||||
WMOLoader: loaded 9 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/dungeon/az_deadmines/az_deadmines_c.wmo
|
||||
HITCH 52.43ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=27 wmobuild=3 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmobuild=52.28
|
||||
WMOLoader: loaded 1 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/khazmodan/buildings/greatwall/greatwall_gate.wmo
|
||||
WMOLoader: loaded 3 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/outland/draenibuildings/draenihuthooded01.wmo
|
||||
HITCH 47.74ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=26 wmobuild=1 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.40 wmobuild=47.28
|
||||
WMOLoader: loaded 2 groups from C:/Users/sindo/open-wc-m01-server-spawn-renderer/data/extracted/world/wmo/outland/draenibuildings/outland_draeni_hut_1.wmo
|
||||
HITCH 34.06ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=26 wmobuild=1 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.41 wmobuild=33.59
|
||||
TERRAIN_QUALITY target=100 ready=0 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=100 queue=0 focus=32_48:stream done=false
|
||||
RENDER_CHECKPOINT saved C:/Users/sindo/AppData/Roaming/Godot/app_userdata/OpenWC/server_spawn_renderer_m01_gui/azerothcore_human_warrior_start__warm_revisit.png sha256=18c9fb2dbd9ba03205fa6484245cebe13813007d6f86f0c9b75cd1f05b6d5aff
|
||||
RENDER_BASELINE report=C:/Users/sindo/AppData/Roaming/Godot/app_userdata/OpenWC/server_spawn_renderer_m01_gui/report.json results=2
|
||||
@@ -0,0 +1,66 @@
|
||||
ERROR: CreateDescriptorHeap failed with error 0x80070057.
|
||||
at: initialize (drivers/d3d12/rendering_device_driver_d3d12.cpp:377)
|
||||
ERROR: Condition "err != OK" is true. Returning: ERR_CANT_CREATE
|
||||
at: _initialize_frames (drivers/d3d12/rendering_device_driver_d3d12.cpp:6226)
|
||||
ERROR: Condition "err != OK" is true. Returning: ERR_CANT_CREATE
|
||||
at: initialize (drivers/d3d12/rendering_device_driver_d3d12.cpp:6289)
|
||||
ERROR: Failed to initialize driver for device.
|
||||
at: initialize (servers/rendering/rendering_device.cpp:6990)
|
||||
WARNING: Your video card drivers seem not to support Direct3D 12, switching to Vulkan.
|
||||
at: DisplayServerWindows (platform/windows/display_server_windows.cpp:7309)
|
||||
ERROR: Cannot open file 'res://.godot/imported/HumanMale.glb-cc6df109a9e0b3e04d68c0bac80c872b.scn'.
|
||||
at: load (core/io/resource_format_binary.cpp:1220)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] _load_character_visual (res://src/scenes/player/third_person_wow_controller.gd:185)
|
||||
[1] _ready (res://src/scenes/player/third_person_wow_controller.gd:73)
|
||||
[2] _capture_async (res://src/tools/capture_render_checkpoints.gd:70)
|
||||
ERROR: Failed loading resource: res://.godot/imported/HumanMale.glb-cc6df109a9e0b3e04d68c0bac80c872b.scn.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] _load_character_visual (res://src/scenes/player/third_person_wow_controller.gd:185)
|
||||
[1] _ready (res://src/scenes/player/third_person_wow_controller.gd:73)
|
||||
[2] _capture_async (res://src/tools/capture_render_checkpoints.gd:70)
|
||||
ERROR: Failed loading resource: res://src/resources/characters/HUMAN/MALE/HumanMale.glb.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] _load_character_visual (res://src/scenes/player/third_person_wow_controller.gd:185)
|
||||
[1] _ready (res://src/scenes/player/third_person_wow_controller.gd:73)
|
||||
[2] _capture_async (res://src/tools/capture_render_checkpoints.gd:70)
|
||||
WARNING: ThirdPersonWowController: cannot load character model: res://src/resources/characters/HUMAN/MALE/HumanMale.glb
|
||||
at: push_warning (core/variant/variant_utility.cpp:1034)
|
||||
GDScript backtrace (most recent call first):
|
||||
[0] _load_character_visual (res://src/scenes/player/third_person_wow_controller.gd:187)
|
||||
[1] _ready (res://src/scenes/player/third_person_wow_controller.gd:73)
|
||||
[2] _capture_async (res://src/tools/capture_render_checkpoints.gd:70)
|
||||
ERROR: Cannot open file 'res://.godot/imported/bird01.glb-546b30d3f40f30f24114031716d917f1.scn'.
|
||||
at: load (core/io/resource_format_binary.cpp:1220)
|
||||
ERROR: Failed loading resource: res://.godot/imported/bird01.glb-546b30d3f40f30f24114031716d917f1.scn.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Failed loading resource: res://data/cache/m2_glb/bird01.glb.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Cannot open file 'res://.godot/imported/butterflypurple01.glb-5a34ee32df92519e1f8306bffc805c67.scn'.
|
||||
at: load (core/io/resource_format_binary.cpp:1220)
|
||||
ERROR: Failed loading resource: res://.godot/imported/butterflypurple01.glb-5a34ee32df92519e1f8306bffc805c67.scn.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Failed loading resource: res://data/cache/m2_glb/butterflypurple01.glb.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Cannot open file 'res://.godot/imported/bird02.glb-3ba59afe7fc6b2ef54faacc4f47c9283.scn'.
|
||||
at: load (core/io/resource_format_binary.cpp:1220)
|
||||
ERROR: Failed loading resource: res://.godot/imported/bird02.glb-3ba59afe7fc6b2ef54faacc4f47c9283.scn.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Failed loading resource: res://data/cache/m2_glb/bird02.glb.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Cannot open file 'res://.godot/imported/butterflywhite01.glb-7e37fe83139958ce1126cbb5fa6605bf.scn'.
|
||||
at: load (core/io/resource_format_binary.cpp:1220)
|
||||
ERROR: Failed loading resource: res://.godot/imported/butterflywhite01.glb-7e37fe83139958ce1126cbb5fa6605bf.scn.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Failed loading resource: res://data/cache/m2_glb/butterflywhite01.glb.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Cannot open file 'res://.godot/imported/fireflies01.glb-e8dbc25fb275fba81ddded25ff2a283c.scn'.
|
||||
at: load (core/io/resource_format_binary.cpp:1220)
|
||||
ERROR: Failed loading resource: res://.godot/imported/fireflies01.glb-e8dbc25fb275fba81ddded25ff2a283c.scn.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
ERROR: Failed loading resource: res://data/cache/m2_glb/fireflies01.glb.
|
||||
at: _load (core/io/resource_loader.cpp:343)
|
||||
WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
|
||||
at: cleanup (core/object/object.cpp:2641)
|
||||
@@ -0,0 +1,536 @@
|
||||
Godot Engine v4.6.1.stable.official.14d19694e - https://godotengine.org
|
||||
Vulkan 1.4.341 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 5070
|
||||
|
||||
WowSkyController: loaded 850 LightParams profiles, 2307 area records and 81 Azeroth light volumes
|
||||
SKY_LIGHT time=13.00 map=0 area=12:Элвиннский лес zone=12:Элвиннский лес wow=(-9333.3,266.7,67.2) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 12, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded 687 ADT tiles from WDT for Azeroth
|
||||
StreamingWorld: focus_tile=(32, 48) wanted=276 queued=276
|
||||
StreamingWorld: focus_tile=(32, 48) wanted=276 queued=275
|
||||
StreamingWorld: loaded streaming tile 32,48
|
||||
HITCH 32.46ms refresh=true queues[tile=274 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=1 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=0 wmobuild=1 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=31.56 terrainq=0.48 details=0.32
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded streaming tile 31,48
|
||||
StreamingWorld: loaded streaming tile 32,49
|
||||
HITCH 21.23ms refresh=false queues[tile=272 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=1 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=2 wmobuild=5 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.56 terrainq=0.25 m2mesh=17.74 m2build=0.06 details=0.49
|
||||
StreamingWorld: loaded streaming tile 31,49
|
||||
StreamingWorld: loaded streaming tile 32,47
|
||||
HITCH 50.00ms refresh=false queues[tile=270 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=5 wmobuild=7 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=12.95 terrainq=21.87 m2results=0.07 m2mesh=9.95 m2build=4.97 wmobuild=0.07
|
||||
StreamingWorld: loaded streaming tile 33,48
|
||||
StreamingWorld: loaded streaming tile 31,47
|
||||
HITCH 24.18ms refresh=false queues[tile=268 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=1 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=6 wmobuild=8 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.55 terrainctl=2.92 water=2.31 terrainq=0.27 m2results=0.06 m2mesh=12.38 m2build=3.44 wmobuild=0.11 details=0.07
|
||||
StreamingWorld: loaded streaming tile 33,49
|
||||
HITCH 162.55ms refresh=false queues[tile=267 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=2 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=7 wmobuild=9 wmogroups=1 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.75 terrainctl=10.23 terrainq=0.35 m2results=0.05 wmogroups=148.71 details=0.30
|
||||
StreamingWorld: loaded streaming tile 30,48
|
||||
HITCH 20.18ms refresh=true queues[tile=266 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=2 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=8 wmobuild=10 wmogroups=1 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.85 terrainctl=2.42 water=0.76 terrainq=0.32 m2mesh=11.76 m2build=1.59 wmobuild=0.07 wmogroups=0.18 details=0.09 refresh=0.05
|
||||
StreamingWorld: loaded streaming tile 33,47
|
||||
StreamingWorld: loaded streaming tile 32,50
|
||||
StreamingWorld: loaded streaming tile 30,49
|
||||
TERRAIN_QUALITY target=12 ready=11 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
StreamingWorld: loaded streaming tile 31,50
|
||||
StreamingWorld: loaded streaming tile 30,47
|
||||
StreamingWorld: loaded streaming tile 33,50
|
||||
HITCH 69.28ms refresh=true queues[tile=260 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=1 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=14 wmobuild=18 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=44.62 water=1.29 terrainq=1.96 m2results=0.08 m2mesh=19.21 m2build=1.88 wmobuild=0.09 refresh=0.05
|
||||
StreamingWorld: loaded streaming tile 32,46
|
||||
HITCH 25.01ms refresh=false queues[tile=259 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=2 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=14 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.85 terrainq=9.15 m2mesh=10.90 m2build=1.49 wmobuild=0.43 details=0.07
|
||||
HITCH 37.96ms refresh=false queues[tile=259 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=1 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=14 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=3.35 m2build=0.09 wmobuild=0.07 wmogroups=34.37
|
||||
StreamingWorld: loaded streaming tile 34,48
|
||||
HITCH 151.22ms refresh=false queues[tile=258 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=1 detail=0 m2task=1 m2anim=0 m2mesh=2 m2build=14 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=0.91 m2build=0.27 wmobuild=0.06 wmogroups=149.90
|
||||
StreamingWorld: loaded streaming tile 31,46
|
||||
HITCH 20.81ms refresh=true queues[tile=257 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=2 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=15 wmobuild=20 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.99 terrainctl=3.70 terrainq=0.30 m2results=0.05 m2mesh=9.78 m2build=3.52 wmobuild=0.28 refresh=0.06
|
||||
HITCH 41.52ms refresh=false queues[tile=257 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=1 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=15 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=15.66 terrainq=7.07 m2mesh=16.38 m2build=2.25 wmobuild=0.07
|
||||
StreamingWorld: loaded streaming tile 34,49
|
||||
HITCH 195.86ms refresh=false queues[tile=256 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=2 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=15 wmobuild=20 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.81 terrainctl=12.81 terrainq=11.16 m2build=0.14 wmobuild=0.07 wmogroups=168.32 details=0.46
|
||||
StreamingWorld: loaded streaming tile 30,50
|
||||
HITCH 27.83ms refresh=true queues[tile=255 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=2 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=16 wmobuild=20 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.50 terrainctl=6.78 water=0.76 terrainq=0.30 m2results=0.06 m2build=0.09 wmobuild=0.06 wmogroups=16.75 details=0.42 refresh=0.06
|
||||
StreamingWorld: loaded streaming tile 33,46
|
||||
HITCH 189.90ms refresh=false queues[tile=254 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=3 detail=0 m2task=1 m2anim=0 m2mesh=2 m2build=17 wmobuild=20 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.47 wmobuild=0.08 wmogroups=189.27
|
||||
StreamingWorld: loaded streaming tile 34,47
|
||||
HITCH 92.73ms refresh=true queues[tile=253 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=3 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=18 wmobuild=19 wmogroups=2 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.34 terrainctl=2.75 water=3.01 terrainq=0.37 m2mesh=10.57 m2build=3.36 wmobuild=0.09 wmogroups=69.94 details=0.13 refresh=0.06
|
||||
StreamingWorld: loaded streaming tile 29,48
|
||||
DBG QUEUES tiles_load=252 tile_lod_create=1 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=23
|
||||
PERF fps=42.0 tiles=23 wanted=23 retained=23 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=4 src[baked=0 ctl=22 splat=0] cache=17 lod_rid=22 lod_node=0 lod_hidden=0 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=252 detail=0 m2_task=1 m2_anim=0 m2_mesh=0 m2_build=19 wmo_build=21 wmo_groups=2 lod+=1 lod-=0 chunk+=0 chunk-=0] m2_tiles=20 m2_mm=48 m2_inst=1636 wmo=12
|
||||
TERRAIN_QUALITY target=23 ready=22 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
HITCH 161.26ms refresh=true queues[tile=252 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=4 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=19 wmobuild=21 wmogroups=2 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.33 terrainctl=2.76 terrainq=1.86 m2mesh=9.39 m2build=3.53 wmobuild=0.69 wmogroups=135.92 details=0.14 refresh=4.50
|
||||
StreamingWorld: loaded streaming tile 30,46
|
||||
HITCH 25.32ms refresh=false queues[tile=251 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=3 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=20 wmobuild=21 wmogroups=5 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=17.10 water=7.84 terrainq=0.10 m2build=0.07 wmogroups=0.14
|
||||
StreamingWorld: loaded streaming tile 32,51
|
||||
HITCH 71.77ms refresh=false queues[tile=250 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=4 detail=0 m2task=1 m2anim=0 m2mesh=3 m2build=20 wmobuild=24 wmogroups=4 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.26 wmobuild=0.20 wmogroups=71.23
|
||||
StreamingWorld: loaded streaming tile 29,49
|
||||
HITCH 89.84ms refresh=true queues[tile=249 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=4 detail=0 m2task=1 m2anim=0 m2mesh=2 m2build=21 wmobuild=24 wmogroups=4 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.99 terrainctl=3.89 water=1.48 terrainq=0.27 m2results=0.05 m2mesh=9.93 m2build=5.07 wmobuild=0.11 wmogroups=65.80 details=0.10 refresh=0.08
|
||||
StreamingWorld: loaded streaming tile 31,51
|
||||
HITCH 33.66ms refresh=true queues[tile=248 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=5 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=22 wmobuild=24 wmogroups=5 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.63 terrainctl=11.11 terrainq=1.78 m2results=0.06 m2mesh=8.93 m2build=1.33 wmobuild=0.17 wmogroups=6.86 details=0.58 refresh=0.09
|
||||
StreamingWorld: loaded streaming tile 34,50
|
||||
HITCH 212.83ms refresh=false queues[tile=247 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=5 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=23 wmobuild=24 wmogroups=6 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.67 terrainctl=13.44 water=11.67 terrainq=0.32 m2results=0.08 m2mesh=8.60 m2build=6.60 wmobuild=0.13 wmogroups=168.70 details=0.55
|
||||
StreamingWorld: loaded streaming tile 29,47
|
||||
HITCH 91.02ms refresh=false queues[tile=246 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=5 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=25 wmobuild=24 wmogroups=8 lod+=2 lod-=0 chunk+=0 chunk-=0] terrainctl=12.86 water=1.13 terrainq=0.17 m2mesh=9.30 m2build=0.13 wmogroups=67.24
|
||||
StreamingWorld: loaded streaming tile 33,51
|
||||
HITCH 137.39ms refresh=true queues[tile=245 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=6 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=25 wmobuild=25 wmogroups=9 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.81 terrainq=0.23 m2build=0.08 wmogroups=133.79 details=0.27 refresh=0.09
|
||||
StreamingWorld: loaded streaming tile 34,46
|
||||
HITCH 57.73ms refresh=true queues[tile=244 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=6 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=26 wmobuild=26 wmogroups=10 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.79 terrainctl=3.27 water=1.74 terrainq=0.23 m2build=0.06 wmogroups=49.28 details=0.12 refresh=0.09
|
||||
StreamingWorld: loaded streaming tile 29,50
|
||||
HITCH 81.87ms refresh=false queues[tile=243 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=7 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=27 wmobuild=28 wmogroups=10 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.64 terrainctl=3.04 terrainq=0.21 m2build=0.06 wmobuild=0.22 wmogroups=75.23 details=0.36
|
||||
StreamingWorld: loaded streaming tile 32,45
|
||||
HITCH 27.48ms refresh=true queues[tile=242 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=7 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=28 wmobuild=28 wmogroups=10 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.65 terrainctl=3.14 water=9.37 terrainq=0.23 m2results=0.05 m2build=0.06 wmogroups=11.74 details=0.05 refresh=0.11
|
||||
StreamingWorld: loaded streaming tile 30,51
|
||||
TERRAIN_QUALITY target=34 ready=33 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
HITCH 51.02ms refresh=false queues[tile=241 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=8 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=28 wmobuild=29 wmogroups=11 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.67 terrainctl=3.26 terrainq=0.23 m2build=0.20 wmobuild=0.05 wmogroups=41.89 details=0.36
|
||||
StreamingWorld: loaded streaming tile 31,45
|
||||
HITCH 43.84ms refresh=false queues[tile=240 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=8 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=29 wmobuild=29 wmogroups=12 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.68 terrainctl=3.48 water=2.71 terrainq=0.23 m2mesh=8.95 m2build=3.88 wmobuild=0.07 wmogroups=21.73
|
||||
StreamingWorld: loaded streaming tile 35,48
|
||||
StreamingWorld: loaded streaming tile 35,49
|
||||
HITCH 34.28ms refresh=false queues[tile=238 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=9 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=30 wmobuild=31 wmogroups=14 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.92 terrainctl=10.77 water=3.73 terrainq=0.26 m2mesh=14.01 m2build=0.11 wmogroups=2.14 details=0.19
|
||||
StreamingWorld: loaded streaming tile 33,45
|
||||
HITCH 59.40ms refresh=false queues[tile=237 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=10 detail=0 m2task=1 m2anim=0 m2mesh=1 m2build=31 wmobuild=32 wmogroups=15 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.67 terrainctl=3.39 terrainq=0.22 m2build=0.37 wmobuild=0.06 wmogroups=52.49 details=0.10
|
||||
StreamingWorld: loaded streaming tile 29,46
|
||||
HITCH 39.87ms refresh=true queues[tile=236 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=10 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=34 wmogroups=15 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.75 terrainctl=3.38 water=6.46 terrainq=0.27 m2mesh=8.44 m2build=3.84 wmobuild=0.43 wmogroups=14.04 details=0.05 refresh=0.11
|
||||
StreamingWorld: loaded streaming tile 35,47
|
||||
HITCH 125.14ms refresh=false queues[tile=235 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=11 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=32 wmobuild=34 wmogroups=15 lod+=3 lod-=0 chunk+=0 chunk-=0] finalize=2.89 terrainctl=3.23 terrainq=0.38 m2build=0.08 wmogroups=118.33 details=0.12
|
||||
StreamingWorld: loaded streaming tile 34,51
|
||||
HITCH 37.01ms refresh=false queues[tile=234 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=11 detail=0 m2task=1 m2anim=0 m2mesh=0 m2build=33 wmobuild=34 wmogroups=17 lod+=2 lod-=0 chunk+=0 chunk-=0] m2build=0.10 wmogroups=36.74
|
||||
StreamingWorld: loaded streaming tile 30,45
|
||||
StreamingWorld: loaded streaming tile 28,48
|
||||
StreamingWorld: loaded streaming tile 35,50
|
||||
StreamingWorld: loaded streaming tile 28,49
|
||||
HITCH 41.20ms refresh=false queues[tile=230 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=12 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=38 wmogroups=19 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.85 terrainctl=4.21 terrainq=16.03 m2build=17.31 wmobuild=0.52 wmogroups=0.17
|
||||
HITCH 93.62ms refresh=false queues[tile=230 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=11 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=38 wmogroups=19 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=20.38 water=10.07 terrainq=17.67 m2mesh=32.35 m2build=12.70 wmobuild=0.09 wmogroups=0.22
|
||||
StreamingWorld: loaded streaming tile 32,52
|
||||
HITCH 33.90ms refresh=true queues[tile=229 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=12 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=39 wmogroups=19 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=10.56 terrainq=0.28 m2mesh=11.14 m2build=10.88 wmobuild=0.49 wmogroups=0.21 details=0.06 refresh=0.18
|
||||
HITCH 20.87ms refresh=false queues[tile=229 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=11 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=36 wmogroups=19 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=10.01 water=0.72 terrainq=0.23 m2mesh=9.44 m2build=0.16 wmobuild=0.07 wmogroups=0.15
|
||||
StreamingWorld: loaded streaming tile 31,52
|
||||
HITCH 20.91ms refresh=true queues[tile=228 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=12 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=37 wmogroups=19 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.96 terrainq=0.30 m2mesh=12.86 m2build=4.02 wmobuild=0.10 wmogroups=0.29 details=0.07 refresh=0.22
|
||||
StreamingWorld: loaded streaming tile 29,51
|
||||
DBG QUEUES tiles_load=227 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=48
|
||||
PERF fps=23.0 tiles=48 wanted=48 retained=48 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=12 src[baked=0 ctl=47 splat=0] cache=28 lod_rid=48 lod_node=0 lod_hidden=0 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=227 detail=0 m2_task=0 m2_anim=0 m2_mesh=1 m2_build=34 wmo_build=39 wmo_groups=19 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=79 m2_inst=2481 wmo=30
|
||||
TERRAIN_QUALITY target=48 ready=47 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
StreamingWorld: loaded streaming tile 28,47
|
||||
HITCH 48.93ms refresh=true queues[tile=226 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=12 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=40 wmogroups=17 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.66 terrainctl=5.09 water=2.37 terrainq=10.56 m2mesh=14.93 m2build=0.44 wmobuild=0.26 wmogroups=12.32 details=0.06 refresh=0.16
|
||||
StreamingWorld: loaded streaming tile 34,45
|
||||
HITCH 32.65ms refresh=false queues[tile=225 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=13 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=39 wmogroups=14 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.98 terrainctl=26.85 terrainq=0.29 m2build=0.28 wmobuild=0.07 wmogroups=2.06
|
||||
StreamingWorld: loaded streaming tile 35,46
|
||||
HITCH 45.90ms refresh=true queues[tile=224 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=13 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=38 wmogroups=15 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.00 terrainctl=7.50 water=1.39 terrainq=0.70 m2mesh=10.45 m2build=2.89 wmobuild=0.12 wmogroups=19.59 refresh=0.17
|
||||
StreamingWorld: loaded streaming tile 33,52
|
||||
HITCH 32.89ms refresh=false queues[tile=223 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=14 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=39 wmogroups=13 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.74 terrainctl=11.72 terrainq=0.31 m2mesh=9.52 m2build=0.28 wmobuild=0.08 wmogroups=8.09 details=0.06
|
||||
StreamingWorld: loaded streaming tile 28,50
|
||||
HITCH 42.72ms refresh=true queues[tile=222 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=14 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=40 wmogroups=8 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.68 terrainctl=11.96 water=1.67 terrainq=0.28 m2build=19.21 wmobuild=0.10 wmogroups=6.50 details=0.06 refresh=0.18
|
||||
StreamingWorld: loaded streaming tile 30,52
|
||||
HITCH 94.33ms refresh=false queues[tile=221 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=15 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=41 wmogroups=3 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.66 terrainctl=22.52 terrainq=0.30 m2mesh=9.06 m2build=0.48 wmobuild=0.26 wmogroups=58.89 details=0.06
|
||||
StreamingWorld: loaded streaming tile 29,45
|
||||
HITCH 32.83ms refresh=true queues[tile=220 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=15 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=40 wmogroups=3 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.55 terrainctl=3.64 water=1.36 terrainq=0.26 m2mesh=9.93 m2build=0.43 wmobuild=0.08 wmogroups=14.36 refresh=0.17
|
||||
StreamingWorld: loaded streaming tile 32,44
|
||||
HITCH 130.32ms refresh=false queues[tile=219 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=16 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=41 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=8.50 wmobuild=0.08 wmogroups=121.61
|
||||
StreamingWorld: loaded streaming tile 31,44
|
||||
HITCH 22.26ms refresh=true queues[tile=218 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=16 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=41 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.59 terrainctl=3.23 water=2.47 terrainq=0.31 m2mesh=9.16 m2build=4.15 wmobuild=0.06 refresh=0.18
|
||||
StreamingWorld: loaded streaming tile 28,46
|
||||
StreamingWorld: loaded streaming tile 36,48
|
||||
HITCH 97.47ms refresh=false queues[tile=216 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=17 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=42 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=13.61 terrainctl=3.05 water=0.73 terrainq=0.29 m2mesh=11.66 m2build=0.29 wmobuild=0.10 wmogroups=67.62 details=0.06
|
||||
StreamingWorld: loaded streaming tile 35,51
|
||||
HITCH 20.82ms refresh=true queues[tile=215 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=42 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=2.72 terrainctl=3.46 terrainq=0.23 m2mesh=9.04 m2build=4.62 wmobuild=0.48 refresh=0.19
|
||||
StreamingWorld: loaded streaming tile 36,49
|
||||
HITCH 22.47ms refresh=false queues[tile=214 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=43 wmogroups=0 lod+=3 lod-=0 chunk+=0 chunk-=0] finalize=2.90 terrainctl=9.52 water=9.17 terrainq=0.36 m2build=0.22 wmobuild=0.20
|
||||
StreamingWorld: loaded streaming tile 33,44
|
||||
HITCH 102.27ms refresh=false queues[tile=213 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=17 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=47 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=10.67 m2build=0.30 wmobuild=0.07 wmogroups=91.12
|
||||
StreamingWorld: loaded streaming tile 34,52
|
||||
TERRAIN_QUALITY target=63 ready=62 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
StreamingWorld: loaded streaming tile 36,47
|
||||
HITCH 20.91ms refresh=false queues[tile=211 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=45 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.10 terrainctl=3.53 water=1.84 terrainq=0.29 m2mesh=9.96 m2build=1.99 wmobuild=0.06
|
||||
StreamingWorld: loaded streaming tile 30,44
|
||||
StreamingWorld: loaded streaming tile 35,45
|
||||
HITCH 61.49ms refresh=false queues[tile=209 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=50 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=54.56 water=1.85 terrainq=4.50 m2build=0.15 wmobuild=0.32
|
||||
HITCH 52.15ms refresh=false queues[tile=209 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=51 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.09 wmobuild=0.06 wmogroups=51.93
|
||||
HITCH 66.52ms refresh=true queues[tile=209 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=17 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=50 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] water=19.27 m2mesh=40.31 m2build=3.48 wmobuild=0.11 wmogroups=2.94 refresh=0.30
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded streaming tile 28,51
|
||||
HITCH 86.18ms refresh=false queues[tile=208 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=47 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.32 terrainq=7.23 m2mesh=10.71 m2build=9.24 wmobuild=0.13 wmogroups=55.39 details=0.06
|
||||
StreamingWorld: loaded streaming tile 29,52
|
||||
HITCH 44.72ms refresh=false queues[tile=207 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=46 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.08 wmogroups=44.46
|
||||
StreamingWorld: loaded streaming tile 36,50
|
||||
HITCH 61.41ms refresh=false queues[tile=206 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=49 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.25 wmobuild=0.06 wmogroups=61.04
|
||||
StreamingWorld: loaded streaming tile 27,48
|
||||
HITCH 22.97ms refresh=true queues[tile=205 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=47 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.24 terrainctl=4.22 water=2.18 terrainq=0.49 m2mesh=9.91 m2build=2.47 wmobuild=0.11 refresh=0.27
|
||||
StreamingWorld: loaded streaming tile 27,49
|
||||
HITCH 64.10ms refresh=false queues[tile=204 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=19 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=46 wmogroups=1 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.18 terrainctl=24.73 terrainq=0.28 m2build=0.08 wmobuild=0.05 wmogroups=35.70
|
||||
StreamingWorld: loaded streaming tile 32,53
|
||||
HITCH 30.18ms refresh=true queues[tile=203 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=19 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=46 wmogroups=1 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.74 terrainctl=4.21 water=6.49 terrainq=0.29 m2build=0.10 wmobuild=0.07 wmogroups=14.83 details=0.09 refresh=0.28
|
||||
StreamingWorld: loaded streaming tile 34,44
|
||||
StreamingWorld: loaded streaming tile 31,53
|
||||
HITCH 38.89ms refresh=false queues[tile=201 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=19 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=49 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=26.38 m2mesh=9.75 m2build=0.32 wmobuild=0.10 wmogroups=2.25
|
||||
HITCH 122.17ms refresh=false queues[tile=201 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=18 detail=0 m2task=0 m2anim=0 m2mesh=4 m2build=34 wmobuild=50 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=0.70 m2build=0.33 wmobuild=0.08 wmogroups=120.95
|
||||
StreamingWorld: loaded streaming tile 27,47
|
||||
DBG QUEUES tiles_load=200 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=75
|
||||
PERF fps=30.0 tiles=75 wanted=75 retained=75 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=19 src[baked=0 ctl=74 splat=0] cache=41 lod_rid=75 lod_node=0 lod_hidden=0 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=200 detail=0 m2_task=0 m2_anim=0 m2_mesh=4 m2_build=34 wmo_build=47 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=116 m2_inst=3446 wmo=56
|
||||
TERRAIN_QUALITY target=75 ready=74 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
HITCH 21.22ms refresh=true queues[tile=200 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=19 detail=0 m2task=0 m2anim=0 m2mesh=4 m2build=34 wmobuild=47 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.05 terrainq=2.14 m2mesh=10.29 m2build=0.28 wmobuild=0.06 refresh=5.32
|
||||
StreamingWorld: loaded streaming tile 36,46
|
||||
HITCH 25.00ms refresh=false queues[tile=199 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=19 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=47 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.10 terrainctl=3.20 water=0.95 terrainq=0.29 m2mesh=17.23 m2build=0.11
|
||||
StreamingWorld: loaded streaming tile 28,45
|
||||
StreamingWorld: loaded streaming tile 33,53
|
||||
HITCH 33.06ms refresh=false queues[tile=197 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=20 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=48 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.06 terrainctl=3.64 water=15.86 terrainq=0.28 m2mesh=9.82 m2build=0.28
|
||||
StreamingWorld: loaded streaming tile 29,44
|
||||
HITCH 25.02ms refresh=true queues[tile=196 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=21 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=34 wmobuild=50 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.31 terrainctl=10.66 terrainq=0.37 m2mesh=9.76 m2build=0.37 wmobuild=0.22 refresh=0.22
|
||||
StreamingWorld: loaded streaming tile 27,50
|
||||
HITCH 34.66ms refresh=false queues[tile=195 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=21 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=52 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.20 terrainctl=13.83 water=1.54 terrainq=0.36 m2mesh=15.15 m2build=0.14 wmobuild=0.31 details=0.05
|
||||
StreamingWorld: loaded streaming tile 35,52
|
||||
HITCH 27.51ms refresh=false queues[tile=194 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=21 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=54 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=7.61 m2mesh=18.95 m2build=0.60 wmobuild=0.21
|
||||
StreamingWorld: loaded streaming tile 30,53
|
||||
HITCH 71.30ms refresh=false queues[tile=193 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=22 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=56 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=9.35 terrainctl=31.04 terrainq=19.07 m2mesh=11.00 m2build=0.45 wmobuild=0.23
|
||||
HITCH 126.27ms refresh=true queues[tile=193 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=21 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] terrainctl=20.89 water=5.57 m2mesh=67.05 m2build=0.07 wmobuild=0.10 wmogroups=32.26 refresh=0.21
|
||||
StreamingWorld: loaded streaming tile 36,51
|
||||
StreamingWorld: loaded streaming tile 27,46
|
||||
HITCH 196.45ms refresh=false queues[tile=191 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=22 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=54 wmogroups=1 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=4.47 terrainctl=9.74 water=1.52 terrainq=0.38 m2build=0.09 wmobuild=0.05 wmogroups=180.10
|
||||
StreamingWorld: loaded streaming tile 32,43
|
||||
HITCH 25.49ms refresh=true queues[tile=190 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=23 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=55 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.23 terrainctl=8.33 terrainq=0.30 m2mesh=8.47 m2build=4.23 wmobuild=0.51 wmogroups=0.06 refresh=0.21
|
||||
StreamingWorld: loaded streaming tile 31,43
|
||||
StreamingWorld: loaded streaming tile 28,52
|
||||
HITCH 68.20ms refresh=true queues[tile=188 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=22 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=60 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=0.07 terrainctl=40.04 water=1.17 terrainq=10.56 m2build=15.59 wmobuild=0.46 refresh=0.21
|
||||
StreamingWorld: loaded streaming tile 34,53
|
||||
HITCH 180.58ms refresh=false queues[tile=187 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=23 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=62 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=7.29 wmobuild=0.17 wmogroups=173.04
|
||||
StreamingWorld: loaded streaming tile 37,48
|
||||
TERRAIN_QUALITY target=89 ready=88 pending=1 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=1 focus=32_48:control_splat_cache done=false
|
||||
HITCH 29.79ms refresh=true queues[tile=186 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=23 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=60 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=5.62 terrainctl=4.80 water=1.26 terrainq=0.87 m2mesh=11.04 m2build=2.51 wmobuild=0.37 details=0.07 refresh=3.16
|
||||
StreamingWorld: loaded streaming tile 35,44
|
||||
HITCH 92.22ms refresh=false queues[tile=185 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=24 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=59 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=4.71 terrainctl=14.91 terrainq=0.28 m2build=0.22 wmobuild=0.09 wmogroups=71.87 details=0.06
|
||||
StreamingWorld: loaded streaming tile 37,49
|
||||
HITCH 27.00ms refresh=true queues[tile=184 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=24 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=61 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.36 terrainctl=9.25 water=2.65 terrainq=1.86 m2mesh=8.04 m2build=1.05 wmobuild=0.44 refresh=0.22
|
||||
StreamingWorld: loaded streaming tile 36,45
|
||||
HITCH 26.75ms refresh=false queues[tile=183 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=25 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=61 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.30 terrainctl=22.90 terrainq=0.33 m2build=0.07
|
||||
HITCH 26.26ms refresh=false queues[tile=183 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=25 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=61 wmogroups=1 lod+=2 lod-=0 chunk+=0 chunk-=0] terrainctl=4.11 terrainq=0.31 m2build=0.11 wmobuild=0.06 wmogroups=21.61
|
||||
StreamingWorld: loaded streaming tile 33,43
|
||||
HITCH 53.99ms refresh=true queues[tile=182 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=25 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=61 wmogroups=0 lod+=2 lod-=0 chunk+=0 chunk-=0] finalize=3.46 water=11.36 terrainq=0.33 m2build=0.08 wmobuild=0.06 wmogroups=38.34 details=0.07 refresh=0.22
|
||||
StreamingWorld: loaded streaming tile 37,47
|
||||
HITCH 67.80ms refresh=false queues[tile=181 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=26 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=62 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] m2build=0.05 wmogroups=67.64
|
||||
StreamingWorld: loaded streaming tile 27,51
|
||||
HITCH 40.17ms refresh=false queues[tile=180 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=26 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=62 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] terrainctl=12.98 terrainq=0.71 m2build=0.09 wmobuild=0.06 wmogroups=26.23
|
||||
StreamingWorld: loaded streaming tile 29,53
|
||||
HITCH 26.11ms refresh=false queues[tile=179 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=26 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=63 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.27 water=10.20 terrainq=0.29 m2mesh=8.05 m2build=3.87 wmobuild=0.30
|
||||
StreamingWorld: loaded streaming tile 30,43
|
||||
StreamingWorld: loaded streaming tile 37,50
|
||||
HITCH 44.57ms refresh=false queues[tile=177 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=27 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=67 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmobuild=0.05 wmogroups=44.34
|
||||
StreamingWorld: loaded streaming tile 28,44
|
||||
HITCH 27.49ms refresh=true queues[tile=176 loading=1 terrainup=0 terrainctl=1 terrainsplat=0 water=27 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=66 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=3.74 terrainctl=11.61 water=11.01 terrainq=0.32 m2build=0.08 wmobuild=0.42 refresh=0.25
|
||||
HITCH 23.58ms refresh=false queues[tile=176 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=27 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=67 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] terrainctl=23.02 terrainq=0.13 m2build=0.08 wmobuild=0.27
|
||||
StreamingWorld: loaded streaming tile 27,45
|
||||
StreamingWorld: loaded streaming tile 26,48
|
||||
HITCH 25.37ms refresh=true queues[tile=174 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=28 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=65 wmogroups=0 lod+=1 lod-=0 chunk+=0 chunk-=0] finalize=2.71 terrainctl=21.64 terrainq=0.54 m2build=0.11 wmobuild=0.06 refresh=0.25
|
||||
HITCH 28.39ms refresh=false queues[tile=174 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=27 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=65 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=10.97 terrainq=0.08 m2build=0.56 wmobuild=0.09 wmogroups=16.60
|
||||
StreamingWorld: loaded streaming tile 34,43
|
||||
HITCH 28.92ms refresh=false queues[tile=173 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=28 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=65 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.51 terrainq=25.79 m2build=0.16 wmobuild=0.33
|
||||
StreamingWorld: loaded streaming tile 36,52
|
||||
DBG QUEUES tiles_load=172 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=103
|
||||
PERF fps=19.0 tiles=103 wanted=103 retained=103 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=28 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=103 lod_node=0 lod_hidden=3 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=172 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=34 wmo_build=64 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=151 m2_inst=4517 wmo=74
|
||||
HITCH 243.55ms refresh=true queues[tile=172 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=28 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=64 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.52 water=15.90 terrainq=2.49 m2mesh=169.62 m2build=0.11 wmobuild=0.08 wmogroups=49.86 refresh=2.89
|
||||
StreamingWorld: loaded streaming tile 26,49
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
StreamingWorld: loaded streaming tile 37,46
|
||||
StreamingWorld: loaded streaming tile 32,54
|
||||
HITCH 47.62ms refresh=false queues[tile=169 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=29 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=64 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.65 water=16.67 terrainq=0.33 m2build=0.09 wmobuild=0.07 wmogroups=27.74
|
||||
StreamingWorld: loaded streaming tile 35,53
|
||||
HITCH 20.38ms refresh=true queues[tile=168 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=30 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=65 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=8.95 terrainq=0.33 m2mesh=9.83 m2build=0.50 wmobuild=0.41 refresh=0.26
|
||||
StreamingWorld: loaded streaming tile 26,47
|
||||
StreamingWorld: loaded streaming tile 31,54
|
||||
HITCH 45.37ms refresh=true queues[tile=166 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=31 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=62 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.48 terrainq=0.35 m2mesh=10.69 m2build=0.37 wmobuild=0.11 wmogroups=31.00 refresh=0.27
|
||||
StreamingWorld: loaded streaming tile 29,43
|
||||
HITCH 31.78ms refresh=false queues[tile=165 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=31 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=60 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.48 water=13.83 terrainq=0.34 m2mesh=10.57 m2build=4.32 wmobuild=0.11 wmogroups=0.05
|
||||
StreamingWorld: loaded streaming tile 33,54
|
||||
HITCH 22.55ms refresh=false queues[tile=164 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=32 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=59 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.09 wmogroups=22.37
|
||||
StreamingWorld: loaded streaming tile 26,50
|
||||
StreamingWorld: loaded streaming tile 37,51
|
||||
StreamingWorld: loaded streaming tile 30,54
|
||||
HITCH 70.06ms refresh=false queues[tile=161 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=32 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=61 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.61 water=2.52 terrainq=0.36 m2build=0.12 wmobuild=0.08 wmogroups=64.31
|
||||
StreamingWorld: loaded streaming tile 27,52
|
||||
HITCH 105.25ms refresh=false queues[tile=160 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=33 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=60 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmogroups=105.08
|
||||
StreamingWorld: loaded streaming tile 36,44
|
||||
HITCH 25.60ms refresh=true queues[tile=159 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=33 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=58 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.26 water=1.93 terrainq=0.27 m2build=0.07 wmobuild=0.06 wmogroups=20.71 refresh=0.25
|
||||
StreamingWorld: loaded streaming tile 28,53
|
||||
HITCH 123.73ms refresh=false queues[tile=158 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=34 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=59 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmogroups=123.58
|
||||
StreamingWorld: loaded streaming tile 26,46
|
||||
StreamingWorld: loaded streaming tile 35,43
|
||||
HITCH 27.30ms refresh=false queues[tile=156 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=34 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=59 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.53 water=1.44 terrainq=21.49 m2build=0.12 wmobuild=0.08 wmogroups=1.54
|
||||
StreamingWorld: loaded streaming tile 37,45
|
||||
StreamingWorld: loaded streaming tile 34,54
|
||||
StreamingWorld: loaded streaming tile 32,42
|
||||
StreamingWorld: loaded streaming tile 31,42
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
StreamingWorld: loaded streaming tile 27,44
|
||||
StreamingWorld: loaded streaming tile 38,48
|
||||
StreamingWorld: loaded streaming tile 26,51
|
||||
HITCH 22.25ms refresh=false queues[tile=149 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=36 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=54 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.52 terrainq=9.42 m2mesh=10.02 m2build=0.14 wmobuild=0.06
|
||||
StreamingWorld: loaded streaming tile 33,42
|
||||
HITCH 85.24ms refresh=false queues[tile=148 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=36 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=56 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.23 wmobuild=0.06 wmogroups=84.90
|
||||
StreamingWorld: loaded streaming tile 38,49
|
||||
StreamingWorld: loaded streaming tile 29,54
|
||||
HITCH 63.84ms refresh=false queues[tile=146 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=37 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=56 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmogroups=63.66
|
||||
StreamingWorld: loaded streaming tile 28,43
|
||||
StreamingWorld: loaded streaming tile 38,47
|
||||
StreamingWorld: loaded streaming tile 36,53
|
||||
StreamingWorld: loaded streaming tile 30,42
|
||||
HITCH 22.19ms refresh=false queues[tile=142 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=38 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=54 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=20.91 m2build=0.18 wmobuild=0.08 wmogroups=0.88
|
||||
StreamingWorld: loaded streaming tile 37,52
|
||||
StreamingWorld: loaded streaming tile 26,45
|
||||
HITCH 234.42ms refresh=false queues[tile=140 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=39 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=56 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.31 terrainq=0.39 m2mesh=23.27 m2build=6.47 wmobuild=0.13 wmogroups=200.75
|
||||
StreamingWorld: loaded streaming tile 38,50
|
||||
StreamingWorld: loaded streaming tile 34,42
|
||||
StreamingWorld: loaded streaming tile 35,54
|
||||
HITCH 85.52ms refresh=false queues[tile=137 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=40 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=52 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.10 wmogroups=85.28
|
||||
StreamingWorld: loaded streaming tile 38,46
|
||||
DBG QUEUES tiles_load=136 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=139
|
||||
PERF fps=41.0 tiles=139 wanted=139 retained=139 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=40 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=139 lod_node=0 lod_hidden=39 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=136 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=34 wmo_build=53 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=203 m2_inst=5910 wmo=110
|
||||
HITCH 36.58ms refresh=true queues[tile=136 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=40 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.55 water=11.33 terrainq=2.98 m2mesh=13.11 m2build=2.92 wmobuild=0.38 refresh=3.19
|
||||
StreamingWorld: loaded streaming tile 25,48
|
||||
HITCH 206.60ms refresh=false queues[tile=135 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=41 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=53 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.76 terrainq=0.42 m2build=0.52 wmobuild=0.11 wmogroups=202.70
|
||||
StreamingWorld: loaded streaming tile 27,53
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 30.85ms refresh=true queues[tile=134 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=41 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=53 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.95 water=9.96 terrainq=0.30 m2mesh=9.27 m2build=4.10 wmobuild=0.36 wmogroups=0.31 refresh=3.50
|
||||
StreamingWorld: loaded streaming tile 25,49
|
||||
StreamingWorld: loaded streaming tile 36,43
|
||||
HITCH 30.75ms refresh=false queues[tile=132 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=42 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.47 water=14.12 terrainq=0.38 m2build=0.39 wmobuild=0.10 wmogroups=13.20
|
||||
StreamingWorld: loaded streaming tile 29,42
|
||||
HITCH 21.01ms refresh=true queues[tile=131 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=43 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.58 terrainq=10.31 m2build=7.29 wmobuild=0.33 refresh=0.38
|
||||
StreamingWorld: loaded streaming tile 37,44
|
||||
HITCH 56.45ms refresh=false queues[tile=130 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=43 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.44 water=1.30 terrainq=0.29 m2mesh=12.38 m2build=11.38 wmobuild=0.16 wmogroups=28.42
|
||||
StreamingWorld: loaded streaming tile 32,55
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
HITCH 38.84ms refresh=true queues[tile=129 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=43 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=54 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=31.45 m2build=6.75 wmobuild=0.13 wmogroups=0.08 refresh=0.33
|
||||
StreamingWorld: loaded streaming tile 25,47
|
||||
HITCH 27.65ms refresh=false queues[tile=128 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=44 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.54 terrainq=3.68 m2build=0.32 wmobuild=0.10 wmogroups=20.91
|
||||
StreamingWorld: loaded streaming tile 31,55
|
||||
HITCH 25.24ms refresh=false queues[tile=127 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=44 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=52 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.52 water=22.04 terrainq=0.38 m2build=0.10 wmobuild=0.07 wmogroups=0.05
|
||||
StreamingWorld: loaded streaming tile 26,52
|
||||
StreamingWorld: loaded streaming tile 28,54
|
||||
StreamingWorld: loaded streaming tile 38,51
|
||||
HITCH 44.69ms refresh=false queues[tile=124 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=45 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.59 water=14.64 terrainq=0.53 m2mesh=13.74 m2build=2.23 wmobuild=0.13 wmogroups=10.72
|
||||
StreamingWorld: loaded streaming tile 33,55
|
||||
StreamingWorld: loaded streaming tile 25,50
|
||||
StreamingWorld: loaded streaming tile 30,55
|
||||
HITCH 101.61ms refresh=false queues[tile=121 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=47 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=53 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.78 terrainq=16.05 m2build=0.16 wmobuild=0.07 wmogroups=82.44
|
||||
StreamingWorld: loaded streaming tile 27,43
|
||||
HITCH 27.32ms refresh=false queues[tile=120 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=47 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=50 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.09 wmogroups=27.10
|
||||
StreamingWorld: loaded streaming tile 35,42
|
||||
RENDER_CHECKPOINT saved C:/Users/sindo/AppData/Roaming/Godot/app_userdata/OpenWC/server_spawn_renderer_m01_gui_run2/azerothcore_human_warrior_start__cold_process.png sha256=c08c43bcb75e5b3277105afb0d4e5a76caae9db91a7db64488770ffa03e32589
|
||||
StreamingWorld: focus_tile=(32, 48) wanted=276 queued=119
|
||||
StreamingWorld: loaded streaming tile 26,44
|
||||
StreamingWorld: loaded streaming tile 38,45
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 93.10ms refresh=false queues[tile=117 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=48 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=50 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.12 wmobuild=0.05 wmogroups=92.83
|
||||
StreamingWorld: loaded streaming tile 37,53
|
||||
StreamingWorld: loaded streaming tile 34,55
|
||||
StreamingWorld: loaded streaming tile 36,54
|
||||
HITCH 144.20ms refresh=false queues[tile=114 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=48 detail=0 m2task=0 m2anim=1 m2mesh=0 m2build=34 wmobuild=48 wmogroups=3 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=6.78 wmobuild=0.11 wmogroups=137.19
|
||||
StreamingWorld: loaded streaming tile 32,41
|
||||
HITCH 95.40ms refresh=true queues[tile=113 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=48 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=45 wmogroups=2 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.42 water=6.07 terrainq=0.31 m2build=0.21 wmobuild=0.07 wmogroups=85.91 refresh=0.33
|
||||
StreamingWorld: loaded streaming tile 28,42
|
||||
HITCH 23.25ms refresh=true queues[tile=112 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=49 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=46 wmogroups=2 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.42 terrainq=0.31 m2mesh=8.56 m2build=3.98 wmobuild=0.47 wmogroups=7.09 refresh=0.33
|
||||
StreamingWorld: loaded streaming tile 25,51
|
||||
HITCH 29.88ms refresh=false queues[tile=111 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=49 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=47 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.09 wmobuild=0.05 wmogroups=29.68
|
||||
StreamingWorld: loaded streaming tile 31,41
|
||||
HITCH 20.38ms refresh=false queues[tile=110 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=49 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=45 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.50 water=1.88 terrainq=0.38 m2mesh=14.89 m2build=0.45 wmobuild=0.06 wmogroups=0.15
|
||||
StreamingWorld: loaded streaming tile 29,55
|
||||
HITCH 126.59ms refresh=true queues[tile=109 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=50 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=45 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.45 terrainq=0.49 m2build=0.14 wmobuild=0.08 wmogroups=122.97 refresh=0.35
|
||||
StreamingWorld: loaded streaming tile 39,48
|
||||
HITCH 28.16ms refresh=true queues[tile=108 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=50 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=45 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.42 water=12.25 terrainq=0.40 m2mesh=12.50 m2build=0.14 refresh=0.33
|
||||
StreamingWorld: loaded streaming tile 33,41
|
||||
StreamingWorld: loaded streaming tile 39,49
|
||||
StreamingWorld: loaded streaming tile 38,52
|
||||
StreamingWorld: loaded streaming tile 39,47
|
||||
DBG QUEUES tiles_load=104 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=171
|
||||
PERF fps=19.0 tiles=171 wanted=171 retained=171 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=52 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=171 lod_node=0 lod_hidden=71 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=104 detail=0 m2_task=0 m2_anim=0 m2_mesh=1 m2_build=34 wmo_build=44 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=239 m2_inst=7114 wmo=138
|
||||
StreamingWorld: loaded streaming tile 30,41
|
||||
HITCH 42.09ms refresh=false queues[tile=103 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=52 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=42 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.42 water=1.26 terrainq=0.28 m2build=5.65 wmobuild=0.14 wmogroups=32.25
|
||||
StreamingWorld: loaded streaming tile 26,53
|
||||
StreamingWorld: loaded streaming tile 27,54
|
||||
HITCH 43.28ms refresh=true queues[tile=101 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=53 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=43 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.18 water=25.08 terrainq=0.45 m2mesh=11.90 m2build=1.82 wmobuild=0.33 refresh=0.43
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 38.84ms refresh=false queues[tile=101 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=53 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=43 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=6.96 wmobuild=0.11 wmogroups=27.79
|
||||
StreamingWorld: loaded streaming tile 37,43
|
||||
StreamingWorld: loaded streaming tile 39,50
|
||||
StreamingWorld: loaded streaming tile 35,55
|
||||
HITCH 23.82ms refresh=false queues[tile=98 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=54 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=42 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.14 wmobuild=0.06 wmogroups=23.52
|
||||
StreamingWorld: loaded streaming tile 36,42
|
||||
HITCH 43.92ms refresh=true queues[tile=97 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=54 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=40 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.40 water=10.25 terrainq=0.32 m2mesh=18.71 m2build=0.20 wmobuild=0.08 wmogroups=11.54 refresh=0.35
|
||||
StreamingWorld: loaded streaming tile 34,41
|
||||
HITCH 62.75ms refresh=false queues[tile=96 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=54 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=40 wmogroups=2 lod+=0 lod-=0 chunk+=0 chunk-=0] water=0.77 m2build=5.07 wmobuild=0.08 wmogroups=56.75
|
||||
StreamingWorld: loaded streaming tile 38,44
|
||||
StreamingWorld: loaded streaming tile 39,46
|
||||
StreamingWorld: loaded streaming tile 25,52
|
||||
StreamingWorld: loaded streaming tile 29,41
|
||||
StreamingWorld: loaded streaming tile 28,55
|
||||
StreamingWorld: loaded streaming tile 32,56
|
||||
HITCH 21.96ms refresh=false queues[tile=90 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=57 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=35 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.49 terrainq=0.38 m2mesh=18.70 m2build=0.16 wmobuild=0.07 wmogroups=0.06
|
||||
StreamingWorld: loaded streaming tile 27,42
|
||||
HITCH 30.96ms refresh=false queues[tile=89 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=57 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=35 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.79 water=10.57 terrainq=0.33 m2mesh=10.90 m2build=3.64 wmobuild=0.08 wmogroups=2.56
|
||||
StreamingWorld: loaded streaming tile 31,56
|
||||
StreamingWorld: loaded streaming tile 39,51
|
||||
StreamingWorld: loaded streaming tile 37,54
|
||||
StreamingWorld: loaded streaming tile 33,56
|
||||
StreamingWorld: loaded streaming tile 38,53
|
||||
StreamingWorld: loaded streaming tile 35,41
|
||||
HITCH 40.89ms refresh=true queues[tile=83 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=60 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=33 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.86 terrainq=0.36 m2mesh=22.54 m2build=0.18 wmobuild=0.07 wmogroups=14.37 refresh=0.42
|
||||
StreamingWorld: loaded streaming tile 30,56
|
||||
StreamingWorld: loaded streaming tile 39,45
|
||||
HITCH 20.85ms refresh=true queues[tile=81 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=60 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=33 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=9.92 wmobuild=0.12 wmogroups=10.13 refresh=0.54
|
||||
StreamingWorld: loaded streaming tile 36,55
|
||||
HITCH 36.53ms refresh=false queues[tile=80 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=60 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=34 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.61 water=16.42 terrainq=0.40 m2mesh=14.79 m2build=1.69 wmobuild=0.52
|
||||
StreamingWorld: loaded streaming tile 28,41
|
||||
HITCH 39.81ms refresh=true queues[tile=79 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=61 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=33 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.70 terrainq=4.80 m2mesh=23.30 m2build=7.65 wmobuild=0.12 wmogroups=0.68 refresh=0.44
|
||||
StreamingWorld: loaded streaming tile 26,54
|
||||
StreamingWorld: loaded streaming tile 34,56
|
||||
StreamingWorld: loaded streaming tile 37,42
|
||||
StreamingWorld: loaded streaming tile 38,43
|
||||
StreamingWorld: loaded streaming tile 25,53
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
StreamingWorld: loaded streaming tile 32,40
|
||||
HITCH 24.44ms refresh=false queues[tile=73 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=62 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=31 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=5.27 water=10.05 terrainq=0.33 m2mesh=8.44 m2build=0.14 wmobuild=0.07 wmogroups=0.08
|
||||
StreamingWorld: loaded streaming tile 39,52
|
||||
StreamingWorld: loaded streaming tile 29,56
|
||||
HITCH 26.38ms refresh=false queues[tile=71 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=63 detail=0 m2task=0 m2anim=1 m2mesh=0 m2build=34 wmobuild=32 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.66 water=9.59 terrainq=0.30 m2mesh=8.57 m2build=4.93 wmobuild=0.27
|
||||
StreamingWorld: loaded streaming tile 27,55
|
||||
HITCH 38.34ms refresh=false queues[tile=70 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=64 detail=0 m2task=0 m2anim=1 m2mesh=0 m2build=34 wmobuild=31 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.81 terrainq=0.26 m2build=4.03 wmobuild=0.07 wmogroups=30.08
|
||||
StreamingWorld: loaded streaming tile 31,40
|
||||
StreamingWorld: loaded streaming tile 40,48
|
||||
HITCH 266.94ms refresh=false queues[tile=68 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=64 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=29 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.09 wmogroups=266.72
|
||||
StreamingWorld: loaded streaming tile 33,40
|
||||
StreamingWorld: loaded streaming tile 40,49
|
||||
StreamingWorld: loaded streaming tile 30,40
|
||||
StreamingWorld: loaded streaming tile 40,47
|
||||
StreamingWorld: loaded streaming tile 36,41
|
||||
StreamingWorld: loaded streaming tile 39,44
|
||||
HITCH 29.77ms refresh=false queues[tile=62 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=66 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=28 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.70 terrainq=9.79 m2mesh=9.46 m2build=7.58 wmobuild=0.09
|
||||
StreamingWorld: loaded streaming tile 35,56
|
||||
StreamingWorld: loaded streaming tile 40,50
|
||||
StreamingWorld: loaded streaming tile 34,40
|
||||
HITCH 20.35ms refresh=false queues[tile=59 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=67 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.83 terrainq=0.30 m2mesh=8.65 m2build=8.37 wmobuild=0.07
|
||||
StreamingWorld: loaded streaming tile 38,54
|
||||
HITCH 23.29ms refresh=false queues[tile=58 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=67 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.68 water=9.62 terrainq=0.28 m2mesh=10.10 m2build=0.45 wmobuild=0.07
|
||||
StreamingWorld: loaded streaming tile 40,46
|
||||
StreamingWorld: loaded streaming tile 27,41
|
||||
HITCH 20.07ms refresh=false queues[tile=56 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=68 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.62 water=4.67 terrainq=0.27 m2mesh=8.63 m2build=3.72 wmobuild=0.06
|
||||
StreamingWorld: loaded streaming tile 28,56
|
||||
StreamingWorld: loaded streaming tile 37,55
|
||||
StreamingWorld: loaded streaming tile 29,40
|
||||
StreamingWorld: loaded streaming tile 39,53
|
||||
DBG QUEUES tiles_load=52 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=223
|
||||
PERF fps=45.0 tiles=223 wanted=223 retained=223 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=70 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=52 detail=0 m2_task=0 m2_anim=0 m2_mesh=2 m2_build=34 wmo_build=27 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=302 m2_inst=8101 wmo=199
|
||||
HITCH 30.71ms refresh=true queues[tile=52 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=70 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.65 water=12.68 terrainq=2.35 m2mesh=9.12 m2build=0.40 wmobuild=0.07 refresh=3.32
|
||||
StreamingWorld: loaded streaming tile 40,51
|
||||
HITCH 23.72ms refresh=false queues[tile=50 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=70 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=0.41 water=13.01 terrainq=0.25 m2mesh=9.40 m2build=0.47 wmobuild=0.07
|
||||
HITCH 24.41ms refresh=false queues[tile=49 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=69 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=9.84 m2mesh=9.17 m2build=5.23 wmobuild=0.07
|
||||
StreamingWorld: loaded streaming tile 25,54
|
||||
StreamingWorld: loaded streaming tile 26,55
|
||||
HITCH 35.03ms refresh=false queues[tile=47 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=70 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.81 water=18.71 terrainq=0.26 m2mesh=12.87 m2build=0.13 wmobuild=0.11 wmogroups=0.06
|
||||
StreamingWorld: loaded streaming tile 38,42
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 48.66ms refresh=true queues[tile=46 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=71 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.64 terrainq=0.24 m2mesh=31.91 m2build=0.13 refresh=13.57
|
||||
StreamingWorld: loaded streaming tile 35,40
|
||||
StreamingWorld: loaded streaming tile 36,56
|
||||
StreamingWorld: loaded streaming tile 40,45
|
||||
HITCH 24.93ms refresh=false queues[tile=42 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=71 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.81 terrainq=0.26 m2mesh=21.12 m2build=0.52 wmobuild=0.08 wmogroups=0.05
|
||||
StreamingWorld: loaded streaming tile 37,41
|
||||
StreamingWorld: loaded streaming tile 39,43
|
||||
StreamingWorld: loaded streaming tile 28,40
|
||||
StreamingWorld: loaded streaming tile 24,53
|
||||
HITCH 26.67ms refresh=false queues[tile=37 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=71 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.71 water=10.23 terrainq=0.27 m2mesh=9.31 m2build=3.93 wmobuild=0.08
|
||||
StreamingWorld: loaded streaming tile 27,56
|
||||
HITCH 25.81ms refresh=false queues[tile=35 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=71 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=26 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.89 water=10.10 terrainq=0.27 m2mesh=7.95 m2build=4.44 wmobuild=0.08
|
||||
StreamingWorld: loaded streaming tile 40,52
|
||||
HITCH 48.86ms refresh=false queues[tile=34 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=72 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=26 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.63 terrainq=0.24 m2build=0.22 wmobuild=0.06 wmogroups=45.65
|
||||
StreamingWorld: loaded streaming tile 38,55
|
||||
HITCH 22.97ms refresh=false queues[tile=32 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=72 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=27 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.75 terrainq=0.25 m2build=1.79 wmobuild=0.07 wmogroups=18.01
|
||||
StreamingWorld: loaded streaming tile 36,40
|
||||
HITCH 22.93ms refresh=false queues[tile=31 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=72 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=25 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.68 water=10.36 terrainq=0.26 m2mesh=8.99 m2build=0.47 wmobuild=0.08
|
||||
StreamingWorld: loaded streaming tile 39,54
|
||||
HITCH 84.51ms refresh=false queues[tile=30 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=73 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=24 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.84 terrainq=0.23 m2build=0.12 wmogroups=81.19
|
||||
StreamingWorld: loaded streaming tile 40,44
|
||||
HITCH 143.16ms refresh=true queues[tile=29 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=73 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=24 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.83 water=0.74 terrainq=0.26 m2mesh=9.95 m2build=0.31 wmobuild=0.07 wmogroups=128.44 refresh=0.47
|
||||
StreamingWorld: loaded streaming tile 37,56
|
||||
StreamingWorld: loaded streaming tile 27,40
|
||||
StreamingWorld: loaded streaming tile 25,55
|
||||
StreamingWorld: loaded streaming tile 40,53
|
||||
StreamingWorld: loaded streaming tile 38,41
|
||||
HITCH 72.76ms refresh=false queues[tile=22 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=73 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=20 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] water=1.33 m2build=8.20 wmobuild=0.07 wmogroups=63.06
|
||||
StreamingWorld: loaded streaming tile 39,42
|
||||
HITCH 96.15ms refresh=true queues[tile=21 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=74 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=20 wmogroups=2 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.55 terrainq=0.28 m2mesh=9.02 m2build=4.90 wmobuild=0.07 wmogroups=78.80 refresh=0.45
|
||||
StreamingWorld: loaded streaming tile 24,54
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
StreamingWorld: loaded streaming tile 26,56
|
||||
HITCH 22.81ms refresh=false queues[tile=18 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=74 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=20 wmogroups=5 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=0.12 water=9.87 terrainq=0.28 m2mesh=7.75 m2build=4.50 wmobuild=0.07 wmogroups=0.15
|
||||
StreamingWorld: loaded streaming tile 37,40
|
||||
HITCH 55.54ms refresh=false queues[tile=17 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=75 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=34 wmobuild=21 wmogroups=3 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.51 terrainq=0.25 m2build=0.44 wmobuild=0.19 wmogroups=52.08
|
||||
StreamingWorld: loaded streaming tile 40,43
|
||||
HITCH 34.26ms refresh=true queues[tile=16 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=75 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=34 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.61 water=1.38 terrainq=0.28 m2mesh=8.13 m2build=5.27 wmobuild=0.10 wmogroups=15.97 refresh=0.45
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
StreamingWorld: loaded streaming tile 39,55
|
||||
StreamingWorld: loaded streaming tile 38,56
|
||||
StreamingWorld: loaded streaming tile 40,54
|
||||
StreamingWorld: loaded streaming tile 24,55
|
||||
HITCH 44.18ms refresh=false queues[tile=11 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=76 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=5.80 wmobuild=0.08 wmogroups=38.17
|
||||
StreamingWorld: loaded streaming tile 25,56
|
||||
HITCH 20.01ms refresh=true queues[tile=10 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=76 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=33 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.78 water=1.30 terrainq=0.25 m2mesh=14.40 m2build=0.29 wmobuild=0.39 refresh=0.53
|
||||
StreamingWorld: loaded streaming tile 39,41
|
||||
HITCH 72.70ms refresh=false queues[tile=9 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=77 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.64 terrainq=0.26 m2mesh=14.27 m2build=0.18 wmobuild=0.08 wmogroups=55.19
|
||||
StreamingWorld: loaded streaming tile 38,40
|
||||
HITCH 20.71ms refresh=true queues[tile=8 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=77 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.63 water=1.46 terrainq=0.23 m2mesh=12.03 m2build=3.09 wmobuild=0.48 refresh=0.69
|
||||
StreamingWorld: loaded streaming tile 40,42
|
||||
StreamingWorld: loaded streaming tile 39,56
|
||||
HITCH 39.82ms refresh=false queues[tile=5 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=77 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=3.08 water=18.53 terrainq=0.38 m2mesh=9.83 m2build=0.15 wmobuild=0.09 wmogroups=7.66
|
||||
StreamingWorld: loaded streaming tile 40,55
|
||||
HITCH 46.32ms refresh=false queues[tile=4 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=78 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.74 terrainq=0.30 m2mesh=42.75 m2build=0.11 wmobuild=0.32
|
||||
StreamingWorld: loaded streaming tile 39,40
|
||||
DBG QUEUES tiles_load=3 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=261
|
||||
PERF fps=35.0 tiles=261 wanted=261 retained=261 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=78 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=3 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=33 wmo_build=19 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=357 m2_inst=8894 wmo=258
|
||||
HITCH 67.46ms refresh=true queues[tile=3 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=78 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] finalize=2.78 water=1.18 terrainq=2.31 m2build=3.58 wmobuild=0.11 wmogroups=52.98 refresh=4.42
|
||||
StreamingWorld: loaded streaming tile 40,41
|
||||
HITCH 52.34ms refresh=false queues[tile=2 loading=1 terrainup=0 terrainctl=0 terrainsplat=0 water=78 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=20 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=40.49 m2mesh=11.13 m2build=0.18 wmobuild=0.40
|
||||
StreamingWorld: loaded streaming tile 40,56
|
||||
StreamingWorld: loaded streaming tile 40,40
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 53.33ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=78 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=33 wmobuild=21 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=39.85 m2mesh=12.34 m2build=0.43 wmobuild=0.09 refresh=0.48
|
||||
HITCH 29.86ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=77 detail=0 m2task=0 m2anim=0 m2mesh=4 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.36 wmobuild=0.09 wmogroups=29.30
|
||||
HITCH 68.71ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=76 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=33 wmobuild=18 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=11.02 m2mesh=19.66 m2build=0.20 wmobuild=0.12 wmogroups=37.04 refresh=0.57
|
||||
HITCH 52.57ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=76 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=33 wmobuild=18 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=52.26 m2build=0.13 wmobuild=0.06
|
||||
HITCH 26.36ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=75 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=19 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=13.46 m2build=0.19 wmobuild=0.10 wmogroups=12.49
|
||||
HITCH 20.58ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=73 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=1.40 m2mesh=18.39 m2build=0.15 refresh=0.52
|
||||
HITCH 51.39ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=73 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=16 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.14 wmobuild=0.07 wmogroups=51.08
|
||||
HITCH 34.33ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=71 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=17 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=33.91 m2build=0.12 wmobuild=0.06 wmogroups=0.14
|
||||
HITCH 40.07ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=69 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=16 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] water=1.01 m2mesh=9.40 m2build=0.14 wmobuild=0.08 wmogroups=29.34
|
||||
HITCH 28.77ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=63 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=15 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=10.24 m2build=0.12 wmobuild=0.08 wmogroups=18.26
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 20.54ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=61 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=15 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=4.58 m2mesh=9.20 m2build=5.79 wmobuild=0.34 refresh=0.57
|
||||
HITCH 95.81ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=59 detail=0 m2task=0 m2anim=0 m2mesh=2 m2build=33 wmobuild=13 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.12 wmobuild=0.08 wmogroups=95.52
|
||||
HITCH 25.30ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=58 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=11 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=24.95 m2build=0.13 wmogroups=0.11
|
||||
HITCH 34.41ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=56 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=12 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.07 wmogroups=33.62 refresh=0.61
|
||||
HITCH 28.22ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=51 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=33 wmobuild=7 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=9.08 m2build=0.29 wmobuild=0.07 wmogroups=18.69
|
||||
HITCH 48.41ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=50 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=33 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=47.86 m2build=0.11 wmobuild=0.34
|
||||
HITCH 20.39ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=49 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=9.48 m2mesh=10.63 m2build=0.13 wmobuild=0.06
|
||||
DBG QUEUES tiles_load=0 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=264
|
||||
PERF fps=56.0 tiles=264 wanted=264 retained=264 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=49 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=0 detail=0 m2_task=0 m2_anim=0 m2_mesh=0 m2_build=33 wmo_build=9 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=418 m2_inst=9407 wmo=318
|
||||
HITCH 25.03ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=47 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=10 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=1.13 m2build=8.17 wmobuild=0.12 wmogroups=15.53
|
||||
HITCH 26.54ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=45 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=12.27 m2mesh=9.11 m2build=4.78 wmobuild=0.31
|
||||
HITCH 21.74ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=44 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=33 wmobuild=8 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=21.47 m2build=0.15
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 48.36ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=40 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=6 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=21.25 m2mesh=9.11 m2build=17.73 wmobuild=0.10 wmogroups=0.09
|
||||
HITCH 220.47ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=39 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=6 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.13 wmobuild=0.07 wmogroups=220.17
|
||||
HITCH 31.76ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=38 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=5 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=16.67 m2mesh=13.85 m2build=0.21 wmobuild=0.09 refresh=0.82
|
||||
HITCH 49.79ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=38 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=6 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.18 wmobuild=0.09 wmogroups=49.39
|
||||
HITCH 46.97ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=37 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=6 wmogroups=2 lod+=0 lod-=0 chunk+=0 chunk-=0] water=10.48 m2mesh=26.65 m2build=8.48 wmobuild=0.15 wmogroups=0.24 refresh=0.85
|
||||
HITCH 185.44ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=36 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=5 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] water=1.83 m2build=14.98 wmobuild=0.16 wmogroups=167.47 refresh=0.87
|
||||
HITCH 99.87ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=34 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=2 wmogroups=1 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.20 wmobuild=0.08 wmogroups=98.73 refresh=0.70
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 20.89ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=32 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=3 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=1.40 m2build=19.24 wmobuild=0.12
|
||||
HITCH 84.24ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=31 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=2 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=0.17 wmobuild=0.11 wmogroups=83.06 refresh=0.80
|
||||
HITCH 49.68ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=30 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=9.94 m2build=0.11 wmobuild=0.07 wmogroups=39.48
|
||||
HITCH 21.48ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=20 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=11.96 m2mesh=9.23 m2build=0.19
|
||||
DBG QUEUES tiles_load=0 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=264
|
||||
PERF fps=34.0 tiles=264 wanted=264 retained=264 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=16 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=0 detail=0 m2_task=0 m2_anim=0 m2_mesh=1 m2_build=32 wmo_build=0 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=488 m2_inst=10014 wmo=345
|
||||
HITCH 20.62ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=16 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=13.14 terrainq=2.65 m2build=0.80
|
||||
HITCH 22.09ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=7 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=11.17 m2build=10.15 refresh=0.68
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 27.27ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=5 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=32 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=18.14 m2mesh=8.90 m2build=0.14
|
||||
SKY_LIGHT time=13.00 map=0 area=9:Долина Североземья zone=12:Элвиннский лес wow=(-8950.0,-132.5,83.5) profiles=[{ "id": 28, "weight": 1.0, "source": "area", "area": 9, "zone": 12 }] skybox=0 fog=8000..16000 density=0.056
|
||||
HITCH 21.43ms refresh=true queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=1 detail=0 m2task=0 m2anim=0 m2mesh=0 m2build=32 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] water=11.72 m2mesh=8.85 m2build=0.14 refresh=0.62
|
||||
HITCH 22.79ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=3 m2build=31 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2build=22.66
|
||||
TERRAIN_QUALITY target=100 ready=100 pending=0 fallback[baked=0 stream=0 hidden=0 other=0] missing_cache=0 queue=0 focus=32_48:control_splat_cache done=true
|
||||
HITCH 22.02ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=4 m2build=29 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=17.38 m2build=0.49
|
||||
HITCH 42.16ms refresh=false queues[tile=0 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 detail=0 m2task=0 m2anim=0 m2mesh=1 m2build=27 wmobuild=0 wmogroups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2mesh=41.92 m2build=0.17
|
||||
RENDER_CHECKPOINT saved C:/Users/sindo/AppData/Roaming/Godot/app_userdata/OpenWC/server_spawn_renderer_m01_gui_run2/azerothcore_human_warrior_start__warm_revisit.png sha256=1b75237a090ea163836372a8e39e778c909773f4508063adc3f70a3e12a85a62
|
||||
RENDER_BASELINE report=C:/Users/sindo/AppData/Roaming/Godot/app_userdata/OpenWC/server_spawn_renderer_m01_gui_run2/report.json results=2
|
||||
DBG QUEUES tiles_load=0 tile_lod_create=0 tile_lod_remove=0 chunk_create=0 chunk_remove=0 created=0 null=0 states=264
|
||||
PERF fps=83.0 tiles=264 wanted=264 retained=264 loading=0 terrainup=0 terrainctl=0 terrainsplat=0 water=0 src[baked=0 ctl=100 splat=0] cache=48 lod_rid=221 lod_node=0 lod_hidden=121 lod_prepared=0 chunk_rid=0 chunk_node=0 queues[tile=0 detail=0 m2_task=0 m2_anim=0 m2_mesh=1 m2_build=27 wmo_build=0 wmo_groups=0 lod+=0 lod-=0 chunk+=0 chunk-=0] m2_tiles=35 m2_mm=616 m2_inst=11440 wmo=345
|
||||
@@ -0,0 +1,44 @@
|
||||
class_name AdtChunkCoordinate
|
||||
extends RefCounted
|
||||
|
||||
## Immutable MCNK chunk indices inside one ADT tile.
|
||||
## `chunk_x` grows east and `chunk_y` grows south, matching the ADT header and
|
||||
## tile conversion contract rather than Godot's X/Z member names.
|
||||
|
||||
const MINIMUM_CHUNK_INDEX: int = 0
|
||||
const MAXIMUM_CHUNK_INDEX: int = 15
|
||||
|
||||
var tile_coordinate: AdtTileCoordinate:
|
||||
get:
|
||||
return _tile_coordinate
|
||||
|
||||
var chunk_x: int:
|
||||
get:
|
||||
return _chunk_x
|
||||
|
||||
var chunk_y: int:
|
||||
get:
|
||||
return _chunk_y
|
||||
|
||||
var _tile_coordinate: AdtTileCoordinate
|
||||
var _chunk_x: int
|
||||
var _chunk_y: int
|
||||
|
||||
|
||||
## Creates chunk indices without clamping so invalid parser input is visible.
|
||||
func _init(tile_coordinate_value: AdtTileCoordinate, chunk_x_value: int, chunk_y_value: int) -> void:
|
||||
_tile_coordinate = tile_coordinate_value
|
||||
_chunk_x = chunk_x_value
|
||||
_chunk_y = chunk_y_value
|
||||
|
||||
|
||||
## Returns whether the tile and both chunk indices are inside standard bounds.
|
||||
func is_within_map_grid() -> bool:
|
||||
return (
|
||||
_tile_coordinate != null
|
||||
and _tile_coordinate.is_within_map_grid()
|
||||
and _chunk_x >= MINIMUM_CHUNK_INDEX
|
||||
and _chunk_x <= MAXIMUM_CHUNK_INDEX
|
||||
and _chunk_y >= MINIMUM_CHUNK_INDEX
|
||||
and _chunk_y <= MAXIMUM_CHUNK_INDEX
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
uid://b1lf5w5p3b6ye
|
||||
@@ -0,0 +1,29 @@
|
||||
class_name AdtPlacementPosition
|
||||
extends RefCounted
|
||||
|
||||
## Immutable MDDF/MODF position in ADT file field order.
|
||||
## `x_offset_yards` and `z_offset_yards` are measured from the north-west map
|
||||
## extent; `height_yards` is the vertical field stored between them.
|
||||
|
||||
var x_offset_yards: float:
|
||||
get:
|
||||
return _x_offset_yards
|
||||
|
||||
var height_yards: float:
|
||||
get:
|
||||
return _height_yards
|
||||
|
||||
var z_offset_yards: float:
|
||||
get:
|
||||
return _z_offset_yards
|
||||
|
||||
var _x_offset_yards: float
|
||||
var _height_yards: float
|
||||
var _z_offset_yards: float
|
||||
|
||||
|
||||
## Creates an ADT placement position in on-disk X/height/Z field order.
|
||||
func _init(x_offset_yards_value: float, height_yards_value: float, z_offset_yards_value: float) -> void:
|
||||
_x_offset_yards = x_offset_yards_value
|
||||
_height_yards = height_yards_value
|
||||
_z_offset_yards = z_offset_yards_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://cxxlbkjmdtg7m
|
||||
@@ -0,0 +1,35 @@
|
||||
class_name AdtTileCoordinate
|
||||
extends RefCounted
|
||||
|
||||
## Immutable indices from an ADT filename `Map_tileX_tileY.adt`.
|
||||
## Both axes use the inclusive range 0..63 for a normal WotLK world map.
|
||||
|
||||
const MINIMUM_TILE_INDEX: int = 0
|
||||
const MAXIMUM_TILE_INDEX: int = 63
|
||||
|
||||
var tile_x: int:
|
||||
get:
|
||||
return _tile_x
|
||||
|
||||
var tile_y: int:
|
||||
get:
|
||||
return _tile_y
|
||||
|
||||
var _tile_x: int
|
||||
var _tile_y: int
|
||||
|
||||
|
||||
## Creates file indices without clamping so out-of-map input remains diagnosable.
|
||||
func _init(tile_x_value: int, tile_y_value: int) -> void:
|
||||
_tile_x = tile_x_value
|
||||
_tile_y = tile_y_value
|
||||
|
||||
|
||||
## Returns whether both file indices address the standard 64 by 64 ADT grid.
|
||||
func is_within_map_grid() -> bool:
|
||||
return (
|
||||
_tile_x >= MINIMUM_TILE_INDEX
|
||||
and _tile_x <= MAXIMUM_TILE_INDEX
|
||||
and _tile_y >= MINIMUM_TILE_INDEX
|
||||
and _tile_y <= MAXIMUM_TILE_INDEX
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bg0a286yty1jw
|
||||
@@ -0,0 +1,29 @@
|
||||
class_name AdtTileLocalPosition
|
||||
extends RefCounted
|
||||
|
||||
## Immutable position relative to the north-west corner of one ADT tile.
|
||||
## East and south offsets are normally in `[0, ADT_TILE_SIZE_YARDS)`; height
|
||||
## remains in the canonical vertical space.
|
||||
|
||||
var east_yards: float:
|
||||
get:
|
||||
return _east_yards
|
||||
|
||||
var height_yards: float:
|
||||
get:
|
||||
return _height_yards
|
||||
|
||||
var south_yards: float:
|
||||
get:
|
||||
return _south_yards
|
||||
|
||||
var _east_yards: float
|
||||
var _height_yards: float
|
||||
var _south_yards: float
|
||||
|
||||
|
||||
## Creates a tile-local position without clamping boundary values.
|
||||
func _init(east_yards_value: float, height_yards_value: float, south_yards_value: float) -> void:
|
||||
_east_yards = east_yards_value
|
||||
_height_yards = height_yards_value
|
||||
_south_yards = south_yards_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://cpit2uvrdud6h
|
||||
@@ -0,0 +1,29 @@
|
||||
class_name CanonicalWowWorldPosition
|
||||
extends RefCounted
|
||||
|
||||
## Immutable WoW 3.3.5a world position in client/server axis order and yards.
|
||||
## X and Y are the horizontal coordinates reported by the client and world
|
||||
## server; Z is height. This type deliberately does not expose a [Vector3].
|
||||
|
||||
var x_yards: float:
|
||||
get:
|
||||
return _x_yards
|
||||
|
||||
var y_yards: float:
|
||||
get:
|
||||
return _y_yards
|
||||
|
||||
var z_yards: float:
|
||||
get:
|
||||
return _z_yards
|
||||
|
||||
var _x_yards: float
|
||||
var _y_yards: float
|
||||
var _z_yards: float
|
||||
|
||||
|
||||
## Creates a canonical position without changing precision or validating map bounds.
|
||||
func _init(x_yards_value: float, y_yards_value: float, z_yards_value: float) -> void:
|
||||
_x_yards = x_yards_value
|
||||
_y_yards = y_yards_value
|
||||
_z_yards = z_yards_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://b75i20d4vnkyh
|
||||
@@ -0,0 +1,16 @@
|
||||
class_name CanonicalWowWorldYaw
|
||||
extends RefCounted
|
||||
|
||||
## Immutable canonical world-facing yaw in radians.
|
||||
## Zero faces increasing WoW X and positive rotation turns toward increasing Y.
|
||||
|
||||
var radians: float:
|
||||
get:
|
||||
return _radians
|
||||
|
||||
var _radians: float
|
||||
|
||||
|
||||
## Creates a yaw without normalization; [CoordinateMapper] normalizes conversions.
|
||||
func _init(radians_value: float) -> void:
|
||||
_radians = radians_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://ddu5eiobntlrm
|
||||
@@ -0,0 +1,167 @@
|
||||
class_name CoordinateMapper
|
||||
extends RefCounted
|
||||
|
||||
## Pure, stateless conversions between OpenWC coordinate value objects.
|
||||
## This is the only domain contract allowed to change coordinate axes. It does
|
||||
## not depend on Node, Resource, scene state, map assets or renderer globals.
|
||||
|
||||
const ADT_TILES_PER_MAP_AXIS: int = 64
|
||||
const ADT_CHUNKS_PER_TILE_AXIS: int = 16
|
||||
const ADT_TILE_SIZE_YARDS: float = 1600.0 / 3.0
|
||||
const ADT_CHUNK_SIZE_YARDS: float = ADT_TILE_SIZE_YARDS / float(ADT_CHUNKS_PER_TILE_AXIS)
|
||||
const WOW_WORLD_HALF_EXTENT_YARDS: float = ADT_TILE_SIZE_YARDS * float(ADT_TILES_PER_MAP_AXIS) * 0.5
|
||||
|
||||
|
||||
## Converts server/wire X/Y/Z to canonical WoW X/Y/Z without an axis swap.
|
||||
static func server_to_canonical(server_position: ServerWorldPosition) -> CanonicalWowWorldPosition:
|
||||
return CanonicalWowWorldPosition.new(
|
||||
server_position.x_yards,
|
||||
server_position.y_yards,
|
||||
server_position.z_yards
|
||||
)
|
||||
|
||||
|
||||
## Converts canonical WoW X/Y/Z to server/wire X/Y/Z without an axis swap.
|
||||
static func canonical_to_server(canonical_position: CanonicalWowWorldPosition) -> ServerWorldPosition:
|
||||
return ServerWorldPosition.new(
|
||||
canonical_position.x_yards,
|
||||
canonical_position.y_yards,
|
||||
canonical_position.z_yards
|
||||
)
|
||||
|
||||
|
||||
## Converts canonical WoW world axes to the Godot Y-up compatibility basis.
|
||||
static func canonical_to_godot(canonical_position: CanonicalWowWorldPosition) -> GodotWorldPosition:
|
||||
return GodotWorldPosition.new(
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - canonical_position.y_yards,
|
||||
canonical_position.z_yards,
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - canonical_position.x_yards
|
||||
)
|
||||
|
||||
|
||||
## Converts the Godot Y-up compatibility basis to canonical WoW world axes.
|
||||
static func godot_to_canonical(godot_position: GodotWorldPosition) -> CanonicalWowWorldPosition:
|
||||
return CanonicalWowWorldPosition.new(
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - godot_position.z_units,
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - godot_position.x_units,
|
||||
godot_position.y_units
|
||||
)
|
||||
|
||||
|
||||
## Returns ADT filename indices directly from a Godot renderer position.
|
||||
static func godot_to_adt_tile(godot_position: GodotWorldPosition) -> AdtTileCoordinate:
|
||||
return AdtTileCoordinate.new(
|
||||
int(floor(godot_position.x_units / ADT_TILE_SIZE_YARDS)),
|
||||
int(floor(godot_position.z_units / ADT_TILE_SIZE_YARDS))
|
||||
)
|
||||
|
||||
|
||||
## Returns east/height/south offsets inside the owning ADT tile.
|
||||
static func godot_to_adt_tile_local(godot_position: GodotWorldPosition) -> AdtTileLocalPosition:
|
||||
var tile_coordinate := godot_to_adt_tile(godot_position)
|
||||
return AdtTileLocalPosition.new(
|
||||
godot_position.x_units - float(tile_coordinate.tile_x) * ADT_TILE_SIZE_YARDS,
|
||||
godot_position.y_units,
|
||||
godot_position.z_units - float(tile_coordinate.tile_y) * ADT_TILE_SIZE_YARDS
|
||||
)
|
||||
|
||||
|
||||
## Converts an ADT tile/local pair directly to the Godot renderer basis.
|
||||
static func adt_tile_local_to_godot(
|
||||
tile_coordinate: AdtTileCoordinate,
|
||||
local_position: AdtTileLocalPosition
|
||||
) -> GodotWorldPosition:
|
||||
return GodotWorldPosition.new(
|
||||
float(tile_coordinate.tile_x) * ADT_TILE_SIZE_YARDS + local_position.east_yards,
|
||||
local_position.height_yards,
|
||||
float(tile_coordinate.tile_y) * ADT_TILE_SIZE_YARDS + local_position.south_yards
|
||||
)
|
||||
|
||||
|
||||
## Converts canonical WoW coordinates to MDDF/MODF X/height/Z file fields.
|
||||
static func canonical_to_adt_placement(canonical_position: CanonicalWowWorldPosition) -> AdtPlacementPosition:
|
||||
return AdtPlacementPosition.new(
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - canonical_position.x_yards,
|
||||
canonical_position.z_yards,
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - canonical_position.y_yards
|
||||
)
|
||||
|
||||
|
||||
## Converts MDDF/MODF X/height/Z file fields to canonical WoW coordinates.
|
||||
static func adt_placement_to_canonical(adt_position: AdtPlacementPosition) -> CanonicalWowWorldPosition:
|
||||
return CanonicalWowWorldPosition.new(
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - adt_position.x_offset_yards,
|
||||
WOW_WORLD_HALF_EXTENT_YARDS - adt_position.z_offset_yards,
|
||||
adt_position.height_yards
|
||||
)
|
||||
|
||||
|
||||
## Returns unclamped ADT filename indices for a canonical position.
|
||||
## Exact south/east boundaries belong to the next tile by floor semantics.
|
||||
static func canonical_to_adt_tile(canonical_position: CanonicalWowWorldPosition) -> AdtTileCoordinate:
|
||||
return AdtTileCoordinate.new(
|
||||
int(floor(float(ADT_TILES_PER_MAP_AXIS) * 0.5 - canonical_position.y_yards / ADT_TILE_SIZE_YARDS)),
|
||||
int(floor(float(ADT_TILES_PER_MAP_AXIS) * 0.5 - canonical_position.x_yards / ADT_TILE_SIZE_YARDS))
|
||||
)
|
||||
|
||||
|
||||
## Converts a canonical position to east/south offsets inside its ADT tile.
|
||||
static func canonical_to_adt_tile_local(canonical_position: CanonicalWowWorldPosition) -> AdtTileLocalPosition:
|
||||
var tile_coordinate := canonical_to_adt_tile(canonical_position)
|
||||
var tile_west_edge_y_yards := (float(ADT_TILES_PER_MAP_AXIS) * 0.5 - float(tile_coordinate.tile_x)) * ADT_TILE_SIZE_YARDS
|
||||
var tile_north_edge_x_yards := (float(ADT_TILES_PER_MAP_AXIS) * 0.5 - float(tile_coordinate.tile_y)) * ADT_TILE_SIZE_YARDS
|
||||
return AdtTileLocalPosition.new(
|
||||
tile_west_edge_y_yards - canonical_position.y_yards,
|
||||
canonical_position.z_yards,
|
||||
tile_north_edge_x_yards - canonical_position.x_yards
|
||||
)
|
||||
|
||||
|
||||
## Reconstructs canonical coordinates from an ADT tile and tile-local offsets.
|
||||
static func adt_tile_local_to_canonical(
|
||||
tile_coordinate: AdtTileCoordinate,
|
||||
local_position: AdtTileLocalPosition
|
||||
) -> CanonicalWowWorldPosition:
|
||||
var tile_west_edge_y_yards := (float(ADT_TILES_PER_MAP_AXIS) * 0.5 - float(tile_coordinate.tile_x)) * ADT_TILE_SIZE_YARDS
|
||||
var tile_north_edge_x_yards := (float(ADT_TILES_PER_MAP_AXIS) * 0.5 - float(tile_coordinate.tile_y)) * ADT_TILE_SIZE_YARDS
|
||||
return CanonicalWowWorldPosition.new(
|
||||
tile_north_edge_x_yards - local_position.south_yards,
|
||||
tile_west_edge_y_yards - local_position.east_yards,
|
||||
local_position.height_yards
|
||||
)
|
||||
|
||||
|
||||
## Returns unclamped MCNK indices for a tile-local position.
|
||||
static func adt_tile_local_to_chunk(
|
||||
tile_coordinate: AdtTileCoordinate,
|
||||
local_position: AdtTileLocalPosition
|
||||
) -> AdtChunkCoordinate:
|
||||
return AdtChunkCoordinate.new(
|
||||
tile_coordinate,
|
||||
int(floor(local_position.east_yards / ADT_CHUNK_SIZE_YARDS)),
|
||||
int(floor(local_position.south_yards / ADT_CHUNK_SIZE_YARDS))
|
||||
)
|
||||
|
||||
|
||||
## Converts server movement yaw to canonical yaw and normalizes it to [-PI, PI).
|
||||
static func server_to_canonical_yaw(server_yaw: ServerWorldYaw) -> CanonicalWowWorldYaw:
|
||||
return CanonicalWowWorldYaw.new(_normalize_yaw(server_yaw.radians))
|
||||
|
||||
|
||||
## Converts canonical yaw to server movement yaw and normalizes it to [-PI, PI).
|
||||
static func canonical_to_server_yaw(canonical_yaw: CanonicalWowWorldYaw) -> ServerWorldYaw:
|
||||
return ServerWorldYaw.new(_normalize_yaw(canonical_yaw.radians))
|
||||
|
||||
|
||||
## Converts canonical world yaw to Godot Y-axis yaw in the mapped world basis.
|
||||
static func canonical_to_godot_yaw(canonical_yaw: CanonicalWowWorldYaw) -> GodotWorldYaw:
|
||||
return GodotWorldYaw.new(_normalize_yaw(canonical_yaw.radians))
|
||||
|
||||
|
||||
## Converts Godot Y-axis world yaw to canonical yaw in the mapped world basis.
|
||||
static func godot_to_canonical_yaw(godot_yaw: GodotWorldYaw) -> CanonicalWowWorldYaw:
|
||||
return CanonicalWowWorldYaw.new(_normalize_yaw(godot_yaw.radians))
|
||||
|
||||
|
||||
static func _normalize_yaw(radians: float) -> float:
|
||||
return fposmod(radians + PI, TAU) - PI
|
||||
@@ -0,0 +1 @@
|
||||
uid://bg8p8rrkmg84d
|
||||
@@ -0,0 +1,29 @@
|
||||
class_name GodotWorldPosition
|
||||
extends RefCounted
|
||||
|
||||
## Immutable Godot Y-up renderer position.
|
||||
## One Godot unit equals one WoW yard in the compatibility renderer. X grows
|
||||
## east, Y grows up and Z grows south from the north-west map extent.
|
||||
|
||||
var x_units: float:
|
||||
get:
|
||||
return _x_units
|
||||
|
||||
var y_units: float:
|
||||
get:
|
||||
return _y_units
|
||||
|
||||
var z_units: float:
|
||||
get:
|
||||
return _z_units
|
||||
|
||||
var _x_units: float
|
||||
var _y_units: float
|
||||
var _z_units: float
|
||||
|
||||
|
||||
## Creates a renderer position without exposing it as a cross-layer [Vector3].
|
||||
func _init(x_units_value: float, y_units_value: float, z_units_value: float) -> void:
|
||||
_x_units = x_units_value
|
||||
_y_units = y_units_value
|
||||
_z_units = z_units_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://tp7jo14w25nc
|
||||
@@ -0,0 +1,17 @@
|
||||
class_name GodotWorldYaw
|
||||
extends RefCounted
|
||||
|
||||
## Immutable Godot Y-axis yaw in radians for the canonical world basis.
|
||||
## With Godot forward `-Z`, the numeric angle equals WoW world yaw after the
|
||||
## position basis conversion. Model-local MDDF/MODF corrections are separate.
|
||||
|
||||
var radians: float:
|
||||
get:
|
||||
return _radians
|
||||
|
||||
var _radians: float
|
||||
|
||||
|
||||
## Creates a Godot world yaw without normalization.
|
||||
func _init(radians_value: float) -> void:
|
||||
_radians = radians_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://cuy2skhdv3f6g
|
||||
@@ -0,0 +1,29 @@
|
||||
class_name ServerWorldPosition
|
||||
extends RefCounted
|
||||
|
||||
## Immutable TrinityCore/AzerothCore world position in wire/database X/Y/Z order.
|
||||
## Units are WoW yards. A distinct type prevents server positions from being
|
||||
## passed directly to renderer APIs even though the scalar values are canonical.
|
||||
|
||||
var x_yards: float:
|
||||
get:
|
||||
return _x_yards
|
||||
|
||||
var y_yards: float:
|
||||
get:
|
||||
return _y_yards
|
||||
|
||||
var z_yards: float:
|
||||
get:
|
||||
return _z_yards
|
||||
|
||||
var _x_yards: float
|
||||
var _y_yards: float
|
||||
var _z_yards: float
|
||||
|
||||
|
||||
## Creates a server position without changing precision or validating map bounds.
|
||||
func _init(x_yards_value: float, y_yards_value: float, z_yards_value: float) -> void:
|
||||
_x_yards = x_yards_value
|
||||
_y_yards = y_yards_value
|
||||
_z_yards = z_yards_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://dilhr7ym3xr43
|
||||
@@ -0,0 +1,16 @@
|
||||
class_name ServerWorldYaw
|
||||
extends RefCounted
|
||||
|
||||
## Immutable TrinityCore/AzerothCore movement orientation in radians.
|
||||
## It uses the WoW client convention: zero faces +X and positive turns toward +Y.
|
||||
|
||||
var radians: float:
|
||||
get:
|
||||
return _radians
|
||||
|
||||
var _radians: float
|
||||
|
||||
|
||||
## Creates a server yaw without normalization.
|
||||
func _init(radians_value: float) -> void:
|
||||
_radians = radians_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://dr8k82t2qgewd
|
||||
@@ -0,0 +1,43 @@
|
||||
class_name ContentId
|
||||
extends RefCounted
|
||||
|
||||
## Stable authored-content identity serialized as canonical lowercase UUID text.
|
||||
## It is independent of runtime entities, server database entries and wire GUIDs.
|
||||
|
||||
var uuid_text: String:
|
||||
get:
|
||||
return _uuid_text
|
||||
|
||||
var _uuid_text: String
|
||||
|
||||
|
||||
## Normalizes surrounding whitespace and hexadecimal letter case.
|
||||
func _init(uuid_text_value: String) -> void:
|
||||
_uuid_text = uuid_text_value.strip_edges().to_lower()
|
||||
|
||||
|
||||
## Reports whether the value has the canonical 8-4-4-4-12 UUID text shape.
|
||||
func is_valid() -> bool:
|
||||
if _uuid_text.length() != 36:
|
||||
return false
|
||||
for character_index in range(_uuid_text.length()):
|
||||
if character_index in [8, 13, 18, 23]:
|
||||
if _uuid_text[character_index] != "-":
|
||||
return false
|
||||
elif not _is_lowercase_hexadecimal_character(_uuid_text[character_index]):
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
## Compares stable content identity by normalized UUID text.
|
||||
func equals(other_content_id: ContentId) -> bool:
|
||||
return other_content_id != null and _uuid_text == other_content_id.uuid_text
|
||||
|
||||
|
||||
## Returns the canonical dictionary/serialization key.
|
||||
func to_key() -> String:
|
||||
return _uuid_text
|
||||
|
||||
|
||||
func _is_lowercase_hexadecimal_character(character: String) -> bool:
|
||||
return (character >= "0" and character <= "9") or (character >= "a" and character <= "f")
|
||||
@@ -0,0 +1 @@
|
||||
uid://dk6splyui2an1
|
||||
@@ -0,0 +1,31 @@
|
||||
class_name EntityId
|
||||
extends RefCounted
|
||||
|
||||
## Session-local runtime entity identity.
|
||||
## This sequence is never a stable content ID, server entry or WoW wire GUID.
|
||||
|
||||
var session_sequence: int:
|
||||
get:
|
||||
return _session_sequence
|
||||
|
||||
var _session_sequence: int
|
||||
|
||||
|
||||
## Stores an allocator-issued session sequence without persistence semantics.
|
||||
func _init(session_sequence_value: int) -> void:
|
||||
_session_sequence = session_sequence_value
|
||||
|
||||
|
||||
## Reports whether this is a positive allocator-issued sequence.
|
||||
func is_valid() -> bool:
|
||||
return _session_sequence > 0
|
||||
|
||||
|
||||
## Compares identity inside the same explicitly owned runtime session.
|
||||
func equals(other_entity_id: EntityId) -> bool:
|
||||
return other_entity_id != null and _session_sequence == other_entity_id.session_sequence
|
||||
|
||||
|
||||
## Returns a diagnostic key; it must not be persisted across sessions.
|
||||
func to_debug_key() -> String:
|
||||
return "entity:%d" % _session_sequence
|
||||
@@ -0,0 +1 @@
|
||||
uid://bqdd8el4me5ng
|
||||
@@ -0,0 +1,41 @@
|
||||
class_name ServerEntryId
|
||||
extends RefCounted
|
||||
|
||||
## Adapter-namespaced numeric entry from a server database or canonical snapshot.
|
||||
## Equal numbers in different template tables are intentionally different IDs.
|
||||
|
||||
var entry_namespace: String:
|
||||
get:
|
||||
return _entry_namespace
|
||||
|
||||
var entry_value: int:
|
||||
get:
|
||||
return _entry_value
|
||||
|
||||
var _entry_namespace: String
|
||||
var _entry_value: int
|
||||
|
||||
|
||||
## Normalizes a table/adapter namespace and preserves its positive entry value.
|
||||
func _init(entry_namespace_value: String, entry_value_value: int) -> void:
|
||||
_entry_namespace = entry_namespace_value.strip_edges().to_lower()
|
||||
_entry_value = entry_value_value
|
||||
|
||||
|
||||
## Reports whether both collision-prevention fields are present.
|
||||
func is_valid() -> bool:
|
||||
return not _entry_namespace.is_empty() and _entry_value > 0
|
||||
|
||||
|
||||
## Compares both namespace and numeric entry.
|
||||
func equals(other_server_entry_id: ServerEntryId) -> bool:
|
||||
return (
|
||||
other_server_entry_id != null
|
||||
and _entry_namespace == other_server_entry_id.entry_namespace
|
||||
and _entry_value == other_server_entry_id.entry_value
|
||||
)
|
||||
|
||||
|
||||
## Returns the stable adapter key without implying a ContentId mapping.
|
||||
func to_key() -> String:
|
||||
return "%s:%d" % [_entry_namespace, _entry_value]
|
||||
@@ -0,0 +1 @@
|
||||
uid://cg3mht5bhgsya
|
||||
@@ -0,0 +1,53 @@
|
||||
class_name WowGuid
|
||||
extends RefCounted
|
||||
|
||||
## Opaque 64-bit WoW wire GUID stored as two lossless unsigned 32-bit words.
|
||||
## Build-specific high-type decoding belongs to the protocol adapter and must be
|
||||
## fixture-backed before becoming a domain contract.
|
||||
|
||||
const MAXIMUM_UNSIGNED_32_BIT_VALUE := 0xffffffff
|
||||
|
||||
var high_32_bits: int:
|
||||
get:
|
||||
return _high_32_bits
|
||||
|
||||
var low_32_bits: int:
|
||||
get:
|
||||
return _low_32_bits
|
||||
|
||||
var _high_32_bits: int
|
||||
var _low_32_bits: int
|
||||
|
||||
|
||||
## Preserves both wire words without signed 64-bit conversion.
|
||||
func _init(high_32_bits_value: int, low_32_bits_value: int) -> void:
|
||||
_high_32_bits = high_32_bits_value
|
||||
_low_32_bits = low_32_bits_value
|
||||
|
||||
|
||||
## Reports whether both words fit their unsigned wire ranges.
|
||||
func has_valid_word_ranges() -> bool:
|
||||
return _is_unsigned_32_bit_word(_high_32_bits) and _is_unsigned_32_bit_word(_low_32_bits)
|
||||
|
||||
|
||||
## Reports the all-zero protocol sentinel without assigning gameplay meaning.
|
||||
func is_empty() -> bool:
|
||||
return _high_32_bits == 0 and _low_32_bits == 0
|
||||
|
||||
|
||||
## Compares all 64 opaque wire bits.
|
||||
func equals(other_wow_guid: WowGuid) -> bool:
|
||||
return (
|
||||
other_wow_guid != null
|
||||
and _high_32_bits == other_wow_guid.high_32_bits
|
||||
and _low_32_bits == other_wow_guid.low_32_bits
|
||||
)
|
||||
|
||||
|
||||
## Returns exactly sixteen lowercase hexadecimal digits for diagnostics/replays.
|
||||
func to_hex_string() -> String:
|
||||
return "%08x%08x" % [_high_32_bits, _low_32_bits]
|
||||
|
||||
|
||||
func _is_unsigned_32_bit_word(word_value: int) -> bool:
|
||||
return word_value >= 0 and word_value <= MAXIMUM_UNSIGNED_32_BIT_VALUE
|
||||
@@ -0,0 +1 @@
|
||||
uid://bmwlyacooq2lc
|
||||
@@ -0,0 +1,17 @@
|
||||
class_name StreamingFocus
|
||||
extends RefCounted
|
||||
|
||||
## Immutable world-streaming point independent of cameras and the scene tree.
|
||||
## Renderer adapters may obtain this position from a player, spectator, editor
|
||||
## viewport or capture tool, but streaming consumers receive only this value.
|
||||
|
||||
var world_position: GodotWorldPosition:
|
||||
get:
|
||||
return _world_position
|
||||
|
||||
var _world_position: GodotWorldPosition
|
||||
|
||||
|
||||
## Creates a focus at an explicit position in the Godot renderer basis.
|
||||
func _init(world_position_value: GodotWorldPosition) -> void:
|
||||
_world_position = world_position_value
|
||||
@@ -0,0 +1 @@
|
||||
uid://ehv78jvge0q2
|
||||
@@ -3,9 +3,12 @@ extends CharacterBody3D
|
||||
const GEOSET_CONTROLLER_SCRIPT := preload("res://src/scenes/character/character_geoset_controller.gd")
|
||||
const TEXTURE_COMPOSITOR_SCRIPT := preload("res://src/scenes/character/character_texture_compositor.gd")
|
||||
const OUTFIT_RESOLVER_SCRIPT := preload("res://src/scenes/character/wow_character_outfit_resolver.gd")
|
||||
const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.gd")
|
||||
const ADT_TILE_COORDINATE_SCRIPT := preload("res://src/domain/coordinates/adt_tile_coordinate.gd")
|
||||
const ADT_TILE_LOCAL_POSITION_SCRIPT := preload("res://src/domain/coordinates/adt_tile_local_position.gd")
|
||||
|
||||
const TILE_SIZE := 533.33333
|
||||
const CHUNK_SIZE := TILE_SIZE / 16.0
|
||||
const CHUNK_SIZE := COORDINATE_MAPPER_SCRIPT.ADT_CHUNK_SIZE_YARDS
|
||||
const UNIT_SIZE := CHUNK_SIZE / 8.0
|
||||
|
||||
@export var extracted_dir: String = "res://data/extracted"
|
||||
@@ -62,8 +65,11 @@ func _ready() -> void:
|
||||
_camera.current = true
|
||||
_camera.far = 50000.0
|
||||
if spawn_at_tile_center:
|
||||
global_position.x = (float(spawn_tile_x) + 0.5) * TILE_SIZE
|
||||
global_position.z = (float(spawn_tile_y) + 0.5) * TILE_SIZE
|
||||
var spawn_tile = ADT_TILE_COORDINATE_SCRIPT.new(spawn_tile_x, spawn_tile_y)
|
||||
var half_tile_size := COORDINATE_MAPPER_SCRIPT.ADT_TILE_SIZE_YARDS * 0.5
|
||||
var spawn_local = ADT_TILE_LOCAL_POSITION_SCRIPT.new(half_tile_size, global_position.y, half_tile_size)
|
||||
var spawn_position = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_godot(spawn_tile, spawn_local)
|
||||
global_position = Vector3(spawn_position.x_units, spawn_position.y_units, spawn_position.z_units)
|
||||
_load_character_visual()
|
||||
var ground := _sample_ground_height(global_position)
|
||||
if is_finite(ground):
|
||||
@@ -324,16 +330,17 @@ func _apply_camera_transform() -> void:
|
||||
|
||||
|
||||
func _sample_ground_height(world_pos: Vector3) -> float:
|
||||
var tx := int(floor(world_pos.x / TILE_SIZE))
|
||||
var ty := int(floor(world_pos.z / TILE_SIZE))
|
||||
var data := _load_adt(tx, ty)
|
||||
var typed_world_position = GODOT_WORLD_POSITION_SCRIPT.new(world_pos.x, world_pos.y, world_pos.z)
|
||||
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile(typed_world_position)
|
||||
var tile_local_position = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile_local(typed_world_position)
|
||||
var chunk_coordinate = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_chunk(tile_coordinate, tile_local_position)
|
||||
var data := _load_adt(tile_coordinate.tile_x, tile_coordinate.tile_y)
|
||||
if data.is_empty():
|
||||
return NAN
|
||||
|
||||
var tile_origin := _get_tile_origin(data)
|
||||
var local := world_pos - tile_origin
|
||||
var chunk_x := clampi(int(floor(local.x / CHUNK_SIZE)), 0, 15)
|
||||
var chunk_y := clampi(int(floor(local.z / CHUNK_SIZE)), 0, 15)
|
||||
var chunk_x := clampi(chunk_coordinate.chunk_x, 0, 15)
|
||||
var chunk_y := clampi(chunk_coordinate.chunk_y, 0, 15)
|
||||
var chunk := _find_chunk(data, chunk_x, chunk_y, tile_origin)
|
||||
if chunk.is_empty():
|
||||
return NAN
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
extends Node
|
||||
|
||||
const M2_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/m2_builder.gd")
|
||||
const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.gd")
|
||||
|
||||
const TILE_SIZE := 533.33333
|
||||
const WOW_WORLD_CENTER := 17066.666
|
||||
const LIGHT_COORD_SCALE := 36.0
|
||||
const HALF_MINUTES_PER_DAY := 2880
|
||||
|
||||
@@ -701,28 +701,30 @@ func _get_target_wow_position() -> Vector3:
|
||||
var world_pos := Vector3.ZERO
|
||||
if _target:
|
||||
world_pos = _target.global_position
|
||||
return Vector3(
|
||||
WOW_WORLD_CENTER - world_pos.z,
|
||||
WOW_WORLD_CENTER - world_pos.x,
|
||||
world_pos.y)
|
||||
var canonical_position = COORDINATE_MAPPER_SCRIPT.godot_to_canonical(_typed_godot_position(world_pos))
|
||||
return Vector3(canonical_position.x_yards, canonical_position.y_yards, canonical_position.z_yards)
|
||||
|
||||
|
||||
func _get_target_area_id() -> int:
|
||||
if not _target or map_name.is_empty():
|
||||
return 0
|
||||
var world_pos := _target.global_position
|
||||
var tile_x := int(floor(world_pos.x / TILE_SIZE))
|
||||
var tile_y := int(floor(world_pos.z / TILE_SIZE))
|
||||
var local_x := world_pos.x - float(tile_x) * TILE_SIZE
|
||||
var local_y := world_pos.z - float(tile_y) * TILE_SIZE
|
||||
var chunk_x := clampi(int(floor(local_x / (TILE_SIZE / 16.0))), 0, 15)
|
||||
var chunk_y := clampi(int(floor(local_y / (TILE_SIZE / 16.0))), 0, 15)
|
||||
var areas := _load_adt_area_grid(tile_x, tile_y)
|
||||
var typed_world_position = _typed_godot_position(world_pos)
|
||||
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile(typed_world_position)
|
||||
var local_position = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile_local(typed_world_position)
|
||||
var chunk_coordinate = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_chunk(tile_coordinate, local_position)
|
||||
var areas := _load_adt_area_grid(tile_coordinate.tile_x, tile_coordinate.tile_y)
|
||||
if areas.is_empty():
|
||||
return 0
|
||||
var chunk_x := clampi(chunk_coordinate.chunk_x, 0, 15)
|
||||
var chunk_y := clampi(chunk_coordinate.chunk_y, 0, 15)
|
||||
return int(areas[chunk_y * 16 + chunk_x])
|
||||
|
||||
|
||||
func _typed_godot_position(world_position: Vector3):
|
||||
return GODOT_WORLD_POSITION_SCRIPT.new(world_position.x, world_position.y, world_position.z)
|
||||
|
||||
|
||||
func _load_adt_area_grid(tile_x: int, tile_y: int) -> PackedInt32Array:
|
||||
var key := "%d_%d" % [tile_x, tile_y]
|
||||
if _adt_area_cache.has(key):
|
||||
|
||||
@@ -53,6 +53,7 @@ fog_depth_end = 5200.0
|
||||
|
||||
[node name="StreamingWorld" type="Node3D" unique_id=1063159974]
|
||||
script = ExtResource("1_stream")
|
||||
streaming_focus_source_path = NodePath("ThirdPersonPlayer")
|
||||
camera_path = NodePath("ThirdPersonPlayer/CameraPivot/Camera3D")
|
||||
quality_preset = "High"
|
||||
update_interval = 0.1
|
||||
|
||||
@@ -54,6 +54,7 @@ fog_depth_end = 5200.0
|
||||
[node name="StreamingWorld" type="Node3D" unique_id=1063159974]
|
||||
script = ExtResource("1_sisqv")
|
||||
map_name = "Kalimdor"
|
||||
streaming_focus_source_path = NodePath("ThirdPersonPlayer")
|
||||
camera_path = NodePath("ThirdPersonPlayer/CameraPivot/Camera3D")
|
||||
quality_preset = "High"
|
||||
update_interval = 0.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@tool
|
||||
## Streams Azeroth terrain around the active camera with chunk-based LODs.
|
||||
## Streams Azeroth terrain around an explicit [StreamingFocus] with chunk-based LODs.
|
||||
extends Node3D
|
||||
|
||||
const ADT_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/adt_builder.gd")
|
||||
@@ -12,14 +12,19 @@ const WMO_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/wmo_buil
|
||||
const M2_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/m2_builder.gd")
|
||||
const M2_NATIVE_ANIMATED_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/m2_native_animated_builder.gd")
|
||||
const M2_NATIVE_ANIMATOR_SCRIPT := preload("res://src/scenes/streaming/m2_native_animator.gd")
|
||||
const STREAMING_FOCUS_SCRIPT := preload("res://src/domain/streaming/streaming_focus.gd")
|
||||
const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.gd")
|
||||
const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const ADT_TILE_COORDINATE_SCRIPT := preload("res://src/domain/coordinates/adt_tile_coordinate.gd")
|
||||
const ADT_TILE_LOCAL_POSITION_SCRIPT := preload("res://src/domain/coordinates/adt_tile_local_position.gd")
|
||||
const REQUIRED_BAKED_TILE_FORMAT_VERSION := 5
|
||||
const REQUIRED_SPLAT_TILE_FORMAT_VERSION := 1
|
||||
const REQUIRED_CONTROL_SPLAT_TILE_FORMAT_VERSION := 3
|
||||
const M2_MATERIAL_REFRESH_VERSION := 2
|
||||
const WMO_MATERIAL_REFRESH_VERSION := 10
|
||||
|
||||
const TILE_SIZE := 533.33333
|
||||
const CHUNK_SIZE := TILE_SIZE / 16.0
|
||||
const TILE_SIZE := COORDINATE_MAPPER_SCRIPT.ADT_TILE_SIZE_YARDS
|
||||
const CHUNK_SIZE := COORDINATE_MAPPER_SCRIPT.ADT_CHUNK_SIZE_YARDS
|
||||
const ADT_CLIFFROCK_WORLD_YAW_OFFSET := PI
|
||||
const ADT_WATERFALL_WORLD_YAW_OFFSET := PI * 0.5
|
||||
const QUALITY_CUSTOM := "Custom"
|
||||
@@ -29,6 +34,9 @@ const QUALITY_HIGH := "High"
|
||||
|
||||
@export var extracted_dir: String = "res://data/extracted"
|
||||
@export var map_name: String = "Azeroth"
|
||||
## Optional scene adapter source. Any Node3D may provide the runtime focus.
|
||||
@export var streaming_focus_source_path: NodePath
|
||||
## Camera used only by the optional automatic overview positioning feature.
|
||||
@export var camera_path: NodePath
|
||||
@export_enum("Custom", "Performance", "Balanced", "High") var quality_preset: String = QUALITY_CUSTOM
|
||||
|
||||
@@ -213,6 +221,8 @@ var _tile_min := Vector2i(63, 63)
|
||||
var _tile_max := Vector2i(0, 0)
|
||||
var _camera_initialized := false
|
||||
var _editor_signature := ""
|
||||
var _streaming_focus: StreamingFocus
|
||||
var _missing_focus_source_reported := false
|
||||
var _last_focus_pos := Vector3.ZERO
|
||||
var _dbg_chunks_created := 0
|
||||
var _dbg_chunks_null := 0
|
||||
@@ -293,6 +303,8 @@ func _ready() -> void:
|
||||
_tick_editor_streaming()
|
||||
elif auto_position_camera:
|
||||
_position_camera_over_world()
|
||||
if not Engine.is_editor_hint():
|
||||
_capture_streaming_focus_from_source()
|
||||
|
||||
set_process(true)
|
||||
call_deferred("_refresh_streaming_targets_after_ready")
|
||||
@@ -364,7 +376,7 @@ func _process(delta: float) -> void:
|
||||
if Engine.is_editor_hint():
|
||||
_tick_editor_streaming()
|
||||
else:
|
||||
_refresh_streaming_targets(false)
|
||||
refresh_streaming_focus(false)
|
||||
did_refresh = true
|
||||
_profile_section(timings, "refresh", section_start, profile_enabled)
|
||||
_log_hitch_profile(profile_start, timings, did_refresh, profile_enabled)
|
||||
@@ -590,10 +602,11 @@ func _tick_editor_streaming() -> void:
|
||||
|
||||
var focus_world := _tile_center_to_world(editor_preview_center_x, editor_preview_center_y)
|
||||
if editor_follow_view_camera:
|
||||
var editor_camera := _get_stream_camera()
|
||||
var editor_camera := _get_editor_view_camera()
|
||||
if editor_camera:
|
||||
focus_world += editor_camera.global_position
|
||||
_refresh_editor_streaming_targets_at(focus_world, false)
|
||||
_set_streaming_focus_from_vector3(focus_world)
|
||||
_refresh_editor_streaming_targets_at(_streaming_focus_to_vector3(), false)
|
||||
|
||||
|
||||
func _scan_available_tiles() -> void:
|
||||
@@ -681,24 +694,28 @@ func _load_tiles_from_directory() -> void:
|
||||
_tile_max.y = max(_tile_max.y, ty)
|
||||
|
||||
|
||||
func _refresh_streaming_targets(force: bool) -> void:
|
||||
var camera := _get_stream_camera()
|
||||
if camera == null:
|
||||
return
|
||||
## Replaces the current streaming point without requiring a Node or Camera3D.
|
||||
func set_streaming_focus(streaming_focus: StreamingFocus) -> void:
|
||||
_streaming_focus = streaming_focus
|
||||
|
||||
|
||||
## Samples the configured scene source, then refreshes streaming from the typed focus.
|
||||
## Returns false when no valid focus is available; existing streamed content is retained.
|
||||
func refresh_streaming_focus(force: bool = false) -> bool:
|
||||
_capture_streaming_focus_from_source()
|
||||
if _streaming_focus == null or _streaming_focus.world_position == null:
|
||||
return false
|
||||
_terrain_root.position = Vector3.ZERO
|
||||
_refresh_streaming_targets_at(camera.global_position, force)
|
||||
_refresh_streaming_targets_at(_streaming_focus_to_vector3(), force)
|
||||
return true
|
||||
|
||||
|
||||
func _refresh_streaming_targets_after_ready() -> void:
|
||||
var camera := _get_stream_camera()
|
||||
if camera == null:
|
||||
return
|
||||
_terrain_root.position = Vector3.ZERO
|
||||
_has_refresh_focus = false
|
||||
_refresh_streaming_targets_at(camera.global_position, false)
|
||||
refresh_streaming_focus(false)
|
||||
|
||||
|
||||
## Core streaming update — works for both game (camera pos) and editor (preview center pos).
|
||||
## Core streaming update for runtime and editor focus positions.
|
||||
func _refresh_editor_streaming_targets_at(focus_pos: Vector3, force: bool) -> void:
|
||||
if not force and not _should_refresh_focus(focus_pos):
|
||||
return
|
||||
@@ -772,10 +789,9 @@ func _apply_streaming_target(wanted_tiles: Dictionary, retained_tiles: Dictionar
|
||||
var parts: PackedStringArray = key.split("_")
|
||||
var tx: int = int(parts[0])
|
||||
var ty: int = int(parts[1])
|
||||
var tcx: float = (tx + 0.5) * TILE_SIZE
|
||||
var tcz: float = (ty + 0.5) * TILE_SIZE
|
||||
var dx: float = tcx - focus_pos.x
|
||||
var dz: float = tcz - focus_pos.z
|
||||
var tile_center := _tile_center_to_world(tx, ty)
|
||||
var dx: float = tile_center.x - focus_pos.x
|
||||
var dz: float = tile_center.z - focus_pos.z
|
||||
_tile_load_queue.append({
|
||||
"key": key,
|
||||
"tx": tx,
|
||||
@@ -2895,8 +2911,10 @@ func _predictive_focus_tiles(focus_pos: Vector3) -> Array[Vector2i]:
|
||||
if threshold <= 0.0:
|
||||
return result
|
||||
|
||||
var local_x := fposmod(focus_pos.x, TILE_SIZE) / TILE_SIZE
|
||||
var local_z := fposmod(focus_pos.z, TILE_SIZE) / TILE_SIZE
|
||||
var typed_focus_position = GODOT_WORLD_POSITION_SCRIPT.new(focus_pos.x, focus_pos.y, focus_pos.z)
|
||||
var tile_local_position = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile_local(typed_focus_position)
|
||||
var local_x: float = tile_local_position.east_yards / TILE_SIZE
|
||||
var local_z: float = tile_local_position.south_yards / TILE_SIZE
|
||||
var x_offsets: Array[int] = [0]
|
||||
var z_offsets: Array[int] = [0]
|
||||
|
||||
@@ -3019,10 +3037,17 @@ func _is_tile_chunk_set_ready(state: Dictionary) -> bool:
|
||||
|
||||
|
||||
func _tile_dist_sq(state: Dictionary, cam_pos: Vector3) -> float:
|
||||
var min_x: float = float(state["tx"]) * TILE_SIZE
|
||||
var max_x: float = min_x + TILE_SIZE
|
||||
var min_z: float = float(state["ty"]) * TILE_SIZE
|
||||
var max_z: float = min_z + TILE_SIZE
|
||||
var tile_coordinate = ADT_TILE_COORDINATE_SCRIPT.new(int(state["tx"]), int(state["ty"]))
|
||||
var north_west_position = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_godot(
|
||||
tile_coordinate,
|
||||
ADT_TILE_LOCAL_POSITION_SCRIPT.new(0.0, 0.0, 0.0))
|
||||
var south_east_position = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_godot(
|
||||
tile_coordinate,
|
||||
ADT_TILE_LOCAL_POSITION_SCRIPT.new(TILE_SIZE, 0.0, TILE_SIZE))
|
||||
var min_x: float = north_west_position.x_units
|
||||
var max_x: float = south_east_position.x_units
|
||||
var min_z: float = north_west_position.z_units
|
||||
var max_z: float = south_east_position.z_units
|
||||
|
||||
var dx := 0.0
|
||||
if cam_pos.x < min_x:
|
||||
@@ -3048,32 +3073,46 @@ func _is_tile_queued(key: String) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func _get_stream_camera() -> Camera3D:
|
||||
if Engine.is_editor_hint():
|
||||
# The 3D editor viewport camera lives in EditorInterface, not get_viewport().
|
||||
# get_viewport().get_camera_3d() from a @tool script returns whichever Camera3D
|
||||
# belongs to the edited scene (often null), so editor-view movement is invisible
|
||||
# unless we reach into EditorInterface.
|
||||
var vp := EditorInterface.get_editor_viewport_3d(0)
|
||||
if vp != null:
|
||||
var cam := vp.get_camera_3d()
|
||||
if cam:
|
||||
return cam
|
||||
func _capture_streaming_focus_from_source() -> void:
|
||||
if streaming_focus_source_path == NodePath():
|
||||
return
|
||||
var focus_source := get_node_or_null(streaming_focus_source_path) as Node3D
|
||||
if focus_source == null:
|
||||
if not _missing_focus_source_reported:
|
||||
push_warning("Streaming focus source is missing or is not Node3D: %s" % streaming_focus_source_path)
|
||||
_missing_focus_source_reported = true
|
||||
return
|
||||
_missing_focus_source_reported = false
|
||||
_set_streaming_focus_from_vector3(focus_source.global_position)
|
||||
|
||||
if camera_path != NodePath():
|
||||
var from_path := get_node_or_null(camera_path)
|
||||
if from_path is Camera3D:
|
||||
return from_path
|
||||
|
||||
var viewport_camera := get_viewport().get_camera_3d()
|
||||
if viewport_camera:
|
||||
return viewport_camera
|
||||
func _set_streaming_focus_from_vector3(world_position: Vector3) -> void:
|
||||
var typed_world_position = GODOT_WORLD_POSITION_SCRIPT.new(
|
||||
world_position.x,
|
||||
world_position.y,
|
||||
world_position.z
|
||||
)
|
||||
set_streaming_focus(STREAMING_FOCUS_SCRIPT.new(typed_world_position))
|
||||
|
||||
for child in get_children():
|
||||
if child is Camera3D and child.current:
|
||||
return child
|
||||
|
||||
return null
|
||||
func _streaming_focus_to_vector3() -> Vector3:
|
||||
var world_position: GodotWorldPosition = _streaming_focus.world_position
|
||||
return Vector3(world_position.x_units, world_position.y_units, world_position.z_units)
|
||||
|
||||
|
||||
func _get_editor_view_camera() -> Camera3D:
|
||||
# EditorInterface owns this camera. This method is the explicit editor adapter;
|
||||
# runtime streaming never discovers a viewport camera.
|
||||
var editor_viewport := EditorInterface.get_editor_viewport_3d(0)
|
||||
if editor_viewport == null:
|
||||
return null
|
||||
return editor_viewport.get_camera_3d()
|
||||
|
||||
|
||||
func _get_auto_position_camera() -> Camera3D:
|
||||
if camera_path == NodePath():
|
||||
return null
|
||||
return get_node_or_null(camera_path) as Camera3D
|
||||
|
||||
|
||||
func _can_use_baked_tile_cache() -> bool:
|
||||
@@ -5365,13 +5404,13 @@ func _position_camera_over_world() -> void:
|
||||
if _camera_initialized:
|
||||
return
|
||||
|
||||
var camera := _get_stream_camera()
|
||||
var camera := _get_auto_position_camera()
|
||||
if camera == null:
|
||||
return
|
||||
|
||||
var center_tx: float = (_tile_min.x + _tile_max.x) * 0.5
|
||||
var center_ty: float = (_tile_min.y + _tile_max.y) * 0.5
|
||||
var center := _tile_center_to_world(center_tx, center_ty)
|
||||
var minimum_tile_center := _tile_center_to_world(_tile_min.x, _tile_min.y)
|
||||
var maximum_tile_center := _tile_center_to_world(_tile_max.x, _tile_max.y)
|
||||
var center := (minimum_tile_center + maximum_tile_center) * 0.5
|
||||
var tile_span: int = int(max(_tile_max.x - _tile_min.x + 1, _tile_max.y - _tile_min.y + 1))
|
||||
var height: float = max(2000.0, float(tile_span) * TILE_SIZE * 0.18)
|
||||
|
||||
@@ -5380,19 +5419,19 @@ func _position_camera_over_world() -> void:
|
||||
_camera_initialized = true
|
||||
|
||||
|
||||
## Tile (tx, ty) NW corner sits at Godot (tx*TILE_SIZE, 0, ty*TILE_SIZE).
|
||||
## This matches wow_to_godot output: chunk origins ≈ (TX*TILE_SIZE, h, TY*TILE_SIZE).
|
||||
func _tile_center_to_world(tile_x: float, tile_y: float) -> Vector3:
|
||||
return Vector3(
|
||||
(tile_x + 0.5) * TILE_SIZE,
|
||||
0.0,
|
||||
(tile_y + 0.5) * TILE_SIZE)
|
||||
func _tile_center_to_world(tile_x: int, tile_y: int) -> Vector3:
|
||||
var tile_coordinate = ADT_TILE_COORDINATE_SCRIPT.new(tile_x, tile_y)
|
||||
var half_tile_size := TILE_SIZE * 0.5
|
||||
var tile_center_position = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_godot(
|
||||
tile_coordinate,
|
||||
ADT_TILE_LOCAL_POSITION_SCRIPT.new(half_tile_size, 0.0, half_tile_size))
|
||||
return Vector3(tile_center_position.x_units, tile_center_position.y_units, tile_center_position.z_units)
|
||||
|
||||
|
||||
func _world_to_tile(world_pos: Vector3) -> Vector2i:
|
||||
return Vector2i(
|
||||
int(floor(world_pos.x / TILE_SIZE)),
|
||||
int(floor(world_pos.z / TILE_SIZE)))
|
||||
var typed_world_position = GODOT_WORLD_POSITION_SCRIPT.new(world_pos.x, world_pos.y, world_pos.z)
|
||||
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile(typed_world_position)
|
||||
return Vector2i(tile_coordinate.tile_x, tile_coordinate.tile_y)
|
||||
|
||||
|
||||
func _tile_key(tx: int, ty: int) -> String:
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"coordinate_contract_version": 2,
|
||||
"tolerances": {
|
||||
"position_yards": 0.002,
|
||||
"yaw_radians": 0.000001
|
||||
},
|
||||
"sources": {
|
||||
"azerothcore_playercreateinfo": {
|
||||
"status": "verified",
|
||||
"repository": "azerothcore/database-wotlk",
|
||||
"revision": "68fcf0098b16388093989627f37be530fc91f07d",
|
||||
"path": "sql/base/playercreateinfo.sql",
|
||||
"url": "https://raw.githubusercontent.com/azerothcore/database-wotlk/68fcf0098b16388093989627f37be530fc91f07d/sql/base/playercreateinfo.sql"
|
||||
},
|
||||
"trinitycore_playercreateinfo": {
|
||||
"status": "not_verified",
|
||||
"repository": "TrinityCore/TrinityCore",
|
||||
"branch": "3.3.5",
|
||||
"reason": "The base development schema does not provide a pinned populated playercreateinfo row; verify against a pinned TDB snapshot before claiming equivalence."
|
||||
},
|
||||
"azeroth_32_48_adt": {
|
||||
"status": "verified_private_metadata",
|
||||
"file_name": "Azeroth_32_48.adt",
|
||||
"sha256": "D66E27FD82B461AE38B78562952AED428E619777A3F3E35DD8FF97444644770A",
|
||||
"distribution": "Numeric metadata only; proprietary file remains outside Git."
|
||||
},
|
||||
"original_client_build_12340": {
|
||||
"status": "verified_private_observation",
|
||||
"build": 12340,
|
||||
"manifest": "res://src/tools/render_baseline_manifest.json",
|
||||
"evidence_document": "docs/M00_FINAL_PAIRED_EVIDENCE.md"
|
||||
}
|
||||
},
|
||||
"server_spawns": [
|
||||
{
|
||||
"name": "azerothcore_human_warrior_start",
|
||||
"source": "azerothcore_playercreateinfo",
|
||||
"backend": "AzerothCore",
|
||||
"table": "playercreateinfo",
|
||||
"key": {"race": 1, "class": 1},
|
||||
"map_id": 0,
|
||||
"map_directory": "Azeroth",
|
||||
"zone_id": 12,
|
||||
"server_position": [-8949.95, -132.493, 83.5312],
|
||||
"server_yaw_radians": 0.0,
|
||||
"expected_adt_placement": [26016.616666667, 83.5312, 17199.159666667],
|
||||
"expected_adt_tile": [32, 48],
|
||||
"expected_adt_chunk": [3, 12],
|
||||
"expected_adt_tile_local": [132.493, 83.5312, 416.616666667],
|
||||
"expected_godot_position": [17199.159666667, 83.5312, 26016.616666667],
|
||||
"expected_godot_yaw_radians": 0.0
|
||||
}
|
||||
],
|
||||
"raw_adt_chunks": [
|
||||
{
|
||||
"name": "azeroth_32_48_mcnk_3_12",
|
||||
"source": "azeroth_32_48_adt",
|
||||
"map_directory": "Azeroth",
|
||||
"adt_tile": [32, 48],
|
||||
"mcnk_index": [3, 12],
|
||||
"raw_header_canonical_origin": [-8933.33203125, -100.0, 84.238929749],
|
||||
"sample_position": "chunk_center",
|
||||
"expected_godot_chunk_center": [17183.333333333, 84.238929749, 26016.665364583]
|
||||
}
|
||||
],
|
||||
"original_client_points": [
|
||||
{
|
||||
"name": "elwynn_terrain_overview",
|
||||
"source": "original_client_build_12340",
|
||||
"client_position": [-9153.334, 386.666, 180.0],
|
||||
"expected_godot_position": [16680.0, 180.0, 26220.0]
|
||||
},
|
||||
{
|
||||
"name": "elwynn_adt_boundary",
|
||||
"source": "original_client_build_12340",
|
||||
"client_position": [-9523.334, 46.666, 105.0],
|
||||
"expected_godot_position": [17020.0, 105.0, 26590.0]
|
||||
},
|
||||
{
|
||||
"name": "goldshire_dense_m2",
|
||||
"source": "original_client_build_12340",
|
||||
"client_position": [-9400.0, 110.0, 150.0],
|
||||
"expected_godot_position": [16956.666, 150.0, 26466.666]
|
||||
},
|
||||
{
|
||||
"name": "goldshire_inn_large_wmo",
|
||||
"source": "original_client_build_12340",
|
||||
"client_position": [-9385.0, 53.0, 72.0],
|
||||
"expected_godot_position": [17013.666, 72.0, 26451.666]
|
||||
},
|
||||
{
|
||||
"name": "elwynn_waterfall_liquid",
|
||||
"source": "original_client_build_12340",
|
||||
"client_position": [-9300.0, 585.0, 190.0],
|
||||
"expected_godot_position": [16481.666, 190.0, 26366.666]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -64,7 +64,7 @@ func _capture_async() -> void:
|
||||
camera.far = 50000.0
|
||||
camera.position = _vector3(first.get("camera", [0.0, 0.0, 0.0]))
|
||||
(world as Node3D).add_child(camera)
|
||||
world.set("camera_path", NodePath("CheckpointCamera"))
|
||||
world.set("streaming_focus_source_path", NodePath("CheckpointCamera"))
|
||||
world.set("debug_streaming", true)
|
||||
world.set("runtime_stats_enabled", true)
|
||||
get_root().add_child(world)
|
||||
@@ -126,8 +126,8 @@ func _capture_async() -> void:
|
||||
if player != null:
|
||||
player.global_position = _vector3(checkpoint.get("player", checkpoint.get("target", [0.0, 0.0, 0.0])))
|
||||
_set_sky_time(world, float(checkpoint.get("time_hours", 13.0)))
|
||||
if world.has_method("_refresh_streaming_targets_at"):
|
||||
world.call("_refresh_streaming_targets_at", camera.global_position, true)
|
||||
if world.has_method("refresh_streaming_focus"):
|
||||
world.call("refresh_streaming_focus", true)
|
||||
|
||||
if dry_run:
|
||||
print("RENDER_CHECKPOINT dry_run name=%s coverage=%s camera=%s target=%s yaw_offset=%.2f pitch_offset=%.2f time=%.2f" % [
|
||||
@@ -246,6 +246,8 @@ func _result_record(checkpoint: Dictionary, pass_name: String, load_time_ms: flo
|
||||
|
||||
|
||||
func _create_probe(checkpoint: Dictionary, dry_run: bool) -> Node3D:
|
||||
if bool(checkpoint.get("diagnostic_spawn_marker", false)):
|
||||
return null if dry_run else _create_diagnostic_spawn_marker(checkpoint)
|
||||
var rel_path := String(checkpoint.get("probe_model", ""))
|
||||
if rel_path.is_empty() or dry_run:
|
||||
return null
|
||||
@@ -265,6 +267,43 @@ func _create_probe(checkpoint: Dictionary, dry_run: bool) -> Node3D:
|
||||
return M2_NATIVE_ANIMATED_BUILDER.build(data, extracted_dir)
|
||||
|
||||
|
||||
## Creates a renderer-native marker whose origin is the exact mapped server
|
||||
## spawn. The vertical mast grows upward from that origin, so terrain occlusion
|
||||
## remains visible instead of being hidden by an always-on-top overlay.
|
||||
func _create_diagnostic_spawn_marker(checkpoint: Dictionary) -> Node3D:
|
||||
var marker_root := Node3D.new()
|
||||
marker_root.name = "DiagnosticServerSpawnMarker"
|
||||
var marker_height := maxf(float(checkpoint.get("diagnostic_marker_height", 6.0)), 0.5)
|
||||
var marker_radius := maxf(float(checkpoint.get("diagnostic_marker_radius", 0.35)), 0.05)
|
||||
|
||||
var marker_material := StandardMaterial3D.new()
|
||||
marker_material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
marker_material.albedo_color = Color(1.0, 0.05, 0.7, 1.0)
|
||||
marker_material.emission_enabled = true
|
||||
marker_material.emission = Color(1.0, 0.01, 0.35, 1.0)
|
||||
|
||||
var mast_mesh := CylinderMesh.new()
|
||||
mast_mesh.height = marker_height
|
||||
mast_mesh.top_radius = marker_radius
|
||||
mast_mesh.bottom_radius = marker_radius
|
||||
mast_mesh.material = marker_material
|
||||
var mast := MeshInstance3D.new()
|
||||
mast.name = "SpawnOriginMast"
|
||||
mast.mesh = mast_mesh
|
||||
mast.position.y = marker_height * 0.5
|
||||
marker_root.add_child(mast)
|
||||
|
||||
var origin_mesh := SphereMesh.new()
|
||||
origin_mesh.radius = marker_radius * 1.8
|
||||
origin_mesh.height = marker_radius * 3.6
|
||||
origin_mesh.material = marker_material
|
||||
var origin := MeshInstance3D.new()
|
||||
origin.name = "SpawnOrigin"
|
||||
origin.mesh = origin_mesh
|
||||
marker_root.add_child(origin)
|
||||
return marker_root
|
||||
|
||||
|
||||
func _set_sky_time(world: Node, time_hours: float) -> void:
|
||||
var sky := world.get_node_or_null("WowSkyController")
|
||||
if sky != null:
|
||||
|
||||
@@ -28,7 +28,7 @@ func _run_async() -> void:
|
||||
camera.name = "OccluderProbeCamera"
|
||||
camera.current = true
|
||||
world.add_child(camera)
|
||||
world.set("camera_path", NodePath(camera.name))
|
||||
world.set("streaming_focus_source_path", NodePath(camera.name))
|
||||
world.set("debug_streaming", false)
|
||||
get_root().add_child(world)
|
||||
await process_frame
|
||||
@@ -47,8 +47,8 @@ func _run_async() -> void:
|
||||
var camera_position := _vector3(checkpoint.get("camera", []))
|
||||
var target_position := _vector3(checkpoint.get("target", []))
|
||||
camera.global_position = camera_position
|
||||
if world.has_method("_refresh_streaming_targets_at"):
|
||||
world.call("_refresh_streaming_targets_at", camera_position, true)
|
||||
if world.has_method("refresh_streaming_focus"):
|
||||
world.call("refresh_streaming_focus", true)
|
||||
await create_timer(maxf(0.1, wait_seconds)).timeout
|
||||
var geometry_nodes: Array[Node3D] = []
|
||||
_collect_geometry_nodes(world, geometry_nodes)
|
||||
|
||||
@@ -5,7 +5,8 @@ extends SceneTree
|
||||
## [--wait 3.0] [--output user://render_terrain_height/report.json]
|
||||
|
||||
const MANIFEST_PATH := "res://src/tools/render_baseline_manifest.json"
|
||||
const TILE_SIZE := 533.33333
|
||||
const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.gd")
|
||||
const RAY_HEIGHT := 5000.0
|
||||
|
||||
|
||||
@@ -36,7 +37,7 @@ func _run_async() -> void:
|
||||
var camera := Camera3D.new()
|
||||
camera.current = true
|
||||
world.add_child(camera)
|
||||
world.set("camera_path", NodePath(camera.name))
|
||||
world.set("streaming_focus_source_path", NodePath(camera.name))
|
||||
world.set("debug_streaming", false)
|
||||
get_root().add_child(world)
|
||||
await process_frame
|
||||
@@ -53,8 +54,8 @@ func _run_async() -> void:
|
||||
continue
|
||||
var camera_position := _vector3(checkpoint.get("camera", []))
|
||||
camera.global_position = camera_position
|
||||
if world.has_method("_refresh_streaming_targets_at"):
|
||||
world.call("_refresh_streaming_targets_at", camera_position, true)
|
||||
if world.has_method("refresh_streaming_focus"):
|
||||
world.call("refresh_streaming_focus", true)
|
||||
await create_timer(maxf(0.1, wait_seconds)).timeout
|
||||
var terrain_sample := _sample_terrain(world, camera_position)
|
||||
terrain_sample["name"] = checkpoint.get("name", "checkpoint")
|
||||
@@ -90,9 +91,7 @@ func _run_async() -> void:
|
||||
|
||||
|
||||
func _sample_terrain(world: Node3D, world_position: Vector3) -> Dictionary:
|
||||
var tile_coordinate := Vector2i(
|
||||
int(floor(world_position.x / TILE_SIZE)),
|
||||
int(floor(world_position.z / TILE_SIZE)))
|
||||
var tile_coordinate := _adt_tile_vector2i(world_position)
|
||||
var tile_states: Dictionary = world.get("_tile_states")
|
||||
var highest_terrain_height := -INF
|
||||
var intersected_tile_key := ""
|
||||
@@ -198,9 +197,7 @@ func _nearest_terrain_sample(world: Node3D, world_position: Vector3) -> Dictiona
|
||||
for radius in [2.0, 5.0, 10.0, 20.0, 40.0]:
|
||||
for offset in [Vector2(radius, 0.0), Vector2(-radius, 0.0), Vector2(0.0, radius), Vector2(0.0, -radius)]:
|
||||
var sample_position := world_position + Vector3(offset.x, 0.0, offset.y)
|
||||
var sample_tile := Vector2i(
|
||||
int(floor(sample_position.x / TILE_SIZE)),
|
||||
int(floor(sample_position.z / TILE_SIZE)))
|
||||
var sample_tile := _adt_tile_vector2i(sample_position)
|
||||
var sample_key := "%d_%d" % [sample_tile.x, sample_tile.y]
|
||||
if not tile_states.has(sample_key):
|
||||
continue
|
||||
@@ -214,6 +211,12 @@ func _nearest_terrain_sample(world: Node3D, world_position: Vector3) -> Dictiona
|
||||
return {"nearest_sample_distance": null}
|
||||
|
||||
|
||||
func _adt_tile_vector2i(world_position: Vector3) -> Vector2i:
|
||||
var typed_world_position = GODOT_WORLD_POSITION_SCRIPT.new(world_position.x, world_position.y, world_position.z)
|
||||
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile(typed_world_position)
|
||||
return Vector2i(tile_coordinate.tile_x, tile_coordinate.tile_y)
|
||||
|
||||
|
||||
func _vector3_array(value: Vector3) -> Array[float]:
|
||||
return [value.x, value.y, value.z]
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"profile": "Blizzlike335",
|
||||
"scene": "res://src/scenes/streaming/eastern_kingdoms_streaming.tscn",
|
||||
"map": "Azeroth",
|
||||
"quality_preset": "High",
|
||||
"viewport": [1280, 900],
|
||||
"camera_fov": 62.0,
|
||||
"default_wait_seconds": 10.0,
|
||||
"default_measure_seconds": 1.0,
|
||||
"source_fixture": "res://src/tests/fixtures/coordinate_golden_points.json",
|
||||
"source_spawn_name": "azerothcore_human_warrior_start",
|
||||
"required_coverage": ["server_spawn"],
|
||||
"checkpoints": [
|
||||
{
|
||||
"name": "azerothcore_human_warrior_start",
|
||||
"coverage": ["server_spawn"],
|
||||
"camera": [17168.0, 105.0, 25984.0],
|
||||
"target": [17199.159666667, 83.5312, 26016.616666667],
|
||||
"player": [17199.159666667, 83.5312, 26016.616666667],
|
||||
"time_hours": 13.0,
|
||||
"diagnostic_spawn_marker": true,
|
||||
"diagnostic_marker_height": 6.0,
|
||||
"diagnostic_marker_radius": 0.35,
|
||||
"expected_adt_tile": [32, 48],
|
||||
"expected_adt_chunk": [3, 12]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
extends SceneTree
|
||||
|
||||
## Repository-wide M01 gate against manual cross-space world coordinate formulas.
|
||||
## Model-local M2/WMO basis transforms and ordinary Godot-space geometry are not
|
||||
## world-space conversions and are intentionally outside these signatures.
|
||||
|
||||
const SCAN_ROOTS: Array[String] = ["res://src", "res://addons"]
|
||||
const SOURCE_EXTENSIONS: Array[String] = ["gd", "cpp", "h", "hpp"]
|
||||
const EXCLUDED_DIRECTORY_PREFIXES: Array[String] = ["res://src/native/build/"]
|
||||
const GATE_PATH := "res://src/tools/verify_coordinate_conversion_boundaries.gd"
|
||||
const COORDINATE_MAPPER_PATH := "res://src/domain/coordinates/coordinate_mapper.gd"
|
||||
const CALIBRATION_ORACLE_PATH := "res://src/tools/verify_render_coordinate_calibration.gd"
|
||||
const NATIVE_BOUNDARY_PATH := "res://src/native/src/wow_chunk_reader.h"
|
||||
const ALLOWED_LEGACY_NAME_PATHS: Array[String] = [
|
||||
NATIVE_BOUNDARY_PATH,
|
||||
"res://src/native/src/adt_loader.cpp",
|
||||
"res://src/native/src/wdt_loader.cpp",
|
||||
CALIBRATION_ORACLE_PATH,
|
||||
]
|
||||
const REQUIRED_MAPPER_CALLS := {
|
||||
"res://src/scenes/sky/wow_sky_controller.gd": ["godot_to_canonical", "godot_to_adt_tile", "godot_to_adt_tile_local"],
|
||||
"res://src/scenes/streaming/streaming_world_loader.gd": ["godot_to_adt_tile", "godot_to_adt_tile_local", "adt_tile_local_to_godot"],
|
||||
"res://src/scenes/player/third_person_wow_controller.gd": ["godot_to_adt_tile", "adt_tile_local_to_godot"],
|
||||
"res://src/tools/probe_render_terrain_height.gd": ["godot_to_adt_tile"],
|
||||
}
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var failures: Array[String] = []
|
||||
var source_paths: Array[String] = []
|
||||
for scan_root in SCAN_ROOTS:
|
||||
_collect_source_paths(scan_root, source_paths, failures)
|
||||
|
||||
var native_boundary_definition_count := 0
|
||||
var independent_oracle_definition_count := 0
|
||||
for source_path in source_paths:
|
||||
if source_path == GATE_PATH:
|
||||
continue
|
||||
var source := _read_text(source_path, failures)
|
||||
var source_lines := source.split("\n")
|
||||
for line_index in range(source_lines.size()):
|
||||
var source_line := String(source_lines[line_index])
|
||||
var violation := _coordinate_violation(source_path, source_line)
|
||||
if not violation.is_empty():
|
||||
failures.append("%s:%d %s" % [source_path, line_index + 1, violation])
|
||||
if source_path == NATIVE_BOUNDARY_PATH and source_line.contains("inline void wow_to_godot"):
|
||||
native_boundary_definition_count += 1
|
||||
if source_path == CALIBRATION_ORACLE_PATH and source_line.contains("func _wow_to_godot"):
|
||||
independent_oracle_definition_count += 1
|
||||
|
||||
_expect_equal(native_boundary_definition_count, 1, "native world conversion definition count", failures)
|
||||
_expect_equal(independent_oracle_definition_count, 1, "independent calibration oracle count", failures)
|
||||
_verify_required_mapper_calls(failures)
|
||||
_verify_classifier_guards(failures)
|
||||
|
||||
if not failures.is_empty():
|
||||
for failure in failures:
|
||||
push_error("COORDINATE_CONVERSION_BOUNDARIES: %s" % failure)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
print("COORDINATE_CONVERSION_BOUNDARIES PASS files=%d native_boundary=1 oracle=1 consumers=4 classifier_cases=6" % source_paths.size())
|
||||
quit(0)
|
||||
|
||||
|
||||
func _coordinate_violation(source_path: String, source_line: String) -> String:
|
||||
var stripped_line := source_line.strip_edges()
|
||||
if stripped_line.is_empty():
|
||||
return ""
|
||||
if (source_line.contains("wow_to_godot") or source_line.contains("godot_to_wow")) and source_path not in ALLOWED_LEGACY_NAME_PATHS:
|
||||
return "manual WoW/Godot conversion name outside mapper boundary"
|
||||
if (source_line.contains("17066.666") or source_line.contains("WOW_WORLD_CENTER")) and source_path not in [NATIVE_BOUNDARY_PATH, CALIBRATION_ORACLE_PATH]:
|
||||
return "manual WoW world-center formula outside native boundary/oracle"
|
||||
if source_line.contains("1600.0 / 3.0") and source_path != COORDINATE_MAPPER_PATH:
|
||||
return "duplicated ADT tile-size formula outside CoordinateMapper"
|
||||
if source_path != COORDINATE_MAPPER_PATH and source_line.contains("floor(") and source_line.contains("TILE_SIZE") and (source_line.contains(".x") or source_line.contains(".z")):
|
||||
return "manual Godot world-position to ADT tile formula"
|
||||
if source_path != COORDINATE_MAPPER_PATH and source_line.contains("fposmod(") and source_line.contains("TILE_SIZE"):
|
||||
return "manual Godot world-position to ADT tile-local formula"
|
||||
if source_path != COORDINATE_MAPPER_PATH and source_line.contains("+ 0.5) * TILE_SIZE"):
|
||||
return "manual ADT tile-center to Godot world-position formula"
|
||||
return ""
|
||||
|
||||
|
||||
func _verify_required_mapper_calls(failures: Array[String]) -> void:
|
||||
for source_path in REQUIRED_MAPPER_CALLS:
|
||||
var source := _read_text(source_path, failures)
|
||||
for required_call in REQUIRED_MAPPER_CALLS[source_path]:
|
||||
if not source.contains(String(required_call)):
|
||||
failures.append("%s must call CoordinateMapper.%s" % [source_path, required_call])
|
||||
|
||||
|
||||
func _verify_classifier_guards(failures: Array[String]) -> void:
|
||||
_expect_true(not _coordinate_violation("res://src/example.gd", "const CENTER := 17066.666").is_empty(), "world-center classifier", failures)
|
||||
_expect_true(not _coordinate_violation("res://src/example.gd", "func wow_to_godot():").is_empty(), "conversion-name classifier", failures)
|
||||
_expect_true(not _coordinate_violation("res://src/example.gd", "floor(world_position.x / TILE_SIZE)").is_empty(), "world-to-tile classifier", failures)
|
||||
_expect_true(not _coordinate_violation("res://src/example.gd", "fposmod(world_position.z, TILE_SIZE)").is_empty(), "world-to-tile-local classifier", failures)
|
||||
_expect_true(not _coordinate_violation("res://src/example.gd", "(tile_x + 0.5) * TILE_SIZE").is_empty(), "tile-center classifier", failures)
|
||||
_expect_true(_coordinate_violation(NATIVE_BOUNDARY_PATH, "inline void wow_to_godot(float wx) { gx = -(wx - 17066.666f); }").is_empty(), "native boundary exception", failures)
|
||||
|
||||
|
||||
func _collect_source_paths(directory_path: String, source_paths: Array[String], failures: Array[String]) -> void:
|
||||
var directory := DirAccess.open(directory_path)
|
||||
if directory == null:
|
||||
failures.append("cannot scan directory %s" % directory_path)
|
||||
return
|
||||
for entry_name in directory.get_files():
|
||||
var source_path := directory_path.path_join(entry_name)
|
||||
if entry_name.get_extension().to_lower() in SOURCE_EXTENSIONS:
|
||||
source_paths.append(source_path)
|
||||
for child_directory_name in directory.get_directories():
|
||||
var child_directory_path := directory_path.path_join(child_directory_name) + "/"
|
||||
if _has_excluded_prefix(child_directory_path):
|
||||
continue
|
||||
_collect_source_paths(child_directory_path.trim_suffix("/"), source_paths, failures)
|
||||
|
||||
|
||||
func _has_excluded_prefix(path: String) -> bool:
|
||||
for excluded_prefix in EXCLUDED_DIRECTORY_PREFIXES:
|
||||
if path.begins_with(excluded_prefix):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _read_text(path: String, failures: Array[String]) -> String:
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
failures.append("cannot open %s" % path)
|
||||
return ""
|
||||
return file.get_as_text()
|
||||
|
||||
|
||||
func _expect_equal(actual_value, expected_value, label: String, failures: Array[String]) -> void:
|
||||
if actual_value != expected_value:
|
||||
failures.append("%s expected %s, got %s" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_true(actual_value: bool, label: String, failures: Array[String]) -> void:
|
||||
if not actual_value:
|
||||
failures.append("%s expected true" % label)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bnj844sd2n6ln
|
||||
@@ -0,0 +1,197 @@
|
||||
extends SceneTree
|
||||
|
||||
## Validates the non-proprietary M01 coordinate fixture against coordinate
|
||||
## contract version 2 and the existing M00 build-12340 manifest. The script does
|
||||
## not read server databases, proprietary ADT bytes or original-client images.
|
||||
|
||||
const CoordinateMapperScript = preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const CanonicalWowWorldPositionScript = preload("res://src/domain/coordinates/canonical_wow_world_position.gd")
|
||||
const ServerWorldPositionScript = preload("res://src/domain/coordinates/server_world_position.gd")
|
||||
const ServerWorldYawScript = preload("res://src/domain/coordinates/server_world_yaw.gd")
|
||||
|
||||
const FIXTURE_PATH := "res://src/tests/fixtures/coordinate_golden_points.json"
|
||||
const RENDER_MANIFEST_PATH := "res://src/tools/render_baseline_manifest.json"
|
||||
const SUPPORTED_FIXTURE_SCHEMA_VERSION := 1
|
||||
const REQUIRED_COORDINATE_CONTRACT_VERSION := 2
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var failures: Array[String] = []
|
||||
var fixture := _load_json_object(FIXTURE_PATH, failures)
|
||||
var render_manifest := _load_json_object(RENDER_MANIFEST_PATH, failures)
|
||||
if fixture.is_empty() or render_manifest.is_empty():
|
||||
_report_and_quit(failures)
|
||||
return
|
||||
|
||||
_expect_equal(fixture.get("schema_version", -1), SUPPORTED_FIXTURE_SCHEMA_VERSION, "fixture schema version", failures)
|
||||
_expect_equal(fixture.get("coordinate_contract_version", -1), REQUIRED_COORDINATE_CONTRACT_VERSION, "coordinate contract version", failures)
|
||||
var position_tolerance_yards := float(fixture.get("tolerances", {}).get("position_yards", 0.0))
|
||||
var yaw_tolerance_radians := float(fixture.get("tolerances", {}).get("yaw_radians", 0.0))
|
||||
_expect_true(position_tolerance_yards > 0.0, "positive position tolerance", failures)
|
||||
_expect_true(yaw_tolerance_radians > 0.0, "positive yaw tolerance", failures)
|
||||
_verify_source_provenance(fixture.get("sources", {}), failures)
|
||||
_verify_server_spawns(fixture.get("server_spawns", []), position_tolerance_yards, yaw_tolerance_radians, failures)
|
||||
_verify_raw_adt_chunks(fixture.get("raw_adt_chunks", []), position_tolerance_yards, failures)
|
||||
_verify_original_client_points(fixture.get("original_client_points", []), render_manifest, position_tolerance_yards, failures)
|
||||
|
||||
if not failures.is_empty():
|
||||
_report_and_quit(failures)
|
||||
return
|
||||
print("COORDINATE_GOLDEN_FIXTURES PASS server_spawns=1 raw_adt_chunks=1 original_client_points=5")
|
||||
quit(0)
|
||||
|
||||
|
||||
func _verify_source_provenance(sources: Dictionary, failures: Array[String]) -> void:
|
||||
var azerothcore_source: Dictionary = sources.get("azerothcore_playercreateinfo", {})
|
||||
_expect_equal(azerothcore_source.get("status", ""), "verified", "AzerothCore source status", failures)
|
||||
_expect_equal(String(azerothcore_source.get("revision", "")).length(), 40, "AzerothCore pinned revision length", failures)
|
||||
_expect_true(String(azerothcore_source.get("url", "")).contains(String(azerothcore_source.get("revision", ""))), "AzerothCore URL contains pinned revision", failures)
|
||||
|
||||
var trinitycore_source: Dictionary = sources.get("trinitycore_playercreateinfo", {})
|
||||
_expect_equal(trinitycore_source.get("status", ""), "not_verified", "TrinityCore source status", failures)
|
||||
_expect_true(not String(trinitycore_source.get("reason", "")).is_empty(), "TrinityCore gap reason", failures)
|
||||
|
||||
var adt_source: Dictionary = sources.get("azeroth_32_48_adt", {})
|
||||
_expect_equal(adt_source.get("status", ""), "verified_private_metadata", "ADT source status", failures)
|
||||
_expect_equal(String(adt_source.get("sha256", "")).length(), 64, "ADT SHA-256 length", failures)
|
||||
|
||||
|
||||
func _verify_server_spawns(server_spawns: Array, position_tolerance_yards: float, yaw_tolerance_radians: float, failures: Array[String]) -> void:
|
||||
_expect_equal(server_spawns.size(), 1, "server spawn count", failures)
|
||||
for spawn_variant in server_spawns:
|
||||
if not (spawn_variant is Dictionary):
|
||||
failures.append("server spawn must be an object")
|
||||
continue
|
||||
var spawn: Dictionary = spawn_variant
|
||||
var name := String(spawn.get("name", "server_spawn"))
|
||||
var server_position_values := _require_three_numbers(spawn.get("server_position", null), "%s server_position" % name, failures)
|
||||
if server_position_values.is_empty():
|
||||
continue
|
||||
var server_position = ServerWorldPositionScript.new(server_position_values[0], server_position_values[1], server_position_values[2])
|
||||
var canonical_position = CoordinateMapperScript.server_to_canonical(server_position)
|
||||
var godot_position = CoordinateMapperScript.canonical_to_godot(canonical_position)
|
||||
var adt_placement = CoordinateMapperScript.canonical_to_adt_placement(canonical_position)
|
||||
var adt_tile = CoordinateMapperScript.canonical_to_adt_tile(canonical_position)
|
||||
var adt_local = CoordinateMapperScript.canonical_to_adt_tile_local(canonical_position)
|
||||
var adt_chunk = CoordinateMapperScript.adt_tile_local_to_chunk(adt_tile, adt_local)
|
||||
|
||||
_expect_three_near([godot_position.x_units, godot_position.y_units, godot_position.z_units], spawn.get("expected_godot_position", null), position_tolerance_yards, "%s Godot position" % name, failures)
|
||||
_expect_three_near([adt_placement.x_offset_yards, adt_placement.height_yards, adt_placement.z_offset_yards], spawn.get("expected_adt_placement", null), position_tolerance_yards, "%s ADT placement" % name, failures)
|
||||
_expect_three_near([adt_local.east_yards, adt_local.height_yards, adt_local.south_yards], spawn.get("expected_adt_tile_local", null), position_tolerance_yards, "%s ADT local" % name, failures)
|
||||
_expect_pair([adt_tile.tile_x, adt_tile.tile_y], spawn.get("expected_adt_tile", null), "%s ADT tile" % name, failures)
|
||||
_expect_pair([adt_chunk.chunk_x, adt_chunk.chunk_y], spawn.get("expected_adt_chunk", null), "%s ADT chunk" % name, failures)
|
||||
|
||||
var server_yaw = ServerWorldYawScript.new(float(spawn.get("server_yaw_radians", 0.0)))
|
||||
var godot_yaw = CoordinateMapperScript.canonical_to_godot_yaw(CoordinateMapperScript.server_to_canonical_yaw(server_yaw))
|
||||
_expect_near(godot_yaw.radians, float(spawn.get("expected_godot_yaw_radians", 0.0)), yaw_tolerance_radians, "%s Godot yaw" % name, failures)
|
||||
|
||||
|
||||
func _verify_raw_adt_chunks(raw_adt_chunks: Array, position_tolerance_yards: float, failures: Array[String]) -> void:
|
||||
_expect_equal(raw_adt_chunks.size(), 1, "raw ADT chunk count", failures)
|
||||
for chunk_variant in raw_adt_chunks:
|
||||
if not (chunk_variant is Dictionary):
|
||||
failures.append("raw ADT chunk must be an object")
|
||||
continue
|
||||
var chunk: Dictionary = chunk_variant
|
||||
var name := String(chunk.get("name", "raw_adt_chunk"))
|
||||
var origin_values := _require_three_numbers(chunk.get("raw_header_canonical_origin", null), "%s raw origin" % name, failures)
|
||||
if origin_values.is_empty():
|
||||
continue
|
||||
var half_chunk_size_yards := CoordinateMapperScript.ADT_CHUNK_SIZE_YARDS * 0.5
|
||||
var chunk_center = CanonicalWowWorldPositionScript.new(
|
||||
origin_values[0] - half_chunk_size_yards,
|
||||
origin_values[1] - half_chunk_size_yards,
|
||||
origin_values[2]
|
||||
)
|
||||
var tile_coordinate = CoordinateMapperScript.canonical_to_adt_tile(chunk_center)
|
||||
var local_position = CoordinateMapperScript.canonical_to_adt_tile_local(chunk_center)
|
||||
var chunk_coordinate = CoordinateMapperScript.adt_tile_local_to_chunk(tile_coordinate, local_position)
|
||||
_expect_pair([tile_coordinate.tile_x, tile_coordinate.tile_y], chunk.get("adt_tile", null), "%s ADT tile" % name, failures)
|
||||
_expect_pair([chunk_coordinate.chunk_x, chunk_coordinate.chunk_y], chunk.get("mcnk_index", null), "%s MCNK index" % name, failures)
|
||||
var godot_center = CoordinateMapperScript.canonical_to_godot(chunk_center)
|
||||
_expect_three_near([godot_center.x_units, godot_center.y_units, godot_center.z_units], chunk.get("expected_godot_chunk_center", null), position_tolerance_yards, "%s Godot center" % name, failures)
|
||||
|
||||
|
||||
func _verify_original_client_points(original_client_points: Array, render_manifest: Dictionary, position_tolerance_yards: float, failures: Array[String]) -> void:
|
||||
_expect_equal(original_client_points.size(), 5, "original-client point count", failures)
|
||||
var manifest_checkpoint_by_name: Dictionary = {}
|
||||
for checkpoint_variant in render_manifest.get("checkpoints", []):
|
||||
if checkpoint_variant is Dictionary:
|
||||
manifest_checkpoint_by_name[String(checkpoint_variant.get("name", ""))] = checkpoint_variant
|
||||
|
||||
for point_variant in original_client_points:
|
||||
if not (point_variant is Dictionary):
|
||||
failures.append("original-client point must be an object")
|
||||
continue
|
||||
var point: Dictionary = point_variant
|
||||
var name := String(point.get("name", "original_client_point"))
|
||||
var client_position_values := _require_three_numbers(point.get("client_position", null), "%s client position" % name, failures)
|
||||
if client_position_values.is_empty():
|
||||
continue
|
||||
var canonical_position = CanonicalWowWorldPositionScript.new(client_position_values[0], client_position_values[1], client_position_values[2])
|
||||
var godot_position = CoordinateMapperScript.canonical_to_godot(canonical_position)
|
||||
_expect_three_near([godot_position.x_units, godot_position.y_units, godot_position.z_units], point.get("expected_godot_position", null), position_tolerance_yards, "%s mapped position" % name, failures)
|
||||
|
||||
var manifest_checkpoint: Dictionary = manifest_checkpoint_by_name.get(name, {})
|
||||
_expect_true(not manifest_checkpoint.is_empty(), "%s exists in render manifest" % name, failures)
|
||||
if not manifest_checkpoint.is_empty():
|
||||
_expect_three_near(client_position_values, manifest_checkpoint.get("reference_wow_camera", null), position_tolerance_yards, "%s manifest client position" % name, failures)
|
||||
_expect_three_near(point.get("expected_godot_position", null), manifest_checkpoint.get("camera", null), position_tolerance_yards, "%s manifest Godot position" % name, failures)
|
||||
|
||||
|
||||
func _require_three_numbers(value_variant, label: String, failures: Array[String]) -> Array[float]:
|
||||
if not (value_variant is Array) or value_variant.size() != 3:
|
||||
failures.append("%s must contain three numbers" % label)
|
||||
return []
|
||||
return [float(value_variant[0]), float(value_variant[1]), float(value_variant[2])]
|
||||
|
||||
|
||||
func _expect_three_near(actual_values, expected_variant, tolerance: float, label: String, failures: Array[String]) -> void:
|
||||
var expected_values := _require_three_numbers(expected_variant, label, failures)
|
||||
if expected_values.is_empty() or not (actual_values is Array) or actual_values.size() != 3:
|
||||
return
|
||||
for component_index in range(3):
|
||||
_expect_near(float(actual_values[component_index]), expected_values[component_index], tolerance, "%s[%d]" % [label, component_index], failures)
|
||||
|
||||
|
||||
func _expect_pair(actual_values: Array, expected_variant, label: String, failures: Array[String]) -> void:
|
||||
if not (expected_variant is Array) or expected_variant.size() != 2:
|
||||
failures.append("%s must contain two integers" % label)
|
||||
return
|
||||
_expect_equal(actual_values[0], int(expected_variant[0]), "%s[0]" % label, failures)
|
||||
_expect_equal(actual_values[1], int(expected_variant[1]), "%s[1]" % label, failures)
|
||||
|
||||
|
||||
func _expect_near(actual_value: float, expected_value: float, tolerance: float, label: String, failures: Array[String]) -> void:
|
||||
if absf(actual_value - expected_value) > tolerance:
|
||||
failures.append("%s expected %.9f, got %.9f" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_equal(actual_value, expected_value, label: String, failures: Array[String]) -> void:
|
||||
if actual_value != expected_value:
|
||||
failures.append("%s expected %s, got %s" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_true(actual_value: bool, label: String, failures: Array[String]) -> void:
|
||||
if not actual_value:
|
||||
failures.append("%s expected true" % label)
|
||||
|
||||
|
||||
func _load_json_object(path: String, failures: Array[String]) -> Dictionary:
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
failures.append("cannot open JSON fixture: %s" % path)
|
||||
return {}
|
||||
var parsed = JSON.parse_string(file.get_as_text())
|
||||
if not (parsed is Dictionary):
|
||||
failures.append("JSON fixture is not an object: %s" % path)
|
||||
return {}
|
||||
return parsed
|
||||
|
||||
|
||||
func _report_and_quit(failures: Array[String]) -> void:
|
||||
if failures.is_empty():
|
||||
failures.append("fixture validation stopped without a diagnostic")
|
||||
for failure in failures:
|
||||
push_error("COORDINATE_GOLDEN_FIXTURES: %s" % failure)
|
||||
quit(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cr8f88swvk002
|
||||
@@ -0,0 +1,231 @@
|
||||
extends SceneTree
|
||||
|
||||
## Headless contract verification for M01 canonical coordinate value objects and
|
||||
## [CoordinateMapper]. Uses synthetic boundaries plus five positions observed in
|
||||
## the original WoW 3.3.5a build 12340 during the M00 paired renderer session.
|
||||
## The Elwynn filename case regression-checks a raw `Azeroth_31_49.adt` corpus.
|
||||
|
||||
const CoordinateMapperScript = preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const CanonicalWowWorldPositionScript = preload("res://src/domain/coordinates/canonical_wow_world_position.gd")
|
||||
const ServerWorldPositionScript = preload("res://src/domain/coordinates/server_world_position.gd")
|
||||
const AdtPlacementPositionScript = preload("res://src/domain/coordinates/adt_placement_position.gd")
|
||||
const AdtTileCoordinateScript = preload("res://src/domain/coordinates/adt_tile_coordinate.gd")
|
||||
const AdtTileLocalPositionScript = preload("res://src/domain/coordinates/adt_tile_local_position.gd")
|
||||
const CanonicalWowWorldYawScript = preload("res://src/domain/coordinates/canonical_wow_world_yaw.gd")
|
||||
const ServerWorldYawScript = preload("res://src/domain/coordinates/server_world_yaw.gd")
|
||||
|
||||
const RENDER_BASELINE_MANIFEST_PATH := "res://src/tools/render_baseline_manifest.json"
|
||||
const GOLDEN_POSITION_TOLERANCE_YARDS := 0.002
|
||||
const ROUND_TRIP_TOLERANCE_YARDS := 0.000001
|
||||
const BOUNDARY_EPSILON_YARDS := 0.001
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var failures: Array[String] = []
|
||||
_verify_build_12340_golden_positions(failures)
|
||||
_verify_server_and_adt_round_trips(failures)
|
||||
_verify_tile_and_chunk_boundaries(failures)
|
||||
_verify_recorded_raw_adt_chunk_axes(failures)
|
||||
_verify_world_yaw_conversions(failures)
|
||||
|
||||
if not failures.is_empty():
|
||||
for failure in failures:
|
||||
push_error("COORDINATE_MAPPER: %s" % failure)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
print("COORDINATE_MAPPER PASS golden_points=5 tile_boundaries=8 raw_mcnk=2 yaw_cases=5")
|
||||
quit(0)
|
||||
|
||||
|
||||
func _verify_build_12340_golden_positions(failures: Array[String]) -> void:
|
||||
var manifest := _load_json_object(RENDER_BASELINE_MANIFEST_PATH, failures)
|
||||
if manifest.is_empty():
|
||||
return
|
||||
|
||||
var golden_point_count := 0
|
||||
for checkpoint_variant in manifest.get("checkpoints", []):
|
||||
if not (checkpoint_variant is Dictionary):
|
||||
continue
|
||||
var checkpoint: Dictionary = checkpoint_variant
|
||||
var reference_wow_camera_variant = checkpoint.get("reference_wow_camera", null)
|
||||
if not (reference_wow_camera_variant is Array) or reference_wow_camera_variant.size() != 3:
|
||||
continue
|
||||
|
||||
var expected_godot_camera_variant = checkpoint.get("camera", null)
|
||||
if not (expected_godot_camera_variant is Array) or expected_godot_camera_variant.size() != 3:
|
||||
failures.append("%s has no three-component renderer camera" % checkpoint.get("name", "checkpoint"))
|
||||
continue
|
||||
|
||||
var canonical_position = CanonicalWowWorldPositionScript.new(
|
||||
float(reference_wow_camera_variant[0]),
|
||||
float(reference_wow_camera_variant[1]),
|
||||
float(reference_wow_camera_variant[2])
|
||||
)
|
||||
var godot_position = CoordinateMapperScript.canonical_to_godot(canonical_position)
|
||||
var checkpoint_name := String(checkpoint.get("name", "checkpoint"))
|
||||
_expect_near(godot_position.x_units, float(expected_godot_camera_variant[0]), GOLDEN_POSITION_TOLERANCE_YARDS, "%s Godot X" % checkpoint_name, failures)
|
||||
_expect_near(godot_position.y_units, float(expected_godot_camera_variant[1]), GOLDEN_POSITION_TOLERANCE_YARDS, "%s Godot Y" % checkpoint_name, failures)
|
||||
_expect_near(godot_position.z_units, float(expected_godot_camera_variant[2]), GOLDEN_POSITION_TOLERANCE_YARDS, "%s Godot Z" % checkpoint_name, failures)
|
||||
|
||||
var round_trip_position = CoordinateMapperScript.godot_to_canonical(godot_position)
|
||||
_expect_canonical_position(round_trip_position, canonical_position, ROUND_TRIP_TOLERANCE_YARDS, "%s Godot round trip" % checkpoint_name, failures)
|
||||
golden_point_count += 1
|
||||
|
||||
_expect_equal(golden_point_count, 5, "build 12340 golden point count", failures)
|
||||
|
||||
|
||||
func _verify_server_and_adt_round_trips(failures: Array[String]) -> void:
|
||||
var server_position = ServerWorldPositionScript.new(-9153.334, 386.666, 180.0)
|
||||
var canonical_position = CoordinateMapperScript.server_to_canonical(server_position)
|
||||
_expect_near(canonical_position.x_yards, server_position.x_yards, ROUND_TRIP_TOLERANCE_YARDS, "server X remains canonical X", failures)
|
||||
_expect_near(canonical_position.y_yards, server_position.y_yards, ROUND_TRIP_TOLERANCE_YARDS, "server Y remains canonical Y", failures)
|
||||
_expect_near(canonical_position.z_yards, server_position.z_yards, ROUND_TRIP_TOLERANCE_YARDS, "server Z remains canonical Z", failures)
|
||||
|
||||
var round_trip_server = CoordinateMapperScript.canonical_to_server(canonical_position)
|
||||
_expect_near(round_trip_server.x_yards, server_position.x_yards, ROUND_TRIP_TOLERANCE_YARDS, "server X round trip", failures)
|
||||
_expect_near(round_trip_server.y_yards, server_position.y_yards, ROUND_TRIP_TOLERANCE_YARDS, "server Y round trip", failures)
|
||||
_expect_near(round_trip_server.z_yards, server_position.z_yards, ROUND_TRIP_TOLERANCE_YARDS, "server Z round trip", failures)
|
||||
|
||||
var adt_position = CoordinateMapperScript.canonical_to_adt_placement(canonical_position)
|
||||
_expect_near(adt_position.x_offset_yards, 26220.000666666667, GOLDEN_POSITION_TOLERANCE_YARDS, "ADT placement X offset", failures)
|
||||
_expect_near(adt_position.height_yards, 180.0, ROUND_TRIP_TOLERANCE_YARDS, "ADT placement height", failures)
|
||||
_expect_near(adt_position.z_offset_yards, 16680.000666666667, GOLDEN_POSITION_TOLERANCE_YARDS, "ADT placement Z offset", failures)
|
||||
var adt_round_trip = CoordinateMapperScript.adt_placement_to_canonical(adt_position)
|
||||
_expect_canonical_position(adt_round_trip, canonical_position, ROUND_TRIP_TOLERANCE_YARDS, "ADT placement round trip", failures)
|
||||
|
||||
var direct_adt_position = AdtPlacementPositionScript.new(26220.000666666667, 180.0, 16680.000666666667)
|
||||
var direct_canonical = CoordinateMapperScript.adt_placement_to_canonical(direct_adt_position)
|
||||
_expect_canonical_position(direct_canonical, canonical_position, GOLDEN_POSITION_TOLERANCE_YARDS, "direct ADT placement conversion", failures)
|
||||
|
||||
|
||||
func _verify_tile_and_chunk_boundaries(failures: Array[String]) -> void:
|
||||
var half_extent := CoordinateMapperScript.WOW_WORLD_HALF_EXTENT_YARDS
|
||||
var tile_size := CoordinateMapperScript.ADT_TILE_SIZE_YARDS
|
||||
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(half_extent, half_extent, 0.0)), 0, 0, true, "north-west extent", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(0.0, 0.0, 0.0)), 32, 32, true, "map center", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(BOUNDARY_EPSILON_YARDS, BOUNDARY_EPSILON_YARDS, 0.0)), 31, 31, true, "north-west of center boundary", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(-BOUNDARY_EPSILON_YARDS, -BOUNDARY_EPSILON_YARDS, 0.0)), 32, 32, true, "south-east of center boundary", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(-half_extent + BOUNDARY_EPSILON_YARDS, -half_extent + BOUNDARY_EPSILON_YARDS, 0.0)), 63, 63, true, "inside south-east extent", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(-half_extent, -half_extent, 0.0)), 64, 64, false, "exclusive south-east extent", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(tile_size, -tile_size, 0.0)), 33, 31, true, "whole-tile offsets", failures)
|
||||
_expect_tile(CoordinateMapperScript.canonical_to_adt_tile(CanonicalWowWorldPositionScript.new(-9153.334, 386.666, 180.0)), 31, 49, true, "raw Azeroth_31_49 filename", failures)
|
||||
|
||||
var tile_coordinate = AdtTileCoordinateScript.new(31, 49)
|
||||
var local_position = CoordinateMapperScript.canonical_to_adt_tile_local(CanonicalWowWorldPositionScript.new(-9153.334, 386.666, 180.0))
|
||||
var local_round_trip = CoordinateMapperScript.adt_tile_local_to_canonical(tile_coordinate, local_position)
|
||||
_expect_canonical_position(local_round_trip, CanonicalWowWorldPositionScript.new(-9153.334, 386.666, 180.0), ROUND_TRIP_TOLERANCE_YARDS, "ADT tile-local round trip", failures)
|
||||
_expect_true(local_position.east_yards >= 0.0 and local_position.east_yards < tile_size, "tile-local east offset is half-open", failures)
|
||||
_expect_true(local_position.south_yards >= 0.0 and local_position.south_yards < tile_size, "tile-local south offset is half-open", failures)
|
||||
|
||||
var godot_position = CoordinateMapperScript.canonical_to_godot(CanonicalWowWorldPositionScript.new(-9153.334, 386.666, 180.0))
|
||||
var direct_godot_tile = CoordinateMapperScript.godot_to_adt_tile(godot_position)
|
||||
var direct_godot_local = CoordinateMapperScript.godot_to_adt_tile_local(godot_position)
|
||||
var direct_godot_round_trip = CoordinateMapperScript.adt_tile_local_to_godot(direct_godot_tile, direct_godot_local)
|
||||
_expect_equal(direct_godot_tile.tile_x, 31, "direct Godot ADT tile X", failures)
|
||||
_expect_equal(direct_godot_tile.tile_y, 49, "direct Godot ADT tile Y", failures)
|
||||
_expect_near(direct_godot_local.east_yards, 146.66677, GOLDEN_POSITION_TOLERANCE_YARDS, "direct Godot tile-local east", failures)
|
||||
_expect_near(direct_godot_local.south_yards, 86.66677, GOLDEN_POSITION_TOLERANCE_YARDS, "direct Godot tile-local south", failures)
|
||||
_expect_near(direct_godot_round_trip.x_units, godot_position.x_units, ROUND_TRIP_TOLERANCE_YARDS, "direct Godot tile-local X round trip", failures)
|
||||
_expect_near(direct_godot_round_trip.y_units, godot_position.y_units, ROUND_TRIP_TOLERANCE_YARDS, "direct Godot tile-local Y round trip", failures)
|
||||
_expect_near(direct_godot_round_trip.z_units, godot_position.z_units, ROUND_TRIP_TOLERANCE_YARDS, "direct Godot tile-local Z round trip", failures)
|
||||
|
||||
var chunk_local_position = AdtTileLocalPositionScript.new(
|
||||
CoordinateMapperScript.ADT_CHUNK_SIZE_YARDS * 2.0,
|
||||
180.0,
|
||||
CoordinateMapperScript.ADT_CHUNK_SIZE_YARDS
|
||||
)
|
||||
var chunk_coordinate = CoordinateMapperScript.adt_tile_local_to_chunk(tile_coordinate, chunk_local_position)
|
||||
_expect_equal(chunk_coordinate.chunk_x, 2, "exact east chunk boundary", failures)
|
||||
_expect_equal(chunk_coordinate.chunk_y, 1, "exact south chunk boundary", failures)
|
||||
_expect_true(chunk_coordinate.is_within_map_grid(), "chunk coordinate is inside map grid", failures)
|
||||
|
||||
|
||||
func _verify_recorded_raw_adt_chunk_axes(failures: Array[String]) -> void:
|
||||
var half_chunk_size_yards := CoordinateMapperScript.ADT_CHUNK_SIZE_YARDS * 0.5
|
||||
var recorded_chunk_origins := [
|
||||
{
|
||||
"label": "raw MCNK 0,0",
|
||||
"chunk_x": 0,
|
||||
"chunk_y": 0,
|
||||
"canonical_x_origin": -9066.666015625,
|
||||
"canonical_y_origin": 533.333984375,
|
||||
},
|
||||
{
|
||||
"label": "raw MCNK 15,15",
|
||||
"chunk_x": 15,
|
||||
"chunk_y": 15,
|
||||
"canonical_x_origin": -9566.666015625,
|
||||
"canonical_y_origin": 33.333984375,
|
||||
},
|
||||
]
|
||||
for recorded_chunk_origin in recorded_chunk_origins:
|
||||
var chunk_center = CanonicalWowWorldPositionScript.new(
|
||||
float(recorded_chunk_origin.canonical_x_origin) - half_chunk_size_yards,
|
||||
float(recorded_chunk_origin.canonical_y_origin) - half_chunk_size_yards,
|
||||
0.0
|
||||
)
|
||||
var tile_coordinate = CoordinateMapperScript.canonical_to_adt_tile(chunk_center)
|
||||
_expect_tile(tile_coordinate, 31, 49, true, String(recorded_chunk_origin.label), failures)
|
||||
var local_position = CoordinateMapperScript.canonical_to_adt_tile_local(chunk_center)
|
||||
var chunk_coordinate = CoordinateMapperScript.adt_tile_local_to_chunk(tile_coordinate, local_position)
|
||||
_expect_equal(chunk_coordinate.chunk_x, int(recorded_chunk_origin.chunk_x), "%s chunk X" % recorded_chunk_origin.label, failures)
|
||||
_expect_equal(chunk_coordinate.chunk_y, int(recorded_chunk_origin.chunk_y), "%s chunk Y" % recorded_chunk_origin.label, failures)
|
||||
|
||||
|
||||
func _verify_world_yaw_conversions(failures: Array[String]) -> void:
|
||||
var yaw_cases := [0.0, PI * 0.5, -PI * 0.5, PI, TAU + 0.25]
|
||||
for yaw_radians in yaw_cases:
|
||||
var server_yaw = ServerWorldYawScript.new(float(yaw_radians))
|
||||
var canonical_yaw = CoordinateMapperScript.server_to_canonical_yaw(server_yaw)
|
||||
var godot_yaw = CoordinateMapperScript.canonical_to_godot_yaw(canonical_yaw)
|
||||
var canonical_round_trip = CoordinateMapperScript.godot_to_canonical_yaw(godot_yaw)
|
||||
var server_round_trip = CoordinateMapperScript.canonical_to_server_yaw(canonical_round_trip)
|
||||
var expected_normalized_yaw := fposmod(float(yaw_radians) + PI, TAU) - PI
|
||||
_expect_near(canonical_yaw.radians, expected_normalized_yaw, ROUND_TRIP_TOLERANCE_YARDS, "canonical yaw normalization", failures)
|
||||
_expect_near(godot_yaw.radians, expected_normalized_yaw, ROUND_TRIP_TOLERANCE_YARDS, "Godot yaw basis", failures)
|
||||
_expect_near(server_round_trip.radians, expected_normalized_yaw, ROUND_TRIP_TOLERANCE_YARDS, "server yaw round trip", failures)
|
||||
|
||||
var canonical_pi_yaw = CanonicalWowWorldYawScript.new(PI)
|
||||
var normalized_godot_yaw = CoordinateMapperScript.canonical_to_godot_yaw(canonical_pi_yaw)
|
||||
_expect_near(normalized_godot_yaw.radians, -PI, ROUND_TRIP_TOLERANCE_YARDS, "positive PI normalizes to negative PI", failures)
|
||||
|
||||
|
||||
func _expect_tile(tile_coordinate, expected_x: int, expected_y: int, expected_valid: bool, label: String, failures: Array[String]) -> void:
|
||||
_expect_equal(tile_coordinate.tile_x, expected_x, "%s tile X" % label, failures)
|
||||
_expect_equal(tile_coordinate.tile_y, expected_y, "%s tile Y" % label, failures)
|
||||
_expect_equal(tile_coordinate.is_within_map_grid(), expected_valid, "%s validity" % label, failures)
|
||||
|
||||
|
||||
func _expect_canonical_position(actual_position, expected_position, tolerance: float, label: String, failures: Array[String]) -> void:
|
||||
_expect_near(actual_position.x_yards, expected_position.x_yards, tolerance, "%s X" % label, failures)
|
||||
_expect_near(actual_position.y_yards, expected_position.y_yards, tolerance, "%s Y" % label, failures)
|
||||
_expect_near(actual_position.z_yards, expected_position.z_yards, tolerance, "%s Z" % label, failures)
|
||||
|
||||
|
||||
func _expect_near(actual_value: float, expected_value: float, tolerance: float, label: String, failures: Array[String]) -> void:
|
||||
if absf(actual_value - expected_value) > tolerance:
|
||||
failures.append("%s expected %.9f, got %.9f" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_equal(actual_value, expected_value, label: String, failures: Array[String]) -> void:
|
||||
if actual_value != expected_value:
|
||||
failures.append("%s expected %s, got %s" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_true(actual_value: bool, label: String, failures: Array[String]) -> void:
|
||||
if not actual_value:
|
||||
failures.append("%s expected true" % label)
|
||||
|
||||
|
||||
func _load_json_object(path: String, failures: Array[String]) -> Dictionary:
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
failures.append("cannot open JSON fixture: %s" % path)
|
||||
return {}
|
||||
var parsed = JSON.parse_string(file.get_as_text())
|
||||
if not (parsed is Dictionary):
|
||||
failures.append("JSON fixture is not an object: %s" % path)
|
||||
return {}
|
||||
return parsed
|
||||
@@ -0,0 +1 @@
|
||||
uid://bmxjtf1fsrl2x
|
||||
@@ -0,0 +1,87 @@
|
||||
extends SceneTree
|
||||
|
||||
## Headless M01 contract verification for non-interchangeable identity values.
|
||||
|
||||
const ContentIdScript = preload("res://src/domain/identity/content_id.gd")
|
||||
const EntityIdScript = preload("res://src/domain/identity/entity_id.gd")
|
||||
const WowGuidScript = preload("res://src/domain/identity/wow_guid.gd")
|
||||
const ServerEntryIdScript = preload("res://src/domain/identity/server_entry_id.gd")
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var failures: Array[String] = []
|
||||
_verify_content_id(failures)
|
||||
_verify_entity_id(failures)
|
||||
_verify_wow_guid(failures)
|
||||
_verify_server_entry_id(failures)
|
||||
_verify_scene_free_sources(failures)
|
||||
|
||||
if not failures.is_empty():
|
||||
for failure in failures:
|
||||
push_error("DOMAIN_IDENTITIES: %s" % failure)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
print("DOMAIN_IDENTITIES PASS content=5 entity=5 wow_guid=6 server_entry=5")
|
||||
quit(0)
|
||||
|
||||
|
||||
func _verify_content_id(failures: Array[String]) -> void:
|
||||
var normalized = ContentIdScript.new(" 123E4567-E89B-42D3-A456-426614174000 ")
|
||||
_expect_true(normalized.is_valid(), "normalized ContentId is valid", failures)
|
||||
_expect_equal(normalized.to_key(), "123e4567-e89b-42d3-a456-426614174000", "ContentId canonical key", failures)
|
||||
_expect_true(normalized.equals(ContentIdScript.new("123e4567-e89b-42d3-a456-426614174000")), "equal ContentIds", failures)
|
||||
_expect_true(not normalized.equals(ContentIdScript.new("123e4567-e89b-42d3-a456-426614174001")), "different ContentIds", failures)
|
||||
_expect_true(not ContentIdScript.new("123e4567e89b42d3a456426614174000").is_valid(), "malformed ContentId", failures)
|
||||
|
||||
|
||||
func _verify_entity_id(failures: Array[String]) -> void:
|
||||
var entity_id = EntityIdScript.new(42)
|
||||
_expect_true(entity_id.is_valid(), "positive EntityId", failures)
|
||||
_expect_true(not EntityIdScript.new(0).is_valid(), "zero EntityId", failures)
|
||||
_expect_true(not EntityIdScript.new(-1).is_valid(), "negative EntityId", failures)
|
||||
_expect_true(entity_id.equals(EntityIdScript.new(42)), "equal EntityIds", failures)
|
||||
_expect_equal(entity_id.to_debug_key(), "entity:42", "EntityId diagnostic key", failures)
|
||||
|
||||
|
||||
func _verify_wow_guid(failures: Array[String]) -> void:
|
||||
var guid = WowGuidScript.new(0xf1300000, 0xffffffff)
|
||||
_expect_true(guid.has_valid_word_ranges(), "maximum GUID low word", failures)
|
||||
_expect_equal(guid.to_hex_string(), "f1300000ffffffff", "GUID hexadecimal form", failures)
|
||||
_expect_true(guid.equals(WowGuidScript.new(0xf1300000, 0xffffffff)), "equal GUID words", failures)
|
||||
_expect_true(WowGuidScript.new(0, 0).is_empty(), "zero GUID sentinel", failures)
|
||||
_expect_true(not WowGuidScript.new(-1, 0).has_valid_word_ranges(), "negative GUID word", failures)
|
||||
_expect_true(not WowGuidScript.new(0x100000000, 0).has_valid_word_ranges(), "overflow GUID word", failures)
|
||||
|
||||
|
||||
func _verify_server_entry_id(failures: Array[String]) -> void:
|
||||
var creature_entry = ServerEntryIdScript.new(" Creature_Template ", 123)
|
||||
var gameobject_entry = ServerEntryIdScript.new("gameobject_template", 123)
|
||||
_expect_true(creature_entry.is_valid(), "namespaced server entry", failures)
|
||||
_expect_equal(creature_entry.to_key(), "creature_template:123", "server entry key", failures)
|
||||
_expect_true(not creature_entry.equals(gameobject_entry), "cross-table entry collision prevented", failures)
|
||||
_expect_true(not ServerEntryIdScript.new("", 123).is_valid(), "missing entry namespace", failures)
|
||||
_expect_true(not ServerEntryIdScript.new("creature_template", 0).is_valid(), "zero server entry", failures)
|
||||
|
||||
|
||||
func _verify_scene_free_sources(failures: Array[String]) -> void:
|
||||
for file_name in ["content_id.gd", "entity_id.gd", "wow_guid.gd", "server_entry_id.gd"]:
|
||||
var path := "res://src/domain/identity/%s" % file_name
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
failures.append("cannot open %s" % path)
|
||||
continue
|
||||
var source := file.get_as_text()
|
||||
_expect_true(not source.contains("extends Node"), "%s does not inherit Node" % file_name, failures)
|
||||
_expect_true(not source.contains("extends Resource"), "%s does not inherit Resource" % file_name, failures)
|
||||
_expect_true(not source.contains("Vector3"), "%s does not expose Vector3" % file_name, failures)
|
||||
|
||||
|
||||
func _expect_equal(actual_value, expected_value, label: String, failures: Array[String]) -> void:
|
||||
if actual_value != expected_value:
|
||||
failures.append("%s expected %s, got %s" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_true(actual_value: bool, label: String, failures: Array[String]) -> void:
|
||||
if not actual_value:
|
||||
failures.append("%s expected true" % label)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bmig1rwaur44r
|
||||
@@ -0,0 +1,138 @@
|
||||
extends SceneTree
|
||||
|
||||
## Verifies that the pinned AzerothCore spawn is routed through the coordinate
|
||||
## contract into an executable renderer checkpoint. GUI capture is performed by
|
||||
## capture_render_checkpoints.gd with the validated dedicated manifest.
|
||||
|
||||
const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordinate_mapper.gd")
|
||||
const SERVER_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/server_world_position.gd")
|
||||
|
||||
const MANIFEST_PATH := "res://src/tools/server_spawn_render_manifest.json"
|
||||
const EXPECTED_FIXTURE_PATH := "res://src/tests/fixtures/coordinate_golden_points.json"
|
||||
const EXPECTED_SPAWN_NAME := "azerothcore_human_warrior_start"
|
||||
const EXPECTED_PROFILE := "Blizzlike335"
|
||||
const POSITION_TOLERANCE_YARDS := 0.002
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var failures: Array[String] = []
|
||||
var manifest := _load_json_object(MANIFEST_PATH, failures)
|
||||
var fixture_path := String(manifest.get("source_fixture", ""))
|
||||
_expect_equal(fixture_path, EXPECTED_FIXTURE_PATH, "source fixture path", failures)
|
||||
var fixture := _load_json_object(fixture_path, failures) if not fixture_path.is_empty() else {}
|
||||
if manifest.is_empty() or fixture.is_empty():
|
||||
_report_and_quit(failures)
|
||||
return
|
||||
|
||||
_expect_equal(int(manifest.get("schema_version", -1)), 1, "manifest schema version", failures)
|
||||
_expect_equal(String(manifest.get("profile", "")), EXPECTED_PROFILE, "renderer profile", failures)
|
||||
_expect_equal(String(manifest.get("map", "")), "Azeroth", "renderer map", failures)
|
||||
_expect_true(ResourceLoader.exists(String(manifest.get("scene", ""))), "renderer scene exists", failures)
|
||||
_expect_equal(String(manifest.get("source_spawn_name", "")), EXPECTED_SPAWN_NAME, "source spawn name", failures)
|
||||
|
||||
var spawn := _find_named_dictionary(fixture.get("server_spawns", []), EXPECTED_SPAWN_NAME)
|
||||
_expect_true(not spawn.is_empty(), "pinned server spawn exists", failures)
|
||||
var checkpoints: Array = manifest.get("checkpoints", [])
|
||||
_expect_equal(checkpoints.size(), 1, "renderer checkpoint count", failures)
|
||||
if spawn.is_empty() or checkpoints.size() != 1 or not (checkpoints[0] is Dictionary):
|
||||
_report_and_quit(failures)
|
||||
return
|
||||
|
||||
var checkpoint: Dictionary = checkpoints[0]
|
||||
var server_values := _three_floats(spawn.get("server_position", null), "server position", failures)
|
||||
if server_values.is_empty():
|
||||
_report_and_quit(failures)
|
||||
return
|
||||
var server_position = SERVER_WORLD_POSITION_SCRIPT.new(server_values[0], server_values[1], server_values[2])
|
||||
var canonical_position = COORDINATE_MAPPER_SCRIPT.server_to_canonical(server_position)
|
||||
var godot_position = COORDINATE_MAPPER_SCRIPT.canonical_to_godot(canonical_position)
|
||||
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.canonical_to_adt_tile(canonical_position)
|
||||
var tile_local_position = COORDINATE_MAPPER_SCRIPT.canonical_to_adt_tile_local(canonical_position)
|
||||
var chunk_coordinate = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_chunk(tile_coordinate, tile_local_position)
|
||||
var mapped_position := [godot_position.x_units, godot_position.y_units, godot_position.z_units]
|
||||
|
||||
_expect_equal(String(checkpoint.get("name", "")), EXPECTED_SPAWN_NAME, "checkpoint name", failures)
|
||||
_expect_true("server_spawn" in checkpoint.get("coverage", []), "server-spawn coverage", failures)
|
||||
_expect_true(bool(checkpoint.get("diagnostic_spawn_marker", false)), "diagnostic spawn marker enabled", failures)
|
||||
_expect_three_near(checkpoint.get("target", null), mapped_position, "checkpoint target", failures)
|
||||
_expect_three_near(checkpoint.get("player", null), mapped_position, "checkpoint player", failures)
|
||||
_expect_pair(checkpoint.get("expected_adt_tile", null), [tile_coordinate.tile_x, tile_coordinate.tile_y], "ADT tile", failures)
|
||||
_expect_pair(checkpoint.get("expected_adt_chunk", null), [chunk_coordinate.chunk_x, chunk_coordinate.chunk_y], "ADT chunk", failures)
|
||||
_expect_three_near(spawn.get("expected_godot_position", null), mapped_position, "fixture Godot position", failures)
|
||||
var camera_values := _three_floats(checkpoint.get("camera", null), "checkpoint camera", failures)
|
||||
if not camera_values.is_empty():
|
||||
_expect_true(camera_values[1] > godot_position.y_units, "checkpoint camera is above spawn", failures)
|
||||
_expect_true(Vector3(camera_values[0], camera_values[1], camera_values[2]).distance_to(Vector3(mapped_position[0], mapped_position[1], mapped_position[2])) > 1.0, "checkpoint camera is distinct from spawn", failures)
|
||||
|
||||
if not failures.is_empty():
|
||||
_report_and_quit(failures)
|
||||
return
|
||||
print("SERVER_SPAWN_RENDERER PASS spawn=1 checkpoint=1 tile=%d_%d chunk=%d_%d profile=%s" % [
|
||||
tile_coordinate.tile_x,
|
||||
tile_coordinate.tile_y,
|
||||
chunk_coordinate.chunk_x,
|
||||
chunk_coordinate.chunk_y,
|
||||
EXPECTED_PROFILE,
|
||||
])
|
||||
quit(0)
|
||||
|
||||
|
||||
func _find_named_dictionary(entries: Array, expected_name: String) -> Dictionary:
|
||||
for entry_variant in entries:
|
||||
if entry_variant is Dictionary and String(entry_variant.get("name", "")) == expected_name:
|
||||
return entry_variant
|
||||
return {}
|
||||
|
||||
|
||||
func _load_json_object(path: String, failures: Array[String]) -> Dictionary:
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
failures.append("cannot open JSON: %s" % path)
|
||||
return {}
|
||||
var parsed = JSON.parse_string(file.get_as_text())
|
||||
if not (parsed is Dictionary):
|
||||
failures.append("JSON is not an object: %s" % path)
|
||||
return {}
|
||||
return parsed
|
||||
|
||||
|
||||
func _three_floats(value_variant, label: String, failures: Array[String]) -> Array[float]:
|
||||
if not (value_variant is Array) or value_variant.size() != 3:
|
||||
failures.append("%s must contain three numbers" % label)
|
||||
return []
|
||||
return [float(value_variant[0]), float(value_variant[1]), float(value_variant[2])]
|
||||
|
||||
|
||||
func _expect_three_near(actual_variant, expected_values: Array, label: String, failures: Array[String]) -> void:
|
||||
var actual_values := _three_floats(actual_variant, label, failures)
|
||||
if actual_values.is_empty() or expected_values.size() != 3:
|
||||
return
|
||||
for component_index in range(3):
|
||||
if absf(actual_values[component_index] - float(expected_values[component_index])) > POSITION_TOLERANCE_YARDS:
|
||||
failures.append("%s[%d] expected %.9f, got %.9f" % [label, component_index, expected_values[component_index], actual_values[component_index]])
|
||||
|
||||
|
||||
func _expect_pair(actual_variant, expected_values: Array, label: String, failures: Array[String]) -> void:
|
||||
if not (actual_variant is Array) or actual_variant.size() != 2:
|
||||
failures.append("%s must contain two integers" % label)
|
||||
return
|
||||
for component_index in range(2):
|
||||
_expect_equal(int(actual_variant[component_index]), int(expected_values[component_index]), "%s[%d]" % [label, component_index], failures)
|
||||
|
||||
|
||||
func _expect_equal(actual_value, expected_value, label: String, failures: Array[String]) -> void:
|
||||
if actual_value != expected_value:
|
||||
failures.append("%s expected %s, got %s" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_true(actual_value: bool, label: String, failures: Array[String]) -> void:
|
||||
if not actual_value:
|
||||
failures.append("%s expected true" % label)
|
||||
|
||||
|
||||
func _report_and_quit(failures: Array[String]) -> void:
|
||||
if failures.is_empty():
|
||||
failures.append("verification stopped without a diagnostic")
|
||||
for failure in failures:
|
||||
push_error("SERVER_SPAWN_RENDERER: %s" % failure)
|
||||
quit(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://c7f2rpfey0vrs
|
||||
@@ -0,0 +1,101 @@
|
||||
extends SceneTree
|
||||
|
||||
## Headless M01 contract and wiring regression for camera-independent streaming.
|
||||
|
||||
const StreamingFocusScript = preload("res://src/domain/streaming/streaming_focus.gd")
|
||||
const GodotWorldPositionScript = preload("res://src/domain/coordinates/godot_world_position.gd")
|
||||
|
||||
const LOADER_PATH := "res://src/scenes/streaming/streaming_world_loader.gd"
|
||||
const RUNTIME_SCENE_PATHS: Array[String] = [
|
||||
"res://src/scenes/streaming/eastern_kingdoms_streaming.tscn",
|
||||
"res://src/scenes/streaming/kalimdor_streaming.tscn",
|
||||
]
|
||||
const CAPTURE_TOOL_PATHS: Array[String] = [
|
||||
"res://src/tools/capture_render_checkpoints.gd",
|
||||
"res://src/tools/probe_render_camera_occluders.gd",
|
||||
"res://src/tools/probe_render_terrain_height.gd",
|
||||
]
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var failures: Array[String] = []
|
||||
_verify_scene_free_focus_value(failures)
|
||||
_verify_loader_boundary(failures)
|
||||
_verify_runtime_scene_wiring(failures)
|
||||
_verify_capture_tool_wiring(failures)
|
||||
|
||||
if not failures.is_empty():
|
||||
for failure in failures:
|
||||
push_error("STREAMING_FOCUS: %s" % failure)
|
||||
quit(1)
|
||||
return
|
||||
|
||||
print("STREAMING_FOCUS PASS contract=1 runtime_scenes=2 capture_tools=3")
|
||||
quit(0)
|
||||
|
||||
|
||||
func _verify_scene_free_focus_value(failures: Array[String]) -> void:
|
||||
var position = GodotWorldPositionScript.new(17199.159666667, 83.5312, 26016.616666667)
|
||||
var focus = StreamingFocusScript.new(position)
|
||||
_expect_true(focus.world_position == position, "focus retains typed position", failures)
|
||||
_expect_near(focus.world_position.x_units, 17199.159666667, "focus X", failures)
|
||||
_expect_near(focus.world_position.y_units, 83.5312, "focus Y", failures)
|
||||
_expect_near(focus.world_position.z_units, 26016.616666667, "focus Z", failures)
|
||||
|
||||
var focus_source := _read_text("res://src/domain/streaming/streaming_focus.gd", failures)
|
||||
_expect_true(not focus_source.contains("extends Node"), "focus does not inherit Node", failures)
|
||||
_expect_true(not focus_source.contains("extends Resource"), "focus does not inherit Resource", failures)
|
||||
_expect_true(not focus_source.contains("Vector3"), "focus does not expose Vector3", failures)
|
||||
|
||||
|
||||
func _verify_loader_boundary(failures: Array[String]) -> void:
|
||||
var loader_source := _read_text(LOADER_PATH, failures)
|
||||
for required_text in [
|
||||
"@export var streaming_focus_source_path: NodePath",
|
||||
"func set_streaming_focus(streaming_focus: StreamingFocus) -> void:",
|
||||
"func refresh_streaming_focus(force: bool = false) -> bool:",
|
||||
]:
|
||||
_expect_true(loader_source.contains(required_text), "loader contains %s" % required_text, failures)
|
||||
|
||||
for forbidden_text in [
|
||||
"get_viewport().get_camera_3d()",
|
||||
"child is Camera3D and child.current",
|
||||
"func _get_stream_camera()",
|
||||
]:
|
||||
_expect_true(not loader_source.contains(forbidden_text), "loader omits %s" % forbidden_text, failures)
|
||||
|
||||
|
||||
func _verify_runtime_scene_wiring(failures: Array[String]) -> void:
|
||||
for scene_path in RUNTIME_SCENE_PATHS:
|
||||
var scene_source := _read_text(scene_path, failures)
|
||||
_expect_true(
|
||||
scene_source.contains('streaming_focus_source_path = NodePath("ThirdPersonPlayer")'),
|
||||
"%s uses player focus" % scene_path,
|
||||
failures
|
||||
)
|
||||
|
||||
|
||||
func _verify_capture_tool_wiring(failures: Array[String]) -> void:
|
||||
for tool_path in CAPTURE_TOOL_PATHS:
|
||||
var tool_source := _read_text(tool_path, failures)
|
||||
_expect_true(tool_source.contains('world.set("streaming_focus_source_path"'), "%s sets explicit focus source" % tool_path, failures)
|
||||
_expect_true(tool_source.contains('world.call("refresh_streaming_focus", true)'), "%s uses public refresh" % tool_path, failures)
|
||||
_expect_true(not tool_source.contains('world.call("_refresh_streaming_targets_at"'), "%s avoids private refresh" % tool_path, failures)
|
||||
|
||||
|
||||
func _read_text(path: String, failures: Array[String]) -> String:
|
||||
var file := FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
failures.append("cannot open %s" % path)
|
||||
return ""
|
||||
return file.get_as_text()
|
||||
|
||||
|
||||
func _expect_near(actual_value: float, expected_value: float, label: String, failures: Array[String]) -> void:
|
||||
if absf(actual_value - expected_value) > 0.000001:
|
||||
failures.append("%s expected %.9f, got %.9f" % [label, expected_value, actual_value])
|
||||
|
||||
|
||||
func _expect_true(actual_value: bool, label: String, failures: Array[String]) -> void:
|
||||
if not actual_value:
|
||||
failures.append("%s expected true" % label)
|
||||
@@ -0,0 +1 @@
|
||||
uid://b7ayw5a0bn1lq
|
||||
@@ -57,6 +57,8 @@ try {
|
||||
Invoke-GodotStep "runtime-cache-shutdown" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_runtime_cache_shutdown.gd")
|
||||
Invoke-GodotStep "baseline-manifest" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_baseline_manifest.gd")
|
||||
Invoke-GodotStep "coordinate-calibration" @("--headless", "--path", ".", "--script", "res://src/tools/verify_render_coordinate_calibration.gd")
|
||||
Invoke-GodotStep "coordinate-boundaries" @("--headless", "--path", ".", "--script", "res://src/tools/verify_coordinate_conversion_boundaries.gd")
|
||||
Invoke-GodotStep "server-spawn-renderer" @("--headless", "--path", ".", "--script", "res://src/tools/verify_server_spawn_renderer.gd")
|
||||
|
||||
$captureArgs = @(
|
||||
"--path", ".",
|
||||
|
||||
Reference in New Issue
Block a user