06 전장 맵 - kyhsa93/karda GitHub Wiki

06. 전장 맵

6.1 기존 시스템으로 만든다

전장 맵은 새 지형 엔진 없이 기존 src/sim/terrain.ts를 쓴다.

  • new Terrain(seed, { size: 12000, features, roads, pads }) — 12km, 셀 12.5m(961²), 청크 LOD 렌더, 생성 약 1초.
  • features: village(평탄화 + 민가), base, flatten, forest(밀도), bridge(교각·상판). roads: 폴리라인 → 평탄화 + 흙색 리본 + RoadGraph(A*).
  • 캠페인 제거(D13)로 missionTerrain()(임무 JSON → 지형)은 없어졌다. 같은 역할의 battleTerrain(map)을 sim/battle/schema.ts 옆에 둔다(B1-6).
  • 좌표: +x 동쪽, −z 북쪽, [x, z] m.

맵 파일은 src/content/battle/maps/<id>.json(기술 설계 9.6 BattleMapDef).

세 겹의 구역

구역 범위 (하레크 기준) 누가 내용
지상 전투 구역 가운데 약 3 × 3km(거점 7개) 보병·지상 탈것 중심 거점 간격 1.2~1.9km, 엄폐 소품 밀집
상세 지형 / 전투 구역 경계 12 × 12km(경계 ±5,800m) 헬기·지상 탈것 이동·본진 본진, 헬기 BP(엄폐 호버 위치), 능선, 후방 도로
외곽 공역 32 × 32km(경계 ±16,000m) 전투기만 100m 셀 저해상도 원경 지형(산맥), 유닛·거점 없음, 안개 — 전투기 15.3, 추가 결정 A2
  • 지상·헬기가 전투 구역 경계를 넘으면 10초 경고 후 사망(추가 결정 A3), 전투기는 외곽 공역 경계에 같은 규칙.

6.2 거점 배치 원칙 (콘텐츠 테스트로 고정)

# 원칙 수치 이유
1 두 본진 사이 ≥ 9km 본진 방공(전장 사거리 3km)이 서로의 본진·이륙 구역에 닿지 않게
2 본진 방공 본진 SAM 3km·대공포 2km, 어떤 거점도 적 본진 방공 사거리 안에 없다 본진 방공은 스폰 보호용이지 거점 방어가 아님
3 본진 → 가장 가까운 거점 3~3.5km 탈것으로 1.5~3분(도로 트럭 22m/s·장갑차 20m/s). 보병은 거점 스폰으로 전선에 선다
4 거점 사이 1.21.9km(보병 달리기 46분), 인접 거점 사이에 능선·숲·건물 등 시각 가시선 차단 1개 이상 보병 이동이 지루하지 않을 만큼 가깝고, 한 거점의 싸움이 옆 거점에 다 보이지 않을 만큼 떨어지게
5 거점 원·엄폐 반경 50m(마을 80m), 원 + 30m 평탄화, 원 안·주변 20m에 엄폐 소품 ≥ 10개(모래주머니·상자·막사 — 채택 CC0 모델), 건물이 있으면 외벽 엄폐 보병 교전에 12.5m 지형 격자는 너무 거칠다 → 소품이 엄폐를 만든다(보병 12.3)
6 헬기 BP 거점마다 2곳 이상, 거점에서 1.5~5km 팝업 공격(P2)
7 도로 모든 거점·본진이 도로 그래프로 연결 차량 이동
8 보병 격자 모든 거점·본진이 보병 격자(50m, 경사 < 35°)로 연결 걸어서 이동하는 분대
9 공정성 각 본진 → 모든 거점 도로 거리 합의 차이 ≤ 10% 한쪽이 늘 먼저 도착하지 않게(진영 대칭, D8)
10 거점 FARP 맵당 2곳, 각 진영 쪽으로 하나씩 헬기 전진 스폰·재보급의 가치
11 유닛 수 고정 + 편제(대규모) + 겹침 ≤ 150 기술 설계 9.7
12 파일 크기 ≤ 40KB 기존 콘텐츠 규칙
13 배치 금지 유닛·거점·FARP·BP·소품이 물·급경사 위가 아님
14 전투기 본진 상공 출격 지점에서 외곽 공역 경계까지 ≥ 8km, 재보급 회랑이 적 방공 사거리 밖 전투기 15.6
  • 원칙 1·4·9·13은 생성 도구(scripts/battle-map-gen.ts, 빌드 미포함)가 시드를 바꿔 가며 만족하는 지형을 찾는다.
  • 거점 효과(맵 데이터 asset): farp(헬기 스폰·재보급), radar(소유 쪽 미니맵에 5km 안 적 항공기 표시), artillery(선택, B9).

