Files
2nd/00_Raw/2026-04-26-Skybound_Enemy_Movement_Jitter_Stabilization.md
T

4.0 KiB

Skybound Enemy Movement Jitter Stabilization

작성일: 2026-04-26 20:38 KST

요청 요약

  • 특정 적기들이 서로 낀 것처럼 겹친 채 바들바들 떨린다.
  • 적기 이동 로직을 확인하고 원인을 찾아야 한다.

확인 결과

문제는 단일 원인이 아니라 세 가지가 겹친 현상으로 판단했다.

1. Striker 계열이 플레이어 한 점으로 수렴

updateStrikerAI는 각 적기의 편대 위치를 유지하지 않고 player.x를 향해 계속 이동했다.

이 때문에 같은 편대로 나온 엘리트/스트라이커들이 시간이 지나면 거의 같은 x 좌표로 모이게 된다.

2. 분리 로직이 강한 위치 보정으로 작동

applyEnemySeparation은 겹친 적을 매 프레임 직접 밀어냈다.

하지만 직전 AI 로직이 다시 같은 지점으로 끌어당기기 때문에:

  • AI가 모음
  • separation이 밀어냄
  • 다음 프레임에 다시 AI가 모음

이 루프가 반복되며 화면에서는 “끼어서 떠는” 것처럼 보였다.

3. 엔티티 풀링에서 내부 속도 잔여값 가능성

적 엔티티는 풀링으로 재사용된다.

그런데 새로 스폰할 때 vx, vy, 일부 AI 상태값이 명시적으로 초기화되지 않았다.

이전 적이 gravity, knockback, chase 등으로 얻은 내부 속도가 새 적에게 남을 가능성이 있어 이동 불안정성을 키울 수 있었다.

적용한 해결 방향

핵심 원칙:

  • 적기가 완전히 같은 목표점으로 몰리지 않게 한다.
  • 겹침 보정은 강한 튕김이 아니라 작은 안정화 보정으로 한다.
  • 풀링된 적기는 스폰 시 내부 이동 상태를 반드시 초기화한다.

적용한 변경

적 스폰 상태 초기화

수정 파일:

  • /Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/EntityManager.ts

변경:

  • spawnEnemy에서 아래 값을 기본 초기화하도록 추가했다.
    • vx
    • vy
    • hit
    • hitTimer
    • stunTimer
    • targetId
    • telegraphFrame
    • telegraphX
    • telegraphY

의도:

  • 풀링 재사용으로 이전 적의 내부 이동/AI 상태가 새 적에게 이어지는 것을 방지한다.

Striker 편대 lane 유지

수정 파일:

  • /Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts

변경:

  • updateStrikerAIplayer.x만 추적하지 않고, 스폰 당시 targetX 기반의 formation lane을 유지하도록 변경했다.
  • 같은 편대에서 나온 적들이 플레이어 중심으로 완전히 겹치지 않고 좌우 간격을 유지한다.
  • 근접 압박 이동도 player.x 기준이 아니라 desiredX 기준으로 변경했다.

의도:

  • 엘리트/스트라이커가 “한 점으로 뭉치는” 현상을 줄인다.
  • 회피할 수 있는 공격 편대처럼 보이게 한다.

Enemy separation 안정화

수정 파일:

  • /Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts

변경:

  • Elite/MiniBoss의 최소 분리 거리를 늘렸다.
  • 동일 좌표 또는 거의 동일 좌표일 때 deterministic escape vector를 적용했다.
  • 강한 즉시 위치 보정 대신 작은 보정값을 clamp하여 적용했다.
  • 분리 적용 시 vx, vy를 일부 감쇠하여 AI 이동과 separation이 서로 싸우는 힘을 줄였다.

의도:

  • 겹침은 천천히 풀되, 프레임마다 좌우로 튀는 느낌을 줄인다.
  • 적기가 낀 듯한 떨림보다 자연스러운 편대 간격 회복으로 보이게 한다.

검증

  • npm run build 성공
  • 출력 디렉터리: dist/47

후속 체크 포인트

  • Stage 1에서 엘리트/스트라이커 2기가 겹쳤을 때 떨림이 줄었는지 확인한다.
  • 적기가 지나치게 벌어져 난이도가 쉬워지지 않는지 확인한다.
  • Striker가 lane을 유지하면서도 플레이어를 압박하는 느낌이 살아있는지 확인한다.
  • Chase 계열 일반 적도 같은 문제가 계속 보이면 chase AI에도 lane/flow-field 기반 회피를 추가한다.