Compare commits

...

17 Commits

Author SHA1 Message Date
sindoring 0ce3cae208 docs(M02): publish terrain query handoff
Work-Package: M02-GMP-TERRAIN-QUERY-001
Agent: sindo-main-codex
Tests: coordination and documentation gates; diff check
Fidelity: documents inherited height/snap regression and remaining collision evidence gap
2026-07-14 23:11:23 +04:00
sindoring a45d521567 gmp(M02): extract player terrain query
Work-Package: M02-GMP-TERRAIN-QUERY-001
Agent: sindo-main-codex
Tests: terrain query, player input and movement regressions; asset-free scene; renderer dry-run; coordinate, streaming, documentation and coordination gates
Fidelity: preserves existing ADT outer-grid interpolation and player ground snap; build-12340 collision parity remains unverified
2026-07-14 23:10:55 +04:00
sindoring 5206c42cf0 Merge pull request 'gmp(M02): extract local player movement' (#22) from work/sindo-main-codex/m02-local-movement into master
Reviewed-on: #22
2026-07-14 22:01:21 +03:00
sindoring d2d6df3655 docs(M02): publish local movement handoff
Work-Package: M02-GMP-MOVEMENT-001
Agent: sindo-main-codex
Tests: coordination and documentation gates; diff check
Fidelity: documents preserved sandbox behavior and remaining build-12340 evidence gap
2026-07-14 22:59:59 +04:00
sindoring 435e1c95d2 gmp(M02): extract local player movement
Work-Package: M02-GMP-MOVEMENT-001
Agent: sindo-main-codex
Tests: local movement and player input regressions; asset-free scene; renderer dry-run; coordinate, streaming, documentation and coordination gates
Fidelity: preserves current sandbox speed, acceleration, sprint and camera-relative flight behavior; build-12340 parity remains unverified
2026-07-14 22:59:33 +04:00
sindoring 14dead194b Merge pull request 'gmp(M02): add player input intent seam' (#21) from work/sindo-main-codex/m02-player-input into master
Reviewed-on: #21
2026-07-14 21:52:26 +03:00
sindoring e794764269 docs(M02): publish player input handoff
Work-Package: M02-GMP-INPUT-001
Agent: sindo-main-codex
Tests: coordination and documentation gates; diff check
Fidelity: documents regression evidence and unverified build-12340 semantics
2026-07-14 22:45:14 +04:00
sindoring 6bd2e84048 gmp(M02): add player input intent seam
Work-Package: M02-GMP-INPUT-001
Agent: sindo-main-codex
Tests: verify_player_input; renderer baseline dry-run; coordinate, streaming, documentation and coordination gates
Fidelity: preserves current sandbox bindings and movement/camera behavior; exact build-12340 semantics remain unverified
2026-07-14 22:44:44 +04:00
sindoring 62eece991c Merge pull request 'docs(M01): claim milestone closeout' (#20) from work/sindo-main-codex/m01-integrator-closeout into master
Reviewed-on: #20
2026-07-14 12:55:09 +03:00
sindoring fc81059dfa docs(M01): mark milestone closeout ready
Work-Package: M01-QAR-INTEGRATOR-CLOSEOUT-001

Agent: sindo-main-codex
2026-07-14 12:14:39 +04:00
sindoring dd412e6d0d test(M01): close coordinates and seams milestone
Work-Package: M01-QAR-INTEGRATOR-CLOSEOUT-001

Agent: sindo-main-codex

Tests: all M01 domain gates, unified renderer dry-run, coordination and documentation gates

Fidelity: five build-12340 points, raw ADT and mapped AzerothCore spawn evidence; no 1:1 claim
2026-07-14 12:13:43 +04:00
sindoring 07f08044f4 docs(M01): claim milestone closeout
Work-Package: M01-QAR-INTEGRATOR-CLOSEOUT-001

Agent: sindo-main-codex
2026-07-14 12:01:49 +04:00
sindoring c8e99f28d6 Merge pull request 'chore(M01): remove local spawn capture logs' (#19) from work/sindo-main-codex/m01-server-spawn-renderer into master
Reviewed-on: #19
2026-07-14 10:58:37 +03:00
sindoring 48cc976ba0 docs(M01): mark server spawn renderer ready
Work-Package: M01-QAR-SERVER-SPAWN-RENDERER-001

Agent: sindo-main-codex

Tests: server spawn GUI cold/warm, unified renderer dry-run, domain and documentation gates
2026-07-14 11:56:39 +04:00
sindoring 318e6ae757 chore(M01): remove local spawn capture logs
Work-Package: M01-QAR-SERVER-SPAWN-RENDERER-001

Agent: sindo-main-codex

Tests: renderer dry-run, coordinate/domain gates, GUI cold/warm inspection
2026-07-14 11:55:05 +04:00
sindoring 747fae8e2e Merge pull request 'координаты' (#18) from work/sindo-main-codex/m01-server-spawn-renderer into master
Reviewed-on: #18
2026-07-14 10:48:53 +03:00
sindoring 52b6fa2ebb Merge pull request 'docs(M01): claim server spawn renderer evidence' (#17) from work/sindo-main-codex/m01-server-spawn-renderer into master
Reviewed-on: #17
2026-07-14 10:42:14 +03:00
46 changed files with 2380 additions and 5343 deletions
+4
View File
@@ -35,3 +35,7 @@
# CMake build директория # CMake build директория
/src/native/build/ /src/native/build/
# Local root-level diagnostic capture logs
/*.stdout.log
/*.stderr.log
@@ -1,7 +1,7 @@
# M01-FND-COORD-BOUNDARY-GATE-001 — Coordinate conversion boundary gate # 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_CLAIM:M01-FND-COORD-BOUNDARY-GATE-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M01-FND-COORD-BOUNDARY-GATE-001:47dec6c --> <!-- OPENWC_INTEGRATION:ACCEPTED:M01-FND-COORD-BOUNDARY-GATE-001:c8e99f2 -->
## Ownership ## Ownership
@@ -1,7 +1,7 @@
# M01-FND-COORD-TILE-AXIS-002 — ADT filename axis correction # 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_CLAIM:M01-FND-COORD-TILE-AXIS-002:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M01-FND-COORD-TILE-AXIS-002:a7072e3 --> <!-- OPENWC_INTEGRATION:ACCEPTED:M01-FND-COORD-TILE-AXIS-002:c8e99f2 -->
## Ownership ## Ownership
+1 -1
View File
@@ -1,7 +1,7 @@
# M01-FND-COORDS-001 — Canonical coordinate contracts # M01-FND-COORDS-001 — Canonical coordinate contracts
<!-- OPENWC_CLAIM:M01-FND-COORDS-001:sindo-main-codex:2026-07-15 --> <!-- OPENWC_CLAIM:M01-FND-COORDS-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M01-FND-COORDS-001:f45695c --> <!-- OPENWC_INTEGRATION:ACCEPTED:M01-FND-COORDS-001:c8e99f2 -->
## Ownership ## Ownership
@@ -1,7 +1,7 @@
# M01-FND-DOMAIN-IDENTITIES-001 — Stable domain identity namespaces # M01-FND-DOMAIN-IDENTITIES-001 — Stable domain identity namespaces
<!-- OPENWC_CLAIM:M01-FND-DOMAIN-IDENTITIES-001:sindo-main-codex:2026-07-15 --> <!-- OPENWC_CLAIM:M01-FND-DOMAIN-IDENTITIES-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M01-FND-DOMAIN-IDENTITIES-001:c1dc07c --> <!-- OPENWC_INTEGRATION:ACCEPTED:M01-FND-DOMAIN-IDENTITIES-001:c8e99f2 -->
## Ownership ## Ownership
@@ -1,7 +1,7 @@
# M01-QAR-COORD-FIXTURES-001 — Coordinate golden fixtures # M01-QAR-COORD-FIXTURES-001 — Coordinate golden fixtures
<!-- OPENWC_CLAIM:M01-QAR-COORD-FIXTURES-001:sindo-main-codex:2026-07-15 --> <!-- OPENWC_CLAIM:M01-QAR-COORD-FIXTURES-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M01-QAR-COORD-FIXTURES-001:ce4f7ec --> <!-- OPENWC_INTEGRATION:ACCEPTED:M01-QAR-COORD-FIXTURES-001:c8e99f2 -->
## Ownership ## Ownership
@@ -0,0 +1,101 @@
# M01-QAR-INTEGRATOR-CLOSEOUT-001 — M01 milestone closeout
<!-- OPENWC_CLAIM:M01-QAR-INTEGRATOR-CLOSEOUT-001:sindo-main-codex:2026-07-16 -->
<!-- OPENWC_HANDOFF:READY:M01-QAR-INTEGRATOR-CLOSEOUT-001:dd412e6 -->
## Ownership
- Target: M01
- Program: QAR
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m01-integrator-closeout`
- Lease expires UTC: 2026-07-16
- Integrator: sindo-main-codex, continuing the user-directed milestone workflow on 2026-07-14
## Outcome
Audit every merged M01 work package on current `master`, record final evidence,
close M01 and activate M02 only if all target verification and documentation
criteria pass.
## Non-goals
- Change coordinate, identity, streaming or renderer behavior.
- Start M02 implementation.
- Add new compatibility or visual-parity claims.
- Commit proprietary assets, generated UIDs, caches or capture output.
## Paths
- Exclusive: M01/M02 target status, M01 final Evidence and M01 claim acceptance markers
- Shared/hotspots: `targets/README.md`, `targets/DEVELOPMENT_ROADMAP.md`, this claim
- Generated/ignored: local Godot imports, renderer corpus and `user://` reports
## Contracts and data
- Public APIs, schemas, cache formats and migrations: unchanged
- Coordinate contract remains version 2
- Fixture schema remains version 1
- Consumers: milestone sequence and M02 work packages
## Dependencies
- Requires: all seven M01 READY commits integrated through master `c8e99f2`
- Blocks: M02 activation
- External state: server-spawn GUI hashes and original-client numeric evidence are recorded; proprietary files remain outside Git
## Verification
- Commands: all M01 domain/fixture/boundary/focus/identity/spawn gates,
unified renderer dry-run, coordination/documentation checks and diff hygiene
- Fidelity evidence: five build-12340 points, raw ADT metadata, pinned
AzerothCore spawn and cache-complete GUI marker capture
- Performance: no runtime change; preserve recorded renderer cold/warm evidence
## Documentation deliverables
- M01 final target Evidence and checklist
- M01 claim integration-acceptance markers
- Target index and roadmap transition to M02
- API/module specifications and diagrams are audited, not changed unless a gap is found
## Simplicity and naming
- Important names introduced: none beyond the closeout work-package ID
- Simplest approach: evidence/status-only integrator patch
- Rejected complexity: new one-off closeout framework or behavioral changes
- Unavoidable complexity: none
## Status
- State: ready-for-review
- Done: accepted seven M01 packages, reran post-merge gates, recorded complete
target Evidence, closed M01 and activated M02
- Next: merge closeout commit before starting an M02 implementation claim
- Blocked by:
## Handoff
- Commit: `dd412e6`
- Branch: `work/sindo-main-codex/m01-integrator-closeout`
- Outcome: M01 is `DONE` with all seven checklist items and complete Evidence;
M02 is the only `ACTIVE` target and `targets/README.md` points to it.
- Integration audit: all seven M01 READY commits are ancestors of master
`c8e99f2`; their claims now carry `OPENWC_INTEGRATION:ACCEPTED` markers.
- Verification: unified renderer dry-run passed project load, material/dedupe/
shutdown gates, manifest `7/7/7`, calibration maximum error `0.000015`,
coordinate boundary (`84` files) and server-spawn renderer `(32,48)/(3,12)`;
coordinate mapper, golden fixtures, StreamingFocus and domain identity gates
passed. Coordination and documentation gates passed; coordination reports
only five already-expired M00 claim warnings.
- Fidelity: closeout preserves five build-12340 coordinate observations, raw ADT
evidence, pinned AzerothCore spawn mapping and cache-complete Northshire GUI
evidence without claiming original-client visual parity or TrinityCore row
equivalence.
- Rebuild/migration: none. Coordinate contract remains version 2; fixture schema
remains version 1; renderer cache formats are unchanged.
- Remaining risks: recorded in M01 Evidence—TrinityCore populated spawn,
placement Euler parity, native parser boundary and broader renderer parity.
- Documentation: M01 target Evidence/checklist, target index and roadmap current
state updated. Existing coordinate, identity and renderer module specs/API/
diagrams were audited and passed the documentation gate.
@@ -1,6 +1,7 @@
# M01-QAR-SERVER-SPAWN-RENDERER-001 — Golden server spawn renderer evidence # 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 --> <!-- OPENWC_CLAIM:M01-QAR-SERVER-SPAWN-RENDERER-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_INTEGRATION:ACCEPTED:M01-QAR-SERVER-SPAWN-RENDERER-001:c8e99f2 -->
## Ownership ## Ownership
@@ -79,7 +80,56 @@ ADT tile/chunk.
## Status ## Status
- State: active - State: ready-for-review
- Done: merged-package and target evidence audit - Done: fixture-to-renderer manifest/verifier, renderer-native marker, unified
- Next: implement manifest/verifier/marker, capture GUI evidence and hand off baseline integration, cold/warm GUI evidence, documentation and log cleanup
- Next: integrator review, merge cleanup/handoff and M01 closeout audit
- Blocked by: - Blocked by:
## Handoff
- Commits: implementation `24ddc99`; required cleanup `318e6ae`
- Branch: `work/sindo-main-codex/m01-server-spawn-renderer`
- Outcome: the pinned AzerothCore Human Warrior start is routed through
`CoordinateMapper` into the ordinary Eastern Kingdoms capture scene. A
depth-tested magenta marker begins at the exact mapped spawn origin.
- Contract/schema: additive diagnostic manifest schema 1 and marker metadata;
coordinate contract version 2, production renderer APIs, cache formats and
`Blizzlike335` behavior are unchanged.
- Verification: `SERVER_SPAWN_RENDERER PASS spawn=1 checkpoint=1 tile=32_48
chunk=3_12 profile=Blizzlike335`; unified renderer dry-run passed project,
materials, M2 dedupe, shutdown, `7/7/7` manifest, five-point calibration,
coordinate-boundary and server-spawn steps; coordinate golden fixtures,
mapper, StreamingFocus, domain identities, documentation and whitespace gates
passed. Coordination passed with five expired M00-claim warnings only.
- GUI evidence: two `1280x900` cold/warm PNGs captured under
`user://server_spawn_renderer_m01_gui_run2`; focus tile `(32,48)`, terrain
quality `100/100`, missing cache `0`, queues drained, report results `2`.
Human inspection confirms the marker is on rendered terrain beside the road
at Northshire Abbey rather than below terrain or in an adjacent tile. PNG
hashes: cold `c08c43bcb75e5b3277105afb0d4e5a76caae9db91a7db64488770ffa03e32589`,
warm `1b75237a090ea163836372a8e39e778c909773f4508063adc3f70a3e12a85a62`.
- Fidelity: source remains AzerothCore revision
`68fcf0098b16388093989627f37be530fc91f07d`; server
`(-8949.95,-132.493,83.5312)` maps to Godot
`(17199.159666667,83.5312,26016.616666667)`, ADT `(32,48)`, MCNK `(3,12)`.
This proves coordinate/renderer integration, not original-client visual parity
or TrinityCore populated-row equivalence.
- Runtime notes: D3D12 descriptor-heap initialization fell back to Vulkan;
optional ignored character/ambient GLB imports were unavailable. Neither
affected terrain/marker evidence. The known anonymous ObjectDB teardown
warning remained; no Node, renderer resource or RID leak diagnostic occurred
in the cache-complete run.
- Repository hygiene: four accidentally committed local GUI logs are removed by
`318e6ae`; root `*.stdout.log`/`*.stderr.log` files are now ignored. Generated
PNG/JSON evidence and proprietary corpus remain outside Git.
- Remaining risks: the diagnostic marker is not a production network entity;
live server adapters belong to M06/M08. Exact original-client character spawn
presentation and TrinityCore database equivalence remain unverified.
- Documentation: `RENDER.md`, renderer-baseline procedure, coordinate-mapping
and world-renderer module API/input-output/data-flow/capability/source-map
sections updated. No lifecycle/state diagram changed because the verifier and
mapper path are synchronous; capture reuses the documented renderer lifecycle.
- Recommended merge order: `318e6ae` after master merge `747fae8`. Then the M01
milestone integrator may accept all M01 claims, update target Evidence/checks
and evaluate `OPENWC_TARGET_DONE`.
@@ -1,7 +1,7 @@
# M01-RND-STREAMING-FOCUS-001 — Explicit streaming focus contract # M01-RND-STREAMING-FOCUS-001 — Explicit streaming focus contract
<!-- OPENWC_CLAIM:M01-RND-STREAMING-FOCUS-001:sindo-main-codex:2026-07-15 --> <!-- OPENWC_CLAIM:M01-RND-STREAMING-FOCUS-001:sindo-main-codex:2026-07-15 -->
<!-- OPENWC_HANDOFF:READY:M01-RND-STREAMING-FOCUS-001:7815385 --> <!-- OPENWC_INTEGRATION:ACCEPTED:M01-RND-STREAMING-FOCUS-001:c8e99f2 -->
## Ownership ## Ownership
+112
View File
@@ -0,0 +1,112 @@
# M02-GMP-INPUT-001 — Player input intent seam
<!-- OPENWC_CLAIM:M02-GMP-INPUT-001:sindo-main-codex:2026-07-16 -->
<!-- OPENWC_HANDOFF:READY:M02-GMP-INPUT-001:6bd2e84 -->
## Ownership
- Target: M02
- Program: GMP/FND
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m02-player-input`
- Lease expires UTC: 2026-07-16
- Integrator: M02 milestone integrator
## Outcome
Replace direct keyboard polling in the runtime player with remappable Input Map
actions and an immutable `PlayerInputSource → MoveIntent` boundary while
preserving the current render-sandbox movement behavior.
## Non-goals
- Extract local movement, terrain query, camera rig or character presenters.
- Claim exact build-12340 movement/keybinding parity before original-client fixtures.
- Change movement speeds, camera geometry, terrain sampling or renderer behavior.
- Mark M02 complete or edit its checklist/Evidence.
## Paths
- Exclusive: `src/domain/input/`, `src/gameplay/input/`,
`src/tests/scenes/player_input_regression.tscn`,
`src/tools/verify_player_input.gd`, `docs/modules/player-input.md`, this claim
- Shared/hotspots: `project.godot`,
`src/scenes/player/third_person_wow_controller.gd`, `docs/modules/README.md`
- Generated/ignored: Godot import metadata, `.uid` files and local renderer corpus
## Contracts and data
- Public API: immutable `MoveIntent`; `PlayerInputSource.sample_move_intent`
- Configuration: additive `openwc_player_*` Input Map actions
- Persistence/schema/cache: unchanged
- Consumers: current sandbox player controller; later local movement controller
## Dependencies
- Requires: merged M01 coordinate/streaming-focus contracts on master `62eece9`
- Blocks: later M02 movement-controller extraction
- External state: none; tests use synthetic Input Map events
## Verification
- Commands: dedicated player-input verifier, headless project load, coordinate
boundary gate, coordination/documentation gates and diff hygiene
- Fixtures: synthetic action strengths and configured default bindings
- Fidelity evidence: current W/S/A/D, Shift, E/Q and Space sandbox behavior remains
mapped through actions; exact 3.3.5a semantics remain unverified
- Performance budget: one immutable intent allocation per physics tick; no I/O
## Documentation deliverables
- Inline API documentation for `MoveIntent`, `PlayerInputActions` and
`PlayerInputSource`
- Player-input module specification with inputs/outputs, data-flow and sequence diagrams
- Module registry/source map and honest capability status
## Simplicity and naming
- Important names: `MoveIntent`, `PlayerInputSource`, `PlayerInputActions`
- Simplest approach: immutable value, one input adapter and one controller consumer
- Rejected complexity: input provider hierarchy, event bus and generic command framework
- Unavoidable complexity: none
- Measured optimization evidence: not applicable
## Status
- State: ready-for-review
- Done: twelve remappable actions, immutable `MoveIntent`, stateless
`PlayerInputSource`, controller migration, asset-free regression scene,
dedicated verifier and module specification
- Next: M02 integrator reviews and merges before local movement extraction
- Blocked by:
## Handoff
- Commit: `6bd2e84`
- Branch: `work/sindo-main-codex/m02-player-input`
- Outcome: the runtime player no longer polls physical keyboard keys. Movement
action strengths cross an immutable `MoveIntent` seam; camera and immediate
sandbox-flight events use the same remappable action catalog.
- Public contract: additive `MoveIntent`, `PlayerInputActions` and
`PlayerInputSource`; no schema, cache, coordinate or renderer contract change.
- Verification: `PLAYER_INPUT PASS actions=12 intent_cases=6 controller=1
regression_scene=1`; asset-free scene smoke exited `0`; coordinate boundary
(`88` files) and StreamingFocus gates passed; unified renderer dry-run passed
all eight pre-capture gates and produced seven dry-run checkpoint results;
coordination/documentation/diff gates passed.
- Fidelity: W/S/A/D, Shift, E/Q, Space, right mouse, wheel and Escape remain the
default sandbox bindings. Regression drives forward movement, camera zoom and
immediate flight toggle through the real controller. This does not establish
exact build-12340 default bindings, turn/strafe policy or gameplay movement parity.
- Local verification inputs: the isolated worktree reused the existing ignored
native DLL and generated ADT resource scripts. Proprietary extracted data and
the character GLB were absent, so the renderer dry-run logged the expected
missing-corpus diagnostics while all contract steps returned success.
- Rebuild/migration: none. Action names are additive; persisted user-binding
migration does not exist yet and is documented as a gap.
- Remaining risks: production profile gating for sprint/free flight, exact
3.3.5a bindings, local movement/terrain/camera/presentation extraction and
broader movement/camera state tests remain M02 work.
- Documentation: inline API comments plus `docs/modules/player-input.md` with
inputs/outputs, data-flow and sequence diagrams, ownership, recovery,
capability status, known gaps and source map.
+117
View File
@@ -0,0 +1,117 @@
# M02-GMP-MOVEMENT-001 — Local movement state/controller
<!-- OPENWC_CLAIM:M02-GMP-MOVEMENT-001:sindo-main-codex:2026-07-16 -->
<!-- OPENWC_HANDOFF:READY:M02-GMP-MOVEMENT-001:435e1c9 -->
## Ownership
- Target: M02
- Program: GMP
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m02-local-movement`
- Lease expires UTC: 2026-07-16
- Integrator: M02 milestone integrator
## Outcome
Move local velocity, sandbox flight state, acceleration and directional speed
calculation from `ThirdPersonWowController` into a scene-free,
independently-testable local movement controller without changing current
sandbox motion.
## Non-goals
- Extract terrain queries, camera rig, character presentation or animation.
- Add jump/fall/swim, server prediction or reconciliation.
- Change current movement speeds, acceleration, camera-relative flight or ground snap.
- Gate debug movement by build profile; that remains a separate M02 package.
- Mark M02 complete or edit its checklist/Evidence.
## Paths
- Exclusive: `src/gameplay/movement/`,
`src/tools/verify_local_player_movement.gd`,
`docs/modules/local-player-movement.md`, this claim
- Shared/hotspots: `src/scenes/player/third_person_wow_controller.gd`,
`src/tools/verify_player_input.gd`, `docs/modules/player-input.md`,
`docs/modules/README.md`
- Generated/ignored: local `.godot`, native DLL, generated ADT resources and renderer corpus
## Contracts and data
- Public API: stateful `LocalPlayerMovementController`
- Inputs: immutable `MoveIntent`, local Godot movement basis and physics delta seconds
- Outputs: local Godot displacement and read-only velocity/flight state
- Schema/cache/coordinate contracts: unchanged
- Consumer: current sandbox player scene; later gameplay composition root
## Dependencies
- Requires: merged input seam on master `14dead1`
- Blocks: terrain query and camera/presentation extraction from the player hotspot
- External state: none; unit tests use synthetic intents and bases
## Verification
- Commands: dedicated pure movement verifier, player-input regression, asset-free
scene smoke, coordinate/StreamingFocus gates, renderer dry-run and repository gates
- Fixtures: identity/rotated/pitched bases, acceleration steps, sprint and flight transitions
- Fidelity evidence: exact current 7.0/4.5/4.5 speeds, 28.0 acceleration,
6x sandbox sprint and camera-relative free flight are regression-locked only
- Performance budget: one small state update per physics tick; no allocation, I/O or scene lookup
## Documentation deliverables
- Inline public API docs for movement state/configuration and update methods
- Local movement module specification with data-flow, state and sequence diagrams
- Updated player-input consumer diagram/status and module registry
## Simplicity and naming
- Important name: `LocalPlayerMovementController`
- Simplest approach: one stateful RefCounted owning velocity and flight toggle
- Rejected complexity: generic locomotion framework, ECS component hierarchy and event bus
- Unavoidable complexity: movement basis remains an explicit local-space input
so the pure controller does not discover player/camera Nodes
- Measured optimization evidence: not applicable
## Status
- State: ready-for-review
- Done: scene-free movement state/controller, player scene migration, twelve
numeric cases, two flight transitions, integrated regression and module documentation
- Next: M02 integrator reviews and merges before TerrainQuery extraction
- Blocked by:
## Handoff
- Commit: `435e1c9`
- Branch: `work/sindo-main-codex/m02-local-movement`
- Outcome: `ThirdPersonWowController` no longer owns velocity, flight state,
acceleration or directional speed calculation. It selects an explicit
Godot-world basis, applies returned displacement, and retains terrain and
presentation adapters for later M02 packages.
- Public contract: additive `LocalPlayerMovementController` with read-only
Godot-world velocity/flight state, `toggle_sandbox_flight` and `advance`.
Input, coordinate, cache and renderer contracts remain unchanged.
- Verification: `LOCAL_PLAYER_MOVEMENT PASS cases=12 state_transitions=2
scene_boundary=1`; `PLAYER_INPUT PASS actions=12 intent_cases=6 controller=1
regression_scene=1`; asset-free scene smoke exited `0`; coordinate boundary
and StreamingFocus passed; renderer dry-run passed all eight pre-capture gates
and seven checkpoint plans; coordination/documentation/diff gates passed.
- Fidelity: exact existing defaults are regression-locked—forward `7.0`,
backward/strafe `4.5`, acceleration `28.0`, sandbox sprint `6x`, vertical
flight `7.0`, velocity reset on toggle and camera-relative pitched flight.
This preserves the sandbox baseline but is not original-client evidence.
- Local verification inputs: the isolated worktree reused the existing ignored
native DLL and generated ADT resource scripts. Proprietary extracted data and
character GLB were absent, so renderer dry-run logged expected missing-corpus
diagnostics while every contract step returned success.
- Rebuild/migration: none; transient movement state is not persisted.
- Remaining risks: exported speed changes after `_ready` do not reconfigure the
controller; exact build-12340 movement semantics, terrain/collision state,
jump/fall/swim, server prediction and debug profile gating remain open.
- Documentation: inline public API plus `docs/modules/local-player-movement.md`
with inputs/outputs, data-flow, state and sequence diagrams, ownership,
recovery, capability status, risks and source map; player-input consumer
diagrams/status were updated.
@@ -0,0 +1,118 @@
# M02-GMP-TERRAIN-QUERY-001 — Player terrain query boundary
<!-- OPENWC_CLAIM:M02-GMP-TERRAIN-QUERY-001:sindo-main-codex:2026-07-16 -->
<!-- OPENWC_HANDOFF:READY:M02-GMP-TERRAIN-QUERY-001:a45d521 -->
## Ownership
- Target: M02
- Program: GMP/RND
- Owner/Agent ID: sindo-main-codex
- Branch: `work/sindo-main-codex/m02-terrain-query`
- Lease expires UTC: 2026-07-16
- Integrator: M02 milestone integrator
## Outcome
Introduce a typed `TerrainQuery` boundary and move ADT loading, caching, chunk
selection and height interpolation out of `ThirdPersonWowController` without
changing current spawn/ground-snap behavior.
## Non-goals
- Change ADT topology, coordinate formulas, terrain mesh or renderer caches.
- Add physics collision, slopes, water, jump/fall/swim or server movement.
- Reuse the streaming renderer cache before its public terrain-query contract exists.
- Extract camera or character presentation.
- Mark M02 complete or edit its checklist/Evidence.
## Paths
- Exclusive: `src/gameplay/terrain/`, `src/tools/verify_terrain_query.gd`,
`docs/modules/terrain-query.md`, this claim
- Shared/hotspots: `src/scenes/player/third_person_wow_controller.gd`,
`src/tools/verify_player_input.gd`,
`src/tools/verify_coordinate_conversion_boundaries.gd`,
`docs/modules/local-player-movement.md`,
`docs/modules/README.md`
- Generated/ignored: local `.godot`, native DLL, generated ADT resources and renderer corpus
## Contracts and data
- Public API: `TerrainQuery.sample_ground_height(GodotWorldPosition)` returning
immutable `TerrainGroundSample`
- Production adapter: `AdtTerrainQuery` with owned per-tile parse cache
- Test/data-source seam: optional ADT tile loader callable at construction
- Coordinate contract version, ADT format, renderer cache and persistence: unchanged
- Consumers: current player scene; future movement/collision policies
## Dependencies
- Requires: merged movement controller on master `5206c42`
- Blocks: camera/presentation extraction from the player hotspot
- External state: production uses existing native `ADTLoader`; synthetic tests need no proprietary data
## Verification
- Commands: synthetic height/cache/failure verifier, player input/movement
regressions, asset-free scene, coordinate/StreamingFocus gates, renderer dry-run
and repository gates
- Fixtures: synthetic 145-height chunk payload and injected flat terrain query
- Fidelity evidence: preserves existing outer-grid bilinear interpolation,
spawn ground offset and per-tick snap formula only
- Performance budget: one cached tile lookup and local interpolation per ground query;
no new I/O after first tile load
## Documentation deliverables
- Inline public API docs for query, sample and ADT adapter
- Terrain-query module spec with inputs/outputs, data-flow, cache lifecycle and sequence diagrams
- Updated movement/coordinate consumer boundaries, source maps and module registry
## Simplicity and naming
- Important names: `TerrainQuery`, `TerrainGroundSample`, `AdtTerrainQuery`
- Simplest approach: one narrow query contract, one typed result and one existing-format adapter
- Rejected complexity: general collision framework, terrain service locator and renderer-cache coupling
- Unavoidable complexity: ADT 145-height layout and chunk lookup stay isolated in adapter
- Measured optimization evidence: existing per-tile cache retained; no new optimization
## Status
- State: ready-for-review
- Done: typed query/sample contract, cached ADT adapter, player migration,
synthetic interpolation/cache/failure tests, injected scene regression and documentation
- Next: M02 integrator reviews and merges before camera-rig extraction
- Blocked by:
## Handoff
- Commit: `a45d521`
- Branch: `work/sindo-main-codex/m02-terrain-query`
- Outcome: `ThirdPersonWowController` no longer loads ADTs, caches tile
dictionaries, selects chunks or interpolates height grids. It consumes a
replaceable typed `TerrainQuery` and retains only existing offset/snap policy.
- Public contracts: additive immutable `TerrainGroundSample`, replaceable
`TerrainQuery`, cached `AdtTerrainQuery` and player `set_terrain_query`.
Coordinate contract version, ADT/native format and renderer caches are unchanged.
- Verification: `TERRAIN_QUERY PASS contract=4 interpolation=1 cache=1
failures=2 player_injection=1`; player-input and local-movement regressions
passed; asset-free scene exited `0`; coordinate boundary passed with five
required consumers and StreamingFocus passed; renderer dry-run passed eight
pre-capture gates and seven checkpoint plans; coordination/documentation/diff gates passed.
- Fidelity: synthetic fractional-grid fixture locks the inherited 145-height
outer-grid bilinear result within `0.002` Godot units; injected scene locks
spawn offset `0.05` and physics snap. This is sandbox-regression evidence,
not build-12340 triangle/hole/collision parity.
- Local verification inputs: isolated worktree reused the existing ignored
native DLL and generated ADT resource scripts. Proprietary extracted data and
character GLB were absent, so renderer dry-run logged expected missing-corpus
diagnostics while all contract steps returned success.
- Rebuild/migration: none; caches are transient and existing formats remain unchanged.
- Remaining risks: first ADT parse remains synchronous as before; unavailable
tiles cache until query replacement; player still owns snap policy; exact
ADT triangle choice, holes, slopes, liquids and collision remain open.
- Documentation: inline public APIs plus `docs/modules/terrain-query.md` with
inputs/outputs, data-flow, cache state and cross-boundary sequence diagrams,
ownership, failure/recovery, capability status and source map. Coordinate and
movement consumer specifications were updated.
+3
View File
@@ -9,6 +9,9 @@
| Foundation/data | Planned/Partial | [`../../targets/roadmap/01-foundation-and-data.md`](../../targets/roadmap/01-foundation-and-data.md) | | 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) | | Coordinate mapping | Implemented | [`coordinate-mapping.md`](coordinate-mapping.md) |
| Domain identities | Implemented contract | [`domain-identities.md`](domain-identities.md) | | Domain identities | Implemented contract | [`domain-identities.md`](domain-identities.md) |
| Player input | Partial | [`player-input.md`](player-input.md) |
| Local player movement | Implemented | [`local-player-movement.md`](local-player-movement.md) |
| Terrain query | Implemented | [`terrain-query.md`](terrain-query.md) |
| Renderer | Partial | [`world-renderer.md`](world-renderer.md), [`../../RENDER.md`](../../RENDER.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) | | 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) | | Gameplay | Prototype/Planned | [`../../targets/roadmap/04-gameplay-systems.md`](../../targets/roadmap/04-gameplay-systems.md) |
+10 -4
View File
@@ -5,9 +5,9 @@
| Field | Value | | Field | Value |
|---|---| |---|---|
| Status | Implemented | | 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` | | 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`, `M02-GMP-TERRAIN-QUERY-001` consumer migration |
| Owners | Foundation/domain | | Owners | Foundation/domain |
| Last verified | Worktree `work/sindo-main-codex/m01-server-spawn-renderer`, 2026-07-13 | | Last verified | `a45d521`, 2026-07-14 |
| Profiles/capabilities | All profiles; contract version 2 | | Profiles/capabilities | All profiles; contract version 2 |
## Purpose ## Purpose
@@ -86,7 +86,7 @@ Forbidden dependencies:
| Input | `AdtPlacementPosition` | Future ADT 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 | | 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 | `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 | `AdtTileCoordinate`, `AdtTileLocalPosition`, `AdtChunkCoordinate` | `CoordinateMapper` | Streaming/content/terrain-query adapters | New immutable values | Caller-owned references |
| Output | `GodotWorldPosition`, `GodotWorldYaw` | `CoordinateMapper` | Future render/scene adapter | 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 | | 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 |
@@ -115,6 +115,10 @@ flowchart LR
Canonical -->|half extent - Y; Z; half extent - X| Godot[GodotWorldPosition] Canonical -->|half extent - Y; Z; half extent - X| Godot[GodotWorldPosition]
Godot -->|typed direct adapter| Tile Godot -->|typed direct adapter| Tile
Godot -->|typed direct adapter| Local Godot -->|typed direct adapter| Local
Godot --> TerrainQuery[AdtTerrainQuery consumer]
TerrainQuery --> Tile
TerrainQuery --> Local
TerrainQuery --> Chunk
Tile -->|tile plus local| Godot Tile -->|tile plus local| Godot
ServerYaw[ServerWorldYaw] -->|normalize only| CanonicalYaw[CanonicalWowWorldYaw] ServerYaw[ServerWorldYaw] -->|normalize only| CanonicalYaw[CanonicalWowWorldYaw]
CanonicalYaw -->|same numeric world angle| GodotYaw[GodotWorldYaw] CanonicalYaw -->|same numeric world angle| GodotYaw[GodotWorldYaw]
@@ -185,7 +189,8 @@ raw three-number arrays are not an accepted new persistence contract.
- Boundary enforcement: `src/tools/verify_coordinate_conversion_boundaries.gd`. - Boundary enforcement: `src/tools/verify_coordinate_conversion_boundaries.gd`.
- Server-spawn renderer contract: `src/tools/verify_server_spawn_renderer.gd` - Server-spawn renderer contract: `src/tools/verify_server_spawn_renderer.gd`
validates the dedicated manifest against the same pinned fixture before GUI capture. validates the dedicated manifest against the same pinned fixture before GUI capture.
- Integration/E2E: sky, player, streamer and terrain probe use mapper boundaries; - Integration/E2E: sky, player spawn, streamer, terrain probe and the extracted
`AdtTerrainQuery` use mapper boundaries;
`StreamingFocus` provides typed renderer focus, and the pinned AzerothCore `StreamingFocus` provides typed renderer focus, and the pinned AzerothCore
Human Warrior spawn is captured in the Eastern Kingdoms renderer at ADT Human Warrior spawn is captured in the Eastern Kingdoms renderer at ADT
`(32,48)`, chunk `(3,12)`. `(32,48)`, chunk `(3,12)`.
@@ -243,6 +248,7 @@ raw three-number arrays are not an accepted new persistence contract.
| `src/tests/fixtures/coordinate_golden_points.json` | Versioned cross-source values, provenance and tolerances | | `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_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/verify_coordinate_conversion_boundaries.gd` | Repository-wide manual conversion and required-consumer gate |
| `src/gameplay/terrain/adt_terrain_query.gd` | Typed Godot-position consumer for ADT tile/local/chunk lookup |
| `src/tools/server_spawn_render_manifest.json` | Pinned server-spawn camera, player, marker and expected ADT ownership | | `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 | | `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 | | `docs/adr/0001-canonical-world-coordinates.md` | Normative axes, units, boundaries and rollout decision |
+245
View File
@@ -0,0 +1,245 @@
# Local Player Movement
## Metadata
| Field | Value |
|---|---|
| Status | Implemented |
| Target/work package | M02 / M02-GMP-MOVEMENT-001 |
| Owners | Gameplay local movement state; scene composition owns the instance |
| Last verified | `a45d521`, 2026-07-14 |
| Profiles/capabilities | Current render sandbox; production/debug profile gate pending |
## Purpose
Own current local velocity, acceleration and sandbox flight state independently
of the player scene. Convert an immutable `MoveIntent` plus an explicit
Godot-world movement basis into deterministic per-tick displacement without
querying terrain, cameras, input devices or visual assets.
## Non-goals
- Apply world transforms or own a `CharacterBody3D`.
- Query terrain height, collision, water or slopes.
- Implement jump, fall, swim, server prediction or reconciliation.
- Select the player basis versus camera-pivot basis; the scene adapter owns that decision.
- Claim build-12340 movement fidelity from sandbox regression alone.
## Context and boundaries
```mermaid
flowchart LR
Input[MoveIntent] --> Movement[LocalPlayerMovementController]
Basis[Explicit local movement Basis] --> Movement
Delta[Physics delta seconds] --> Movement
Movement --> Displacement[Godot-world displacement]
Movement --> Velocity[Read-only velocity state]
Scene[ThirdPersonWowController] --> Basis
Displacement --> Scene
Scene --> Transform[Player world transform]
Scene --> Terrain[TerrainQuery and ground snap adapter]
Velocity --> Presentation[Visual facing and animation adapter]
```
Allowed dependencies:
- `MoveIntent` from the gameplay input boundary.
- Godot value types `Basis` and `Vector3` for renderer world-space direction math.
- Main-thread scene adapter for basis selection and displacement application.
Forbidden dependencies:
- `Node`, `Resource`, `Input`, `Camera3D`, `ADTLoader` or scene lookup.
- World-coordinate conversion or manual ADT/tile formulas.
- Character assets, animation players, materials, packets or server state.
## Public API
| Symbol | Kind | Purpose | Thread/lifetime | Errors |
|---|---|---|---|---|
| `LocalPlayerMovementController.new(...)` | Constructor | Sets explicit speeds, acceleration and sandbox sprint multiplier | Created by composition root; retained for player scene lifetime | Caller owns configuration validation |
| `godot_world_velocity_units_per_second` | Read-only state | Current Godot-world velocity after the last update | Stable until next mutation on owning thread | None |
| `is_flight_enabled` | Read-only state | Current sandbox free-flight mode | Stable until toggle | None |
| `toggle_sandbox_flight()` | Command | Toggles flight and clears velocity | Owning physics/input thread | Returns new flight state |
| `advance(move_intent, godot_world_movement_basis, delta_seconds)` | Stateful update | Accelerates toward requested velocity and returns displacement for the tick | Owning physics thread; one call per tick | Negative delta is treated as zero |
Constructor units:
| Parameter | Unit/meaning |
|---|---|
| `run_speed_units_per_second` | Forward Godot units per second |
| `backward_speed_units_per_second` | Backward Godot units per second |
| `strafe_speed_units_per_second` | Lateral Godot units per second |
| `flight_vertical_speed_units_per_second` | Sandbox vertical Godot units per second |
| `acceleration_units_per_second_squared` | Velocity change per second |
| `sandbox_sprint_multiplier` | Dimensionless debug multiplier |
## Inputs and outputs
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|---|---|---|---|---|---|
| Input | `MoveIntent` | `PlayerInputSource` | Movement controller | Immutable caller-held value | One physics tick |
| Input | Godot-world `Basis` | Player scene adapter | Movement controller | Value copy | One physics tick |
| Input | Delta seconds | Godot physics loop | Movement controller | Scalar value | One physics tick |
| Input | Flight toggle command | Remappable sandbox action via scene adapter | Movement controller | Synchronous command | Input event dispatch |
| Output | Displacement `Vector3` | Movement controller | Player scene adapter | Value copy | Applied in same tick |
| Output | Velocity `Vector3` | Movement controller | Facing/animation adapter | Read-only value copy | Until next update |
| Output | Flight state | Movement controller | Basis/terrain scene adapter | Read-only boolean | Until next toggle |
Side effects:
- Mutates only controller-owned velocity and flight state.
- Does not mutate scene tree, transforms, resources, filesystem, network or cache.
- The scene adapter remains responsible for transform mutation and ground snap.
## Data flow
```mermaid
flowchart LR
Intent[MoveIntent axes] --> Target[Calculate target velocity]
Basis[Player or camera-pivot Basis] --> Directions[Forward/right directions]
Directions --> Target
Config[Speeds and sprint multiplier] --> Target
Previous[Owned velocity] --> Integrate[move_toward by acceleration × delta]
Target --> Integrate
Integrate --> Current[Updated velocity]
Current --> Step[velocity × delta]
Step --> Displacement[Scene-applied displacement]
```
## Lifecycle/state
```mermaid
stateDiagram-v2
[*] --> GroundedSandbox
GroundedSandbox --> FlyingSandbox: toggle / clear velocity
FlyingSandbox --> GroundedSandbox: toggle / clear velocity
GroundedSandbox --> GroundedSandbox: advance
FlyingSandbox --> FlyingSandbox: advance
```
The names describe the existing sandbox mode only. They are not authoritative
gameplay movement states and do not imply terrain contact or server permission.
## Main sequence
```mermaid
sequenceDiagram
participant Input as PlayerInputSource
participant Scene as ThirdPersonWowController
participant Move as LocalPlayerMovementController
participant Present as Facing/Animation adapter
Input-->>Scene: MoveIntent
Scene->>Move: advance(intent, selected basis, delta)
Move-->>Scene: displacement
Scene->>Scene: apply global position and ground snap
Scene->>Move: godot_world_velocity_units_per_second
Scene->>Present: horizontal motion
```
## Ownership, threading and resources
- The player scene creates and exclusively owns one movement controller.
- Velocity and flight state have the same lifetime as that controller.
- All mutations currently occur on the main input/physics thread.
- Read-only value returns are copies; consumers cannot mutate owned state.
- No Nodes, Resources, RIDs, files, jobs or worker threads are created.
- The supplied `Basis` is a Godot-world direction basis, not a typed world-position contract or coordinate conversion.
## Errors, cancellation and recovery
| Failure | Detection | Behavior | Diagnostic | Recovery |
|---|---|---|---|---|
| Negative physics delta | `advance` guard | Returns zero displacement; velocity unchanged | Unit regression | Resume with valid non-negative delta |
| Missing scene basis owner | Scene composition defect | Controller cannot be called correctly | Scene/parser error or boundary test | Restore explicit scene dependency |
| Flight toggle during motion | Command path | Velocity clears before next step | State-transition regression | Continue from zero velocity |
| Missing terrain data | `TerrainGroundSample.is_available == false` | Scene skips existing ground snap | Stable terrain failure code | Replace/recover query backend |
There is no asynchronous cancellation, retry or rollback. Recreating the
controller resets velocity and flight state deterministically.
## Configuration and capabilities
| Setting/capability | Default | Profile | Runtime mutable | Effect |
|---|---|---|---|---|
| Forward speed | `7.0` units/s | Current sandbox | Fixed for controller lifetime | Target forward velocity |
| Backward speed | `4.5` units/s | Current sandbox | Fixed for controller lifetime | Target backward velocity |
| Strafe speed | `4.5` units/s | Current sandbox | Fixed for controller lifetime | Target lateral velocity |
| Acceleration | `28.0` units/s² | Current sandbox | Fixed for controller lifetime | Acceleration and deceleration |
| Flight vertical speed | `7.0` units/s | Sandbox debug | Fixed for controller lifetime | Vertical free-flight target |
| Sprint multiplier | `6.0` | Sandbox debug | Fixed for controller lifetime | Multiplies planar and vertical targets |
| Camera-relative basis | Selected only while flight is enabled | Sandbox debug | Per tick | Preserves existing pitched flight direction |
## Persistence, cache and migration
Movement state is transient and not serialized. No schema, cache, migration or
saved settings change is introduced. Future reconnect/replay state requires a
separate versioned movement snapshot contract.
## Diagnostics and observability
- Logs: verifier emits `LOCAL_PLAYER_MOVEMENT PASS` or named invariant failures.
- Metrics: none yet; update is constant-time vector math.
- Debug views: current character facing and animation remain observable scene outputs.
- Correlation IDs: not applicable to synchronous local sandbox state.
## Verification
- Unit/contract: `src/tools/verify_local_player_movement.gd` covers forward,
backward, strafe, rotated basis, acceleration, deceleration, sprint, flight,
pitched camera basis, state reset and invalid delta.
- Boundary: verifier rejects Node/Input/Camera/ADT dependencies and movement
integration/state remaining in the player scene.
- Scene integration: `verify_player_input.gd` drives the asset-free player
regression scene through forward motion and immediate flight toggle.
- Fidelity evidence: default values and formulas are regression-locked against
the pre-extraction sandbox. No original-client comparison is claimed.
- Performance budget: constant-time vector math, no per-tick I/O or scene lookup;
`MoveIntent` allocation remains owned by the input package.
## Extension points
- Terrain/collision policy can consume displacement without changing input or velocity ownership.
- A future server-aware predictor may replace this controller behind the scene composition boundary.
- A typed movement snapshot may expose deterministic replay state when M08/M09 require it.
- Sandbox debug capability gating can reject sprint/flight before commands reach this controller.
## Capability status
| Capability | Status | Evidence | Gap/next step |
|---|---|---|---|
| Scene-free local velocity state | Implemented | Pure controller and source boundary regression | Integrate target checklist after review |
| Existing planar acceleration/speeds | Implemented | Exact numeric unit cases and real scene regression | Compare with build 12340 before fidelity claim |
| Existing camera-relative free flight | Implemented | Pitched-basis and toggle/reset cases | Restrict to sandbox profile |
| Terrain height query | Implemented | Typed `TerrainQuery` and injected player regression | Ground-snap policy remains scene-owned |
| Terrain collision movement policy | Planned | Height-only query does not model collision | Add slopes/holes/collision later |
| Jump/fall/swim | Planned | M02/M09 roadmap | Requires terrain/liquid and server contracts |
| Prediction/reconciliation | Planned | M08/M09 roadmap | Requires movement snapshot/network contract |
## Known gaps and risks
- Numeric defaults preserve the existing sandbox but are not original-client evidence.
- Configuration is captured at scene `_ready`; runtime mutation of exported speed
properties does not reconfigure an existing controller.
- Ground snap remains in the player scene, but its ADT data access is now behind
a replaceable `TerrainQuery`.
- Sprint and free flight still lack a typed sandbox capability gate.
- The module uses Godot math value types; a future engine-independent gameplay
predictor may require scalar/domain movement contracts.
## Source map
| Path | Responsibility |
|---|---|
| `src/gameplay/movement/local_player_movement_controller.gd` | Owned velocity/flight state and deterministic integration |
| `src/gameplay/terrain/terrain_query.gd` | Replaceable ground-height input boundary |
| `src/scenes/player/third_person_wow_controller.gd` | Composition, basis selection, displacement/terrain/presentation adapters |
| `src/tools/verify_local_player_movement.gd` | Pure numeric, state-transition and dependency regression |
| `src/tests/scenes/player_input_regression.tscn` | Asset-free integrated player fixture |
| `src/tools/verify_player_input.gd` | Input-to-movement scene regression |
## Related decisions and references
- ADR: none; this follows the existing M02 decomposition boundary.
- Upstream/reference: `targets/02-player-decomposition.md`,
`targets/roadmap/04-gameplay-systems.md`, `docs/ARCHITECTURE.md`.
+215
View File
@@ -0,0 +1,215 @@
# Player Input
## Metadata
| Field | Value |
|---|---|
| Status | Partial |
| Target/work package | M02 / M02-GMP-INPUT-001, M02-GMP-MOVEMENT-001 consumer update |
| Owners | Gameplay input boundary; `sindo-main-codex` for current package |
| Last verified | `435e1c9`, 2026-07-14 |
| Profiles/capabilities | Current render-sandbox defaults; `Blizzlike335` binding semantics not yet verified |
## Purpose
Convert remappable Godot Input Map actions into an immutable, scene-free
`MoveIntent` that can be consumed by the current player controller and a later
independently testable local movement controller.
## Non-goals
- Define authoritative server movement, prediction or reconciliation.
- Own character transform, terrain queries, camera state or animation state.
- Claim that the current W/S/A/D sandbox mapping exactly matches build 12340.
- Make sprint or free flight available to the production compatibility profile;
their profile gate remains a later M02 package.
## Context and boundaries
```mermaid
flowchart LR
Devices[Keyboard and mouse] --> InputMap[Godot Input Map]
InputMap --> Source[PlayerInputSource]
Source --> Intent[MoveIntent]
Intent --> Movement[LocalPlayerMovementController]
Movement --> Controller[ThirdPersonWowController adapter]
Controller --> Camera[Current camera adapter]
```
Allowed dependencies:
- `PlayerInputSource` may read Godot's process-wide `Input` adapter.
- The scene controller may consume `MoveIntent` and camera-specific action names.
- `MoveIntent` may contain scalar axes and request flags only.
Forbidden dependencies:
- `MoveIntent` must not read `Input`, inherit `Node`/`Resource`, or contain world coordinates.
- The input source must not mutate player transforms, camera nodes or animation state.
- Renderer, terrain parsers and network codecs must not read Input Map actions.
## Public API
| Symbol | Kind | Purpose | Thread/lifetime | Errors |
|---|---|---|---|---|
| `MoveIntent` | Immutable value | Carries normalized forward, strafe and vertical axes plus the sandbox sprint request | Created and consumed on the main physics tick; caller retains reference | Constructor clamps axes; no I/O failure |
| `MoveIntent.has_translation()` | Query | Reports whether any translation axis is non-zero | Any thread while value remains immutable | None |
| `PlayerInputActions` | Constants | Provides stable action names shared by configuration and adapters | Process lifetime | Missing project actions are detected by verification |
| `PlayerInputSource.sample_move_intent()` | Adapter method | Samples configured actions for one physics tick | Main thread; returned intent is independent of adapter lifetime | Missing actions resolve to zero strength and are a configuration defect |
| `PlayerInputSource.compose_move_intent(...)` | Pure factory | Clamps strengths, cancels opposites and normalizes diagonal planar input | Any thread with scalar inputs | None |
## Inputs and outputs
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|---|---|---|---|---|---|
| Input | Movement action strengths | Godot `InputMap`/`Input` | `PlayerInputSource` | Engine-owned snapshot | Sampled on main physics tick |
| Input | Mouse action events | Godot `_unhandled_input` dispatch | Current scene controller | Engine-owned event | Current input dispatch only |
| Output | `MoveIntent` | `PlayerInputSource` | `LocalPlayerMovementController` through scene composition | Immutable caller-held value | One physics tick |
| Output | Camera action names | `PlayerInputActions` | Current scene controller | Static constants | Process lifetime |
Side effects:
- `PlayerInputSource` has no side effects beyond reading current engine input.
- The existing controller still mutates player/camera transforms and mouse mode;
those responsibilities are intentionally not moved by this package.
- No filesystem, cache, network, database or renderer-resource mutation occurs.
## Data flow
```mermaid
flowchart LR
Project[project.godot action defaults] --> Map[InputMap]
Remap[User or editor remapping] --> Map
Map -->|movement strengths| Source[PlayerInputSource]
Source -->|clamp cancel normalize| Intent[MoveIntent]
Intent --> Consumer[LocalPlayerMovementController]
Consumer --> Adapter[ThirdPersonWowController]
```
## Lifecycle/state
The adapter is stateless. The scene composition root creates one
`PlayerInputSource` and `LocalPlayerMovementController` in `_ready`; each physics
tick produces a new immutable intent. Flight enabled/disabled state is owned by
the movement controller and is not hidden in the input adapter.
## Main sequence
```mermaid
sequenceDiagram
participant Engine as Godot Input
participant Source as PlayerInputSource
participant Intent as MoveIntent
participant Move as LocalPlayerMovementController
participant Player as ThirdPersonWowController adapter
Engine->>Source: movement action strengths
Source->>Intent: compose normalized axes and requests
Source-->>Player: sample_move_intent()
Player->>Move: advance(intent, selected basis, delta)
Move-->>Player: displacement and velocity state
```
## Ownership, threading and resources
- The controller owns the input-source reference for its scene lifetime.
- Each `MoveIntent` is immutable and retained only by its consumer.
- Sampling and controller mutation occur on the main physics thread.
- The module creates no Nodes, Resources, RIDs, workers or background jobs.
- Input Map definitions are project configuration; runtime remapping remains
engine-owned and does not mutate the domain value.
## Errors, cancellation and recovery
| Failure | Detection | Behavior | Diagnostic | Recovery |
|---|---|---|---|---|
| Required action missing | Headless contract verifier | Godot returns zero input for that action | `PLAYER_INPUT` failure naming action | Restore action or user mapping |
| Conflicting opposite actions | Pure composition | Strengths cancel deterministically | Covered by contract test | Release/remap one action |
| Strength outside range | Pure composition | Value clamps to `[0, 1]` before axis calculation | Covered by contract test | Input adapter may be corrected independently |
| Controller disabled/unloaded | Scene lifecycle | Sampling stops with physics processing | Existing scene lifecycle | Re-enable or recreate scene |
There is no asynchronous operation to cancel and no persisted state to roll back.
## Configuration and capabilities
| Setting/capability | Default | Profile | Runtime mutable | Effect |
|---|---|---|---|---|
| Forward/backward | Physical W/S | Current render sandbox | Yes, through Input Map | Produces signed forward axis |
| Strafe left/right | Physical A/D | Current render sandbox | Yes | Produces signed right axis |
| Camera rotate | Right mouse button | Current render sandbox | Yes | Captures/releases mouse for orbit |
| Camera zoom | Mouse wheel | Current render sandbox | Yes | Adjusts current camera distance |
| Debug sprint | Shift | Sandbox debug only by intent; profile gate pending | Yes | Requests existing speed multiplier |
| Debug flight up/down/toggle | E/Q/Space | Sandbox debug only by intent; profile gate pending | Yes | Requests existing free-flight controls |
## Persistence, cache and migration
The action names are additive project configuration. No saved binding schema,
cache or migration exists yet. Renaming an action is a contract change and must
provide a settings migration once user settings are persisted.
## Diagnostics and observability
- Logs: dedicated verifier emits `PLAYER_INPUT PASS` or one failure per invariant.
- Metrics: none; sampling cost is one small value allocation per physics tick.
- Debug views: none.
- Correlation IDs: not applicable to local synchronous input.
## Verification
- Unit/contract tests: `src/tools/verify_player_input.gd` validates all actions,
default bindings, axis cancellation/clamping/normalization and debug request flags.
- Integration/E2E: `src/tests/scenes/player_input_regression.tscn` is loaded by
the verifier, which drives forward, camera-zoom and immediate sandbox-flight
actions through the real scene controller and also rejects direct
physical-key polling.
- Fidelity evidence: current sandbox defaults retain W/S/A/D, E/Q, Shift, Space,
right mouse and wheel bindings. This is observable-regression coverage only.
- Performance budgets: no I/O, jobs or scene lookup per sample; one immutable
intent allocation per physics tick.
- Manual diagnostics: run the Eastern Kingdoms scene and remap one movement
action in Project Settings before checking movement.
## Extension points
- A gamepad/accessibility adapter may call `compose_move_intent` without changing
movement consumers.
- A later input-context owner may suppress gameplay actions while preserving the
same intent contract.
- A future server-aware movement predictor may replace the current local
movement consumer without changing `PlayerInputSource`.
## Capability status
| Capability | Status | Evidence | Gap/next step |
|---|---|---|---|
| Remappable current sandbox controls | Implemented | `verify_player_input.gd` action/default checks | Add persisted user binding settings later |
| `PlayerInputSource → MoveIntent` seam | Implemented | Pure composition and controller boundary checks | Local movement consumer is now extracted |
| Exact 3.3.5a default semantics | Unknown | No original-client binding fixture in this package | Capture build-12340 defaults and mouse-turn/strafe policy |
| Production profile exclusion of sprint/flight | Partial | Debug actions are named explicitly | Add typed profile/capability gate in M02 |
| Jump/fall/swim/fly gameplay semantics | Planned | M02 target and gameplay roadmap | Implement after terrain/movement state extraction |
## Known gaps and risks
- The defaults preserve the pre-M02 sandbox behavior, not verified original-client semantics.
- Sprint and free flight are still executable by the sandbox controller until a
typed build-profile gate is introduced.
- Camera input is action-mapped but camera state/collision remains in the monolithic controller.
- There is no persisted user keybinding format or UI yet.
## Source map
| Path | Responsibility |
|---|---|
| `project.godot` | Additive default Input Map bindings |
| `src/domain/input/move_intent.gd` | Immutable locomotion request contract |
| `src/gameplay/input/player_input_actions.gd` | Stable project action names |
| `src/gameplay/input/player_input_source.gd` | Engine Input Map adapter and pure composition |
| `src/gameplay/movement/local_player_movement_controller.gd` | Scene-free movement consumer |
| `src/scenes/player/third_person_wow_controller.gd` | Composition and camera/input-event adapter |
| `src/tests/scenes/player_input_regression.tscn` | Asset-free controller movement/camera regression fixture |
| `src/tools/verify_player_input.gd` | Headless contract/integration regression |
## Related decisions and references
- ADR: none; this implements the existing architecture and M02 seam.
- Upstream/reference: `targets/02-player-decomposition.md`,
`targets/roadmap/04-gameplay-systems.md`, `docs/ARCHITECTURE.md`.
+251
View File
@@ -0,0 +1,251 @@
# Terrain Query
## Metadata
| Field | Value |
|---|---|
| Status | Implemented |
| Target/work package | M02 / M02-GMP-TERRAIN-QUERY-001 |
| Owners | Gameplay terrain-query contract; ADT adapter owns parsed tile cache |
| Last verified | `a45d521`, 2026-07-14 |
| Profiles/capabilities | Current sandbox ADT ground height; renderer/physics backend planned |
## Purpose
Provide a replaceable, scene-free ground-height query for player movement.
Isolate native ADT loading, per-tile caching, chunk selection and legacy outer
height-grid interpolation from the player scene behind a typed
`GodotWorldPosition → TerrainGroundSample` contract.
## Non-goals
- Own player transforms, movement velocity or ground-snap policy.
- Provide collision normals, slopes, holes, liquids, WMO/M2 collision or ray queries.
- Change ADT topology, coordinate conversion, renderer caches or native parser format.
- Claim original-client terrain-contact parity from height regression alone.
- Couple gameplay to the monolithic streaming renderer before a public backend exists.
## Context and boundaries
```mermaid
flowchart LR
Scene[ThirdPersonWowController adapter] --> Position[GodotWorldPosition]
Position --> Contract[TerrainQuery]
Contract --> Adapter[AdtTerrainQuery]
Adapter --> Mapper[CoordinateMapper]
Adapter --> Native[ADTLoader]
Native --> Tile[ADT tile Dictionary]
Tile --> Cache[Owned tile cache]
Cache --> Sample[TerrainGroundSample]
Sample --> Scene
Scene --> Snap[Existing ground-snap policy]
```
Allowed dependencies:
- Typed `GodotWorldPosition` and `CoordinateMapper` contracts.
- Existing native `ADTLoader` at the ADT adapter boundary.
- Dynamic dictionaries only inside the native-format adapter.
- Player scene composition may inject any `TerrainQuery` implementation.
Forbidden dependencies:
- `TerrainQuery` contract depending on Nodes, cameras, input or renderer state.
- Player scene loading/parsing ADT data or owning a parsed tile cache.
- Manual WoW/Godot/ADT world-coordinate conversion outside `CoordinateMapper`.
- Terrain query mutating transforms, gameplay movement state or visual meshes.
## Public API
| Symbol | Kind | Purpose | Thread/lifetime | Errors |
|---|---|---|---|---|
| `TerrainGroundSample.available(height_units)` | Immutable value factory | Creates a finite Godot-world ground height | Any thread; caller-held value | Non-finite height becomes unavailable |
| `TerrainGroundSample.unavailable(failure_code)` | Immutable value factory | Creates explicit unavailable result | Any thread; caller-held value | Empty code normalizes to `terrain_unavailable` |
| `TerrainQuery.sample_ground_height(position)` | Replaceable boundary | Samples ground at typed Godot world position | Implementation-defined; current adapter main-thread owned | Base reports `terrain_query_not_implemented` |
| `AdtTerrainQuery.new(extracted_directory, map_directory_name, loader_override)` | Adapter constructor | Configures one map and optional test/data-source loader | Query lifetime | Production validates native loader and file presence lazily |
| `AdtTerrainQuery.sample_ground_height(position)` | Adapter method | Loads/caches tile and interpolates ADT outer heights | Main thread; cache lives with query | Returns stable failure code |
| `ThirdPersonWowController.set_terrain_query(query)` | Composition method | Replaces terrain backend independently of movement/presentation | Call before scene ready or on main thread | Null is rejected and current query retained |
## Inputs and outputs
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|---|---|---|---|---|---|
| Input | `GodotWorldPosition` | Player scene adapter | `TerrainQuery` | Immutable caller-held value | One query |
| Input | Extracted directory/map name | Scene composition | `AdtTerrainQuery` | Copied strings | Query lifetime |
| Input | ADT file/dictionary | Filesystem/native loader or injected loader | `AdtTerrainQuery` | Adapter-owned cached dictionary | Query lifetime |
| Output | `TerrainGroundSample` | Terrain query | Player ground-snap adapter | Immutable caller-held value | One query |
| Output | Failure code | Terrain query | Diagnostics/tests | Immutable `StringName` | Sample lifetime |
Side effects:
- Production adapter performs lazy file existence check and native ADT parse on first tile query.
- Adapter mutates only its per-query tile/failure caches.
- No scene tree, transform, renderer RID, network, database or persisted setting mutation occurs.
## Data flow
```mermaid
flowchart LR
Position[GodotWorldPosition] --> TileCoord[CoordinateMapper tile/local/chunk]
TileCoord --> Lookup{Tile cached?}
Lookup -->|no| Load[ADTLoader or injected loader]
Load --> Cache[Cache Dictionary or unavailable result]
Lookup -->|yes| Cache
Cache --> Chunk[Select MCNK by origin]
Chunk --> Heights[Validate 145 heights]
Heights --> Bilinear[Interpolate 9x9 outer grid]
Bilinear --> Available[TerrainGroundSample available]
Cache -->|missing/invalid| Unavailable[TerrainGroundSample unavailable]
```
## Lifecycle/state
```mermaid
stateDiagram-v2
[*] --> TileUnknown
TileUnknown --> TileAvailable: first query / successful load
TileUnknown --> TileUnavailable: first query / missing or failed
TileAvailable --> TileAvailable: cached queries
TileUnavailable --> TileUnavailable: cached queries
TileAvailable --> [*]: query released
TileUnavailable --> [*]: query released
```
Unavailable tiles are cached intentionally to avoid repeated filesystem/native
work each physics tick. Recovery after files appear requires replacing the query
instance; hot-reload invalidation is outside this M02 package.
## Main sequence
```mermaid
sequenceDiagram
participant Player as ThirdPersonWowController
participant Query as TerrainQuery
participant ADT as AdtTerrainQuery
participant Mapper as CoordinateMapper
participant Native as ADTLoader
Player->>Query: sample_ground_height(GodotWorldPosition)
Query->>ADT: implementation dispatch
ADT->>Mapper: tile/local/chunk coordinates
alt tile not cached
ADT->>Native: load_adt(absolute path)
Native-->>ADT: ADT Dictionary
end
ADT->>ADT: select chunk and interpolate heights
ADT-->>Player: TerrainGroundSample
Player->>Player: apply existing offset/snap if available
```
## Ownership, threading and resources
- Player scene owns the active `TerrainQuery` reference.
- `AdtTerrainQuery` exclusively owns tile/failure dictionaries until released.
- Current production calls and cache mutations occur on the main physics thread.
- Native loader result dictionaries do not cross the adapter boundary.
- Samples and typed positions are immutable caller-held values.
- The module creates no Nodes, Resources, RIDs or background jobs.
- Future worker-backed queries require an explicit async/result contract rather
than concurrent mutation of the current dictionaries.
## Errors, cancellation and recovery
| Failure | Detection | Behavior | Diagnostic | Recovery |
|---|---|---|---|---|
| Base contract used directly | Base method | Unavailable sample | `terrain_query_not_implemented` | Inject implementation |
| Native loader absent | ClassDB check | Cache unavailable tile | `adt_loader_unavailable` | Load extension and replace query |
| ADT file absent | File check | Cache unavailable tile | `adt_source_missing` | Restore corpus and replace query |
| Native parse empty/fails | Result validation | Cache unavailable tile | `adt_load_failed` | Inspect source/parser; replace query |
| Injected loader returns wrong type | Type check | Cache unavailable tile | `adt_loader_result_invalid` | Fix adapter |
| Chunk absent | Chunk lookup | Unavailable sample | `adt_chunk_missing` | Validate ADT dictionary |
| Height array shorter than 145 | Size check | Unavailable sample | `adt_chunk_heights_invalid` | Fix parser/source |
| Non-finite interpolated height | Sample invariant | Unavailable sample | `terrain_height_not_finite` | Inspect source values |
| Null query injection | Scene guard | Existing query retained | Player composition error | Pass valid query |
There are no asynchronous operations to cancel. Replacing/releasing the query
is the deterministic cache-reset and recovery path.
## Configuration and capabilities
| Setting/capability | Default | Profile | Runtime mutable | Effect |
|---|---|---|---|---|
| Extracted directory | Player `extracted_dir` | Current sandbox | Captured at creation | ADT source root |
| Map directory name | Player `map_name` | Current sandbox | Captured at creation | ADT filename/path |
| Loader override | Invalid callable | Test/custom data source | Constructor only | Bypasses production ClassDB/file loading |
| Tile cache | Enabled | All current uses | Cleared by replacing query | Avoids repeated parse/failure work |
| Height policy | 9x9 outer-grid bilinear | Current sandbox | Fixed | Preserves pre-extraction behavior |
## Persistence, cache and migration
The cache is in-memory and unversioned because it holds native loader output for
one query lifetime. No disk cache, schema or migration changes are introduced.
Existing ADT/native/cache format versions remain unchanged.
## Diagnostics and observability
- Logs: dedicated verifier emits `TERRAIN_QUERY PASS` or named failures.
- Structured status: every unavailable sample has a stable `failure_code`.
- Metrics: synthetic verifier counts loader calls to prove one load per tile.
- Debug views: none.
- Correlation IDs: not applicable to synchronous local query.
## Verification
- Contract: available/unavailable/base/non-finite result invariants.
- Pure synthetic adapter: typed coordinate mapping, exact chunk selection,
145-height layout and bilinear interpolation within `0.002` units (Vector3
source precision), plus cached second query.
- Failures: empty tile and invalid height array produce stable codes.
- Integration: asset-free player scene accepts injected flat query and preserves
spawn offset `0.05` plus physics ground snap.
- Boundary: source regression rejects ADT loader/cache/chunk helpers in player.
- Fidelity evidence: existing interpolation and snap behavior only; no
original-client or collision parity claim.
- Performance budget: one dictionary cache lookup and scalar interpolation per
cached query; native parse only on first tile access.
## Extension points
- Streaming renderer or physics backend may implement `TerrainQuery` without changing player/movement.
- Future result may grow separate slope, surface, liquid or collision contracts;
incompatible additions require a versioned contract rather than Dictionary fields.
- Test/authoring data sources may use constructor loader override.
- Async streaming requires a separate availability/update model.
## Capability status
| Capability | Status | Evidence | Gap/next step |
|---|---|---|---|
| Typed replaceable ground-height query | Implemented | Contract and injected player regression | Integrate target checklist after review |
| Existing ADT height interpolation | Implemented | Synthetic fractional-grid fixture | Compare terrain contact with build 12340 |
| Per-tile success/failure cache | Implemented | Loader call-count regression | Add explicit invalidation only with authoring/hot reload |
| Renderer/streaming cache backend | Planned | Boundary permits replacement | M03 renderer facade/public terrain backend |
| Holes/slopes/collision | Planned | Outside height-only contract | Later movement/physics package |
| Liquid/swim query | Planned | Outside contract | M09/M12 world gameplay |
## Known gaps and risks
- Bilinear outer-grid height is the inherited sandbox approximation; exact ADT
triangle choice, holes and collision are not represented.
- Query is synchronous; first access may parse an ADT on the main thread exactly
as before extraction. A streaming/backend replacement is future work.
- Unavailable results remain cached until query replacement.
- Player still owns ground offset/snap policy; only data access is extracted.
- Existing native dictionaries remain dynamic inside the adapter.
## Source map
| Path | Responsibility |
|---|---|
| `src/gameplay/terrain/terrain_ground_sample.gd` | Immutable available/unavailable result |
| `src/gameplay/terrain/terrain_query.gd` | Replaceable typed query boundary |
| `src/gameplay/terrain/adt_terrain_query.gd` | Native ADT adapter, cache, chunk selection and interpolation |
| `src/scenes/player/third_person_wow_controller.gd` | Query composition and existing ground-snap consumer |
| `src/tools/verify_terrain_query.gd` | Synthetic contract/cache/failure/injection regression |
| `src/tests/scenes/player_input_regression.tscn` | Asset-free player composition fixture |
## Related decisions and references
- ADR: none; no coordinate, format or authority decision changed.
- Upstream/reference: `targets/02-player-decomposition.md`,
`targets/roadmap/02-rendering-and-graphics.md`,
`targets/roadmap/04-gameplay-systems.md`, `docs/ARCHITECTURE.md`.
+63
View File
@@ -19,6 +19,69 @@ config/icon="res://icon.svg"
enabled=PackedStringArray("res://addons/mpq_extractor/plugin.cfg") enabled=PackedStringArray("res://addons/mpq_extractor/plugin.cfg")
[input]
openwc_player_move_forward={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
]
}
openwc_player_move_backward={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
openwc_player_strafe_left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
openwc_player_strafe_right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
]
}
openwc_player_debug_fly_up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
]
}
openwc_player_debug_fly_down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
]
}
openwc_player_debug_sprint={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194325,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
openwc_player_debug_toggle_flight={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":32,"key_label":32,"unicode":32,"location":0,"echo":false,"script":null)
]
}
openwc_player_camera_rotate={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
openwc_player_camera_zoom_in={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
openwc_player_camera_zoom_out={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
openwc_player_release_cursor={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[physics] [physics]
3d/physics_engine="Jolt Physics" 3d/physics_engine="Jolt Physics"
File diff suppressed because it is too large Load Diff
-676
View File
@@ -1,676 +0,0 @@
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
-66
View File
@@ -1,66 +0,0 @@
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)
-536
View File
@@ -1,536 +0,0 @@
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
+47
View File
@@ -0,0 +1,47 @@
class_name MoveIntent
extends RefCounted
## Immutable player locomotion request expressed in character-local axes.
## Axis values are normalized to `[-1, 1]`: forward/right/up are positive.
## The intent contains no world coordinates, engine input events or presentation state.
var forward_axis: float:
get:
return _forward_axis
var strafe_axis: float:
get:
return _strafe_axis
var vertical_axis: float:
get:
return _vertical_axis
var is_sprint_requested: bool:
get:
return _is_sprint_requested
var _forward_axis: float
var _strafe_axis: float
var _vertical_axis: float
var _is_sprint_requested: bool
## Creates one frame's movement request without retaining mutable input state.
func _init(
forward_axis_value: float = 0.0,
strafe_axis_value: float = 0.0,
vertical_axis_value: float = 0.0,
sprint_requested: bool = false
) -> void:
_forward_axis = clampf(forward_axis_value, -1.0, 1.0)
_strafe_axis = clampf(strafe_axis_value, -1.0, 1.0)
_vertical_axis = clampf(vertical_axis_value, -1.0, 1.0)
_is_sprint_requested = sprint_requested
## Returns true when the intent requests planar or vertical translation.
func has_translation() -> bool:
return not is_zero_approx(_forward_axis) \
or not is_zero_approx(_strafe_axis) \
or not is_zero_approx(_vertical_axis)
+1
View File
@@ -0,0 +1 @@
uid://btk7brcavbeec
@@ -0,0 +1,34 @@
class_name PlayerInputActions
extends RefCounted
## Stable Input Map action names consumed by the runtime player input adapter.
## Defaults preserve the current render-sandbox controls; users may remap every
## action through Godot's Input Map without changing gameplay code.
const MOVE_FORWARD := &"openwc_player_move_forward"
const MOVE_BACKWARD := &"openwc_player_move_backward"
const STRAFE_LEFT := &"openwc_player_strafe_left"
const STRAFE_RIGHT := &"openwc_player_strafe_right"
const DEBUG_FLY_UP := &"openwc_player_debug_fly_up"
const DEBUG_FLY_DOWN := &"openwc_player_debug_fly_down"
const DEBUG_SPRINT := &"openwc_player_debug_sprint"
const DEBUG_TOGGLE_FLIGHT := &"openwc_player_debug_toggle_flight"
const CAMERA_ROTATE := &"openwc_player_camera_rotate"
const CAMERA_ZOOM_IN := &"openwc_player_camera_zoom_in"
const CAMERA_ZOOM_OUT := &"openwc_player_camera_zoom_out"
const RELEASE_CURSOR := &"openwc_player_release_cursor"
const REQUIRED_ACTIONS: Array[StringName] = [
MOVE_FORWARD,
MOVE_BACKWARD,
STRAFE_LEFT,
STRAFE_RIGHT,
DEBUG_FLY_UP,
DEBUG_FLY_DOWN,
DEBUG_SPRINT,
DEBUG_TOGGLE_FLIGHT,
CAMERA_ROTATE,
CAMERA_ZOOM_IN,
CAMERA_ZOOM_OUT,
RELEASE_CURSOR,
]
@@ -0,0 +1 @@
uid://bbhtyxm428bkm
+45
View File
@@ -0,0 +1,45 @@
class_name PlayerInputSource
extends RefCounted
## Converts remappable Godot Input Map actions into immutable [MoveIntent] values.
## This adapter owns no movement state and may be replaced independently of the
## local movement controller.
## Samples the current Input singleton state for one physics tick.
func sample_move_intent() -> MoveIntent:
return compose_move_intent(
Input.get_action_strength(PlayerInputActions.MOVE_FORWARD),
Input.get_action_strength(PlayerInputActions.MOVE_BACKWARD),
Input.get_action_strength(PlayerInputActions.STRAFE_LEFT),
Input.get_action_strength(PlayerInputActions.STRAFE_RIGHT),
Input.get_action_strength(PlayerInputActions.DEBUG_FLY_UP),
Input.get_action_strength(PlayerInputActions.DEBUG_FLY_DOWN),
Input.is_action_pressed(PlayerInputActions.DEBUG_SPRINT)
)
## Builds a normalized intent from action strengths for deterministic tests and
## alternative input adapters. Strengths outside `[0, 1]` are clamped.
static func compose_move_intent(
forward_strength: float,
backward_strength: float,
strafe_left_strength: float,
strafe_right_strength: float,
fly_up_strength: float,
fly_down_strength: float,
sprint_requested: bool
) -> MoveIntent:
var planar_axis := Vector2(
clampf(strafe_right_strength, 0.0, 1.0) - clampf(strafe_left_strength, 0.0, 1.0),
clampf(forward_strength, 0.0, 1.0) - clampf(backward_strength, 0.0, 1.0)
)
if planar_axis.length_squared() > 1.0:
planar_axis = planar_axis.normalized()
var vertical_axis := clampf(fly_up_strength, 0.0, 1.0) - clampf(fly_down_strength, 0.0, 1.0)
return MoveIntent.new(
planar_axis.y,
planar_axis.x,
vertical_axis,
sprint_requested
)
@@ -0,0 +1 @@
uid://b050i2lnei8qq
@@ -0,0 +1,97 @@
class_name LocalPlayerMovementController
extends RefCounted
## Scene-free state and velocity integrator for the current local sandbox player.
## Direction inputs use a Godot-world movement basis selected by the scene
## adapter. This class does not discover Nodes, query terrain or mutate transforms.
var godot_world_velocity_units_per_second: Vector3:
get:
return _godot_world_velocity_units_per_second
var is_flight_enabled: bool:
get:
return _is_flight_enabled
var _run_speed_units_per_second: float
var _backward_speed_units_per_second: float
var _strafe_speed_units_per_second: float
var _flight_vertical_speed_units_per_second: float
var _acceleration_units_per_second_squared: float
var _sandbox_sprint_multiplier: float
var _godot_world_velocity_units_per_second := Vector3.ZERO
var _is_flight_enabled := false
## Creates a movement state with explicit Godot-unit speeds and acceleration.
## The current compatibility renderer treats one Godot unit as one WoW yard.
func _init(
run_speed_units_per_second: float,
backward_speed_units_per_second: float,
strafe_speed_units_per_second: float,
flight_vertical_speed_units_per_second: float,
acceleration_units_per_second_squared: float,
sandbox_sprint_multiplier: float
) -> void:
_run_speed_units_per_second = run_speed_units_per_second
_backward_speed_units_per_second = backward_speed_units_per_second
_strafe_speed_units_per_second = strafe_speed_units_per_second
_flight_vertical_speed_units_per_second = flight_vertical_speed_units_per_second
_acceleration_units_per_second_squared = acceleration_units_per_second_squared
_sandbox_sprint_multiplier = sandbox_sprint_multiplier
## Toggles sandbox free flight and clears velocity exactly like the pre-M02 controller.
## Returns the new flight state.
func toggle_sandbox_flight() -> bool:
_is_flight_enabled = not _is_flight_enabled
_godot_world_velocity_units_per_second = Vector3.ZERO
return _is_flight_enabled
## Advances velocity by one physics step and returns local-world displacement.
## `godot_world_movement_basis` is the player basis on ground and camera-pivot basis in flight.
## Negative delta values are treated as zero and do not mutate velocity.
func advance(
move_intent: MoveIntent,
godot_world_movement_basis: Basis,
delta_seconds: float
) -> Vector3:
var safe_delta_seconds := maxf(delta_seconds, 0.0)
if is_zero_approx(safe_delta_seconds):
return Vector3.ZERO
var target_velocity := _calculate_target_velocity(move_intent, godot_world_movement_basis)
_godot_world_velocity_units_per_second = _godot_world_velocity_units_per_second.move_toward(
target_velocity,
_acceleration_units_per_second_squared * safe_delta_seconds
)
return _godot_world_velocity_units_per_second * safe_delta_seconds
func _calculate_target_velocity(move_intent: MoveIntent, godot_world_movement_basis: Basis) -> Vector3:
var forward_direction := -godot_world_movement_basis.z
var right_direction := godot_world_movement_basis.x
if not _is_flight_enabled:
forward_direction.y = 0.0
right_direction.y = 0.0
forward_direction = forward_direction.normalized()
right_direction = right_direction.normalized()
var forward_speed := (
_run_speed_units_per_second
if move_intent.forward_axis > 0.0
else _backward_speed_units_per_second
)
var speed_multiplier := _sandbox_sprint_multiplier if move_intent.is_sprint_requested else 1.0
var target_velocity := (
forward_direction * move_intent.forward_axis * forward_speed
+ right_direction * move_intent.strafe_axis * _strafe_speed_units_per_second
) * speed_multiplier
if _is_flight_enabled:
target_velocity.y += (
move_intent.vertical_axis
* _flight_vertical_speed_units_per_second
* speed_multiplier
)
return target_velocity
@@ -0,0 +1 @@
uid://dxlx5kloh7p5c
+166
View File
@@ -0,0 +1,166 @@
class_name AdtTerrainQuery
extends TerrainQuery
## TerrainQuery adapter for existing native ADT dictionaries.
## Parsed tiles, including unavailable results, are cached for this query's
## lifetime. The adapter is main-thread owned and creates no scene resources.
const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordinate_mapper.gd")
const CHUNK_SIZE_UNITS := COORDINATE_MAPPER_SCRIPT.ADT_CHUNK_SIZE_YARDS
const OUTER_GRID_UNIT_SIZE := CHUNK_SIZE_UNITS / 8.0
var _extracted_directory: String
var _map_directory_name: String
var _adt_tile_loader_override: Callable
var _adt_tile_cache: Dictionary = {}
var _failure_code_by_tile_key: Dictionary = {}
## Creates an ADT query for one map. `adt_tile_loader_override` is an optional
## test/data-source seam receiving the absolute ADT path and returning a Dictionary.
func _init(
extracted_directory: String,
map_directory_name: String,
adt_tile_loader_override: Callable = Callable()
) -> void:
_extracted_directory = extracted_directory
_map_directory_name = map_directory_name
_adt_tile_loader_override = adt_tile_loader_override
## Samples the existing 9x9 outer-height grid with bilinear interpolation.
func sample_ground_height(godot_world_position: GodotWorldPosition) -> TerrainGroundSample:
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile(godot_world_position)
var tile_local_position = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile_local(godot_world_position)
var chunk_coordinate = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_chunk(
tile_coordinate,
tile_local_position
)
var tile_key := _tile_key(tile_coordinate.tile_x, tile_coordinate.tile_y)
var adt_tile_data := _load_adt_tile(tile_coordinate.tile_x, tile_coordinate.tile_y)
if adt_tile_data.is_empty():
return TerrainGroundSample.unavailable(
_failure_code_by_tile_key.get(tile_key, &"adt_tile_unavailable")
)
var tile_origin := _find_tile_origin(adt_tile_data)
var chunk := _find_chunk(
adt_tile_data,
clampi(chunk_coordinate.chunk_x, 0, 15),
clampi(chunk_coordinate.chunk_y, 0, 15),
tile_origin
)
if chunk.is_empty():
return TerrainGroundSample.unavailable(&"adt_chunk_missing")
var heights: PackedFloat32Array = chunk.get("heights", PackedFloat32Array())
if heights.size() < 145:
return TerrainGroundSample.unavailable(&"adt_chunk_heights_invalid")
var chunk_origin: Vector3 = chunk.get("origin", Vector3.ZERO)
var chunk_local_x := godot_world_position.x_units - chunk_origin.x
var chunk_local_z := godot_world_position.z_units - chunk_origin.z
var grid_x := clampf(chunk_local_x / OUTER_GRID_UNIT_SIZE, 0.0, 8.0)
var grid_z := clampf(chunk_local_z / OUTER_GRID_UNIT_SIZE, 0.0, 8.0)
var x0 := clampi(int(floor(grid_x)), 0, 8)
var z0 := clampi(int(floor(grid_z)), 0, 8)
var x1 := mini(x0 + 1, 8)
var z1 := mini(z0 + 1, 8)
var fraction_x := grid_x - float(x0)
var fraction_z := grid_z - float(z0)
var height_x0 := lerpf(
heights[_outer_height_index(z0, x0)],
heights[_outer_height_index(z0, x1)],
fraction_x
)
var height_x1 := lerpf(
heights[_outer_height_index(z1, x0)],
heights[_outer_height_index(z1, x1)],
fraction_x
)
return TerrainGroundSample.available(
chunk_origin.y + lerpf(height_x0, height_x1, fraction_z)
)
func _load_adt_tile(tile_x: int, tile_y: int) -> Dictionary:
var tile_key := _tile_key(tile_x, tile_y)
if _adt_tile_cache.has(tile_key):
return _adt_tile_cache[tile_key]
var resource_path := _extracted_directory.path_join(
"World/Maps/%s/%s_%d_%d.adt" % [_map_directory_name, _map_directory_name, tile_x, tile_y]
)
var absolute_path := ProjectSettings.globalize_path(resource_path)
var adt_tile_data: Dictionary = {}
var failure_code: StringName = &""
if _adt_tile_loader_override.is_valid():
var override_result = _adt_tile_loader_override.call(absolute_path)
if override_result is Dictionary:
adt_tile_data = override_result
else:
failure_code = &"adt_loader_result_invalid"
elif not ClassDB.class_exists("ADTLoader"):
failure_code = &"adt_loader_unavailable"
elif not FileAccess.file_exists(absolute_path):
failure_code = &"adt_source_missing"
else:
var loader = ClassDB.instantiate("ADTLoader")
if loader != null:
var load_result = loader.call("load_adt", absolute_path)
if load_result is Dictionary:
adt_tile_data = load_result
if adt_tile_data.is_empty():
failure_code = &"adt_load_failed"
if adt_tile_data.is_empty() and failure_code.is_empty():
failure_code = &"adt_tile_unavailable"
_adt_tile_cache[tile_key] = adt_tile_data
_failure_code_by_tile_key[tile_key] = failure_code
return adt_tile_data
func _find_chunk(
adt_tile_data: Dictionary,
chunk_x: int,
chunk_y: int,
tile_origin: Vector3
) -> Dictionary:
for chunk in adt_tile_data.get("chunks", []) as Array:
if chunk.is_empty():
continue
var chunk_origin: Vector3 = chunk.get("origin", Vector3.ZERO)
var local_origin := chunk_origin - tile_origin
var candidate_chunk_x := clampi(int(round(local_origin.x / CHUNK_SIZE_UNITS)), 0, 15)
var candidate_chunk_y := clampi(int(round(local_origin.z / CHUNK_SIZE_UNITS)), 0, 15)
if candidate_chunk_x == chunk_x and candidate_chunk_y == chunk_y:
return chunk
return {}
func _find_tile_origin(adt_tile_data: Dictionary) -> Vector3:
var has_origin := false
var minimum_x := 0.0
var minimum_z := 0.0
for chunk in adt_tile_data.get("chunks", []) as Array:
if chunk.is_empty():
continue
var chunk_origin: Vector3 = chunk.get("origin", Vector3.ZERO)
if not has_origin:
minimum_x = chunk_origin.x
minimum_z = chunk_origin.z
has_origin = true
else:
minimum_x = minf(minimum_x, chunk_origin.x)
minimum_z = minf(minimum_z, chunk_origin.z)
return Vector3(minimum_x, 0.0, minimum_z) if has_origin else Vector3.ZERO
func _tile_key(tile_x: int, tile_y: int) -> String:
return "%d_%d" % [tile_x, tile_y]
func _outer_height_index(row: int, column: int) -> int:
return row * 17 + column
@@ -0,0 +1 @@
uid://cq7scvxqw6ffm
@@ -0,0 +1,49 @@
class_name TerrainGroundSample
extends RefCounted
## Immutable result of a terrain ground-height query in Godot world units.
## An unavailable sample carries a stable failure code instead of overloading a
## numeric height with `NAN` at the public boundary.
var is_available: bool:
get:
return _is_available
var height_units: float:
get:
return _height_units
var failure_code: StringName:
get:
return _failure_code
var _is_available: bool
var _height_units: float
var _failure_code: StringName
## Creates an available ground sample in Godot world units.
static func available(height_units_value: float) -> TerrainGroundSample:
return TerrainGroundSample.new(true, height_units_value, &"")
## Creates an unavailable sample with a stable diagnostic code.
static func unavailable(failure_code_value: StringName) -> TerrainGroundSample:
return TerrainGroundSample.new(false, 0.0, failure_code_value)
## Normalizes factory inputs so available samples are finite and unavailable
## samples always carry a non-empty failure code.
func _init(
is_available_value: bool,
height_units_value: float,
failure_code_value: StringName
) -> void:
_is_available = is_available_value and is_finite(height_units_value)
_height_units = height_units_value if _is_available else 0.0
if _is_available:
_failure_code = &""
elif not is_finite(height_units_value):
_failure_code = &"terrain_height_not_finite"
else:
_failure_code = failure_code_value if not failure_code_value.is_empty() else &"terrain_unavailable"
@@ -0,0 +1 @@
uid://boe5qkip6ffku
+12
View File
@@ -0,0 +1,12 @@
class_name TerrainQuery
extends RefCounted
## Replaceable scene-free boundary for gameplay terrain height sampling.
## Implementations receive a typed Godot world position and must return an
## explicit available/unavailable result without mutating the caller.
## Samples terrain ground height at a typed Godot world position.
## The base implementation reports `terrain_query_not_implemented`.
func sample_ground_height(_godot_world_position: GodotWorldPosition) -> TerrainGroundSample:
return TerrainGroundSample.unavailable(&"terrain_query_not_implemented")
@@ -0,0 +1 @@
uid://d3f2hetuo342q
+65 -171
View File
@@ -7,9 +7,10 @@ const COORDINATE_MAPPER_SCRIPT := preload("res://src/domain/coordinates/coordina
const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.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_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 ADT_TILE_LOCAL_POSITION_SCRIPT := preload("res://src/domain/coordinates/adt_tile_local_position.gd")
const PLAYER_INPUT_SOURCE_SCRIPT := preload("res://src/gameplay/input/player_input_source.gd")
const CHUNK_SIZE := COORDINATE_MAPPER_SCRIPT.ADT_CHUNK_SIZE_YARDS const PLAYER_INPUT_ACTIONS_SCRIPT := preload("res://src/gameplay/input/player_input_actions.gd")
const UNIT_SIZE := CHUNK_SIZE / 8.0 const LOCAL_PLAYER_MOVEMENT_CONTROLLER_SCRIPT := preload("res://src/gameplay/movement/local_player_movement_controller.gd")
const ADT_TERRAIN_QUERY_SCRIPT := preload("res://src/gameplay/terrain/adt_terrain_query.gd")
@export var extracted_dir: String = "res://data/extracted" @export var extracted_dir: String = "res://data/extracted"
@export var map_name: String = "Azeroth" @export var map_name: String = "Azeroth"
@@ -52,12 +53,32 @@ var _active_animation := ""
var _captured := false var _captured := false
var _yaw := 0.0 var _yaw := 0.0
var _pitch := deg_to_rad(-18.0) var _pitch := deg_to_rad(-18.0)
var _horizontal_velocity := Vector3.ZERO var _player_input_source: PlayerInputSource
var _flight_enabled := false var _local_movement_controller: LocalPlayerMovementController
var _adt_cache: Dictionary = {} var _terrain_query: TerrainQuery
## Replaces the ground-height backend without changing player movement or presentation.
## Passing null is a composition error and leaves the current query unchanged.
func set_terrain_query(terrain_query: TerrainQuery) -> void:
if terrain_query == null:
push_error("ThirdPersonWowController: terrain query cannot be null")
return
_terrain_query = terrain_query
func _ready() -> void: func _ready() -> void:
_player_input_source = PLAYER_INPUT_SOURCE_SCRIPT.new()
if _terrain_query == null:
_terrain_query = ADT_TERRAIN_QUERY_SCRIPT.new(extracted_dir, map_name)
_local_movement_controller = LOCAL_PLAYER_MOVEMENT_CONTROLLER_SCRIPT.new(
run_speed,
backward_speed,
strafe_speed,
flight_vertical_speed,
acceleration,
sprint_multiplier
)
_camera_pivot = get_node_or_null(camera_pivot_path) as Node3D _camera_pivot = get_node_or_null(camera_pivot_path) as Node3D
_camera = get_node_or_null(camera_path) as Camera3D _camera = get_node_or_null(camera_path) as Camera3D
_visual = get_node_or_null(visual_path) as Node3D _visual = get_node_or_null(visual_path) as Node3D
@@ -71,29 +92,31 @@ func _ready() -> void:
var spawn_position = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_godot(spawn_tile, spawn_local) 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) global_position = Vector3(spawn_position.x_units, spawn_position.y_units, spawn_position.z_units)
_load_character_visual() _load_character_visual()
var ground := _sample_ground_height(global_position) var spawn_ground_sample := _sample_ground_height(global_position)
if is_finite(ground): if spawn_ground_sample.is_available:
global_position.y = ground + ground_offset global_position.y = spawn_ground_sample.height_units + ground_offset
_yaw = rotation.y _yaw = rotation.y
_apply_camera_transform() _apply_camera_transform()
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT: if event.is_action_pressed(PLAYER_INPUT_ACTIONS_SCRIPT.CAMERA_ROTATE):
_captured = event.pressed _captured = true
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if _captured else Input.MOUSE_MODE_VISIBLE Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
elif event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_WHEEL_UP: elif event.is_action_released(PLAYER_INPUT_ACTIONS_SCRIPT.CAMERA_ROTATE):
camera_distance = clampf(camera_distance - camera_zoom_step, camera_min_distance, camera_max_distance)
_apply_camera_transform()
elif event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
camera_distance = clampf(camera_distance + camera_zoom_step, camera_min_distance, camera_max_distance)
_apply_camera_transform()
elif event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
_captured = false _captured = false
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
elif event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_SPACE: elif event.is_action_pressed(PLAYER_INPUT_ACTIONS_SCRIPT.CAMERA_ZOOM_IN):
_flight_enabled = not _flight_enabled camera_distance = clampf(camera_distance - camera_zoom_step, camera_min_distance, camera_max_distance)
_horizontal_velocity = Vector3.ZERO _apply_camera_transform()
elif event.is_action_pressed(PLAYER_INPUT_ACTIONS_SCRIPT.CAMERA_ZOOM_OUT):
camera_distance = clampf(camera_distance + camera_zoom_step, camera_min_distance, camera_max_distance)
_apply_camera_transform()
elif event.is_action_pressed(PLAYER_INPUT_ACTIONS_SCRIPT.RELEASE_CURSOR):
_captured = false
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if _captured else Input.MOUSE_MODE_VISIBLE
elif event.is_action_pressed(PLAYER_INPUT_ACTIONS_SCRIPT.DEBUG_TOGGLE_FLIGHT) and not event.is_echo():
_local_movement_controller.toggle_sandbox_flight()
if _captured and event is InputEventMouseMotion: if _captured and event is InputEventMouseMotion:
_yaw -= event.relative.x * mouse_sensitivity _yaw -= event.relative.x * mouse_sensitivity
@@ -103,72 +126,27 @@ func _unhandled_input(event: InputEvent) -> void:
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
var input_dir := _get_input_dir() var move_intent := _player_input_source.sample_move_intent()
var target_velocity := Vector3.ZERO var godot_world_movement_basis := global_basis
if input_dir.length_squared() > 0.0: if _local_movement_controller.is_flight_enabled and _camera_pivot:
target_velocity = _movement_vector(input_dir) godot_world_movement_basis = _camera_pivot.global_basis
if _flight_enabled: global_position += _local_movement_controller.advance(move_intent, godot_world_movement_basis, delta)
target_velocity.y += _flight_vertical_velocity()
_horizontal_velocity = _horizontal_velocity.move_toward(target_velocity, acceleration * delta) if not _local_movement_controller.is_flight_enabled:
global_position += _horizontal_velocity * delta var ground_sample := _sample_ground_height(global_position)
if ground_sample.is_available:
if not _flight_enabled: var target_y := ground_sample.height_units + ground_offset
var ground := _sample_ground_height(global_position)
if is_finite(ground):
var target_y := ground + ground_offset
global_position.y = lerpf(global_position.y, target_y, clampf(ground_snap_speed * delta, 0.0, 1.0)) global_position.y = lerpf(global_position.y, target_y, clampf(ground_snap_speed * delta, 0.0, 1.0))
var horizontal_motion := Vector2(_horizontal_velocity.x, _horizontal_velocity.z) var movement_velocity := _local_movement_controller.godot_world_velocity_units_per_second
var horizontal_motion := Vector2(movement_velocity.x, movement_velocity.z)
if _visual and horizontal_motion.length_squared() > 0.01: if _visual and horizontal_motion.length_squared() > 0.01:
_visual.global_rotation.y = atan2(-_horizontal_velocity.x, -_horizontal_velocity.z) _visual.global_rotation.y = atan2(-movement_velocity.x, -movement_velocity.z)
_update_character_animation(horizontal_motion.length_squared() > 0.04) _update_character_animation(horizontal_motion.length_squared() > 0.04)
_apply_camera_transform() _apply_camera_transform()
func _get_input_dir() -> Vector2:
var dir := Vector2.ZERO
if Input.is_key_pressed(KEY_W):
dir.y -= 1.0
if Input.is_key_pressed(KEY_S):
dir.y += 1.0
if Input.is_key_pressed(KEY_A):
dir.x -= 1.0
if Input.is_key_pressed(KEY_D):
dir.x += 1.0
return dir.normalized()
func _movement_vector(input_dir: Vector2) -> Vector3:
var forward := -global_basis.z
var right := global_basis.x
if _flight_enabled and _camera_pivot:
forward = -_camera_pivot.global_basis.z
right = _camera_pivot.global_basis.x
else:
forward.y = 0.0
right.y = 0.0
forward = forward.normalized()
right = right.normalized()
var speed_z := run_speed if input_dir.y < 0.0 else backward_speed
var speed_x := strafe_speed
var sprint := sprint_multiplier if Input.is_key_pressed(KEY_SHIFT) else 1.0
return (forward * -input_dir.y * speed_z + right * input_dir.x * speed_x) * sprint
func _flight_vertical_velocity() -> float:
var dir := 0.0
if Input.is_key_pressed(KEY_E):
dir += 1.0
if Input.is_key_pressed(KEY_Q):
dir -= 1.0
var sprint := sprint_multiplier if Input.is_key_pressed(KEY_SHIFT) else 1.0
return dir * flight_vertical_speed * sprint
func _load_character_visual() -> void: func _load_character_visual() -> void:
if character_model_path.is_empty() or _visual == null: if character_model_path.is_empty() or _visual == null:
return return
@@ -329,95 +307,11 @@ func _apply_camera_transform() -> void:
_camera.rotation = Vector3.ZERO _camera.rotation = Vector3.ZERO
func _sample_ground_height(world_pos: Vector3) -> float: func _sample_ground_height(godot_world_position: Vector3) -> TerrainGroundSample:
var typed_world_position = GODOT_WORLD_POSITION_SCRIPT.new(world_pos.x, world_pos.y, world_pos.z) return _terrain_query.sample_ground_height(
var tile_coordinate = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile(typed_world_position) GODOT_WORLD_POSITION_SCRIPT.new(
var tile_local_position = COORDINATE_MAPPER_SCRIPT.godot_to_adt_tile_local(typed_world_position) godot_world_position.x,
var chunk_coordinate = COORDINATE_MAPPER_SCRIPT.adt_tile_local_to_chunk(tile_coordinate, tile_local_position) godot_world_position.y,
var data := _load_adt(tile_coordinate.tile_x, tile_coordinate.tile_y) godot_world_position.z
if data.is_empty(): )
return NAN )
var tile_origin := _get_tile_origin(data)
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
var origin: Vector3 = chunk.get("origin", Vector3.ZERO)
var chunk_local := world_pos - origin
var gx := clampf(chunk_local.x / UNIT_SIZE, 0.0, 8.0)
var gz := clampf(chunk_local.z / UNIT_SIZE, 0.0, 8.0)
var x0 := clampi(int(floor(gx)), 0, 8)
var z0 := clampi(int(floor(gz)), 0, 8)
var x1 := mini(x0 + 1, 8)
var z1 := mini(z0 + 1, 8)
var fx := gx - float(x0)
var fz := gz - float(z0)
var heights: PackedFloat32Array = chunk.get("heights", PackedFloat32Array())
if heights.size() < 145:
return NAN
var h00 := heights[_outer(z0, x0)]
var h10 := heights[_outer(z0, x1)]
var h01 := heights[_outer(z1, x0)]
var h11 := heights[_outer(z1, x1)]
var hx0 := lerpf(h00, h10, fx)
var hx1 := lerpf(h01, h11, fx)
return origin.y + lerpf(hx0, hx1, fz)
func _load_adt(tx: int, ty: int) -> Dictionary:
var key := "%d_%d" % [tx, ty]
if _adt_cache.has(key):
return _adt_cache[key]
if not ClassDB.class_exists("ADTLoader"):
_adt_cache[key] = {}
return {}
var res_path := extracted_dir.path_join("World/Maps/%s/%s_%d_%d.adt" % [map_name, map_name, tx, ty])
var abs_path := ProjectSettings.globalize_path(res_path)
if not FileAccess.file_exists(abs_path):
_adt_cache[key] = {}
return {}
var loader = ClassDB.instantiate("ADTLoader")
var data: Dictionary = loader.call("load_adt", abs_path) if loader else {}
_adt_cache[key] = data
return data
func _find_chunk(data: Dictionary, chunk_x: int, chunk_y: int, tile_origin: Vector3) -> Dictionary:
for chunk in data.get("chunks", []) as Array:
if chunk.is_empty():
continue
var origin: Vector3 = chunk.get("origin", Vector3.ZERO)
var local := origin - tile_origin
var cx := clampi(int(round(local.x / CHUNK_SIZE)), 0, 15)
var cy := clampi(int(round(local.z / CHUNK_SIZE)), 0, 15)
if cx == chunk_x and cy == chunk_y:
return chunk
return {}
func _get_tile_origin(data: Dictionary) -> Vector3:
var found := false
var min_x := 0.0
var min_z := 0.0
for chunk in data.get("chunks", []) as Array:
if chunk.is_empty():
continue
var origin: Vector3 = chunk.get("origin", Vector3.ZERO)
if not found:
min_x = origin.x
min_z = origin.z
found = true
else:
min_x = minf(min_x, origin.x)
min_z = minf(min_z, origin.z)
return Vector3(min_x, 0.0, min_z) if found else Vector3.ZERO
func _outer(row: int, col: int) -> int:
return row * 17 + col
@@ -0,0 +1,14 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://src/scenes/player/third_person_wow_controller.gd" id="1_player"]
[node name="PlayerInputRegression" type="CharacterBody3D"]
script = ExtResource("1_player")
spawn_at_tile_center = false
character_model_path = ""
[node name="Visual" type="Node3D" parent="."]
[node name="CameraPivot" type="Node3D" parent="."]
[node name="Camera3D" type="Camera3D" parent="CameraPivot"]
@@ -20,7 +20,8 @@ const ALLOWED_LEGACY_NAME_PATHS: Array[String] = [
const REQUIRED_MAPPER_CALLS := { 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/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/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/scenes/player/third_person_wow_controller.gd": ["adt_tile_local_to_godot"],
"res://src/gameplay/terrain/adt_terrain_query.gd": ["godot_to_adt_tile", "godot_to_adt_tile_local", "adt_tile_local_to_chunk"],
"res://src/tools/probe_render_terrain_height.gd": ["godot_to_adt_tile"], "res://src/tools/probe_render_terrain_height.gd": ["godot_to_adt_tile"],
} }
@@ -59,7 +60,7 @@ func _initialize() -> void:
quit(1) quit(1)
return return
print("COORDINATE_CONVERSION_BOUNDARIES PASS files=%d native_boundary=1 oracle=1 consumers=4 classifier_cases=6" % source_paths.size()) print("COORDINATE_CONVERSION_BOUNDARIES PASS files=%d native_boundary=1 oracle=1 consumers=5 classifier_cases=6" % source_paths.size())
quit(0) quit(0)
+137
View File
@@ -0,0 +1,137 @@
extends SceneTree
## Headless M02 unit and boundary regression for local player movement state.
const MOVEMENT_CONTROLLER_PATH := "res://src/gameplay/movement/local_player_movement_controller.gd"
const PLAYER_CONTROLLER_PATH := "res://src/scenes/player/third_person_wow_controller.gd"
func _initialize() -> void:
var failures: Array[String] = []
_verify_directional_speeds(failures)
_verify_acceleration_and_deceleration(failures)
_verify_sandbox_sprint(failures)
_verify_flight_state_and_basis(failures)
_verify_invalid_delta(failures)
_verify_scene_boundary(failures)
if not failures.is_empty():
for failure in failures:
push_error("LOCAL_PLAYER_MOVEMENT: %s" % failure)
quit(1)
return
print("LOCAL_PLAYER_MOVEMENT PASS cases=12 state_transitions=2 scene_boundary=1")
quit(0)
func _verify_directional_speeds(failures: Array[String]) -> void:
var forward_controller := _new_controller()
var forward_displacement := forward_controller.advance(_intent(1.0, 0.0), Basis.IDENTITY, 1.0)
_expect_vector_near(forward_controller.godot_world_velocity_units_per_second, Vector3(0.0, 0.0, -7.0), "forward velocity", failures)
_expect_vector_near(forward_displacement, Vector3(0.0, 0.0, -7.0), "forward displacement", failures)
var backward_controller := _new_controller()
backward_controller.advance(_intent(-1.0, 0.0), Basis.IDENTITY, 1.0)
_expect_vector_near(backward_controller.godot_world_velocity_units_per_second, Vector3(0.0, 0.0, 4.5), "backward velocity", failures)
var strafe_controller := _new_controller()
strafe_controller.advance(_intent(0.0, 1.0), Basis.IDENTITY, 1.0)
_expect_vector_near(strafe_controller.godot_world_velocity_units_per_second, Vector3(4.5, 0.0, 0.0), "strafe velocity", failures)
var rotated_controller := _new_controller()
var rotated_basis := Basis(Vector3.UP, deg_to_rad(90.0))
rotated_controller.advance(_intent(1.0, 0.0), rotated_basis, 1.0)
_expect_vector_near(
rotated_controller.godot_world_velocity_units_per_second,
(-rotated_basis.z).normalized() * 7.0,
"rotated character basis",
failures
)
func _verify_acceleration_and_deceleration(failures: Array[String]) -> void:
var controller := _new_controller()
var forward_intent := _intent(1.0, 0.0)
_expect_vector_near(controller.advance(forward_intent, Basis.IDENTITY, 0.1), Vector3(0.0, 0.0, -0.28), "first acceleration displacement", failures)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3(0.0, 0.0, -2.8), "first acceleration velocity", failures)
controller.advance(forward_intent, Basis.IDENTITY, 0.1)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3(0.0, 0.0, -5.6), "second acceleration velocity", failures)
controller.advance(_intent(0.0, 0.0), Basis.IDENTITY, 0.1)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3(0.0, 0.0, -2.8), "deceleration velocity", failures)
func _verify_sandbox_sprint(failures: Array[String]) -> void:
var controller := _new_controller()
controller.advance(_intent(1.0, 0.0, 0.0, true), Basis.IDENTITY, 2.0)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3(0.0, 0.0, -42.0), "sandbox sprint velocity", failures)
func _verify_flight_state_and_basis(failures: Array[String]) -> void:
var controller := _new_controller()
controller.advance(_intent(1.0, 0.0), Basis.IDENTITY, 1.0)
_expect_true(controller.toggle_sandbox_flight(), "flight toggles on", failures)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3.ZERO, "flight toggle clears velocity", failures)
var pitched_basis := Basis(Vector3.RIGHT, deg_to_rad(30.0))
controller.advance(_intent(1.0, 0.0, 1.0), pitched_basis, 1.0)
var expected_flight_velocity := (-pitched_basis.z).normalized() * 7.0 + Vector3.UP * 7.0
_expect_vector_near(controller.godot_world_velocity_units_per_second, expected_flight_velocity, "camera-relative flight velocity", failures)
_expect_true(not controller.toggle_sandbox_flight(), "flight toggles off", failures)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3.ZERO, "landing toggle clears velocity", failures)
func _verify_invalid_delta(failures: Array[String]) -> void:
var controller := _new_controller()
var displacement := controller.advance(_intent(1.0, 0.0), Basis.IDENTITY, -1.0)
_expect_vector_near(displacement, Vector3.ZERO, "negative delta displacement", failures)
_expect_vector_near(controller.godot_world_velocity_units_per_second, Vector3.ZERO, "negative delta state", failures)
func _verify_scene_boundary(failures: Array[String]) -> void:
var movement_source := _read_text(MOVEMENT_CONTROLLER_PATH, failures)
for forbidden_text in ["extends Node", "extends Resource", "Input.", "Camera3D", "ADTLoader", "global_position"]:
_expect_true(not movement_source.contains(forbidden_text), "movement controller omits %s" % forbidden_text, failures)
var player_source := _read_text(PLAYER_CONTROLLER_PATH, failures)
_expect_true(player_source.contains("_local_movement_controller.advance"), "scene delegates movement update", failures)
_expect_true(not player_source.contains("move_toward(target_velocity"), "scene omits velocity integration", failures)
_expect_true(not player_source.contains("func _movement_vector"), "scene omits movement-vector calculation", failures)
_expect_true(not player_source.contains("_horizontal_velocity"), "scene omits movement velocity state", failures)
_expect_true(not player_source.contains("var _flight_enabled"), "scene omits flight state", failures)
func _new_controller() -> LocalPlayerMovementController:
return LocalPlayerMovementController.new(7.0, 4.5, 4.5, 7.0, 28.0, 6.0)
func _intent(
forward_axis: float,
strafe_axis: float,
vertical_axis: float = 0.0,
sprint_requested: bool = false
) -> MoveIntent:
return MoveIntent.new(forward_axis, strafe_axis, vertical_axis, sprint_requested)
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_vector_near(
actual_value: Vector3,
expected_value: Vector3,
label: String,
failures: Array[String]
) -> void:
if not actual_value.is_equal_approx(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)
+162
View File
@@ -0,0 +1,162 @@
extends SceneTree
## Headless M02 contract regression for remappable actions and MoveIntent composition.
const MOVE_INTENT_PATH := "res://src/domain/input/move_intent.gd"
const PLAYER_INPUT_SOURCE_PATH := "res://src/gameplay/input/player_input_source.gd"
const PLAYER_CONTROLLER_PATH := "res://src/scenes/player/third_person_wow_controller.gd"
const REGRESSION_SCENE_PATH := "res://src/tests/scenes/player_input_regression.tscn"
func _initialize() -> void:
_run_verification.call_deferred()
func _run_verification() -> void:
var failures: Array[String] = []
_verify_default_input_actions(failures)
_verify_move_intent_composition(failures)
_verify_controller_boundary(failures)
_verify_regression_scene(failures)
if not failures.is_empty():
for failure in failures:
push_error("PLAYER_INPUT: %s" % failure)
quit(1)
return
print("PLAYER_INPUT PASS actions=%d intent_cases=6 controller=1 regression_scene=1" % PlayerInputActions.REQUIRED_ACTIONS.size())
quit(0)
func _verify_default_input_actions(failures: Array[String]) -> void:
for action_name in PlayerInputActions.REQUIRED_ACTIONS:
_expect_true(InputMap.has_action(action_name), "Input Map contains %s" % action_name, failures)
_expect_key_binding(PlayerInputActions.MOVE_FORWARD, KEY_W, true, failures)
_expect_key_binding(PlayerInputActions.MOVE_BACKWARD, KEY_S, true, failures)
_expect_key_binding(PlayerInputActions.STRAFE_LEFT, KEY_A, true, failures)
_expect_key_binding(PlayerInputActions.STRAFE_RIGHT, KEY_D, true, failures)
_expect_key_binding(PlayerInputActions.DEBUG_FLY_UP, KEY_E, true, failures)
_expect_key_binding(PlayerInputActions.DEBUG_FLY_DOWN, KEY_Q, true, failures)
_expect_key_binding(PlayerInputActions.DEBUG_SPRINT, KEY_SHIFT, false, failures)
_expect_key_binding(PlayerInputActions.DEBUG_TOGGLE_FLIGHT, KEY_SPACE, true, failures)
_expect_key_binding(PlayerInputActions.RELEASE_CURSOR, KEY_ESCAPE, false, failures)
_expect_mouse_binding(PlayerInputActions.CAMERA_ROTATE, MOUSE_BUTTON_RIGHT, failures)
_expect_mouse_binding(PlayerInputActions.CAMERA_ZOOM_IN, MOUSE_BUTTON_WHEEL_UP, failures)
_expect_mouse_binding(PlayerInputActions.CAMERA_ZOOM_OUT, MOUSE_BUTTON_WHEEL_DOWN, failures)
func _verify_move_intent_composition(failures: Array[String]) -> void:
var neutral := PlayerInputSource.compose_move_intent(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)
_expect_near(neutral.forward_axis, 0.0, "neutral forward", failures)
_expect_true(not neutral.has_translation(), "neutral has no translation", failures)
var forward := PlayerInputSource.compose_move_intent(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)
_expect_near(forward.forward_axis, 1.0, "forward axis", failures)
var canceled := PlayerInputSource.compose_move_intent(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, false)
_expect_true(not canceled.has_translation(), "opposite actions cancel", failures)
var diagonal := PlayerInputSource.compose_move_intent(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, false)
_expect_near(Vector2(diagonal.strafe_axis, diagonal.forward_axis).length(), 1.0, "diagonal normalized", failures)
var vertical := PlayerInputSource.compose_move_intent(0.0, 0.0, 0.0, 0.0, 1.5, -0.5, false)
_expect_near(vertical.vertical_axis, 1.0, "vertical strengths clamped", failures)
var debug_requests := PlayerInputSource.compose_move_intent(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true)
_expect_true(debug_requests.is_sprint_requested, "sprint request retained", failures)
func _verify_controller_boundary(failures: Array[String]) -> void:
var controller_source := _read_text(PLAYER_CONTROLLER_PATH, failures)
_expect_true(controller_source.contains("sample_move_intent()"), "controller samples PlayerInputSource", failures)
_expect_true(not controller_source.contains("Input.is_key_pressed"), "controller omits direct keyboard polling", failures)
_expect_true(not controller_source.contains("KEY_"), "controller omits hardcoded key constants", failures)
var move_intent_source := _read_text(MOVE_INTENT_PATH, failures)
_expect_true(not move_intent_source.contains("extends Node"), "MoveIntent does not inherit Node", failures)
_expect_true(not move_intent_source.contains("extends Resource"), "MoveIntent does not inherit Resource", failures)
_expect_true(not move_intent_source.contains("Input."), "MoveIntent does not read engine input", failures)
var input_source := _read_text(PLAYER_INPUT_SOURCE_PATH, failures)
_expect_true(input_source.contains("Input.get_action_strength"), "input source reads action strengths", failures)
_expect_true(not input_source.contains("is_key_pressed"), "input source omits physical-key polling", failures)
func _verify_regression_scene(failures: Array[String]) -> void:
var packed_scene := load(REGRESSION_SCENE_PATH) as PackedScene
_expect_true(packed_scene != null, "regression scene loads", failures)
if packed_scene == null:
return
var player := packed_scene.instantiate() as CharacterBody3D
_expect_true(player != null, "regression player instantiates", failures)
if player == null:
return
root.add_child(player)
player.set_physics_process(false)
Input.action_press(PlayerInputActions.MOVE_FORWARD)
player.call("_physics_process", 1.0)
Input.action_release(PlayerInputActions.MOVE_FORWARD)
_expect_near(player.position.z, -7.0, "forward action moves current sandbox controller", failures)
var camera_distance_before: float = player.get("camera_distance")
var zoom_event := InputEventMouseButton.new()
zoom_event.button_index = MOUSE_BUTTON_WHEEL_UP
zoom_event.pressed = true
player.call("_unhandled_input", zoom_event)
_expect_near(player.get("camera_distance"), camera_distance_before - 1.0, "zoom action updates camera distance", failures)
var flight_toggle_event := InputEventAction.new()
flight_toggle_event.action = PlayerInputActions.DEBUG_TOGGLE_FLIGHT
flight_toggle_event.pressed = true
player.call("_unhandled_input", flight_toggle_event)
var movement_controller: LocalPlayerMovementController = player.get("_local_movement_controller")
_expect_true(movement_controller.is_flight_enabled, "flight action preserves immediate sandbox toggle", failures)
player.free()
func _expect_key_binding(
action_name: StringName,
expected_keycode: Key,
uses_physical_keycode: bool,
failures: Array[String]
) -> void:
for input_event in InputMap.action_get_events(action_name):
if input_event is InputEventKey:
var key_event := input_event as InputEventKey
var configured_keycode := key_event.physical_keycode if uses_physical_keycode else key_event.keycode
if configured_keycode == expected_keycode:
return
failures.append("%s missing expected key binding %s" % [action_name, expected_keycode])
func _expect_mouse_binding(
action_name: StringName,
expected_button: MouseButton,
failures: Array[String]
) -> void:
for input_event in InputMap.action_get_events(action_name):
if input_event is InputEventMouseButton and input_event.button_index == expected_button:
return
failures.append("%s missing expected mouse binding %s" % [action_name, expected_button])
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 %.6f, got %.6f" % [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)
+198
View File
@@ -0,0 +1,198 @@
extends SceneTree
## Headless M02 contract, interpolation, cache and player-injection regression.
const TERRAIN_QUERY_PATH := "res://src/gameplay/terrain/terrain_query.gd"
const ADT_TERRAIN_QUERY_PATH := "res://src/gameplay/terrain/adt_terrain_query.gd"
const PLAYER_CONTROLLER_PATH := "res://src/scenes/player/third_person_wow_controller.gd"
const REGRESSION_SCENE_PATH := "res://src/tests/scenes/player_input_regression.tscn"
var _synthetic_adt_tile_data: Dictionary = {}
var _synthetic_loader_call_count := 0
class FlatTerrainQuery extends TerrainQuery:
var _height_units: float
func _init(height_units: float) -> void:
_height_units = height_units
func sample_ground_height(_godot_world_position: GodotWorldPosition) -> TerrainGroundSample:
return TerrainGroundSample.available(_height_units)
func _initialize() -> void:
_run_verification.call_deferred()
func _run_verification() -> void:
var failures: Array[String] = []
_verify_typed_result_contract(failures)
_verify_synthetic_adt_interpolation_and_cache(failures)
_verify_unavailable_tile(failures)
_verify_player_injection(failures)
_verify_source_boundaries(failures)
if not failures.is_empty():
for failure in failures:
push_error("TERRAIN_QUERY: %s" % failure)
quit(1)
return
print("TERRAIN_QUERY PASS contract=4 interpolation=1 cache=1 failures=2 player_injection=1")
quit(0)
func _verify_typed_result_contract(failures: Array[String]) -> void:
var available_sample := TerrainGroundSample.available(123.5)
_expect_true(available_sample.is_available, "available sample state", failures)
_expect_near(available_sample.height_units, 123.5, "available sample height", failures)
_expect_true(available_sample.failure_code.is_empty(), "available sample has no failure", failures)
var unavailable_sample := TerrainGroundSample.unavailable(&"synthetic_failure")
_expect_true(not unavailable_sample.is_available, "unavailable sample state", failures)
_expect_equal(unavailable_sample.failure_code, &"synthetic_failure", "unavailable failure code", failures)
var base_sample := TerrainQuery.new().sample_ground_height(GodotWorldPosition.new(0.0, 0.0, 0.0))
_expect_equal(base_sample.failure_code, &"terrain_query_not_implemented", "base query failure", failures)
var non_finite_sample := TerrainGroundSample.available(NAN)
_expect_true(not non_finite_sample.is_available, "non-finite sample unavailable", failures)
_expect_equal(non_finite_sample.failure_code, &"terrain_height_not_finite", "non-finite failure code", failures)
func _verify_synthetic_adt_interpolation_and_cache(failures: Array[String]) -> void:
var query_position := GodotWorldPosition.new(17000.0, 999.0, 26525.0)
_synthetic_adt_tile_data = _build_synthetic_adt_tile(query_position)
_synthetic_loader_call_count = 0
var terrain_query := AdtTerrainQuery.new("res://synthetic", "Azeroth", _load_synthetic_adt_tile)
var first_sample := terrain_query.sample_ground_height(query_position)
_expect_true(first_sample.is_available, "synthetic ADT sample available", failures)
_expect_near_with_tolerance(first_sample.height_units, 137.0, 0.002, "synthetic bilinear height", failures)
var second_sample := terrain_query.sample_ground_height(query_position)
_expect_near_with_tolerance(second_sample.height_units, 137.0, 0.002, "cached synthetic height", failures)
_expect_equal(_synthetic_loader_call_count, 1, "ADT tile loaded once", failures)
func _verify_unavailable_tile(failures: Array[String]) -> void:
var query_position := GodotWorldPosition.new(17000.0, 0.0, 26525.0)
var empty_query := AdtTerrainQuery.new("res://synthetic", "Azeroth", func(_path: String) -> Dictionary: return {})
var empty_sample := empty_query.sample_ground_height(query_position)
_expect_true(not empty_sample.is_available, "empty ADT unavailable", failures)
_expect_equal(empty_sample.failure_code, &"adt_tile_unavailable", "empty ADT failure", failures)
var invalid_heights_data := _build_synthetic_adt_tile(query_position)
var invalid_chunks: Array = invalid_heights_data.get("chunks", [])
(invalid_chunks[invalid_chunks.size() - 1] as Dictionary)["heights"] = PackedFloat32Array()
var invalid_query := AdtTerrainQuery.new(
"res://synthetic",
"Azeroth",
func(_path: String) -> Dictionary: return invalid_heights_data
)
var invalid_sample := invalid_query.sample_ground_height(query_position)
_expect_equal(invalid_sample.failure_code, &"adt_chunk_heights_invalid", "invalid heights failure", failures)
func _verify_player_injection(failures: Array[String]) -> void:
var packed_scene := load(REGRESSION_SCENE_PATH) as PackedScene
_expect_true(packed_scene != null, "regression scene loads", failures)
if packed_scene == null:
return
var player := packed_scene.instantiate() as CharacterBody3D
player.set_terrain_query(FlatTerrainQuery.new(20.0))
root.add_child(player)
player.set_physics_process(false)
_expect_near(player.position.y, 20.05, "injected spawn ground height", failures)
player.position.y = 30.0
player.call("_physics_process", 1.0)
_expect_near(player.position.y, 20.05, "injected physics ground snap", failures)
player.free()
func _verify_source_boundaries(failures: Array[String]) -> void:
var terrain_contract_source := _read_text(TERRAIN_QUERY_PATH, failures)
_expect_true(not terrain_contract_source.contains("extends Node"), "TerrainQuery omits Node", failures)
_expect_true(not terrain_contract_source.contains("Vector3"), "TerrainQuery omits untyped Vector3 position", failures)
var adt_query_source := _read_text(ADT_TERRAIN_QUERY_PATH, failures)
_expect_true(adt_query_source.contains("ADTLoader"), "ADT adapter owns native loader", failures)
_expect_true(adt_query_source.contains("_adt_tile_cache"), "ADT adapter owns tile cache", failures)
var player_source := _read_text(PLAYER_CONTROLLER_PATH, failures)
for forbidden_text in ["ADTLoader", "load_adt", "_adt_cache", "_find_chunk", "_outer_height_index"]:
_expect_true(not player_source.contains(forbidden_text), "player omits %s" % forbidden_text, failures)
_expect_true(player_source.contains("set_terrain_query"), "player exposes terrain query injection", failures)
_expect_true(player_source.contains("_terrain_query.sample_ground_height"), "player delegates ground sampling", failures)
func _build_synthetic_adt_tile(query_position: GodotWorldPosition) -> Dictionary:
var tile_coordinate := CoordinateMapper.godot_to_adt_tile(query_position)
var tile_local_position := CoordinateMapper.godot_to_adt_tile_local(query_position)
var chunk_coordinate := CoordinateMapper.adt_tile_local_to_chunk(tile_coordinate, tile_local_position)
var chunk_size := CoordinateMapper.ADT_CHUNK_SIZE_YARDS
var outer_grid_unit_size := chunk_size / 8.0
var target_chunk_origin := Vector3(
query_position.x_units - outer_grid_unit_size * 4.5,
100.0,
query_position.z_units - outer_grid_unit_size * 3.25
)
var tile_origin := target_chunk_origin - Vector3(
chunk_coordinate.chunk_x * chunk_size,
0.0,
chunk_coordinate.chunk_y * chunk_size
)
var heights := PackedFloat32Array()
heights.resize(145)
for row in range(9):
for column in range(9):
heights[row * 17 + column] = float(row * 10 + column)
var target_chunk := {"origin": target_chunk_origin, "heights": heights}
if chunk_coordinate.chunk_x == 0 and chunk_coordinate.chunk_y == 0:
return {"chunks": [target_chunk]}
return {
"chunks": [
{"origin": tile_origin, "heights": PackedFloat32Array()},
target_chunk,
]
}
func _load_synthetic_adt_tile(_absolute_path: String) -> Dictionary:
_synthetic_loader_call_count += 1
return _synthetic_adt_tile_data
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 %.6f, got %.6f" % [label, expected_value, actual_value])
func _expect_near_with_tolerance(
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 %.6f ± %.6f, got %.6f" % [label, expected_value, tolerance, actual_value])
func _expect_equal(actual_value: Variant, expected_value: Variant, 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)
+41 -15
View File
@@ -1,6 +1,7 @@
# M01 — Coordinates and Architecture Seams # M01 — Coordinates and Architecture Seams
<!-- OPENWC_TARGET:ACTIVE --> <!-- OPENWC_TARGET:DONE -->
<!-- OPENWC_TARGET_DONE:M01:work/sindo-main-codex/m01-integrator-closeout:2026-07-14 -->
## Outcome ## Outcome
@@ -8,13 +9,13 @@
## Steps ## Steps
- [ ] Создать domain/value-object слой без `Node`/`Resource` dependencies. - [x] Создать domain/value-object слой без `Node`/`Resource` dependencies.
- [ ] Определить canonical WoW, Godot, ADT tile/chunk и local coordinate types. - [x] Определить canonical WoW, Godot, ADT tile/chunk и local coordinate types.
- [ ] Реализовать единственный `CoordinateMapper` для position и orientation. - [x] Реализовать единственный `CoordinateMapper` для position и orientation.
- [ ] Собрать golden points из ADT, server spawn и оригинального клиента. - [x] Собрать golden points из ADT, server spawn и оригинального клиента.
- [ ] Ввести `StreamingFocus` вместо неявной зависимости от active Camera3D. - [x] Ввести `StreamingFocus` вместо неявной зависимости от active Camera3D.
- [ ] Ввести stable `ContentId`, `EntityId` и отличить их от WoW GUID/server entry. - [x] Ввести stable `ContentId`, `EntityId` и отличить их от WoW GUID/server entry.
- [ ] Запретить ручные axis conversion через code review rule/test search. - [x] Запретить ручные axis conversion через code review rule/test search.
## Verification ## Verification
@@ -28,10 +29,35 @@ Renderer/test scene получают focus через контракт; коор
## Evidence ## Evidence
- Date: - Date: 2026-07-14
- Revision/worktree: - Revision/worktree: merged master `c8e99f2`; closeout
- Commands: `work/sindo-main-codex/m01-integrator-closeout`
- Results: - Commands: `tools/run_render_baseline.ps1 -DryRun -WaitSeconds 0.1
- Fidelity comparison: -MeasureSeconds 0.1`; `verify_coordinate_mapper.gd`;
- Changed files: `verify_coordinate_golden_fixtures.gd`; `verify_streaming_focus.gd`;
- Remaining risks: `verify_domain_identities.gd`; coordination/documentation/diff gates.
- Results: CoordinateMapper PASS (`5` golden points, `8` tile boundaries,
`2` raw MCNK, `5` yaw); golden fixtures PASS (`1` server spawn, `1` raw ADT,
`5` original-client points); StreamingFocus PASS (`1` contract, `2` runtime
scenes, `3` capture tools); identities PASS (`5/5/6/5`); conversion boundary
PASS (`84` files, one native boundary, one oracle, four consumers, six
classifiers); server-spawn renderer PASS at ADT `(32,48)`, MCNK `(3,12)`;
renderer manifest PASS (`7/7/7`) and calibration maximum error `0.000015`.
- Fidelity comparison: five build-12340 camera observations, pinned AzerothCore
Human Warrior spawn and private raw ADT metadata agree through coordinate
contract version 2. Cache-complete cold/warm GUI capture places the mapped
spawn marker on rendered Northshire terrain with focus `(32,48)`, quality
`100/100`, missing cache `0`; PNG SHA-256 values are recorded in the server
spawn handoff. The final ADT-boundary regression passed `2/2`; the full M01
regression captured `14/14`, with `11` strict passes and three low-mean
timing/animation-phase differences rather than coordinate drift.
- Changed files: `src/domain/coordinates/`, `src/domain/identity/`,
`src/domain/streaming/`, migrated sky/player/streaming/terrain consumers,
coordinate/renderer fixtures and tools, runtime scenes, ADR 0001/0002,
coordinate/domain/renderer module specs, coding/render documentation and
M01 coordination claims.
- Remaining risks: TrinityCore populated spawn equivalence is not verified;
native parser conversion remains one separately calibrated boundary; MDDF/
MODF placement Euler parity is outside world-yaw scope; renderer visual parity
gaps and the known anonymous ObjectDB teardown warning continue. No `1:1`
compatibility claim is made by M01.
+1 -1
View File
@@ -1,6 +1,6 @@
# M02 — Player Decomposition # M02 — Player Decomposition
<!-- OPENWC_TARGET:OPEN --> <!-- OPENWC_TARGET:ACTIVE -->
## Outcome ## Outcome
+1 -1
View File
@@ -21,7 +21,7 @@ OpenWC должен предоставить четыре согласованн
- MPQ/BLP/ADT/WDT/M2/WMO native parsing и renderer vertical slice уже существуют. - MPQ/BLP/ADT/WDT/M2/WMO native parsing и renderer vertical slice уже существуют.
- Runtime streaming, terrain quality, MultiMesh M2, WMO caches, liquids, sky и character experiments находятся в рабочем состоянии, но сосредоточены в крупных orchestration scripts. - Runtime streaming, terrain quality, MultiMesh M2, WMO caches, liquids, sky и character experiments находятся в рабочем состоянии, но сосредоточены в крупных orchestration scripts.
- Renderer baseline M00 завершён: paired comparison с оригинальным клиентом записывает измеренные gaps без заявления parity, а обязательные diagnostic gaps закрыты или явно классифицированы. Текущая работа M01 вводит coordinate и architecture seams. - Renderer baseline M00 завершён: paired comparison с оригинальным клиентом записывает измеренные gaps без заявления parity, а обязательные diagnostic gaps закрыты или явно классифицированы. M01 завершил coordinate, identity и streaming-focus seams; текущая работа M02 декомпозирует player input, movement, terrain query, camera и presentation без observable regression.
- Gameplay domain, network protocol, production UI/Lua, audio orchestration и server adapters в основном предстоит реализовать. - Gameplay domain, network protocol, production UI/Lua, audio orchestration и server adapters в основном предстоит реализовать.
- Editor plugin пока решает extraction/preview задачи, но не является полноценной authoring platform. - Editor plugin пока решает extraction/preview задачи, но не является полноценной authoring platform.
+3 -3
View File
@@ -10,7 +10,7 @@
## Current target ## Current target
`M01` — [01-coordinates-and-seams.md](01-coordinates-and-seams.md) `M02` — [02-player-decomposition.md](02-player-decomposition.md)
Одновременно `ACTIVE` может быть только одна цель. Следующая цель становится `ACTIVE` после появления валидной `OPENWC_TARGET_DONE` метки у предыдущей. Одновременно `ACTIVE` может быть только одна цель. Следующая цель становится `ACTIVE` после появления валидной `OPENWC_TARGET_DONE` метки у предыдущей.
@@ -34,8 +34,8 @@
| ID | Цель | Зависит от | Статус | | ID | Цель | Зависит от | Статус |
|---|---|---|---| |---|---|---|---|
| M00 | [Renderer baseline](00-render-baseline.md) | — | DONE | | M00 | [Renderer baseline](00-render-baseline.md) | — | DONE |
| M01 | [Coordinates and architecture seams](01-coordinates-and-seams.md) | M00 | ACTIVE | | M01 | [Coordinates and architecture seams](01-coordinates-and-seams.md) | M00 | DONE |
| M02 | [Player decomposition](02-player-decomposition.md) | M01 | OPEN | | M02 | [Player decomposition](02-player-decomposition.md) | M01 | ACTIVE |
| M03 | [Renderer facade and extraction](03-renderer-facade.md) | M02 | OPEN | | M03 | [Renderer facade and extraction](03-renderer-facade.md) | M02 | OPEN |
| M04 | [Godot Editor shell](04-editor-shell.md) | M03 | OPEN | | M04 | [Godot Editor shell](04-editor-shell.md) | M03 | OPEN |
| M05 | [Content Project](05-content-project.md) | M04 | OPEN | | M05 | [Content Project](05-content-project.md) | M04 | OPEN |