6.3 맵 1 — 하레크 계곡 (점령전·빠른 점령전) — B1·B5

  • 시간대: 주간·해질녘. 바람 기본 4m/s.
  • 지형: 남북으로 긴 계곡, 가운데 낮은 고지, 동서로 흐르는 물길 두 줄기(교량 2), 동·서쪽 끝은 높은 능선(헬기 BP).
                 북 (−z)
   ┌─────────────────────────────────────┐
   │              ■ VPA 본진 (0,−4500)      │
   │                                        │
   │      F 북부 교량        G 마르카 마을    │
   │      (−850,−1250)       (1000,−1350)    │
   │      [FARP]             (VPA 시작)      │
   │  C 곡물 창고   D 레이더 고지   E 송전소    │
   │  (−1450,−50)   (0,0)         (1450,50)  │
   │      A 솔티 마을        B 남부 교량      │
   │      (−1000,1300)       (900,1150)      │
   │      (연합 시작)        [FARP]          │
   │                                        │
   │              ■ 연합 본진 (0,4500)       │
   └─────────────────────────────────────┘
                 남 (+z)      (상세 지형 12km, 바깥은 외곽 공역)
거점 좌표 반경 가치 효과 지형·엄폐
A 솔티 마을 (−1000, 1300) 80 1.0 — village(민가 6, 민간 없음 — D9), 담장 소품
B 남부 교량 (900, 1150) 50 1.5 farp bridge + 동쪽 숲, 교량 양끝 모래주머니
C 곡물 창고 (−1450, −50) 50 1.0 — flatten + 막사 3·상자 더미
D 레이더 고지 (0, 0) 50 1.2 radar flatten 고지 + forest 둘레
E 송전소 (1450, 50) 50 1.0 — flatten + 코드 모델 철탑 2(엄폐·가시선 차단)
F 북부 교량 (−850, −1250) 50 1.5 farp bridge
G 마르카 마을 (1000, −1350) 80 1.0 — village(민가 6)

엄폐 소품·물길 계곡 (B2-3): 거점마다 소품 12개(모래주머니 6·상자 더미 3·담 2·막사 1)를 npm run battle:map -- --props가 도로·민가·물·급경사를 피해 배치했다(원칙 5 테스트). 소품은 충돌 상자(PROP_BOX)이자 가시선을 막고, 1.1m 이하는 넘을 수 있다. 처음 판 물길은 폭 30m에 둑 45m라 150m 깊이의 협곡이 되어 교량 거점 B·F가 허공에 떠 있었다 — 둑을 450m 직선 경사(약 18°)로 바꿔 넓은 계곡 바닥에 좁은 물길이 흐르게 했고, 교량 양끝 땅을 상판 높이로 맞춘다(BRIDGE_APPROACH). 하니스 재측정: 중앙값 12.1 / 11.6분, idle 50% / 35%, proxy 100%.

원점 대칭 (B1-15): 첫 하니스에서 어느 진영을 골라도 연합이 약 80% 이겼다 — 잡음 지형이라 남쪽(연합)이 고지대였고 D 고지를 연합만 내려다봤다. 지형 옵션 symmetry: 'point'(높이·숲·나무·건물을 북쪽 절반에서 원점 대칭으로 복사, 경계 300m 섞음)를 더하고 맵 좌표를 정확히 대칭으로 맞췄다: F (−900, −1150), G (1000, −1300), F 교량·물길·도로도 B 쪽의 대칭. 지형 시드 9. 그 뒤 승률은 진영 무관하게 30~40%(플레이어 진영 −1 분대)로 맞았다.

