145 스테이지 지형 기믹 배치(PD #1097 후속 · 레벨 배치 세션)

- 데이터: Assets/Data/Gimmicks/stage_gimmicks.csv 455행(143 스테이지 · 1-1·1-2 없음 · 샘플 5 스테이지 16행 그대로) = 기획 tables/ 사본(생성·사전 검증 = 기획 tables/_stage_gimmicks_gen.py) → TKS/Import Gimmicks → StageGimmickTable(455)
- 테스트: Tests/PlayMode/StageGimmickPlacementTests 2 — 145 스테이지 GimmickLayer.Build · 편성 좌표 보정 이동 0 · 아군 스폰 반경 2 비움 · 해로운 지대 위 적 스폰 0 · 파괴 불가 장애물 사이 폭 2 통로 · 강마다 다리 · 기믹 많은 5 스테이지 적 턴 결정 ≤ 1.5 초
- 캡처: GimmickImporter.Capture -gimmickStages 1-10,2-10,… = 그 스테이지 시작 화면(전장 전체)만
- 실측: 컴파일 0 · 임포트 OK(정의 16 · 배치 455) · PlayMode 115/115 · console error 0 · AI 적 턴 132~299 ms

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-11-06 02:05:30 +09:00
parent 8a7c565609
commit eda18a939e
6 changed files with 8232 additions and 13 deletions

View File

@ -2,16 +2,455 @@
1-3,thorn_bush,rect,-6,0,3,1,0,,,
1-3,thorn_bush,rect,6,0,3,1,0,,,
1-3,boulder,circle,0,2,0.8,,0,,,
1-4,boulder,circle,-4.5,-8.2,0.9,,0,,,
1-4,boulder,circle,4.5,-8.2,0.9,,0,,,
1-4,pit_trap,circle,2.6,-2.3,0.6,,0,,,
1-5,thorn_bush,rect,-7.5,-3,3,1.2,0,,,
1-5,thorn_bush,rect,7.5,-3,3,1.2,0,,,
1-5,boulder,circle,0,-8.4,0.9,,0,,,
1-5,pit_trap,circle,2.6,-2.4,0.6,,0,,,
1-6,palisade,rect,-1.3,-1.4,5.6,0.4,0,,,
1-6,palisade,rect,4.8,-1.4,2.4,0.4,0,,,
1-7,thorn_bush,rect,-8,-5,3,7,0,,,
1-7,thorn_bush,rect,8,-5,3,7,0,,,
1-7,pit_trap,circle,3.9,-7.5,0.6,,0,,,
1-8,burning_debris,circle,-5,-8.3,1.4,,0,,,
1-8,burning_debris,circle,5.5,-2.5,1.3,,0,,,
1-8,burning_debris,rect,0,4.2,6,1.4,0,,,
1-8,boulder,circle,-2.6,-8.6,0.8,,0,,,
1-9,palisade,rect,0,-1.3,5.6,0.4,0,,,
1-9,pit_trap,circle,-3.9,-2.4,0.6,,0,,,
1-10,palisade,rect,-4.5,4.5,6,0.4,0,,,
1-10,palisade,rect,4.5,4.5,6,0.4,0,,,
1-10,thorn_bush,rect,-7.5,-2.6,3,1.2,0,,,
1-10,thorn_bush,rect,7.5,-2.6,3,1.2,0,,,
1-10,pit_trap,circle,-3.9,-2.4,0.6,,0,,,
2-1,palisade,rect,0,-1.4,4,0.4,0,,,
2-1,banner,circle,-7,-3.5,1.5,,0,,,
2-2,high_ground,rect,7.5,-7,4,4,0,,,
2-2,boulder,circle,-3.5,-8.4,0.9,,0,,,
2-2,boulder,circle,-7,-2.8,0.9,,0,,,
2-3,high_ground,rect,-1.3,1,6.4,2.6,0,,,
2-3,palisade,rect,-1.3,-1.5,5,0.4,0,,,
2-4,fog,rect,0,-6.8,19,4,0,,,
2-4,palisade,rect,-5.5,-1.5,4,0.4,0,,,
2-4,palisade,rect,5.5,-1.5,4,0.4,0,,,
2-5,gate,rect,0,6,4,0.8,0,,,
2-5,wall,rect,-8,6,12,0.8,0,,,
2-5,wall,rect,8,6,12,0.8,0,,,
2-5,high_ground,rect,0,9,20,3,0,,,
2-6,wall,rect,-6.75,-1.6,5.5,0.8,0,,,
2-6,wall,rect,6.75,-1.6,5.5,0.8,0,,,
2-6,gate,rect,0,-1.6,4,0.8,0,,3,
2-6,boulder,circle,0,-8.3,0.8,,0,,,
2-7,palisade,rect,-5,-8,5,0.4,0,,,
2-7,palisade,rect,5,-8,5,0.4,0,,,
2-7,high_ground,rect,0,4.5,8,2.4,0,,,
2-8,high_ground,circle,7.2,-8.5,2,,0,,,
2-8,pit_trap,circle,-3.9,-7.6,0.6,,0,,,
2-9,wall,rect,-8,3.5,3,6,0,,,
2-9,palisade,rect,0,-8,6,0.4,0,,,
2-10,high_ground,rect,0,9,12,3,0,,,
2-10,palisade,rect,-5.5,-1.4,5,0.4,0,,,
2-10,palisade,rect,5.5,-1.4,5,0.4,0,,,
2-10,pit_trap,circle,3.9,-7.6,0.6,,0,,,
3-1,ice,rect,0,-2.5,8,2.6,0,,,
3-2,river,rect,0,-2.6,19,2,0,,,
3-2,bridge,rect,-4,-2.6,1.2,2,0,,,
3-2,bridge,rect,4,-2.6,1.2,2,0,,,
3-2,ice,rect,6.5,-8,5,2.4,0,,,
3-3,river,rect,0,4.2,19,2.2,0,,,
3-3,bridge,rect,0,4.2,1.2,2.2,0,,,
3-3,ice,rect,0,-8.2,8,2,0,,,
3-4,thorn_bush,rect,-4,-7.6,2.4,1,0,,,
3-4,thorn_bush,rect,4,-7.6,2.4,1,0,,,
3-4,palisade,rect,0,-1.4,12,0.4,0,,,
3-5,river,rect,0,4.4,19,2.2,0,,,
3-5,bridge,rect,-4,4.4,1.2,2.2,0,,,
3-5,bridge,rect,4,4.4,1.2,2.2,0,,,
3-5,palisade,rect,0,-1.4,10,0.4,0,,,
3-5,ice,rect,0,-8.4,6,2,0,,,
3-6,boulder,circle,-6.5,-2.6,0.9,,0,,,
3-6,boulder,circle,6.5,-2.6,0.9,,0,,,
3-7,palisade,rect,0,-1.4,5,0.4,0,,,
3-7,banner,circle,6.8,-7.5,1.5,,0,,,
3-8,palisade,rect,-5,-8.2,6,0.4,0,,,
3-8,palisade,rect,5,-8.2,6,0.4,0,,,
3-8,thorn_bush,rect,-7.8,-2.6,3,1.2,0,,,
3-8,thorn_bush,rect,7.8,-2.6,3,1.2,0,,,
3-9,wall,rect,-5.75,4.6,7.5,0.8,0,,,
3-9,gate,rect,0,4.6,4,0.8,0,,3,
3-9,wall,rect,5.75,4.6,7.5,0.8,0,,,
3-10,wall,rect,-5.75,5.2,7.5,0.8,0,,,
3-10,gate,rect,0,5.2,4,0.8,0,,,
3-10,wall,rect,5.75,5.2,7.5,0.8,0,,,
3-10,pit_trap,circle,0,3.2,0.6,,0,,,
3-10,pit_trap,circle,-3.9,-2.3,0.6,,0,,,
3-11,burning_debris,circle,-5.5,-8.2,1.3,,0,,,
3-11,burning_debris,circle,4.5,-2.6,1.3,,0,,,
3-11,burning_debris,rect,0,4.4,6,1.6,0,,,
3-12,palisade,rect,-1.3,-1.4,6,0.4,0,,,
3-12,banner,circle,0,4.4,1.5,,0,,,
3-13,thorn_bush,rect,-7.8,-8.2,3,1.2,0,,,
3-13,thorn_bush,rect,7.8,-8.2,3,1.2,0,,,
3-14,palisade,rect,-4,-1.4,4,0.4,0,,,
3-14,palisade,rect,4,-1.4,4,0.4,0,,,
3-14,banner,circle,-7.5,-3.5,1.5,,0,,,
3-15,palisade,rect,-5,4.4,7,0.4,0,,,
3-15,palisade,rect,5,4.4,7,0.4,0,,,
3-15,banner,circle,0,9.4,1.5,,0,,,
3-15,pit_trap,circle,3.9,-7.6,0.6,,0,,,
4-1,swamp,rect,-6.5,-8,6,3,0,,,
4-2,river,rect,0,4.2,19,2,0,,,
4-2,bridge,rect,-5,4.2,1.2,2,0,,,
4-2,bridge,rect,5,4.2,1.2,2,0,,,
4-2,swamp,rect,5.5,-2.6,5,2.4,0,,,
4-3,swamp,rect,0,-2.6,6,2.4,0,,,
4-3,poison_marsh,circle,-6.5,-7.5,1.6,,0,,,
4-3,poison_marsh,circle,6.5,-7.5,1.6,,0,,,
4-4,fog,rect,0,-6.8,19,4,0,,,
4-4,palisade,rect,-1.3,-1.4,6,0.4,0,,,
4-5,river,rect,0,4.4,19,2.2,0,,,
4-5,bridge,rect,-3.5,4.4,1.2,2.2,0,,,
4-5,bridge,rect,3.5,4.4,1.2,2.2,0,,,
4-5,swamp,rect,-6.5,-2.6,6,2.4,0,,,
4-5,poison_marsh,circle,5.8,-8,1.4,,0,,,
4-6,wall,rect,-6,4.6,7,0.8,0,,,
4-6,wall,rect,6,4.6,7,0.8,0,,,
4-6,fog,rect,0,-7,19,3.6,0,,,
4-7,palisade,rect,-5,-8.2,5,0.4,0,,,
4-7,palisade,rect,5,-8.2,5,0.4,0,,,
4-8,swamp,rect,0,-2.6,19,2.4,0,,,
4-9,high_ground,rect,0,10,6,2.6,0,,,
4-9,palisade,rect,0,-1.4,8,0.4,0,,,
4-10,wall,rect,-6.5,-8.8,6,0.8,0,,,
4-10,wall,rect,6.5,-8.8,6,0.8,0,,,
4-10,palisade,rect,-1.3,-1.4,6,0.4,0,,,
4-10,poison_marsh,circle,6.5,-3,1.4,,0,,,
4-11,swamp,rect,0,4.2,12,2.4,0,,,
4-12,palisade,rect,0,-1.4,8,0.4,0,,,
4-12,pit_trap,circle,3.9,-7.6,0.6,,0,,,
4-12,pit_trap,circle,-2.6,-2.4,0.6,,0,,,
4-13,swamp,rect,0,0,20,6,0,,,
4-13,poison_marsh,circle,-4,2,2,,0,,,
4-13,poison_marsh,circle,4,2,2,,0,,,
4-14,wall,rect,-5.75,5,7.5,0.8,0,,,
4-14,gate,rect,0,5,4,0.8,0,,2,
4-14,wall,rect,5.75,5,7.5,0.8,0,,,
4-14,swamp,rect,0,-8,10,2.4,0,,,
4-15,high_ground,rect,0,10.4,8,2.8,0,,,
4-15,palisade,rect,-4.5,4.4,6,0.4,0,,,
4-15,palisade,rect,4.5,4.4,6,0.4,0,,,
4-15,swamp,rect,-6.8,-8,5,2.4,0,,,
4-15,swamp,rect,6.8,-8,5,2.4,0,,,
5-1,thorn_bush,rect,-6.8,-7.8,2.6,1.6,0,,,
5-1,thorn_bush,rect,6.8,-2.6,2.6,1.6,0,,,
5-1,pit_trap,circle,-1.3,-7.6,0.6,,0,,,
5-2,banner,circle,0,-2.6,1.5,,0,,,
5-3,palisade,rect,-1.3,-1.4,6,0.4,0,,,
5-4,banner,circle,0,4.4,1.5,,0,,,
5-4,palisade,rect,0,-1.4,8,0.4,0,,,
5-5,banner,circle,-7,-3,1.5,,0,,,
5-5,banner,circle,7,-3,1.5,,0,,,
5-5,pit_trap,circle,3.9,-7.6,0.6,,0,,,
5-6,boulder,circle,-6.5,-8,0.9,,0,,,
5-6,boulder,circle,6.5,-2.6,0.9,,0,,,
5-6,boulder,circle,0,4.2,0.9,,0,,,
5-7,fog,circle,-6.5,-2.6,2.6,,0,,,
5-7,fog,circle,6.5,-2.6,2.6,,0,,,
5-7,pit_trap,circle,0,-7.8,0.6,,0,,,
5-8,wall,rect,-5.75,5,7.5,0.8,0,,,
5-8,gate,rect,0,5,4,0.8,0,,,
5-8,wall,rect,5.75,5,7.5,0.8,0,,,
5-8,banner,circle,0,8.8,1.5,,0,,,
5-9,banner,circle,-7,-7.8,1.5,,0,,,
5-9,palisade,rect,0,-1.4,8,0.4,0,,,
5-10,palisade,rect,-5,4.4,7,0.4,0,,,
5-10,palisade,rect,5,4.4,7,0.4,0,,,
5-10,banner,circle,0,9.2,1.5,,0,,,
5-10,pit_trap,circle,3.9,-7.6,0.6,,0,,,
5-11,fog,rect,0,-6.8,19,4,0,,,
5-11,pit_trap,circle,-2.6,-7.6,0.6,,0,,,
5-11,pit_trap,circle,5.2,-7.6,0.6,,0,,,
5-12,swamp,rect,-6.8,-2.6,5,2.4,0,,,
5-12,swamp,rect,6.8,-2.6,5,2.4,0,,,
5-13,banner,circle,0,-8.2,1.5,,0,,,
5-14,pit_trap,circle,0,-2.4,0.6,,0,,,
5-14,pit_trap,circle,-2.6,3.6,0.6,,0,,,
5-14,swamp,rect,-6.8,-8,5,2.4,0,,,
5-15,high_ground,rect,0,-8.6,8,2.6,0,,,
5-15,boulder,circle,-5.5,-2.6,0.9,,0,,,
5-15,boulder,circle,5.5,-2.6,0.9,,0,,,
5-15,banner,circle,0,4.4,1.5,,0,,,
6-1,palisade,rect,-1.3,-1.4,6,0.4,0,,,
6-2,high_ground,rect,-6.8,-7.6,5,3,0,,,
6-3,palisade,rect,-5,4.4,7,0.4,0,,,
6-3,palisade,rect,5,4.4,7,0.4,0,,,
6-3,banner,circle,0,9.2,1.5,,0,,,
6-4,palisade,rect,-7.5,-7.8,3.5,0.4,0,,,
6-4,palisade,rect,7.5,-7.8,3.5,0.4,0,,,
6-4,high_ground,circle,0,-2.6,1.8,,0,,,
6-5,banner,circle,0,11,1.5,,0,,,
6-5,palisade,rect,-5,4.4,7,0.4,0,,,
6-5,palisade,rect,5,4.4,7,0.4,0,,,
6-6,river,rect,0,-2.6,19,2.2,0,,,
6-6,bridge,rect,-4,-2.6,1.2,2.2,0,,,
6-6,bridge,rect,4,-2.6,1.2,2.2,0,,,
6-7,boulder,circle,-6.8,-2.6,0.9,,0,,,
6-7,boulder,circle,6.8,-2.6,0.9,,0,,,
6-7,boulder,circle,0,-8.4,0.8,,0,,,
6-8,high_ground,rect,6.8,-2.6,5,3,0,,,
6-9,river,rect,0,5,19,2.2,0,,,
6-9,bridge,rect,-4.5,5,1.2,2.2,0,,,
6-9,bridge,rect,4.5,5,1.2,2.2,0,,,
6-10,river,rect,0,5,19,2.2,0,,,
6-10,bridge,rect,0,5,1.2,2.2,0,,,
6-10,high_ground,rect,-6.8,-7.8,5,3,0,,,
6-11,wall,rect,-7.25,5,4.5,0.8,0,,,
6-11,gate,rect,-3,5,4,0.8,0,,,
6-11,wall,rect,4.25,5,10.5,0.8,0,,,
6-11,high_ground,rect,0,8.8,19,2.6,0,,,
6-12,pit_trap,circle,0,3.6,0.6,,0,,,
6-12,pit_trap,circle,5.2,-7.6,0.6,,0,,,
6-12,high_ground,rect,-6.8,-8.2,5,2.6,0,,,
6-13,wall,rect,-5.75,5,7.5,0.8,0,,,
6-13,gate,rect,0,5,4,0.8,0,,,
6-13,wall,rect,5.75,5,7.5,0.8,0,,,
6-13,palisade,rect,0,-1.4,8,0.4,0,,,
6-14,pit_trap,circle,-2.6,-7.6,0.6,,0,,,
6-14,pit_trap,circle,2.6,-7.6,0.6,,0,,,
6-14,thorn_bush,rect,-7.8,-2.6,3,1.2,0,,,
6-14,thorn_bush,rect,7.8,-2.6,3,1.2,0,,,
6-15,wall,rect,-5.75,5,7.5,0.8,0,,,
6-15,gate,rect,0,5,4,0.8,0,,,
6-15,wall,rect,5.75,5,7.5,0.8,0,,,
6-15,high_ground,rect,0,9.4,8,2.4,0,,,
6-15,pit_trap,circle,5.2,-7.6,0.6,,0,,,
6-16,fog,rect,0,-6.8,19,4,0,,,
6-17,burning_debris,rect,-6,-7.6,6,1.6,0,,,
6-17,burning_debris,rect,6,-2.6,5,1.6,0,,,
6-17,powder_cart,circle,-2,-1,0.6,,0,,,
6-18,wall,rect,-4.75,5,9.5,0.8,0,,,
6-18,gate,rect,2,5,4,0.8,0,,,
6-18,wall,rect,6.75,5,5.5,0.8,0,,,
6-18,burning_debris,circle,-6.5,-7.8,1.3,,0,,,
6-18,burning_debris,circle,6.5,-7.8,1.3,,0,,,
6-19,river,rect,0,5,19,2.2,0,,,
6-19,bridge,rect,0,5,1.2,2.2,0,,,
6-19,palisade,rect,0,-1.4,8,0.4,0,,,
6-20,river,rect,0,-8.6,19,2,0,,,
6-20,bridge,rect,-6,-8.6,1.2,2,0,,,
6-20,bridge,rect,0,-8.6,1.2,2,0,,,
6-20,bridge,rect,6,-8.6,1.2,2,0,,,
6-20,high_ground,circle,-6.8,-2.6,2,,0,,,
7-1,boulder,circle,-6.8,-8.2,0.9,,0,,,
7-1,boulder,circle,6.8,-8.2,0.9,,0,,,
7-2,palisade,rect,-1.3,-1.4,6,0.4,0,,,
7-2,pit_trap,circle,-5.2,-2.4,0.6,,0,,,
7-3,boulder,circle,0,-2.6,0.9,,0,,,
7-3,boulder,circle,-6.8,-7.8,0.9,,0,,,
7-4,thorn_bush,rect,-7.8,-7.8,3,1.2,0,,,
7-4,thorn_bush,rect,7.8,-7.8,3,1.2,0,,,
7-4,pit_trap,circle,5.2,-7.6,0.6,,0,,,
7-5,boulder,circle,-2.6,-8.2,0.9,,0,,,
7-5,boulder,circle,2.6,-8.2,0.9,,0,,,
7-5,pit_trap,circle,5.2,-7.4,0.6,,0,,,
7-5,banner,circle,0,4.8,1.5,,0,,,
7-6,boulder,circle,-6.8,-2.6,0.9,,0,,,
7-6,boulder,circle,6.8,-2.6,0.9,,0,,,
7-7,palisade,rect,-6.8,-7.6,4,0.4,0,,,
7-7,palisade,rect,6.8,-7.6,4,0.4,0,,,
7-8,boulder,circle,0,-8.4,0.8,,0,,,
7-8,boulder,circle,-6.8,-2.6,0.9,,0,,,
7-8,pit_trap,circle,2.6,-2.4,0.6,,0,,,
7-8,pit_trap,circle,5.2,-7.6,0.6,,0,,,
7-9,thorn_bush,rect,-8.2,-4,2.4,6,0,,,
7-9,thorn_bush,rect,8.2,-4,2.4,6,0,,,
7-9,boulder,circle,0,-2.4,0.9,,0,,,
7-10,thorn_bush,rect,-8,-8,3,1.2,0,,,
7-10,thorn_bush,rect,8,-8,3,1.2,0,,,
7-10,boulder,circle,0,-8.6,0.9,,0,,,
7-10,pit_trap,circle,-3.2,-7.6,0.6,,0,,,
8-1,thorn_bush,rect,-7.8,-7.8,3,1.2,0,,,
8-1,thorn_bush,rect,7.8,-2.6,3,1.2,0,,,
8-2,river,rect,0,4.2,19,2,0,,,
8-2,bridge,rect,-5,4.2,1.2,2,0,,,
8-2,bridge,rect,3,4.2,1.2,2,0,,,
8-3,high_ground,rect,-1.3,1,10,2.6,0,,,
8-3,palisade,rect,-1.3,-1.4,10,0.4,0,,,
8-4,powder_cart,circle,-1.3,-0.9,0.6,,0,,,
8-4,pit_trap,circle,5.2,-7.6,0.6,,0,,,
8-5,river,rect,0,5,19,2.2,0,,,
8-5,bridge,rect,-4,5,1.2,2.2,0,,,
8-5,bridge,rect,4,5,1.2,2.2,0,,,
8-5,powder_cart,circle,-6.8,-2.6,0.6,,0,,,
8-5,powder_cart,circle,6.8,-2.6,0.6,,0,,,
8-5,pit_trap,circle,-5.2,-7.6,0.6,,0,,,
8-6,fog,rect,0,-6.8,19,4,0,,,
8-6,wall,rect,-8.6,-2,1.6,8,0,,,
8-6,wall,rect,8.6,-2,1.6,8,0,,,
8-7,river,rect,0,-8.4,19,1.6,0,,,
8-7,bridge,rect,0,-8.4,1.2,1.6,0,,,
8-7,swamp,rect,-6,-2.6,6,2,0,,,
8-8,pit_trap,circle,-5.2,-7.6,0.6,,0,,,
8-8,pit_trap,circle,5.2,-7.6,0.6,,0,,,
8-8,powder_cart,circle,3.9,-0.9,0.6,,0,,,
8-9,palisade,rect,-4.5,-8,5,0.4,0,,,
8-9,palisade,rect,4.5,-8,5,0.4,0,,,
8-9,swamp,rect,0,-2.6,8,2.4,0,,,
8-10,palisade,rect,-4.5,-1.6,5,0.4,0,,,
8-10,palisade,rect,4.5,-1.6,5,0.4,0,,,
8-10,pit_trap,circle,0,-1.6,0.6,,0,,,
8-10,pit_trap,circle,-8.4,-1.6,0.6,,0,,,
8-10,banner,circle,8,-3.8,1.5,,0,,,
8-11,wall,rect,-5.75,5.2,7.5,0.8,0,,,
8-11,gate,rect,0,5.2,4,0.8,0,,3,
8-11,wall,rect,5.75,5.2,7.5,0.8,0,,,
8-12,wall,rect,-6.75,-8.6,5.5,0.8,0,,,
8-12,wall,rect,0,-8.6,3,0.8,0,,,
8-12,wall,rect,6.75,-8.6,5.5,0.8,0,,,
8-13,ice,rect,0,-8,10,2.2,0,,,
8-13,ice,rect,0,4.6,12,2.4,0,,,
8-13,boulder,circle,-7,-2.6,0.9,,0,,,
8-13,boulder,circle,7,-2.6,0.9,,0,,,
8-14,thorn_bush,rect,-7.6,-7.6,3.2,1.4,0,,,
8-14,thorn_bush,rect,7.6,-7.6,3.2,1.4,0,,,
8-14,thorn_bush,rect,0,5,6,1.2,0,,,
8-14,powder_cart,circle,-1.9,-0.9,0.6,,0,,,
8-15,burning_debris,rect,0,0,20,32,0,,,spawn_on_splash=1;burn_turns=3
8-15,powder_cart,circle,-3,4,0.6,,0,,,
8-15,powder_cart,circle,3,4,0.6,,0,,,
9-1,burning_debris,rect,0,0,20,32,0,,,spawn_on_splash=1;burn_turns=3
9-1,burning_debris,circle,-6.8,-2.6,1.3,,0,,,
9-1,burning_debris,circle,6.8,4.4,1.3,,0,,,
9-1,powder_cart,circle,0.6,-0.9,0.6,,0,,,
9-2,river,rect,0,5.2,19,2,0,,,
9-2,bridge,rect,-3,5.2,1.2,2,0,,,
9-2,bridge,rect,3,5.2,1.2,2,0,,,
9-2,swamp,rect,0,-2.6,19,2.2,0,,,
9-3,river,rect,0,-2.6,19,2,0,,,
9-3,bridge,rect,0,-2.6,1.2,2,0,,,
9-3,fog,circle,-6.5,-7.8,2.4,,0,,,
9-4,river,rect,0,-8.6,19,2,0,,,
9-4,bridge,rect,-6,-8.6,1.2,2,0,,,
9-4,bridge,rect,0,-8.6,1.2,2,0,,,
9-4,bridge,rect,6,-8.6,1.2,2,0,,,
9-5,wall,rect,-5.75,5.2,7.5,0.8,0,,,
9-5,gate,rect,0,5.2,4,0.8,0,,4,
9-5,wall,rect,5.75,5.2,7.5,0.8,0,,,
9-5,high_ground,rect,0,10,12,3,0,,,
9-6,fog,rect,0,-8.4,19,2.6,0,,,
9-6,palisade,rect,-5.5,-8.4,4,0.4,0,,,
9-6,palisade,rect,5.5,-8.4,4,0.4,0,,,
9-7,river,rect,0,5.2,19,2,0,,,
9-7,bridge,rect,-6,5.2,1.2,2,0,,,
9-7,bridge,rect,0,5.2,1.2,2,0,,,
9-7,fog,circle,5.5,-2.6,2.2,,0,,,
9-8,fog,rect,0,-2.4,19,2.6,0,,,
9-8,high_ground,rect,6.8,-7.8,5,2.8,0,,,
9-9,river,rect,0,-2.6,19,2,0,,,
9-9,bridge,rect,-3.5,-2.6,1.2,2,0,,,
9-9,bridge,rect,3.5,-2.6,1.2,2,0,,,
9-9,palisade,rect,0,-0.9,6,0.4,0,,,
9-10,pit_trap,circle,-5.5,-7.8,0.6,,0,,,
9-10,pit_trap,circle,3.6,-7.6,0.6,,0,,,
9-10,high_ground,rect,0,10.6,10,3,0,,,
9-10,fog,circle,6.8,-2,2,,0,,,
9-11,river,rect,0,3,20,2,0,,,
9-11,bridge,rect,0,3,1.2,2,0,,,
9-11,fog,circle,0,8,4,,0,,,
9-12,river,rect,0,5.2,19,2,0,,,
9-12,bridge,rect,-7,5.2,1.2,2,0,,,
9-12,boulder,circle,0,-8.6,0.8,,0,,,
9-13,fog,rect,0,-7,19,3.6,0,,,
9-14,river,rect,0,-8.8,19,2,0,,,
9-14,bridge,rect,-6,-8.8,1.2,2,0,,,
9-14,bridge,rect,0,-8.8,1.2,2,0,,,
9-14,bridge,rect,6,-8.8,1.2,2,0,,,
9-14,fog,circle,0,2,2.4,,0,,,
9-15,river,rect,0,5.2,19,2,0,,,
9-15,bridge,rect,-4,5.2,1.2,2,0,,,
9-15,bridge,rect,4,5.2,1.2,2,0,,,
9-15,high_ground,rect,0,10.4,8,3,0,,,
9-15,fog,circle,-6.8,-7.6,2.2,,0,,,
10-1,banner,circle,0,-8.2,1.5,,0,,,
10-1,palisade,rect,-6.5,-7.6,5,0.4,0,,,
10-1,palisade,rect,6.5,-7.6,5,0.4,0,,,
10-2,river,rect,0,-2.6,19,2.2,0,,,
10-2,bridge,rect,-7,-2.6,1.2,2.2,0,,,
10-2,bridge,rect,0,-2.6,1.2,2.2,0,,,
10-2,bridge,rect,7,-2.6,1.2,2.2,0,,,
10-2,palisade,rect,-4,-0.9,4,0.4,0,,,
10-2,palisade,rect,4,-0.9,4,0.4,0,,,
10-3,river,rect,0,4.4,19,2.2,0,,,
10-3,bridge,rect,-3,4.4,1.2,2.2,0,,,
10-3,bridge,rect,3,4.4,1.2,2.2,0,,,
10-3,palisade,rect,0,-1,12,0.4,0,,,
10-4,ice,rect,0,-2.8,12,1.6,0,,,
10-4,powder_cart,circle,-1.3,-0.9,0.6,,0,,,
10-5,river,rect,0,-8.4,19,1.8,0,,,
10-5,bridge,rect,-5,-8.4,1.2,1.8,0,,,
10-5,bridge,rect,0,-8.4,1.2,1.8,0,,,
10-5,bridge,rect,5,-8.4,1.2,1.8,0,,,
10-5,palisade,rect,-4.5,4.4,6,0.4,0,,,
10-5,palisade,rect,4.5,4.4,6,0.4,0,,,
10-5,powder_cart,circle,-4.4,-1,0.6,,0,,,
10-6,fog,rect,0,-4,19,9,0,,,
10-6,river,rect,0,5,19,2,0,,,
10-6,bridge,rect,0,5,1.2,2,0,,,
10-7,fog,circle,0,-2.4,2.6,,0,,,
10-7,thorn_bush,rect,-7.6,-7.8,3.2,1.4,0,,,
10-7,thorn_bush,rect,7.6,-7.8,3.2,1.4,0,,,
10-8,river,rect,0,-2.8,19,2,0,,,
10-8,bridge,rect,-6,-2.8,1.2,2,0,,,
10-8,bridge,rect,-2,-2.8,1.2,2,0,,,
10-8,bridge,rect,2,-2.8,1.2,2,0,,,
10-8,bridge,rect,6,-2.8,1.2,2,0,,,
10-8,powder_cart,circle,1.3,-0.9,0.6,,0,,,
10-9,palisade,rect,-5,4.6,7,0.4,0,,,
10-9,palisade,rect,5,4.6,7,0.4,0,,,
10-9,fog,rect,0,-7.4,19,3.2,0,,,
10-10,river,rect,0,-8.4,19,1.8,0,,,
10-10,bridge,rect,-6,-8.4,1.2,1.8,0,,,
10-10,bridge,rect,0,-8.4,1.2,1.8,0,,,
10-10,bridge,rect,6,-8.4,1.2,1.8,0,,,
10-10,powder_cart,circle,-1.3,-0.9,0.6,,0,,,
10-10,powder_cart,circle,2.6,-0.9,0.6,,0,,,
10-10,palisade,rect,0,9.2,8,0.4,0,,,
10-11,burning_debris,rect,0,0,20,32,0,,,spawn_on_splash=1;burn_turns=3
10-11,powder_cart,circle,-3.9,-1,0.6,,0,,,
10-11,powder_cart,circle,3.9,-1,0.6,,0,,,
10-12,burning_debris,rect,0,0,20,32,0,,,spawn_on_splash=1;burn_turns=3
10-12,burning_debris,rect,-6,-7.8,5,1.6,0,,,
10-12,burning_debris,rect,6,4.6,5,1.6,0,,,
10-12,river,rect,0,-2.6,19,1.8,0,,,
10-12,bridge,rect,-4,-2.6,1.2,1.8,0,,,
10-12,bridge,rect,4,-2.6,1.2,1.8,0,,,
10-13,burning_debris,circle,-6.8,-2.4,1.3,,0,,,
10-13,burning_debris,circle,6.8,4.6,1.3,,0,,,
10-13,palisade,rect,-4.5,4.6,5,0.4,0,,,
10-13,palisade,rect,2.8,4.6,4,0.4,0,,,
10-14,fog,rect,0,-8.2,19,2.8,0,,,
10-14,powder_cart,circle,-1.9,-0.9,0.6,,0,,,
10-14,powder_cart,circle,3.2,-0.9,0.6,,0,,,
10-15,river,rect,0,5.2,19,2,0,,,
10-15,bridge,rect,-5,5.2,1.2,2,0,,,
10-15,bridge,rect,5,5.2,1.2,2,0,,,
10-15,burning_debris,rect,-6,-2.4,5,1.6,0,,,
10-15,burning_debris,rect,6.5,-2,4,1.6,0,,,
10-15,powder_cart,circle,-4.4,1.4,0.6,,0,,,
10-16,thorn_bush,rect,-7.8,-4,2.8,5,0,,,
10-16,thorn_bush,rect,7.8,-4,2.8,5,0,,,
10-16,fog,circle,0,-7.6,2,,0,,,
10-17,thorn_bush,rect,-8.2,-2,2.4,8,0,,,
10-17,thorn_bush,rect,8.2,-2,2.4,8,0,,,
10-17,burning_debris,circle,-2.6,4.4,0.9,,0,,,
10-17,burning_debris,circle,2.6,4.4,0.9,,0,,,
10-18,swamp,rect,0,-2.6,19,2.4,0,,,
10-18,swamp,rect,-6.5,-8.2,6,2.4,0,,,
10-19,swamp,rect,0,-8.4,12,2,0,,,
10-19,fog,circle,0,4.8,2.2,,0,,,
10-20,thorn_bush,rect,-7.25,-6,4.5,6,0,,,
10-20,thorn_bush,rect,7.25,-6,4.5,6,0,,,
10-20,swamp,rect,0,-8.4,8,2,0,,,
10-20,fog,circle,0,10.6,2.4,,0,,,

1 stage gimmick_id shape cx cy w_or_r h rot points hp_override params
2 1-3 thorn_bush rect -6 0 3 1 0
3 1-3 thorn_bush rect 6 0 3 1 0
4 1-3 boulder circle 0 2 0.8 0
5 1-4 boulder circle -4.5 -8.2 0.9 0
6 1-4 boulder circle 4.5 -8.2 0.9 0
7 1-4 pit_trap circle 2.6 -2.3 0.6 0
8 1-5 thorn_bush rect -7.5 -3 3 1.2 0
9 1-5 thorn_bush rect 7.5 -3 3 1.2 0
10 1-5 boulder circle 0 -8.4 0.9 0
11 1-5 pit_trap circle 2.6 -2.4 0.6 0
12 1-6 palisade rect -1.3 -1.4 5.6 0.4 0
13 1-6 palisade rect 4.8 -1.4 2.4 0.4 0
14 1-7 thorn_bush rect -8 -5 3 7 0
15 1-7 thorn_bush rect 8 -5 3 7 0
16 1-7 pit_trap circle 3.9 -7.5 0.6 0
17 1-8 burning_debris circle -5 -8.3 1.4 0
18 1-8 burning_debris circle 5.5 -2.5 1.3 0
19 1-8 burning_debris rect 0 4.2 6 1.4 0
20 1-8 boulder circle -2.6 -8.6 0.8 0
21 1-9 palisade rect 0 -1.3 5.6 0.4 0
22 1-9 pit_trap circle -3.9 -2.4 0.6 0
23 1-10 palisade rect -4.5 4.5 6 0.4 0
24 1-10 palisade rect 4.5 4.5 6 0.4 0
25 1-10 thorn_bush rect -7.5 -2.6 3 1.2 0
26 1-10 thorn_bush rect 7.5 -2.6 3 1.2 0
27 1-10 pit_trap circle -3.9 -2.4 0.6 0
28 2-1 palisade rect 0 -1.4 4 0.4 0
29 2-1 banner circle -7 -3.5 1.5 0
30 2-2 high_ground rect 7.5 -7 4 4 0
31 2-2 boulder circle -3.5 -8.4 0.9 0
32 2-2 boulder circle -7 -2.8 0.9 0
33 2-3 high_ground rect -1.3 1 6.4 2.6 0
34 2-3 palisade rect -1.3 -1.5 5 0.4 0
35 2-4 fog rect 0 -6.8 19 4 0
36 2-4 palisade rect -5.5 -1.5 4 0.4 0
37 2-4 palisade rect 5.5 -1.5 4 0.4 0
38 2-5 gate rect 0 6 4 0.8 0
39 2-5 wall rect -8 6 12 0.8 0
40 2-5 wall rect 8 6 12 0.8 0
41 2-5 high_ground rect 0 9 20 3 0
42 2-6 wall rect -6.75 -1.6 5.5 0.8 0
43 2-6 wall rect 6.75 -1.6 5.5 0.8 0
44 2-6 gate rect 0 -1.6 4 0.8 0 3
45 2-6 boulder circle 0 -8.3 0.8 0
46 2-7 palisade rect -5 -8 5 0.4 0
47 2-7 palisade rect 5 -8 5 0.4 0
48 2-7 high_ground rect 0 4.5 8 2.4 0
49 2-8 high_ground circle 7.2 -8.5 2 0
50 2-8 pit_trap circle -3.9 -7.6 0.6 0
51 2-9 wall rect -8 3.5 3 6 0
52 2-9 palisade rect 0 -8 6 0.4 0
53 2-10 high_ground rect 0 9 12 3 0
54 2-10 palisade rect -5.5 -1.4 5 0.4 0
55 2-10 palisade rect 5.5 -1.4 5 0.4 0
56 2-10 pit_trap circle 3.9 -7.6 0.6 0
57 3-1 ice rect 0 -2.5 8 2.6 0
58 3-2 river rect 0 -2.6 19 2 0
59 3-2 bridge rect -4 -2.6 1.2 2 0
60 3-2 bridge rect 4 -2.6 1.2 2 0
61 3-2 ice rect 6.5 -8 5 2.4 0
62 3-3 river rect 0 4.2 19 2.2 0
63 3-3 bridge rect 0 4.2 1.2 2.2 0
64 3-3 ice rect 0 -8.2 8 2 0
65 3-4 thorn_bush rect -4 -7.6 2.4 1 0
66 3-4 thorn_bush rect 4 -7.6 2.4 1 0
67 3-4 palisade rect 0 -1.4 12 0.4 0
68 3-5 river rect 0 4.4 19 2.2 0
69 3-5 bridge rect -4 4.4 1.2 2.2 0
70 3-5 bridge rect 4 4.4 1.2 2.2 0
71 3-5 palisade rect 0 -1.4 10 0.4 0
72 3-5 ice rect 0 -8.4 6 2 0
73 3-6 boulder circle -6.5 -2.6 0.9 0
74 3-6 boulder circle 6.5 -2.6 0.9 0
75 3-7 palisade rect 0 -1.4 5 0.4 0
76 3-7 banner circle 6.8 -7.5 1.5 0
77 3-8 palisade rect -5 -8.2 6 0.4 0
78 3-8 palisade rect 5 -8.2 6 0.4 0
79 3-8 thorn_bush rect -7.8 -2.6 3 1.2 0
80 3-8 thorn_bush rect 7.8 -2.6 3 1.2 0
81 3-9 wall rect -5.75 4.6 7.5 0.8 0
82 3-9 gate rect 0 4.6 4 0.8 0 3
83 3-9 wall rect 5.75 4.6 7.5 0.8 0
84 3-10 wall rect -5.75 5.2 7.5 0.8 0
85 3-10 gate rect 0 5.2 4 0.8 0
86 3-10 wall rect 5.75 5.2 7.5 0.8 0
87 3-10 pit_trap circle 0 3.2 0.6 0
88 3-10 pit_trap circle -3.9 -2.3 0.6 0
89 3-11 burning_debris circle -5.5 -8.2 1.3 0
90 3-11 burning_debris circle 4.5 -2.6 1.3 0
91 3-11 burning_debris rect 0 4.4 6 1.6 0
92 3-12 palisade rect -1.3 -1.4 6 0.4 0
93 3-12 banner circle 0 4.4 1.5 0
94 3-13 thorn_bush rect -7.8 -8.2 3 1.2 0
95 3-13 thorn_bush rect 7.8 -8.2 3 1.2 0
96 3-14 palisade rect -4 -1.4 4 0.4 0
97 3-14 palisade rect 4 -1.4 4 0.4 0
98 3-14 banner circle -7.5 -3.5 1.5 0
99 3-15 palisade rect -5 4.4 7 0.4 0
100 3-15 palisade rect 5 4.4 7 0.4 0
101 3-15 banner circle 0 9.4 1.5 0
102 3-15 pit_trap circle 3.9 -7.6 0.6 0
103 4-1 swamp rect -6.5 -8 6 3 0
104 4-2 river rect 0 4.2 19 2 0
105 4-2 bridge rect -5 4.2 1.2 2 0
106 4-2 bridge rect 5 4.2 1.2 2 0
107 4-2 swamp rect 5.5 -2.6 5 2.4 0
108 4-3 swamp rect 0 -2.6 6 2.4 0
109 4-3 poison_marsh circle -6.5 -7.5 1.6 0
110 4-3 poison_marsh circle 6.5 -7.5 1.6 0
111 4-4 fog rect 0 -6.8 19 4 0
112 4-4 palisade rect -1.3 -1.4 6 0.4 0
113 4-5 river rect 0 4.4 19 2.2 0
114 4-5 bridge rect -3.5 4.4 1.2 2.2 0
115 4-5 bridge rect 3.5 4.4 1.2 2.2 0
116 4-5 swamp rect -6.5 -2.6 6 2.4 0
117 4-5 poison_marsh circle 5.8 -8 1.4 0
118 4-6 wall rect -6 4.6 7 0.8 0
119 4-6 wall rect 6 4.6 7 0.8 0
120 4-6 fog rect 0 -7 19 3.6 0
121 4-7 palisade rect -5 -8.2 5 0.4 0
122 4-7 palisade rect 5 -8.2 5 0.4 0
123 4-8 swamp rect 0 -2.6 19 2.4 0
124 4-9 high_ground rect 0 10 6 2.6 0
125 4-9 palisade rect 0 -1.4 8 0.4 0
126 4-10 wall rect -6.5 -8.8 6 0.8 0
127 4-10 wall rect 6.5 -8.8 6 0.8 0
128 4-10 palisade rect -1.3 -1.4 6 0.4 0
129 4-10 poison_marsh circle 6.5 -3 1.4 0
130 4-11 swamp rect 0 4.2 12 2.4 0
131 4-12 palisade rect 0 -1.4 8 0.4 0
132 4-12 pit_trap circle 3.9 -7.6 0.6 0
133 4-12 pit_trap circle -2.6 -2.4 0.6 0
134 4-13 swamp rect 0 0 20 6 0
135 4-13 poison_marsh circle -4 2 2 0
136 4-13 poison_marsh circle 4 2 2 0
137 4-14 wall rect -5.75 5 7.5 0.8 0
138 4-14 gate rect 0 5 4 0.8 0 2
139 4-14 wall rect 5.75 5 7.5 0.8 0
140 4-14 swamp rect 0 -8 10 2.4 0
141 4-15 high_ground rect 0 10.4 8 2.8 0
142 4-15 palisade rect -4.5 4.4 6 0.4 0
143 4-15 palisade rect 4.5 4.4 6 0.4 0
144 4-15 swamp rect -6.8 -8 5 2.4 0
145 4-15 swamp rect 6.8 -8 5 2.4 0
146 5-1 thorn_bush rect -6.8 -7.8 2.6 1.6 0
147 5-1 thorn_bush rect 6.8 -2.6 2.6 1.6 0
148 5-1 pit_trap circle -1.3 -7.6 0.6 0
149 5-2 banner circle 0 -2.6 1.5 0
150 5-3 palisade rect -1.3 -1.4 6 0.4 0
151 5-4 banner circle 0 4.4 1.5 0
152 5-4 palisade rect 0 -1.4 8 0.4 0
153 5-5 banner circle -7 -3 1.5 0
154 5-5 banner circle 7 -3 1.5 0
155 5-5 pit_trap circle 3.9 -7.6 0.6 0
156 5-6 boulder circle -6.5 -8 0.9 0
157 5-6 boulder circle 6.5 -2.6 0.9 0
158 5-6 boulder circle 0 4.2 0.9 0
159 5-7 fog circle -6.5 -2.6 2.6 0
160 5-7 fog circle 6.5 -2.6 2.6 0
161 5-7 pit_trap circle 0 -7.8 0.6 0
162 5-8 wall rect -5.75 5 7.5 0.8 0
163 5-8 gate rect 0 5 4 0.8 0
164 5-8 wall rect 5.75 5 7.5 0.8 0
165 5-8 banner circle 0 8.8 1.5 0
166 5-9 banner circle -7 -7.8 1.5 0
167 5-9 palisade rect 0 -1.4 8 0.4 0
168 5-10 palisade rect -5 4.4 7 0.4 0
169 5-10 palisade rect 5 4.4 7 0.4 0
170 5-10 banner circle 0 9.2 1.5 0
171 5-10 pit_trap circle 3.9 -7.6 0.6 0
172 5-11 fog rect 0 -6.8 19 4 0
173 5-11 pit_trap circle -2.6 -7.6 0.6 0
174 5-11 pit_trap circle 5.2 -7.6 0.6 0
175 5-12 swamp rect -6.8 -2.6 5 2.4 0
176 5-12 swamp rect 6.8 -2.6 5 2.4 0
177 5-13 banner circle 0 -8.2 1.5 0
178 5-14 pit_trap circle 0 -2.4 0.6 0
179 5-14 pit_trap circle -2.6 3.6 0.6 0
180 5-14 swamp rect -6.8 -8 5 2.4 0
181 5-15 high_ground rect 0 -8.6 8 2.6 0
182 5-15 boulder circle -5.5 -2.6 0.9 0
183 5-15 boulder circle 5.5 -2.6 0.9 0
184 5-15 banner circle 0 4.4 1.5 0
185 6-1 palisade rect -1.3 -1.4 6 0.4 0
186 6-2 high_ground rect -6.8 -7.6 5 3 0
187 6-3 palisade rect -5 4.4 7 0.4 0
188 6-3 palisade rect 5 4.4 7 0.4 0
189 6-3 banner circle 0 9.2 1.5 0
190 6-4 palisade rect -7.5 -7.8 3.5 0.4 0
191 6-4 palisade rect 7.5 -7.8 3.5 0.4 0
192 6-4 high_ground circle 0 -2.6 1.8 0
193 6-5 banner circle 0 11 1.5 0
194 6-5 palisade rect -5 4.4 7 0.4 0
195 6-5 palisade rect 5 4.4 7 0.4 0
196 6-6 river rect 0 -2.6 19 2.2 0
197 6-6 bridge rect -4 -2.6 1.2 2.2 0
198 6-6 bridge rect 4 -2.6 1.2 2.2 0
199 6-7 boulder circle -6.8 -2.6 0.9 0
200 6-7 boulder circle 6.8 -2.6 0.9 0
201 6-7 boulder circle 0 -8.4 0.8 0
202 6-8 high_ground rect 6.8 -2.6 5 3 0
203 6-9 river rect 0 5 19 2.2 0
204 6-9 bridge rect -4.5 5 1.2 2.2 0
205 6-9 bridge rect 4.5 5 1.2 2.2 0
206 6-10 river rect 0 5 19 2.2 0
207 6-10 bridge rect 0 5 1.2 2.2 0
208 6-10 high_ground rect -6.8 -7.8 5 3 0
209 6-11 wall rect -7.25 5 4.5 0.8 0
210 6-11 gate rect -3 5 4 0.8 0
211 6-11 wall rect 4.25 5 10.5 0.8 0
212 6-11 high_ground rect 0 8.8 19 2.6 0
213 6-12 pit_trap circle 0 3.6 0.6 0
214 6-12 pit_trap circle 5.2 -7.6 0.6 0
215 6-12 high_ground rect -6.8 -8.2 5 2.6 0
216 6-13 wall rect -5.75 5 7.5 0.8 0
217 6-13 gate rect 0 5 4 0.8 0
218 6-13 wall rect 5.75 5 7.5 0.8 0
219 6-13 palisade rect 0 -1.4 8 0.4 0
220 6-14 pit_trap circle -2.6 -7.6 0.6 0
221 6-14 pit_trap circle 2.6 -7.6 0.6 0
222 6-14 thorn_bush rect -7.8 -2.6 3 1.2 0
223 6-14 thorn_bush rect 7.8 -2.6 3 1.2 0
224 6-15 wall rect -5.75 5 7.5 0.8 0
225 6-15 gate rect 0 5 4 0.8 0
226 6-15 wall rect 5.75 5 7.5 0.8 0
227 6-15 high_ground rect 0 9.4 8 2.4 0
228 6-15 pit_trap circle 5.2 -7.6 0.6 0
229 6-16 fog rect 0 -6.8 19 4 0
230 6-17 burning_debris rect -6 -7.6 6 1.6 0
231 6-17 burning_debris rect 6 -2.6 5 1.6 0
232 6-17 powder_cart circle -2 -1 0.6 0
233 6-18 wall rect -4.75 5 9.5 0.8 0
234 6-18 gate rect 2 5 4 0.8 0
235 6-18 wall rect 6.75 5 5.5 0.8 0
236 6-18 burning_debris circle -6.5 -7.8 1.3 0
237 6-18 burning_debris circle 6.5 -7.8 1.3 0
238 6-19 river rect 0 5 19 2.2 0
239 6-19 bridge rect 0 5 1.2 2.2 0
240 6-19 palisade rect 0 -1.4 8 0.4 0
241 6-20 river rect 0 -8.6 19 2 0
242 6-20 bridge rect -6 -8.6 1.2 2 0
243 6-20 bridge rect 0 -8.6 1.2 2 0
244 6-20 bridge rect 6 -8.6 1.2 2 0
245 6-20 high_ground circle -6.8 -2.6 2 0
246 7-1 boulder circle -6.8 -8.2 0.9 0
247 7-1 boulder circle 6.8 -8.2 0.9 0
248 7-2 palisade rect -1.3 -1.4 6 0.4 0
249 7-2 pit_trap circle -5.2 -2.4 0.6 0
250 7-3 boulder circle 0 -2.6 0.9 0
251 7-3 boulder circle -6.8 -7.8 0.9 0
252 7-4 thorn_bush rect -7.8 -7.8 3 1.2 0
253 7-4 thorn_bush rect 7.8 -7.8 3 1.2 0
254 7-4 pit_trap circle 5.2 -7.6 0.6 0
255 7-5 boulder circle -2.6 -8.2 0.9 0
256 7-5 boulder circle 2.6 -8.2 0.9 0
257 7-5 pit_trap circle 5.2 -7.4 0.6 0
258 7-5 banner circle 0 4.8 1.5 0
259 7-6 boulder circle -6.8 -2.6 0.9 0
260 7-6 boulder circle 6.8 -2.6 0.9 0
261 7-7 palisade rect -6.8 -7.6 4 0.4 0
262 7-7 palisade rect 6.8 -7.6 4 0.4 0
263 7-8 boulder circle 0 -8.4 0.8 0
264 7-8 boulder circle -6.8 -2.6 0.9 0
265 7-8 pit_trap circle 2.6 -2.4 0.6 0
266 7-8 pit_trap circle 5.2 -7.6 0.6 0
267 7-9 thorn_bush rect -8.2 -4 2.4 6 0
268 7-9 thorn_bush rect 8.2 -4 2.4 6 0
269 7-9 boulder circle 0 -2.4 0.9 0
270 7-10 thorn_bush rect -8 -8 3 1.2 0
271 7-10 thorn_bush rect 8 -8 3 1.2 0
272 7-10 boulder circle 0 -8.6 0.9 0
273 7-10 pit_trap circle -3.2 -7.6 0.6 0
274 8-1 thorn_bush rect -7.8 -7.8 3 1.2 0
275 8-1 thorn_bush rect 7.8 -2.6 3 1.2 0
276 8-2 river rect 0 4.2 19 2 0
277 8-2 bridge rect -5 4.2 1.2 2 0
278 8-2 bridge rect 3 4.2 1.2 2 0
279 8-3 high_ground rect -1.3 1 10 2.6 0
280 8-3 palisade rect -1.3 -1.4 10 0.4 0
281 8-4 powder_cart circle -1.3 -0.9 0.6 0
282 8-4 pit_trap circle 5.2 -7.6 0.6 0
283 8-5 river rect 0 5 19 2.2 0
284 8-5 bridge rect -4 5 1.2 2.2 0
285 8-5 bridge rect 4 5 1.2 2.2 0
286 8-5 powder_cart circle -6.8 -2.6 0.6 0
287 8-5 powder_cart circle 6.8 -2.6 0.6 0
288 8-5 pit_trap circle -5.2 -7.6 0.6 0
289 8-6 fog rect 0 -6.8 19 4 0
290 8-6 wall rect -8.6 -2 1.6 8 0
291 8-6 wall rect 8.6 -2 1.6 8 0
292 8-7 river rect 0 -8.4 19 1.6 0
293 8-7 bridge rect 0 -8.4 1.2 1.6 0
294 8-7 swamp rect -6 -2.6 6 2 0
295 8-8 pit_trap circle -5.2 -7.6 0.6 0
296 8-8 pit_trap circle 5.2 -7.6 0.6 0
297 8-8 powder_cart circle 3.9 -0.9 0.6 0
298 8-9 palisade rect -4.5 -8 5 0.4 0
299 8-9 palisade rect 4.5 -8 5 0.4 0
300 8-9 swamp rect 0 -2.6 8 2.4 0
301 8-10 palisade rect -4.5 -1.6 5 0.4 0
302 8-10 palisade rect 4.5 -1.6 5 0.4 0
303 8-10 pit_trap circle 0 -1.6 0.6 0
304 8-10 pit_trap circle -8.4 -1.6 0.6 0
305 8-10 banner circle 8 -3.8 1.5 0
306 8-11 wall rect -5.75 5.2 7.5 0.8 0
307 8-11 gate rect 0 5.2 4 0.8 0 3
308 8-11 wall rect 5.75 5.2 7.5 0.8 0
309 8-12 wall rect -6.75 -8.6 5.5 0.8 0
310 8-12 wall rect 0 -8.6 3 0.8 0
311 8-12 wall rect 6.75 -8.6 5.5 0.8 0
312 8-13 ice rect 0 -8 10 2.2 0
313 8-13 ice rect 0 4.6 12 2.4 0
314 8-13 boulder circle -7 -2.6 0.9 0
315 8-13 boulder circle 7 -2.6 0.9 0
316 8-14 thorn_bush rect -7.6 -7.6 3.2 1.4 0
317 8-14 thorn_bush rect 7.6 -7.6 3.2 1.4 0
318 8-14 thorn_bush rect 0 5 6 1.2 0
319 8-14 powder_cart circle -1.9 -0.9 0.6 0
320 8-15 burning_debris rect 0 0 20 32 0 spawn_on_splash=1;burn_turns=3
321 8-15 powder_cart circle -3 4 0.6 0
322 8-15 powder_cart circle 3 4 0.6 0
323 9-1 burning_debris rect 0 0 20 32 0 spawn_on_splash=1;burn_turns=3
324 9-1 burning_debris circle -6.8 -2.6 1.3 0
325 9-1 burning_debris circle 6.8 4.4 1.3 0
326 9-1 powder_cart circle 0.6 -0.9 0.6 0
327 9-2 river rect 0 5.2 19 2 0
328 9-2 bridge rect -3 5.2 1.2 2 0
329 9-2 bridge rect 3 5.2 1.2 2 0
330 9-2 swamp rect 0 -2.6 19 2.2 0
331 9-3 river rect 0 -2.6 19 2 0
332 9-3 bridge rect 0 -2.6 1.2 2 0
333 9-3 fog circle -6.5 -7.8 2.4 0
334 9-4 river rect 0 -8.6 19 2 0
335 9-4 bridge rect -6 -8.6 1.2 2 0
336 9-4 bridge rect 0 -8.6 1.2 2 0
337 9-4 bridge rect 6 -8.6 1.2 2 0
338 9-5 wall rect -5.75 5.2 7.5 0.8 0
339 9-5 gate rect 0 5.2 4 0.8 0 4
340 9-5 wall rect 5.75 5.2 7.5 0.8 0
341 9-5 high_ground rect 0 10 12 3 0
342 9-6 fog rect 0 -8.4 19 2.6 0
343 9-6 palisade rect -5.5 -8.4 4 0.4 0
344 9-6 palisade rect 5.5 -8.4 4 0.4 0
345 9-7 river rect 0 5.2 19 2 0
346 9-7 bridge rect -6 5.2 1.2 2 0
347 9-7 bridge rect 0 5.2 1.2 2 0
348 9-7 fog circle 5.5 -2.6 2.2 0
349 9-8 fog rect 0 -2.4 19 2.6 0
350 9-8 high_ground rect 6.8 -7.8 5 2.8 0
351 9-9 river rect 0 -2.6 19 2 0
352 9-9 bridge rect -3.5 -2.6 1.2 2 0
353 9-9 bridge rect 3.5 -2.6 1.2 2 0
354 9-9 palisade rect 0 -0.9 6 0.4 0
355 9-10 pit_trap circle -5.5 -7.8 0.6 0
356 9-10 pit_trap circle 3.6 -7.6 0.6 0
357 9-10 high_ground rect 0 10.6 10 3 0
358 9-10 fog circle 6.8 -2 2 0
359 9-11 river rect 0 3 20 2 0
360 9-11 bridge rect 0 3 1.2 2 0
361 9-11 fog circle 0 8 4 0
362 9-12 river rect 0 5.2 19 2 0
363 9-12 bridge rect -7 5.2 1.2 2 0
364 9-12 boulder circle 0 -8.6 0.8 0
365 9-13 fog rect 0 -7 19 3.6 0
366 9-14 river rect 0 -8.8 19 2 0
367 9-14 bridge rect -6 -8.8 1.2 2 0
368 9-14 bridge rect 0 -8.8 1.2 2 0
369 9-14 bridge rect 6 -8.8 1.2 2 0
370 9-14 fog circle 0 2 2.4 0
371 9-15 river rect 0 5.2 19 2 0
372 9-15 bridge rect -4 5.2 1.2 2 0
373 9-15 bridge rect 4 5.2 1.2 2 0
374 9-15 high_ground rect 0 10.4 8 3 0
375 9-15 fog circle -6.8 -7.6 2.2 0
376 10-1 banner circle 0 -8.2 1.5 0
377 10-1 palisade rect -6.5 -7.6 5 0.4 0
378 10-1 palisade rect 6.5 -7.6 5 0.4 0
379 10-2 river rect 0 -2.6 19 2.2 0
380 10-2 bridge rect -7 -2.6 1.2 2.2 0
381 10-2 bridge rect 0 -2.6 1.2 2.2 0
382 10-2 bridge rect 7 -2.6 1.2 2.2 0
383 10-2 palisade rect -4 -0.9 4 0.4 0
384 10-2 palisade rect 4 -0.9 4 0.4 0
385 10-3 river rect 0 4.4 19 2.2 0
386 10-3 bridge rect -3 4.4 1.2 2.2 0
387 10-3 bridge rect 3 4.4 1.2 2.2 0
388 10-3 palisade rect 0 -1 12 0.4 0
389 10-4 ice rect 0 -2.8 12 1.6 0
390 10-4 powder_cart circle -1.3 -0.9 0.6 0
391 10-5 river rect 0 -8.4 19 1.8 0
392 10-5 bridge rect -5 -8.4 1.2 1.8 0
393 10-5 bridge rect 0 -8.4 1.2 1.8 0
394 10-5 bridge rect 5 -8.4 1.2 1.8 0
395 10-5 palisade rect -4.5 4.4 6 0.4 0
396 10-5 palisade rect 4.5 4.4 6 0.4 0
397 10-5 powder_cart circle -4.4 -1 0.6 0
398 10-6 fog rect 0 -4 19 9 0
399 10-6 river rect 0 5 19 2 0
400 10-6 bridge rect 0 5 1.2 2 0
401 10-7 fog circle 0 -2.4 2.6 0
402 10-7 thorn_bush rect -7.6 -7.8 3.2 1.4 0
403 10-7 thorn_bush rect 7.6 -7.8 3.2 1.4 0
404 10-8 river rect 0 -2.8 19 2 0
405 10-8 bridge rect -6 -2.8 1.2 2 0
406 10-8 bridge rect -2 -2.8 1.2 2 0
407 10-8 bridge rect 2 -2.8 1.2 2 0
408 10-8 bridge rect 6 -2.8 1.2 2 0
409 10-8 powder_cart circle 1.3 -0.9 0.6 0
410 10-9 palisade rect -5 4.6 7 0.4 0
411 10-9 palisade rect 5 4.6 7 0.4 0
412 10-9 fog rect 0 -7.4 19 3.2 0
413 10-10 river rect 0 -8.4 19 1.8 0
414 10-10 bridge rect -6 -8.4 1.2 1.8 0
415 10-10 bridge rect 0 -8.4 1.2 1.8 0
416 10-10 bridge rect 6 -8.4 1.2 1.8 0
417 10-10 powder_cart circle -1.3 -0.9 0.6 0
418 10-10 powder_cart circle 2.6 -0.9 0.6 0
419 10-10 palisade rect 0 9.2 8 0.4 0
420 10-11 burning_debris rect 0 0 20 32 0 spawn_on_splash=1;burn_turns=3
421 10-11 powder_cart circle -3.9 -1 0.6 0
422 10-11 powder_cart circle 3.9 -1 0.6 0
423 10-12 burning_debris rect 0 0 20 32 0 spawn_on_splash=1;burn_turns=3
424 10-12 burning_debris rect -6 -7.8 5 1.6 0
425 10-12 burning_debris rect 6 4.6 5 1.6 0
426 10-12 river rect 0 -2.6 19 1.8 0
427 10-12 bridge rect -4 -2.6 1.2 1.8 0
428 10-12 bridge rect 4 -2.6 1.2 1.8 0
429 10-13 burning_debris circle -6.8 -2.4 1.3 0
430 10-13 burning_debris circle 6.8 4.6 1.3 0
431 10-13 palisade rect -4.5 4.6 5 0.4 0
432 10-13 palisade rect 2.8 4.6 4 0.4 0
433 10-14 fog rect 0 -8.2 19 2.8 0
434 10-14 powder_cart circle -1.9 -0.9 0.6 0
435 10-14 powder_cart circle 3.2 -0.9 0.6 0
436 10-15 river rect 0 5.2 19 2 0
437 10-15 bridge rect -5 5.2 1.2 2 0
438 10-15 bridge rect 5 5.2 1.2 2 0
439 10-15 burning_debris rect -6 -2.4 5 1.6 0
440 10-15 burning_debris rect 6.5 -2 4 1.6 0
441 10-15 powder_cart circle -4.4 1.4 0.6 0
442 10-16 thorn_bush rect -7.8 -4 2.8 5 0
443 10-16 thorn_bush rect 7.8 -4 2.8 5 0
444 10-16 fog circle 0 -7.6 2 0
445 10-17 thorn_bush rect -8.2 -2 2.4 8 0
446 10-17 thorn_bush rect 8.2 -2 2.4 8 0
447 10-17 burning_debris circle -2.6 4.4 0.9 0
448 10-17 burning_debris circle 2.6 4.4 0.9 0
449 10-18 swamp rect 0 -2.6 19 2.4 0
450 10-18 swamp rect -6.5 -8.2 6 2.4 0
451 10-19 swamp rect 0 -8.4 12 2 0
452 10-19 fog circle 0 4.8 2.2 0
453 10-20 thorn_bush rect -7.25 -6 4.5 6 0
454 10-20 thorn_bush rect 7.25 -6 4.5 6 0
455 10-20 swamp rect 0 -8.4 8 2 0
456 10-20 fog circle 0 10.6 2.4 0

File diff suppressed because it is too large Load Diff

View File

@ -101,6 +101,7 @@ namespace TKS.EditorTools
/// 기믹 검증 캡처(GUI 에디터 · 사본 프로젝트 권장 · 세이브 = 메모리 전용 · PD #1097):
/// Unity.exe -projectPath &lt;copy&gt; -executeMethod TKS.EditorTools.GimmickImporter.Capture -gimmickDir &lt;dir&gt;
/// 샘플 5 스테이지 1턴씩 + 조준선 반응 2장 + AI 함정 쪽 튕겨내기 1장 PNG + log · 끝나면 스스로 종료.
/// -gimmickStages 1-10,2-10,… 을 주면 그 스테이지들의 시작 화면(전장 전체)만 찍는다(145 배치 확인).
/// </summary>
public static void Capture()
{
@ -110,6 +111,7 @@ namespace TKS.EditorTools
EditorSceneManager.OpenScene(ProjectSetup.ScenePath, OpenSceneMode.Single);
SessionState.SetBool(OutGame.SaveStore.MemoryFlagKey, true);
SessionState.SetString(GimmickCaptureDriver.DirKey, dir);
SessionState.SetString(GimmickCaptureDriver.StagesKey, GetArg("-gimmickStages") ?? "");
Debug.Log("[TKS] 기믹 캡처 시작 → " + dir);
EditorApplication.EnterPlaymode();
}

View File

@ -10,11 +10,14 @@ namespace TKS
/// 지형 기믹·적 AI 검증 캡처(에디터 GimmickImporter.Capture 가 SessionState 로 출력 폴더를 넘기면 생성 · 세이브 = 메모리 전용 · PD #1097 · #1098).
/// ① 샘플 5 스테이지(1-3 · 2-5 · 4-13 · 8-15 · 9-11) 시작 + 1턴(아군 = 가까운 적 쪽 슬링 · 적 = 예측 AI) 뒤 ② 조준선 반응 2장(1-3 바위·덤불 · 9-11 다리 밀기)
/// ③ AI 가 아군을 함정 쪽으로 튕겨내는 장면 1장. 카메라는 기믹 쪽으로 · 끝나면 스스로 종료.
/// 스테이지 목록(StagesKey · -gimmickStages 1-10,2-10,…)이 오면 ①~③ 대신 그 스테이지들의 시작 화면만 전장 전체로 찍는다(145 배치 확인).
/// </summary>
public class GimmickCaptureDriver : MonoBehaviour
{
public const string DirKey = "TKS_GIMMICK_CAPTURE_DIR";
public const string StagesKey = "TKS_GIMMICK_CAPTURE_STAGES";
public string OutputDir;
public string[] StageList;
public int Width = 720;
public int Height = 1280;
@ -31,6 +34,9 @@ namespace TKS
UnityEditor.SessionState.EraseString(DirKey);
var d = new GameObject("GimmickCaptureDriver").AddComponent<GimmickCaptureDriver>();
d.OutputDir = dir;
string stages = UnityEditor.SessionState.GetString(StagesKey, "");
UnityEditor.SessionState.EraseString(StagesKey);
if (stages.Length > 0) d.StageList = stages.Split(',');
}
#endif
@ -51,6 +57,13 @@ namespace TKS
var camCtrl = cam.GetComponent<CameraController>();
Log("gimmickDb=" + (GimmickTables.Db != null ? GimmickTables.Db.defs.Count : -1) + " table=" + (GimmickTables.Table != null ? GimmickTables.Table.rows.Count : -1) + " aiWeights=" + (AiWeights.Load() != null));
if (StageList != null && StageList.Length > 0)
{
yield return LayoutShots(root, bm, cam, camCtrl);
Finish(0);
yield break;
}
foreach (var st in Samples)
{
var parts = st.Split('-');
@ -100,6 +113,37 @@ namespace TKS
Finish(0);
}
/// <summary>StageList 스테이지마다 시작 화면 1장(카메라 = 전장 가운데 · 최대 높이).</summary>
IEnumerator LayoutShots(OutGameRoot root, BattleManager bm, Camera cam, CameraController camCtrl)
{
foreach (var raw in StageList)
{
string st = raw.Trim();
var parts = st.Split('-');
int ch, no;
if (parts.Length != 2 || !int.TryParse(parts[0], out ch) || !int.TryParse(parts[1], out no))
{
Log("skip 「" + st + "」(장-번호 아님)");
continue;
}
root.OpenWorldMap();
yield return null;
root.Map.EnterStage(ch - 1, no - 1);
float t0 = Time.realtimeSinceStartup;
while (bm.Phase != BattlePhase.PlayerTurn && Time.realtimeSinceStartup - t0 < 10f) yield return null;
var layer = bm.Gimmicks;
Log(st + " 「" + bm.Stage.title + "」 기믹 " + (layer != null ? layer.Items.Count : 0) + " · 아군 " + bm.AliveCount(Faction.Player) + " · 적 " + bm.AliveCount(Faction.Enemy));
if (layer != null) foreach (var g in layer.Items) Log(" " + g.Id + " " + g.Shape.Type + " @" + g.Shape.Center + (g.Template ? " (생성 규칙)" : "") + (g.MaxHp > 0 ? " hp" + g.Hp : ""));
if (camCtrl != null)
{
camCtrl.SetViewHeight(camCtrl.MaxViewHeight);
camCtrl.SnapTo(Vector2.zero);
}
yield return Wait();
yield return Shot(cam, "layout_" + st);
}
}
static Vector2 Focus(BattleManager bm, GimmickLayer layer)
{
Vector2 sum = Vector2.zero;

View File

@ -0,0 +1,269 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using NUnit.Framework;
using TKS.OutGame;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;
namespace TKS.Tests
{
/// <summary>
/// 145 스테이지 기믹 배치(레벨 배치 세션 · PD #1097 후속 · 생성·사전 검증 = 기획 tables/_stage_gimmicks_gen.py) — 전 스테이지 GimmickLayer.Build ·
/// 편성 좌표가 장애물에 밀려 옮겨진 유닛 0 · 아군 스폰 반경 2 비움 · 해로운 지대 위 적 스폰 0 · 파괴 불가 장애물 사이 폭 2 통로 · 강마다 다리 ·
/// 기믹 많은 5 스테이지 적 턴 결정 ≤ 1.5 초. 기준(반경 2 · 폭 2 · 1.5 초)은 배치 규칙이고 전투 수치·좌표는 자산에서 읽는다(C45).
/// </summary>
public class StageGimmickPlacementTests
{
/// <summary>기획서 §7 샘플(PD 확정 그대로 · 해로운 지대 검사만 제외 — 4-13 늪이 중군을 덮는 것은 의도).</summary>
static readonly string[] Samples = { "1-3", "2-5", "4-13", "8-15", "9-11" };
const float PlayerClear = 2f;
const float PathRadius = 1f; // 통로 폭 2
const float Cell = 0.25f;
const long TurnBudgetMs = 1500;
BattleManager bm;
BalanceConfig cfg;
[UnitySetUp]
public IEnumerator SetUp()
{
WorldProgress.Reset();
SaveStore.UseMemory(true);
SceneManager.LoadScene("Battle");
yield return null;
yield return null;
bm = BattleManager.Instance;
Assert.IsNotNull(bm);
var wm = WorldMapScreen.Instance;
if (wm != null && wm.HasData) wm.EnterStage(0, 0);
yield return null;
cfg = bm.Config;
Assert.IsNotNull(GimmickTables.Table, "StageGimmickTable(TKS/Import Gimmicks)");
}
[UnityTearDown]
public IEnumerator TearDown()
{
Time.timeScale = 1f;
yield return null;
}
static string Id(BalanceConfig.StageDef st)
{
return st.chapter + "-" + st.stage;
}
static bool Harmful(GimmickZone z)
{
return z == GimmickZone.Poison || z == GimmickZone.Slow || z == GimmickZone.Burn || z == GimmickZone.Slide || z == GimmickZone.Trap || z == GimmickZone.River;
}
[UnityTest]
public IEnumerator AllStages_Build_SpawnsUnmoved_PlayerAreaClear_PathWidth2_RiverBridged()
{
var table = GimmickTables.Table;
var fails = new List<string>();
int built = 0, rows = 0, withGimmicks = 0;
for (int i = 0; i < cfg.stages.Length; i++)
{
var st = cfg.stages[i];
string id = Id(st);
bm.StartStage(i);
yield return null;
var layer = bm.Gimmicks;
int want = table.For(st.chapter, st.stage).Count;
rows += want;
if (layer == null)
{
fails.Add(id + " 레이어 없음");
continue;
}
built++;
if (layer.Items.Count != want) fails.Add(id + " 기믹 " + layer.Items.Count + " ≠ 배치 " + want);
if (want > 0) withGimmicks++;
bool sample = System.Array.IndexOf(Samples, id) >= 0;
foreach (var g in layer.Items)
{
if (g.Template) continue;
if (g.IsBlock && g.Colliders.Count == 0) fails.Add(id + " " + g.Id + " 콜라이더 없음");
foreach (var sp in cfg.playerSpawnPoints)
{
if (g.Shape.SignedDistance(sp) < PlayerClear - 1e-3f) fails.Add(id + " " + g.Id + " 이 아군 스폰 " + sp + " 반경 " + PlayerClear + " 안");
}
}
// 편성 좌표 그대로(ResolveOverlaps 가 옮긴 유닛 없음) · 장애물 · 해로운 지대
foreach (var e in st.enemies)
{
bool kept = false;
foreach (var u in bm.AliveUnits(Faction.Enemy))
{
if (Vector2.Distance(u.Position, e.position) < 0.01f) kept = true;
}
if (!kept) fails.Add(id + " 적 「" + e.name + "」 편성 자리 " + e.position + " 에서 옮겨짐(장애물 겹침)");
}
foreach (var u in bm.AliveUnits(Faction.Player))
{
bool kept = false;
foreach (var sp in cfg.playerSpawnPoints)
{
if (Vector2.Distance(u.Position, sp) < 0.01f) kept = true;
}
if (!kept) fails.Add(id + " 아군 「" + u.DisplayName + "」 스폰 자리에서 옮겨짐");
}
foreach (var u in bm.AliveUnits(Faction.Enemy))
{
foreach (var g in layer.Items)
{
if (g.BlocksMove && g.Shape.SignedDistance(u.Position) < u.Radius) fails.Add(id + " " + u.DisplayName + " 이 " + g.Id + " 과 겹침");
if (!sample && g.ZoneActive && Harmful(g.Zone) && g.Shape.SignedDistance(u.Position) < 0f) fails.Add(id + " " + u.DisplayName + " 스폰이 해로운 지대 " + g.Id + " 위");
}
}
// 강마다 다리 1 이상
foreach (var g in layer.Items)
{
if (g.Zone != GimmickZone.River) continue;
bool bridged = false;
foreach (var o in layer.Items)
{
if (o.IsBridge && g.Shape.Contains(o.Shape.Center)) bridged = true;
}
if (!bridged) fails.Add(id + " 강 " + g.Shape.Center + " 에 다리 없음");
}
string path = PathProblem(layer);
if (path != null) fails.Add(id + " " + path);
}
UnityEngine.Debug.Log("[StageGimmickPlacementTests] 스테이지 " + built + "(기믹 있음 " + withGimmicks + ") · 배치 " + rows + " · 문제 " + fails.Count);
Assert.AreEqual(cfg.stages.Length, built, "전 스테이지 레이어 생성");
Assert.AreEqual(table.rows.Count, rows, "표의 모든 행이 스테이지 표의 스테이지에 놓임");
Assert.AreEqual(0, fails.Count, string.Join("\n", fails.ToArray()));
}
/// <summary>
/// 파괴 불가 장애물(내구 없음 · 이동 막음)을 PathRadius 만큼 부풀린 격자에서 아군 스폰 → 모든 적 스폰 근처(2 × PathRadius)까지 길이 있는가.
/// 목책·성문·수레 = 부술 수 있어 통로로 본다 · 강 = 통과 가능 지대(PD #1101).
/// </summary>
string PathProblem(GimmickLayer layer)
{
var solid = new List<GimmickInstance>();
foreach (var g in layer.Items)
{
if (g.BlocksMove && !g.Def.durable) solid.Add(g);
}
float hw = cfg.boardSize.x * 0.5f, hh = cfg.boardSize.y * 0.5f;
int nx = Mathf.RoundToInt(cfg.boardSize.x / Cell) + 1, ny = Mathf.RoundToInt(cfg.boardSize.y / Cell) + 1;
var free = new bool[nx * ny];
var seen = new bool[nx * ny];
var q = new Queue<int>();
for (int y = 0; y < ny; y++)
{
for (int x = 0; x < nx; x++)
{
var p = new Vector2(x * Cell - hw, y * Cell - hh);
bool ok = Mathf.Abs(p.x) <= hw - PathRadius && Mathf.Abs(p.y) <= hh - PathRadius;
for (int k = 0; ok && k < solid.Count; k++)
{
if (solid[k].Shape.SignedDistance(p) < PathRadius) ok = false;
}
free[y * nx + x] = ok;
}
}
foreach (var sp in cfg.playerSpawnPoints)
{
int best = -1;
float bd = float.MaxValue;
for (int i = 0; i < free.Length; i++)
{
if (!free[i]) continue;
float d = Vector2.Distance(new Vector2((i % nx) * Cell - hw, (i / nx) * Cell - hh), sp);
if (d < bd)
{
bd = d;
best = i;
}
}
if (best >= 0 && !seen[best])
{
seen[best] = true;
q.Enqueue(best);
}
}
if (q.Count == 0) return "아군 스폰 근처에 빈 칸 없음";
while (q.Count > 0)
{
int i = q.Dequeue();
int x = i % nx, y = i / nx;
for (int k = 0; k < 4; k++)
{
int ax = x + (k == 0 ? 1 : k == 1 ? -1 : 0), ay = y + (k == 2 ? 1 : k == 3 ? -1 : 0);
if (ax < 0 || ay < 0 || ax >= nx || ay >= ny) continue;
int j = ay * nx + ax;
if (!free[j] || seen[j]) continue;
seen[j] = true;
q.Enqueue(j);
}
}
foreach (var e in bm.AliveUnits(Faction.Enemy))
{
bool reach = false;
for (int i = 0; i < seen.Length && !reach; i++)
{
if (seen[i] && Vector2.Distance(new Vector2((i % nx) * Cell - hw, (i / nx) * Cell - hh), e.Position) <= 2f * PathRadius) reach = true;
}
if (!reach) return "통로 없음 — 아군에서 「" + e.DisplayName + "」 " + e.Position + " 까지 폭 " + (2f * PathRadius) + " 길이 없다";
}
return null;
}
[UnityTest]
public IEnumerator Top5GimmickStages_EnemyTurnDecisions_Under1500ms()
{
var table = GimmickTables.Table;
var order = new List<int>();
var count = new Dictionary<int, int>();
for (int i = 0; i < cfg.stages.Length; i++)
{
int n = 0;
foreach (var p in table.For(cfg.stages[i].chapter, cfg.stages[i].stage))
{
if (!p.paramsRaw.Contains("spawn_on_splash")) n++; // 생성 규칙 레코드는 지대가 아니다
}
count[i] = n;
order.Add(i);
}
order.Sort((a, b) => count[b] != count[a] ? count[b].CompareTo(count[a]) : a.CompareTo(b));
float aggroAll = cfg.boardSize.magnitude; // 전원 교전(최악) — 교전 범위 밖 대기 없음
var log = new List<string>();
for (int k = 0; k < 5; k++)
{
int idx = order[k];
var st = cfg.stages[idx];
bm.StartStage(idx);
yield return null;
bm.ForcePhase(BattlePhase.EnemyTurn);
var pending = new List<Unit>(bm.AliveUnits(Faction.Enemy));
int enemies = pending.Count;
var rng = new System.Random(7);
int decisions = 0;
var sw = Stopwatch.StartNew();
while (pending.Count > 0)
{
var plan = TacticalAI.Next(bm, pending, st.aiAccuracy, aggroAll, rng);
if (plan == null) break;
pending.Remove(plan.Unit);
decisions++;
}
sw.Stop();
log.Add(Id(st) + " 기믹 " + count[idx] + " · 적 " + enemies + " · 결정 " + decisions + " · " + sw.ElapsedMilliseconds + " ms");
Assert.AreEqual(enemies, decisions, Id(st) + " 적 전원 결정");
Assert.LessOrEqual(sw.ElapsedMilliseconds, TurnBudgetMs, Id(st) + " 적 턴(1기마다 재평가) ≤ 1.5 초");
}
UnityEngine.Debug.Log("[StageGimmickPlacementTests] AI 성능 · " + string.Join(" / ", log.ToArray()));
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0a97b603f392ace4e9355007dce1dea2