TorchCraft - podstawowy skrypt
Ten post jest o rozwijanym przeze mnie bocie do Starcrafta wykorzystującym uczenie maszynowe. Projekt jest rozwijany w ramach konkursu "Daj Się Poznać 2017".
Miałem w tym tygodniu pisać o samym Torchu i o tym jak tworzyć w nim sieci neuronowe, ale zdecydowałem, że zajmę się samymi podstawami samego TorchCrafta i jego interakcji ze Starcraftem. TorchCraft, niestety, ma słabą dokumentację i poza opisem instalacji praktycznie wszystko trzeba rozkminiać na bazie przykładów z katalogu examples
.
Mapy
Zacznijmy od tego, że TorchCrafta można uruchomić w dwóch trybach: micro i w normalnym. W normalnym trybie można grać na zwykłych mapach do multi. Tutaj nie ma żadnych niespodzianek. Mapy do micro nie zawierają budynków i walczą na nich dwie grupy jednostek. Do tego trybu mapy muszą być specjalnie przygotowane. Z TorchCraftem dostarczane są cztery mapy: dragoons_zealots.scm
, m5v5_c_far.scm
, sp_dragoons_zealots.scm
, sp_m5v5_c_far.scm
. Są to tak naprawdę dwie mapy w dwóch wersjach każda. Nie mam pojęcia jaka jest różnica, te z przedrostkiem sp_
może mają jakiś związek z single playerem?
Mapy micro zawierają rozmieszczone równomiernie specjalne, niewidzialne jednostki odkrywające cześć mapy (tak zwane Map Revealery), a także lokacje startowe (Start Location), czyli punkty, w których pojawiają się jednostki.
Żeby te jednostki się pojawiły potrzebne są tak zwane triggery. Tworzy się je w edytorze map w specjalnym panelu. Triggery pozwalają na wiele różnych rzeczy np. umieszczanie jednostek na mapie, sterowanie jednostkami, wypisywanie tekstu na ekranie, ogólnie - pozwalają na sterowanie grą. Triggery zawierają dwie rzeczy: conditions
- czyli warunki dla których trigger jest uruchamiany, a także actions
- czyli akcje uruchamiane w ramach danego triggera. Można jeszcze ustawić osobno, dla jakiego gracza trigger jest uruchamiany.
Zobaczmy na nasze mapy micro:
Widzimy, że triggery na samym początku każdej rozgrywki tworzą po kilka jednostek dla obu graczy, a także, jeśli zachodzi potrzeba następuje wysłanie jednostek do ataku.
Ok, tyle jeśli chodzi o mapy. Czas zająć się kodem.
Kod
Na początek napiszmy minimalny działający przykład:
local hostname = "192.168.56.1"
local port = 11111
local tc = require 'torchcraft'
tc.micro_battles = true
tc:init(hostname, port)
local update = tc:connect(port)
while not tc.state.game_ended do
update = tc:receive()
-- code here
end
tc:close()
Przenalizujmy ten przykład:
Pierwsze dwie linijki to host i port potrzebny do połączenia z hostem (Windows ze Starcraftem):
local hostname = "192.168.56.1"
local port = 11111
Następnie ładujemy bibliotekę TorchCraft:
local tc = require 'torchcraft'
Przełączamy TorchCrafta w tryb micro:
tc.micro_battles = true
Odpalamy połączenie:
tc:init(hostname, port)
local update = tc:connect(port)
Następnie następuje pętla, w której możemy wydawać rozkazy jednostkom. W tym przykładzie nie zdefiniowaliśmy warunków zakończenia pętli, więc rozegrane zostanie nieskończenie wiele bitew:
while not tc.state.game_ended do
update = tc:receive()
-- code here
end
Na samym końcu zamykamy połączenie:
tc:close()
Jak widać, sprawa jest bardzo prosta. Pobawmy się jednak jeszcze trochę. Dodajmy konfigurację nad pętlą while
:
local setup = {
tc.command(tc.set_speed, 20),
tc.command(tc.set_gui, 1),
tc.command(tc.set_cmd_optim, 1),
}
tc:send({table.concat(setup, ':')})
Są to trzy komendy. set_speed
odpowiada za prędkość gry, jeśli damy zero to gra będzie bardzo szybka, bo czas między wykonaniem logicznych klatek (logical frames) będzie praktycznie zerowy. set_gui
ustawione na 1
oznacza, że można zobaczyć przebieg akcji. Natomiast set_cmd_optim
to optymalizacja komend stosowana przez BWAPI, jeśli jest ustawiona BWAPI stara się zredukować liczbę akcji poprzez grupowanie i wykonywanie podobnych rozkazów. Można ustawić wartości od 0 do 4 (dokumentacja).
Zobaczmy jeszcze co jest wysyłane do TorchCrafta:
print({table.concat(setup, ':')})
Otrzymamy:
{
1 : "6,20:8,1:10,1"
}
Widzimy, że komendy są oddzielone dwukropkami, a liczbowe identyfikatory komend są oddzielone od wartości przecinkami.
Podsumowanie
Dobra, to na razie tyle. Niestety, dokumentacja TorchCrafta praktycznie nie istnieje, więc wiele nie zdziałałem. Nie mogłem na razie na przykład wykombinować jak wydać jednostce rozkaz przemieszczenia się do innego miejsca bez atakowania niczego po drodze. Wiedzę trzeba będzie zdobyć poprzez czytanie kodu i ciągłe testowanie co działa, a co nie. Nie będzie lekko :)