AI — 컴퓨터 상대 프로필
ai/*.txt파일은 일반 텍스트로 된 컴퓨터 상대 프로필입니다. 각 프로필은 난이도별 건설 우선순위와 유닛 상한을 선언하며, 엔진은 맵에 AI 플레이어가 설정되면 이를 읽습니다. OTA의aiprofile=키가 맵이 어떤 프로필로 시작할지 고르지만, 사용자는 로비에서 이를 바꿀 수 있습니다.
Tip
직접 해 보세요.
# Plain-text — just read them
ls $(kbot ctx path)/ai/
head -40 $(kbot ctx path)/ai/default.txt
kbot에서 보기. 스튜디오의 에셋 탐색기는 AI Profile 탭에서 프로필을
보여 주고, kbot mount는 describe ai/<name>.txt로 프로필을
출력합니다(kbot이 보여 주는 것 참고).
Go에서 쓰기. kbot-io의 formats/ai를 사용합니다.
import "github.com/coreprime/kbot-io/formats/ai"
raw, _ := os.ReadFile("ai/default.txt")
profile, _ := ai.Parse(raw)
// profile.Preamble: lines before the first plan; profile.Plans: plan.Name,
// plan.Weights, plan.Limits; profile.Diagnostics: lines read unusually.
settings := ai.NewResolver(units).Apply(profile, ai.Easy) // per-unit result
한눈에 보기
프로필은 난이도마다 하나씩인 plan의 연속입니다. 각 plan에는 Weight와
Limit 지시문이 들어 있으며, 그 대상은 유닛 이름 하나(ARMCOM), 분류
단어(PLANT, LEVEL3, SPECIAL), 또는 ALL입니다.
plan easy
Weight ARM 0.2
Weight CORE 0.2
Weight PLANT 2
Weight CONSTR 3
Weight ARMACK 2
Weight CORACK 2
Limit ARMSILO 1
Limit CORSILO 1
plan medium
Weight ARM 1.0
Weight CORE 1.0
...
지시문
| 지시문 | 문법 | 의미 |
|---|---|---|
plan <word>… |
plan easy |
새 plan 블록을 시작합니다. 뒤따르는 Weight/Limit 줄은 다음 plan이 나올 때까지, plan이 게임의 난이도와 일치할 때만 적용됩니다. |
Weight <target> <value> |
Weight ARMCK 0.5 |
대상의 건설 우선순위에 곱합니다(가중치가 합쳐지는 방식 참고). |
Limit <target> <value> |
Limit ARMSILO 1 |
컴퓨터 플레이어가 대상을 몇 개까지 가질 수 있는지 제한합니다. -1은 무제한이고, 0이나 그 밖의 음수는 금지입니다. |
TA 3.1c가 텍스트를 읽는 방식(kbot-io의
formats/ai도
이를 따릅니다):
- 줄은 모든 종류의 공백 문자 — 스페이스, 탭, CR, VT, FF — 에서 단어로
나뉘며,
#은 어디에 나타나든 줄을 끝냅니다. 단어 안에 있어도 마찬가지입니다. - 첫 단어가 지시문이며, 대소문자를 무시하고 비교합니다. 첫 단어가 그 밖의
것인 줄은 무시됩니다. 정식판의
// comment줄이 건너뛰어지는 것도 이 때문입니다. 값 뒤의 단어도 무시되므로, 뒤에 붙은// note는 아무 해가 없습니다. - 값은 세 번째 단어의 앞쪽 숫자 부분입니다. 가중치는 십진수(
0.5,.5,2,1e1)이고, 제한은 32비트로 감기는 정수입니다. 숫자가 아닌 값 단어는 0으로 읽히며 지시문은 여전히 적용됩니다: 정식판krogoth.txt의Limit CORFORT O(영문자 O)는 CORFORT를 금지하고,Limit ARM DECOM 4는 ARM 분류 전체를 0으로 제한합니다. - 첫
plan줄보다 앞에 있는 줄은 게임이 시작할 때 무시됩니다. 아직 일치한 plan이 없기 때문입니다. 게임 도중 프로필이 다시 로드되면 적용될 수도 있습니다. 정식판krogoth.txt는 이런 줄 두 개(weight cormakr 0.2,weight armmakr 0.2)로 시작합니다. TA: Kingdoms의 AI 파일은plan을 아예 쓰지 않습니다 — 아래의 TA: Kingdoms — plan이 없는 프로필을 참고하세요.
난이도
기본 프로필에는 easy, medium, hard라는 plan 세 개가 있습니다. plan은 그
단어 중 하나가(대소문자 무시) 해당 난이도를 가리키거나 — plan medium hard는
둘 다 해당 — 첫 단어가 any일 때 그 난이도에 적용됩니다. 어떤 난이도도 가리키지
않는 plan(plan brutal, 단어 없는 plan)은 아무것과도 일치하지 않으며, 그 아래의
줄은 다음 plan 줄까지 무시됩니다.
유닛 이름과 분류 단어
Weight와 Limit는 모두 다음을 대상으로 삼을 수 있습니다.
- 유닛의
UnitName— 예:ARMCOM,CORRAID(대소문자 무시 비교). 지시문은 그 유닛에만 적용되며 그 유닛을 잠급니다: 이후의Weight줄(가중치의 경우)이나Limit줄(제한의 경우)은 더 이상 그 값을 바꾸지 못합니다. - 분류 단어 —
ARM,CORE,PLANT,CONSTR,LEVEL3,SPECIAL등 — 각 유닛의Category=필드에 있는 단어들과 맞춰 봅니다. 일치하는 유닛 중 잠기지 않은 모든 유닛에 적용됩니다. ALL— 잠기지 않은 모든 유닛.
모든 유닛은 우선순위 100 %, 제한 없음에서 시작합니다. 가중치는 현재
백분율에 곱해지고, 정수로 잘린 다음 0–100 %로 제한되므로, 1보다 큰 가중치는
앞서 줄어든 유닛을 되돌릴 수는 있어도 100 %를 넘게 올리지는 못합니다. 제한은
현재 값을 대체합니다. default.txt의 easy plan에서 Weight ARM 0.2는 모든 Arm
유닛을 20 %로 만들고, 뒤의 Weight ARMRAD 0.25는 Arm 레이더 탑을 5 %로 만들어
잠그며, Weight PLANT 2는 각 Arm 공장을 20 %에서 40 %로 되돌립니다.
Important
분류 별칭은 어떤 분류 체계 파일이 아니라, 유닛의 Category= 토큰 목록과
맞춰 봅니다. 분류 별칭은 적어도 한 유닛이 선언해야만 "존재"합니다. LEVL3처럼
철자를 틀리면 그 지시문은 조용히 아무 일도 하지 않습니다(kbot의 뷰어는 이를
matches no unit으로 표시합니다).
실제 예제 — default.txt의 일부
// DEFAULT PROFILE
//--------------------------- EASY
plan easy
Weight ARM 0.2 // Every Arm unit to 20%
Weight CORE 0.2
Weight ARMRAD 0.25 // Radar towers to 5%, locked
Weight CORRAD 0.25
Weight ARMMAKR .1 // …metal makers to 2%, locked
Weight CORMAKR .1
Weight PLANT 2 // Factories back up to 40%
Weight CONSTR 3 // Constructors to 60%
// encourages advanced units
Weight ARMACK 2 // Advanced Construction Kbots
Weight CORACK 2
Weight ARMACV 2
Weight CORACV 2
Weight ARMACA 2
Weight CORACA 2
Weight SPECIAL 2
Weight LEVEL3 2
읽는 법: easy 난이도에서는 모든 Arm과 Core 유닛의 우선순위가 20 %로 떨어지고,
레이더 탑은 5 %, 금속 생산기는 2 %로 떨어집니다(둘 다 이후 잠김).
공장(PLANT)과 건설 유닛(CONSTR)은 각각 40 %와 60 %로 다시 올라가고, 고급 건설
유닛은 자기 줄이 60 %를 두 배로 만들어 100 % 상한에 도달한 뒤 잠깁니다.
맵별 프로필
Cavedog은 맵에 맞춰 조정한 프로필을 몇 개 함께 배포합니다.
| 프로필 | 사용처 |
|---|---|
default.txt |
대부분의 일반 맵 |
metal.txt |
금속이 풍부한 맵(Metal Heck 등) |
airbattle.txt |
공중전 위주의 맵 |
seabattle.txt |
해전 위주의 맵 |
hover.txt |
호버 유닛 위주의 맵 |
acid.txt |
산성 월드 맵 |
urban.txt |
도시 맵 |
waterwrld.txt |
물 월드 맵 |
krogoth.txt |
Krogoth 보스 미션 |
missions.txt |
캠페인 미션 |
맵의 .ota가 aiprofile=로 어느 것을 쓸지 고릅니다. 예:
aiprofile=metal.
TA: Kingdoms — plan이 없는 프로필
Note
이 절은 TA:K에만 해당하는 차이점입니다. TAK는 같은 ai/*.txt 파일 이름
관례와 같은 weight/limit 지시문 문법을 쓰지만, plan 지시문을 선택 사항으로
취급합니다.
TA: Kingdoms의 모든 정식판 AI 프로필(ai/default.txt, 캠페인용
ai/mission*.txt 묶음)은 plan 줄 없이 weight/limit 지시문만
나열합니다 — 파일마다 암묵적인 난이도가 하나뿐입니다. 구조는 긴 weight 블록
뒤에 긴 limit 블록이 이어지는 형태이며, 유닛 이름 접두사에 따라 진영별로 묶여
있습니다.
실제 예제 — ai/default.txt의 처음 30줄
// Kingdoms Default AI Profile 3-28-99
weight araarch 5
weight araat 1
weight arabow 8
weight arabroad 5
weight arabuild 10
weight aracan 4
weight aracastl 10
weight araclay 5
weight aradrag 25 // Dragons: top priority
weight arafast 1
weight arakeep 10
weight araknigh 5
weight aralode 10
weight aramana 5
weight arangate 0 // 0 = never build
weight arapal 8
weight arapries 10
weight arapult 1
weight arasmith 8
weight araspy 4
weight arassh 1
weight arasword 5
weight aratre 1
weight arawall 0
weight arawar 1
default.txt의 가중치 편향을 훑어보면 Cavedog의 우선순위가 드러납니다.
aradrag 25— Aramon Dragon은 의도적으로 가중치를 높게 잡았습니다. AI는 다른 무엇보다 드래곤을 더 적극적으로 건설합니다.arabuild 10,aracastl 10,arakeep 10,arapries 10— 경제/건설 유형은 모두 가중치 10입니다.arawall 0,arangate 0— 명시적으로 0이므로 절대 건설하지 않습니다.araat 1,arafast 1,arassh 1— AI가 상위 등급의 대안을 위해 우선순위를 낮추는 기본 유닛입니다.
파일 아래쪽의 tar*, ver*, zon* 유닛에도 같은 패턴이 되풀이됩니다.
Limit 블록
weight 블록 아래에는 그와 나란한 limit 블록이 옵니다.
limit araarch 16
limit araat 8
limit arabow 16
limit arabroad 16
limit arabuild 10
limit aracan 3
limit aracastl 2 // Only 2 castles per game
limit araclay 3
limit aradrag 1 // ONE dragon, even though weight=25
limit arafast 4
limit arakeep 2
limit araknigh 16
…
비대칭에 주목하세요: aradrag는 가중치가 25(높은 우선순위)이지만 제한은
1(절대 하나를 넘지 않음)입니다. TA:K의 AI는 이렇게 영웅 유닛을 향해 건설합니다
— 높은 가중치로 일찍 건설하게 하고, 낮은 제한으로 군대 구성을 적당히
유지합니다.
프로필 통계
default.txt와 캠페인 미션 파일은 모두 같은 모양을 따릅니다.
| 프로필 | Weight 줄 | Limit 줄 | Plan |
|---|---|---|---|
ai/default.txt |
104 | 104 | 0 |
ai/mission06.txt |
104 | 104 | 0 |
ai/mission08.txt(Iron Plague 미션) |
161 | 162 | 0 |
Iron Plague 미션 파일은 기본 게임의 default.txt에 없는 Creon(CRE 접두사)
유닛까지 다루므로 weight/limit 테이블이 더 풍부합니다.
kbot이 plan 없는 파일을 처리하는 방법
kbot-io의 ai.Parse는 첫 plan 줄 앞의 모든 줄을 AIFile.Preamble에 넣는데,
이는 TA가 그 줄들을 다루는 방식과 같습니다(위 참고). TA: Kingdoms 프로필이라면
ai.ParseWith(data, ai.ParseOptions{DefaultPlan: true})가 그 줄들을 모든 난이도와 일치하는 암묵적인 plan 하나로 읽습니다. kbot의
뷰어는 이 줄들을 별도의 Before first plan 탭에 보여 주며 두 가지를 모두
알려 줍니다: TA는 게임이 시작할 때 이 줄들을 무시하고, plan 줄이 없는 TA:
Kingdoms 프로필은 이 줄들을 모든 난이도에 적용한다는 것입니다. kbot은 TA:
Kingdoms가 1보다 큰 가중치를 어떻게 적용하는지는 모델링하지 않습니다.
ai.IsAIFile()은 각 줄의 첫 단어를 봅니다: 어떤 줄이 보통의 방식으로 쓴
지시문(easy, medium, hard, any 중 하나를 가리키는 plan 줄, 또는 값이
숫자로 시작하는 weight/limit 줄)으로 시작하면 그 파일은 프로필입니다. 이렇게
하면 plan이 없는 TAK 프로필과 탭으로 구분된 프로필을 찾아내면서도, 본문에서
"weight"나 "limit"을 언급하기만 하는 .txt를 프로필로 착각하지 않습니다.
주의할 점
Warning
게임은 아무것도 알려 주지 않습니다. 철자가 틀린 유닛 이름은 어떤 유닛과도
일치하지 않는 분류로 읽혀 아무 일도 하지 않고, 숫자가 아닌 값은 0으로
읽히며(그래서 제한이 대상을 금지함), 첫 plan 앞의 줄은 게임 시작 때
무시됩니다. 프로필이 망가졌다는 첫 신호는 보통 "AI가 이상하게 행동한다"는
것입니다. kbot의 뷰어는 이 각각을 표시해 줍니다(아래 참고).
Limit 0, 또는-1이 아닌 음수 제한은 AI가 그 대상을 건설하지 못하게 합니다.-1은 상한을 없앱니다.#은 어디서든 줄을 끝냅니다. 단어 안에 있어도 마찬가지이며, 블록 주석은 없습니다.//가 동작하는 것은 첫 단어가 지시문이 아닌 줄이 무시되고 값 뒤의 단어도 무시되기 때문일 뿐입니다.- 1보다 큰 가중치는 유닛을 100 % 넘게 올리지 못합니다. 앞서 분류 가중치가 줄인 유닛을 되돌릴 수 있을 뿐입니다.
- 유닛을 가리키는 첫 줄이 그 유닛을 잠급니다. 유닛별 줄은 그것이 다듬어야 할 분류 줄보다 뒤에 두세요.
- 토큰 사이의 공백은 구분자로서만 의미가 있습니다 — 탭, 스페이스, 여러 칸의 스페이스가 모두 똑같이 동작합니다.
- 중첩되거나 공유되는 섹션은 지원하지 않습니다. 각
plan블록은 필요한 weight/limit를 모두 다시 선언해야 합니다.
kbot이 보여 주는 것
스튜디오의 에셋 탐색기(AI Profile 탭)와 kbot mount의 describe는 게임과
같은 방식으로 프로필을 읽습니다.
- Before first plan — 프리앰블 줄들. 게임이 시작할 때 무시된다는 표시가 붙습니다.
- plan마다 탭 하나 — 각 대상은 설치본의
units/*.fbi(이름과Category=)와 맞춰 unit, category, all units 중 하나로 표시됩니다. 어떤 유닛에도 없는 분류는 — 철자가 틀린 유닛 이름이 이렇게 읽힙니다 — matches no unit으로 표시됩니다. 가중치는 배율로 표시되고, 100 %에서 시작한 유닛에 남는 백분율을 막대로 보여 줍니다. 제한은 ∞ Unlimited, Disabled(0, 또는 -1이 아닌 음수), Max: N으로 표시됩니다. - 게임이 다르게 읽는 줄 — kbot-io의 진단으로, 숫자가 아닌 값 단어(
O는 0으로 읽힘)나 값 뒤의 단어 같은 것입니다. 게임이 읽는 숫자와 다른 값 단어는 그 옆에 표시되며(written "O"),.1이나0.10처럼 같은 숫자를 다르게 쓴 것은 표시되지 않습니다. - At game start(스튜디오.
kbot mount는 개수를 출력) — easy, medium, hard 각각에 대해, 프로필이 가중치나 제한을 바꾸는 모든 유닛을 보여 주며, 유닛 줄이 잠근 값에는 🔒가 붙습니다.
일반적인 크기
| 지표 | Cavedog 프로필에서 관찰된 범위 |
|---|---|
| 파일 크기 | 1–4 KB |
| 파일당 plan 수 | 3(easy/medium/hard) |
| plan당 Weight 지시문 | 20–80 |
| plan당 Limit 지시문 | 0–10 |