구현 (B1-6, src/content/battle/maps/harek.json)

  • 초안 좌표의 B–E가 1.12km로 원칙 4(≥ 1.2km)를 어겨 C·E를 바깥으로 옮겼다: C (−1450, −50), E (1450, 50) — 점대칭 유지.

  • 물길 두 줄기는 새 지형 요소 river(폭 30m, 바닥 −3m, 둑 45m)로 판다: 동쪽 능선 → B 교량 → 서쪽으로 사라짐, 서쪽 능선 → F 교량 → 동쪽으로 사라짐. 도로는 교량에서만 물을 건넌다. 교량 옆 도로 평탄화가 물길을 메우지 않게 교량 전체 폭에서 평탄화를 건너뛴다.

  • 기본 지형이 낮으면 호수가 전장을 덮어 지형 전체를 60m 올린다(terrain.lift).

  • 도로망은 원점 대칭(두 본진 도로 거리 합 차이 0%). FARP: 본진 둘 + B 옆 (1150, 950) + F 옆 (−1150, −1050).

  • 헬기 BP 6곳: (±2300, ±2600), (±2300, 0) — 빠른 점령전 구역(x ±2,500) 안에서도 거점마다 2곳.

  • 본진 고정 대공: 대공포 2(본진 ±120m) + SAM 1(본진 뒤 150m, 점령전만).

  • 지형 시드 290: npm run battle:map -- --search가 원칙 1·4·7·9·13을 만족하는 첫 시드를 찾았다. 원칙 7에 "도로가 교량 밖에서 물을 건너지 않는다"를 더했다.

  • 콘텐츠 테스트(sim/battle/schema.test.ts)가 빠른 점령전·점령전 모두 원칙 1·2·3·4·6·7·9·11·12·13을 검사한다(5·8·10·14는 소품·보병 격자·전투기 작업 때).

  • 거리 확인: 본진↔본진 9.0km(원칙 1). 연합 본진 → A 3.35km·→ B 3.47km(원칙 3). 인접 거점: A–C 1.33, A–D 1.64, A–B 1.9, B–D 1.46, B–E 1.2, C–D 1.3, D–E 1.3, C–F 1.3, D–F 1.5, D–G 1.68, E–G 1.46, F–G 1.85km(원칙 4). VPA 본진 → F 3.36km, SAM 3km 밖(원칙 2).

  • 시작 소유: 연합 A·B, VPA F·G, 중립 C·D·E. 첫 2~3분은 C·D·E로 달려가는 초반 러시.

  • 빠른 점령전: 거점 A(연합 시작)·D(중립)·G(VPA 시작), 전투 구역 x −2,5002,500 × z −5,0005,000.

  • 플레이 의도: D가 공중 전력의 균형추(radar). 교량 거점 B·F는 헬기 전진 기지 — 헬기를 모는 플레이어가 지상 싸움에 끼어들 이유.

6.4 맵 2 — 베로스 저수지 (점령전) — B9

  • 시간대: 주간·야간·안개(야간은 거점 조명과 탐조등, 보병 야간 투시경 없음 → 조명 사각이 엄폐).
  • 지형: 가운데 지름 약 1.8km 호수, 둘레에 거점 6. 가운데 거점이 없다 — 전투가 호수를 따라 돈다. 댐 위 도로가 유일한 지름길.
거점 좌표 효과 지형
A 남쪽 선착장 (−900, 1500) — village 소형
B 댐 서단 (−1500, 200) farp flatten + 댐(bridge 재사용)
C 댐 동단 (−700, −300) — 댐 끝 제어동(코드 모델)
D 수력 발전소 (800, −1500) farp base
E 북쪽 마을 (1500, −300) — village
F 동쪽 숲길 (1300, 1000) radar forest 짙음
  • 본진: 연합 (−2800, 3800), VPA (2800, −3800) — 대각선 9.4km.
  • 플레이 의도: 호수 위는 엄폐가 없다. 헬기가 가로지르면 빠르지만 방공에 노출(P2), 보병은 댐을 건너는 싸움.

6.5 맵 3 — 카르다 고개 (돌파 전용) — B9

  • 시간대: 해질녘(고정). 남→북으로 좁아지는 협곡(폭 약 2.5km, 양쪽 능선).
구역 거점 1 거점 2 수비 요소
1 검문소 (−600, 3000) 주유소 (700, 2600) 보병·경차량 위주, 방공 차량 1
2 고개 마을 (−700, 400) 벙커 진지 (600, 0) 벙커 3(기존 bunker), 전차 소대, 방공 차량 2
3 요새 사령부 (−400, −2600) 헬기장 (800, −3100) 단거리 SAM 2 + sam_radar, 공격 헬기 2(헬기장이 떨어지면 수비 헬기 재생성 중단)
  • 공격 본진 (0, 5200). 구역이 무너질 때마다 공격 본진·FARP가 앞 구역 뒤 1.5km로 전진.
  • 플레이 의도: 뒤 구역일수록 대공망이 두꺼워져 헬기·전투기를 모는 플레이어가 지상군을 먼저 도와야 한다 — 역할 전환(P5)의 이유.

6.6 맵별 콘텐츠 테스트

  • 원칙 1~14 전부(맵마다, 경기 방식마다).
  • 헤드리스 봇만 전투(플레이어 무입력) 20시드: 모든 거점의 소유가 80% 이상의 시드에서 한 번 이상 바뀐다 — 한 번도 안 바뀌는 거점은 배치가 잘못된 것.
  • 진영을 바꾼 하니스(플레이어 쪽 = VPA)에서도 같은 기준(대칭 확인).