AOI Spatial Filtering, Move + Shoot Separation & Entity LERP

How Area of Interest (AOI) reduces bandwidth, how Move separates from Hitscan/Ballistic Shoot, and how clients interpolate discrete server snapshots.

AOI Spatial Filtering, Move + Shoot & Entity Interpolation

Spatial visibility and step validation live in Playna's replication layer rather than inside one hardcoded game loop, allowing AOI to protect bandwidth across shooters, MMORPGs, and physics arenas.

1. Area of Interest (`visibility: "aoi"`)

Marking a component with `visibility: "aoi"` filters outgoing delta snapshots per recipient by `aoi_radius`:

  • Out-of-range entity states stay off the wire → **significantly lower bandwidth**.
  • Remote enemy positions outside interest range never reach client memory → **blocks radar/map hacks**.
  • Server-side `max_step_distance` bounds reject unauthorized teleportation deltas.

2. How Move and Shoot Compose

  • **Move (Locomotion, Speed Bounds & AOI):** Handled by **`kinematic_ecs` (`0x64`)**.
  • **Shoot — Hitscan (Instant Ray Weapons):** Resolved inside `kinematic_ecs` + `lag_compensation` by rewinding target spheres in the history ring buffer to `T - RTT/2` and testing 3D ray-sphere intersection.
  • **Shoot — Projectiles (Gravity/Wind Arrows & Shells):** Movement stays on `kinematic_ecs` while fire commands dispatch to secondary **`ballistics` (`0x62`)**.

3. Smooth Scene Rendering: Entity LERP & SLERP

Because servers snapshot at 20–60 Hz while clients render at 60–240 Hz, client scenes render remote entities slightly behind live time inside an interpolation buffer:

  • `t_render = t_client_now - t_interpolation_delay` (`1.5 ~ 2.0 * dt_tick + jitter_ms`)
  • `alpha = clamp((t_render - t_prev) / (t_next - t_prev), 0.0, 1.0)`
  • Position: `P(t) = lerp(P_prev, P_next, alpha)`
  • Rotation: `R(t) = slerp(R_prev, R_next, alpha)`
  • Brief packet loss triggers velocity-clamped Dead Reckoning (`<= 100 ms`) blended smoothly on arrival of the next authoritative snapshot.

Spatial Query, AOI Görünürlüğü, Move + Shoot ve LERP Enterpolasyon

Spatial Query, AOI ve Move + Shoot Mimarisi

Playna’da konum filtreleme (AOI) doğrudan fizik motorunun içine gömülmez; çoğaltma katmanında tüm fizik sağlayıcılarıyla birlikte çalışır.

1. Area of Interest (`visibility: "aoi"`)

Bileşen tanımında `visibility` alanını `"aoi"` seçtiğinizde veri düzlemi her alıcı için yalnızca tanımlı `aoi_radius` mesafesi içindeki varlıkların delta snapshot paketlerini oluşturur:

  • Uzaktaki oyuncuların koordinatları ağa çıkmaz → **bant genişliği düşer**.
  • İstemci belleğine görüş alanı dışındaki konumlar inmediği için **harita/wallhack hileleri önlenir**.
  • `max_step_distance` denetimi tek adımda ışınlanma (teleport) hilesini engeller.

2. Move ve Shoot Nasıl Birleşir?

  • **Move (Konum, Hız Koruması & AOI):** Oyuncu hareketi **`kinematic_ecs` (`0x64`)** üzerinde akar.
  • **Shoot — Senaryo 1 (Hitscan FPS):** Anlık mermi atışları `kinematic_ecs` + `lag_compensation` yeteneği içinde çözülür; sunucu tarih halkasını `T - RTT/2` anına geri sarıp 3D ışın-küre kesişimini (`verify_ray_hit`) doğrular.
  • **Shoot — Senaryo 2 (Balistik Ok / Mermi / Bomba):** Hareket `kinematic_ecs` üzerinde devam ederken atış komutu ikincil **`ballistics` (`0x62`)** sağlayıcısına yönlendirilir.

3. İstemci Sahnesinde Akıcı Render (Entity Interpolation / LERP)

Sunucu 20 Hz (`50 ms`) veya 60 Hz (`16.6 ms`) anlık görüntü gönderirken monitörler 60/144/240 Hz çalışır. Akıcı görüntü için istemci mevcut zamanın hemen gerisinden enterpolasyon oynatır:

  • `t_render = t_client_now - t_interpolation_delay` (`1.5 ~ 2.0 * dt_tick + jitter_ms`)
  • `alpha = clamp((t_render - t_prev) / (t_next - t_prev), 0.0, 1.0)`
  • Pozisyon: `P(t) = lerp(P_prev, P_next, alpha)`
  • Rotasyon (Quaternion): `R(t) = slerp(R_prev, R_next, alpha)`
  • Paket kaybında kısa süreli Dead Reckoning (maks. ~100 ms hız tahmini) uygulanır ve yeni kare geldiğinde yumuşak karışım yapılır.