모든 형식 페이지 ↓
유닛·스크립트·설정

AI — 컴퓨터 상대 프로필

출처: coreprime/kbot @ 0ab97bf · GitHub에서 편집

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

함께 보기

  • TDF — AI 프로필을 고르는 .ota 맵 메타데이터.
  • 용어집 — side, category.