toimialatyökalu ja -kieli pelitekoälyn kehittämiseen
TRANSCRIPT
Veikko Eeva Toimialatyökalu ja -kieli pelitekoälyn kehittämiseen Diplomityö
Tarkastajat: professori Tommi Mikkonen
professori Ilkka Haikala
Aihe hyväksytty Tieto- ja sähkötekniikan
tiedekuntaneuvoston kokouksessa 3.6.2009.
Tarkastajat hyväksytty Tieto- ja sähkötekniikan
tiedekuntaneuvoston kokouksessa 7.10.2009.
II
Tiivistelmä
TAMPEREEN TEKNILLINEN YLIOPISTO
Tietotekniikan koulutusohjelma
Eeva, Veikko: Toimialatyökalu ja -kieli pelitekoälyn kehittämiseen
Diplomityö, 77 sivua, 3 liitesivua
Lokakuu 2009
Pääaine: Ohjelmistotuotanto
Tarkastajat: professori Tommi Mikkonen, professori Ilkka Haikala
Avainsanat: toimialamallinnus, toimialakieli, tekoäly, pelit, simulaatio,
moniagenttijärjestelmät
Peliteollisuus on laaja ohjelmistoalan haara, jonka tuottamia sovellutuksia käytetään
paitsi viihteessä myös muualla yhteiskunnassa. Pelien tuottaminen on kuitenkin
kallistunut osaltaan tekoälystäkin johtuvista syistä. Ei ole olemassa laajasti hyväksyttyä
yleiskäyttöistä rajapintaa niin pelin muiden alijärjestelmien ja tekoälyn kuin pelin
tekoälyn ja sen työkaluketjunkin välillä, eikä yleisiä tekoälyn primitiivejä ole onnistuttu
määrittelemään. Pelitekoälyn kehittämisen ongelmien ratkaisemiseksi on ehdotettu
muun muassa yleiskäyttöisen rajapinnan määrittelyä, kirjastoja ja tutkimusta primi-
tiivien löytämiseksi.
Toimialamallinnus on viime aikoina esitetty ohjelmistoteollisuudessa menetelmänä
säästää ohjelmistokehityskustannuksia lisäämällä toimiala-asiantuntijoiden suoraa
panosta ja projektiteennösten uudelleenkäytettävyyttä. Nykytiedon perusteella on
kuitenkin vaikea arvioida, voiko saatavilla olevia toimialamallinnustyökaluja käyttää
kustannustehokkaasti pelitekoälyn tuottamiseen ja mitä ongelmia lähestymistavassa on.
Tämän diplomityön tarkoituksena on muuntaa yleiskäyttöisen rajapinnan määrittely
pelitekoälyn kuvaamiseen soveltuvaksi yksinkertaiseksi malliksi, josta voidaan tuottaa
kirjastoja täydentävät tai korvaavat ohjelmistoteennökset. Mallin käyttämiseksi
määritellään sitä tukeva graafinen kieli. Mallin, kielen sekä niillä tuotettujen teennösten
käyttökelpoisuus testataan rakentamalla prototyyppi. Teennösten testattavat ominai-
suudet ovat niiden suorituskyky ja liitettävyys muuhun peliohjelmistoon sekä raken-
teellisesti että toiminnallisesti. Malli ja kieli määritetään yleisesti tähän tarkoitukseen
saatavilla olevaa työkalua käyttäen, jolloin voidaan selvittää, ovatko viime vuosina
ilmestyneet työkalut käyttökelpoisia käytännön ohjelmistotyössä. Alan kirjallisuuden ja
yleisen keskustelun perusteella tekoäly on pirstaleinen toimiala, jonka osatoimialojen
ratkaisutavat saattavat erota toisistaan suurestikin. Työssä kuvataan pelitekoälyä siltä
osin kuin se vaikuttaa kielen rakenteisiin ja suunnitteluun. Myös toimialamallinnuksen
periaatteet ja siihen liittyvä keskeinen käsitteistö esitellään.
III
Projekti ja prototyyppi osoittavat, että menetelmän käyttö on perusteltua ja toimii
ainakin suppeassa mittakaavassa. Työn osana toteutettu käytännön toimiala-
mallinnuksen ohjelmistototeutus tuo esiin ongelmia erityisesti tehokkaassa rinnakkais-
prosessoinnin hyödyntämisessä sekä pelin eri toimijoiden, agenttien, välisessä
viestinnässä. Työn graafinen kieli on melko matalalla tasolla pelitekoälyn toimiala-
käsitteisiin nähden eikä se tue suoraan näiden koostamista laajemmiksi
kokonaisuuksiksi muuten kuin erikseen ohjelmoijan määritteleminä osina. Kieli on myös
graafisuutensa vuoksi kömpelö rinnakkaisuuden tai viestinnän kuvaamiseen, joten niitä
ei voi eksplisiittisesti kuvata, vaikka malli ja kieli sisältävätkin oletuksen tietynlaisesta
automaattisesti huolehditusta ajonaikaisesta käyttäytymisestä. Viestinnän ja rinnak-
kaisuuden ongelmien nykyiset ratkaisuehdotukset viittaavat viimeaikaisten dynaamisten
moniagenttijärjestelmien ja diskreettien tapahtumasimulaatioiden yhdistämiseen.
Kumpaakin on tutkittu laajasti omana toimialanaan, muttei juuri samassa yhteydessä tai
pelien ja niiden tekoälyn näkökulmasta. Pelitekoälyn toimialakäsitteitä esittävä ja tukeva
graafinen kieli lienee tuottavampaa luoda tällaisen perustan päälle.
Hyvin määritelty pelitekoälymalli helpottaa toimialan käsitteiden ja primitiivien
syntymistä. Täten on myös ajateltavissa, että käyttökelpoisimmat mallit, niitä käyttävät
kielet ja soveltuvimmat malleista tuotetut ohjelmistoteennökset leviävät käytössä ja
koontavat alan tietoa. Simulaation ja moniagenttijärjestelmien käsitteet voivat tukea
myös pelitekoälyn primitiivien määrittämistä.
IV
Abstract
TAMPERE UNIVERSITY OF TECHNOLOGY
Master’s Degree Programme in Information Technology
Eeva, Veikko: A domain tool and a language to develop game artificial intelligence
Master of Science Thesis, 77 pages, 3 appendix pages
October 2009
Major: Software engineering
Examiners: Professor Tommi Mikkonen, professor Ilkka Haikala
Keywords: Domain-specific modelling, domain-specific language, artificial intelligence,
games, simulation, multi-agent systems
The game industry is a vast branch of the software business and includes a wide variety
of applications extending beyond entertainment. The cost of producing games has
increased in part due to factors related to artificial intelligence. One factor at present is
the absence of a widely accepted general purpose interface between game artificial
intelligence and other game sub-systems and the game artificial intelligence tool chain.
Efforts to define general artificial intelligence primitives have not been successful. One
proposed solution to the problems in developing game artificial intelligence is to gather
the latest research regarding primitives and craft it into a specification for a general
purpose interface that can be used with libraries.
Recent studies by software researchers portray domain-specific modelling as a
method to cut software development costs. Increasing the direct involvement of domain
experts is said to improve the usefulness of project artefacts and thus further their reuse.
Given the current level of knowledge, however, it is difficult to judge if available domain-
modelling tools can be used to produce game artificial intelligence in a cost-effective
way. Indeed, it is difficult to even identify the associated problems regarding this
approach.
The purpose of this master’s thesis is to transpose the specification of a general
purpose interface into a simple model capable of describing game artificial intelligence.
This model can then be used to produce software artefacts able to complement or
replace libraries. A graphical language is specified to help utilise the model. The
applicability of this model, graphical language and related artefacts are tested by
building a prototype. Testable features of the artefacts include their performance as well
as their structural and functional connectivity to other game sub-systems. The model
and the graphical language are specified using commonly available tools in order to
determine if recently available tools are usable in practical software work. The general
scientific consensus is that artificial intelligence is a fragmented domain in which the
V
solution methods in different sub-domains substantially differ from each other. This
thesis describes game artificial intelligence in terms of the aspects that influence the
structure of the graphical language and its design. It introduces the central concepts of
domain-specific modelling and expounds its principles.
The project and the prototype developed with it demonstrate that the use of this
method is valid and usable at least on a constricted scale. The practical domain-specific
modelling software implementation elicits problems, particularly in the efficiency
utilisation of concurrency and in communication between the different actors and agents
in games. The graphical language operates at a fairly low level pertaining to game
artificial intelligence concepts but does not easily support composing these concepts into
larger entities. The graphical nature of this language makes it ill-suited for describing
concurrency and signalling, but the model and the language contain an assumption of a
certain kind of automatically handled run-time behaviour. The proposed solution to
these signalling and concurrency problems involves combining more recent
developments in dynamic multi-agent systems and discrete event simulations. These
developments have been studied thoroughly in their respective domains, but not in the
same context let alone from the perspective of games and their artificial intelligence. A
more productive domain-specific language portraying game artificial intelligence could
be built on this foundation.
A well defined game artificial intelligence model facilitates the formation of domain
concepts and primitives. The plausibility that the use of the most usable models, the
languages that employ them and the most applicable software artefacts might become
influential enough to codify domain knowledge must be considered. The concepts of
simulation and agent languages may support the definition of game artificial intelligence
primitives.
VI
Alkusanat
Tahdon kiittää Mike Caetanoa, Kurtis Fieldsiä, Tommi Mikkosta ja erityisesti vaimoani
Paula Eevaa. Sain ajatuksen diplomityöhöni Kalevalaa lukiessani, joten seuraavat säkeet
lienevät paikallaan:
Silloin virsikäs Vipunen, tuo vanha varaväkevä,
jonk’ oli suussa suuri tieto, mahti ponnetoin povessa,
aukaisi sanaisen arkun, virsilippahan levitti
lauloaksensa hyviä, parahia pannaksensa,
noita syntyjä syviä, ajan alkuluottehia,
joit’ ei laula kaikki lapset, ymmärrä yhet urohot
tällä inhalla iällä, katoavalla kannikalla.
(Kalevala, 17. runo)
Tampereella 1.10.2009
Veikko Eeva
VII
Sisällys
1 Johdanto .......................................................................................................................... 1
2 Videopelien tekoäly ......................................................................................................... 3
2.1 Videopelien lyhyt historia ja tekoälykehityksen nykytilanne ................................ 3
2.2 Pelitekoälyn ongelmien yleiskatsaus ja erityispiirteitä ..........................................7
2.3 Uskottavan ja toimivan pelitekoälyn piirteet ....................................................... 10
2.4 Pelitekoälyn keskeiset toteutusongelmat ............................................................. 12
3 Tekoälyn mallintaminen ja kieli ................................................................................... 17
3.1 Minkä ongelman toimialamallinnus ratkaisee ..................................................... 17
3.2 Mitä ovat toimialamallinnus ja -kielet .................................................................. 19
3.3 Toimialamallin ja -kielen rakentaminen yleisesti ................................................ 23
3.3.1 Toimialakieli ...................................................................................................... 23
3.3.2 Toimiala ............................................................................................................ 24
3.3.3 Toimialamalli ..................................................................................................... 25
4 Toimialatyökalu Vipunen ja toimialakieli Luote ......................................................... 27
4.1 Luotteen suunnittelulähtökohdat......................................................................... 27
4.2 Microsoft DSL Tools ja XNA's Not Acronymed (XNA) ....................................... 28
4.3 Microsoft DSL Toolsin rakenne ja toiminta ........................................................ 28
4.4 Mallin määrittäminen DSL Toolsilla .................................................................... 30
4.5 Luotteen konkreettinen syntaksi .......................................................................... 33
4.6 DSL Toolsin kielen oikeellisuustarkistukset ........................................................ 35
5 Luotteella tuotetun ohjelmiston toiminta ................................................................... 36
5.1 Luote-kielen ajoympäristö .................................................................................... 36
5.2 Staattinen luokkamalli ..........................................................................................39
5.2.1 Signaalien lähteiden ja nielujen sitominen .......................................................39
5.2.2 Vuorovaikutuksen rakenne ............................................................................... 41
5.3 Vuorovaikutusten suoritussekvenssi ................................................................... 42
5.4 Suorituskyky ja ajonaikainen käyttäytyminen .................................................... 46
5.4.1 Suorituskykyyn vaikuttavat yleistekijät ........................................................... 46
5.4.2 Luotteen nopeusmittaukset ja profilointi .................................................... 48
6 Tulokset ja päätelmät .................................................................................................... 55
6.1 Luotteen arviointi .................................................................................................. 55
VIII
6.2 Käytännön kokemuksia ja huomioitavaa ............................................................ 56
6.3 Välittömät lisäominaisuudet ................................................................................ 58
6.4 Muut vastaavat projektit tai tuotteet ................................................................... 58
6.5 Päätelmät .............................................................................................................. 60
7 Yhteenveto .................................................................................................................... 64
Lähteet .................................................................................................................................. 66
Liite A: Testauslaitteistojen kokoonpanotiedot ................................................................. 78
Liite B: Testiohjelman runko ............................................................................................... 79
Liite C: Esimerkkikoodi ....................................................................................................... 80
IX
Kuvat
Kuva 2-1: Joitakin tekoälyn toimialoja ja niiden ominaisuuksia. ......................................... 11
Kuva 2-2: Tekoälyjärjestelmän arkkitehtuuri pelissä Ian Millingtonin mukaan. ............... 14
Kuva 2-3: Pelitekoälyn kerrosarkkitehtuuri Dan Klinen mukaan. ...................................... 15
Kuva 3-1: Toimialamallinnus sulkee kuilun konkreettisen ratkaisun ja sen idean välillä. 20
Kuva 3-2: Koodi ja sen toimiala-esitys.................................................................................. 21
Kuva 3-3: Tuotelinja-arkkitehtuurin kustannuksista. ......................................................... 22
Kuva 3-4: Toimialamallinnuksen peruslähtökohdat. ......................................................... 26
Kuva 4-1: Tyypillinen toimialamallin kehityskiertokulku. ................................................. 29
Kuva 4-2: Luote-kielen metamalli. ....................................................................................... 31
Kuva 4-3: DSL Toolsin metakielen rakentamisessa käytetty työkaluvalikko. .................... 32
Kuva 4-4: Toimialaluokka ja sen konkreettinen syntaksi. .................................................. 33
Kuva 4-5: Vipunen-editorin muokkausalue ja esimerkki Luote-kielestä. .......................... 34
Kuva 5-6: Havaintokuva toimijaan liitetystä tilakoneesta ja signaaleista. .......................... 37
Kuva 5-7: Luote-kielestä tuotetun ajonaikaisen rakenteen luokkakaavio. .........................39
Kuva 5-8: Luotteen komentojen suorittaminen. ................................................................ 42
Kuva 5-9: Luotteen ajonaikainen komentosilmukka.......................................................... 44
Kuva 5-10: Moniydinkoneiden suoritusteho eri ytimien lukumäärällä ............................. 47
Kuva 5-11: Luote demo -ohjelma resurssienkulutuksen jakautumisen mittaamiseksi. ...... 52
Kuva 5-12: Tyypillinen Luote-demon profilointiajon tulos. ................................................ 53
X
Taulukot
Taulukko 2-1: Joitakin pelien lajityyppejä ja niissä käytettyjä pelien ratkaisutapoja. ......... 9
Taulukko 5-1: Luotteen läpisyötön mittausdataa. .............................................................. 50
Taulukko 6-1: Yhdeksän ominaisuutta toimialakielen arviointiin. .................................... 56
XI
Termit ja määritelmät
.NET Compact Framework Microsoftin .NET-kehyksen kevennetty versio esimerkiksi älypuhelimiin ja konsoleihin.
Artificial Intelligence for Interactive Digital Entertainment Conference (AIIDE)
Association for the Advancement of Artificial Intelligencen viihdeteollisuuden ja akateemisten tekoälytutkijoiden vuorovaikutukseen pyrkivä konferenssi.
Behavior Tree (BT) Peliohjelmoinnissa viime aikoina yleistynyt päätös-puiden muoto, missä puun päätössolmuihin on liitetty myös toiminnallisuutta.
Belief-Desire-Intention (BDI) Eräs tekoälyssäkin käytettävä käyttäytymisen (formalisoitu agenttiarkkitehtuurin) malli.
Cache Coherent Non-Uniform Memory Access (ccNUMA, tässä työssä vain NUMA)
Synkronoidun välimuistin erillisten suorittimien epäyhtenäinen muistipääsy. Tekniikka, joka pitää suorittimien välimuistin sisällön keskenään synkro-noituna ja jossa muistipääsy eri suorittimilta muistiin on yhtenäinen, mutta pääsyaika voi olla eri.
Common Intermediate Language (CIL)
.NET-kehyksen alimman tason assembly-kieli, eli alimman tason vielä tekstinä luettava ohjelmakoodi.
Emergenssi Emergenssi on muutos, joka ilmenee, kun yksinkertaisista säännöistä sukeutuu ylemmän tason järjestelmä (engl. emergence).
Game Developers Conference (GDC)
Vuosittainen videopelikehittäjille suunnattu oppimis- ja palkinnonjakotapahtuma, jossa on ammattilais-paneeleja, oppitunteja ja näyttelyitä liittyen mm. ohjelmointiin ja liiketoimintaan.
Hystereesi Tässä työssä kahden eri tilan välillä tapahtuvat ei-toivotut siirtymät silloin, kun uuden tilan siirtymäehto täyttyy heti siirtymän jälkeen ja tapahtuu siirtymä takaisin edelliseen tilaan.
International Game Developers Association (IGDA)
Kansainvälinen pelinkehittäjien yhdistys.
Just-In-time (JIT) compilation Vaihe käännettäessä ohjelmakoodi juuri ennen käyttöä konekieliseksi suoritinta varten ja ohjelmaan linkitettäväksi.
XII
Memory wall Muistiseinä, epäsuhta suorittimen nopeuden ja sen kyvyn käyttää muistia sekä muistijärjestelmän toimintanopeuden välillä.
Näennäisjakaminen Kun data on muistissa siten, että prosessoinnin kannalta yhteenkuulumattomia osia joutuu samaan välimuistin lohkoon vieden tilaa mahdollisesti tarvittavalta datalta sekä pakottaen koko blokin synkronoinnin muihin välimuisteihin, vaikkei se välttämättä ole tarpeellista (engl. false sharing).
Object-Oriented Programming, Systems, Languages & Applications (OOPSLA)
Association for Computing Machineryn (ACM) vuosittain järjestämä oliokeskeinen konferenssi.
Open Computing Language (OpenCL)
Khronos Groupin määrittämä data- ja tehtävä-rinnakkainen kirjasto eri alustoille.
Proseduraalinen luotu sisältö Ohjelmallisesti, algoritmisesti luotua sisältöä, jota graa-fikot eivät ole luoneet. Peleissä tällaista sisältöä voivat olla esimerkiksi metsät, kaupungit tai pilvet taivaalla.
Single Instruction, Multiple Data (SIMD)
Yhdellä käskyllä voidaan operoida monta data-alkiota, tunnetaan myös vektorikäskyinä.
Special Interest Group (SIG) Erityissidosryhmä.
Suoritinelementti Suoritinelementti voi tarkoittaa joko yksittäisiä tietokoneita, fyysisiä suorittimia, suoritinytimiä, laitteistosäikeitä kuten Intelin Hyper-Threading tai vastaavia.
Suoritusvuoron riistäminen (riistäminen)
Kun rinnakkaisohjelmistossa on useampia säikeitä kuin suorituselementtejä, järjestelmä vuorontaa säikeille suoritinaikaa – eli toinen säie siirtyy suoritukseen (engl. pre-emption).
Teennös Esimerkiksi jonkin prosessin tuotos (engl. artefact).
Text Template Transformation Toolkit (T4)
Microsoftin tekstuaalinen kaavainkieli muunnosten tekemiseen.
Toimialakieli Jotakin toimialaa kuvaava kieli (esimerkiksi toimialan tunnetut symbolit ja jargon), jota käytetään toimialamallinnuksessa (engl. Domain-Specific Language (DSL)).
Toimialamallinnus Metodologia, jossa jotakin toimialaa mallinnetaan ohjelmistotuotannon tehostamiseksi (engl. Domain-Specific Modelling (DSM)).
Välimuistihuti Osoitus muistiin, jota ei ole valmiina välimuistissa, vaan se täytyy hakea päämuistista (engl. cache miss). Huteja on kahdenlaisia: käsky- ja datahuti (engl. cache data miss ja cache instruction miss).
1 Johdanto
Nykyään kuulee useasti mainittavan, että peliteollisuus on interaktiivisen viihteen
tulevaisuus, kestää taantumat ja tuottaa jo enemmän voittoja kuin suuri elokuva-
teollisuus. Tällainen ei ehkä pidä paikkaansa, mutta peliteollisuus on yhtä kaikki noussut
merkittävään kulttuuriseen asemaan ja aktiivisen tutkimuksen kohteeksi. Peli-
teollisuuden kasvun myötä myös pelien tuottamisen kustannukset ovat nousseet
huimasti. Videopelien tekoäly on osa ongelmaa. Tekoälyä tarvitaan kiinnostavuuden
luomiseksi, mutta sen tuottaminen maksaa.
Videopelien tekoälyn tuottamista on akateemisesti tutkittu melko vähän sellaisten
algoritmisten ongelmien kuin reitinhaun ja hermoverkkojen näkökulmasta, ja vasta
aivan viime vuosina. Muun muassa Alexander Nareyek (2004a) on kritisoinut
voimakkaasti akateemisia tutkijoita pelien tekoälyn tutkimuksen laiminlyömisestä.
Toisaalta peliteollisuus on hittivetoinen, ja sesonkien mukaan aikataulutettujen
projektien parissa työskentelevillä, yleensä nuorilla ammattilaisilla ei ole joko tarpeeksi
koulutusta tai mahdollisuuksia ottaa vastaan uutta tietoa, eikä välttämättä edes aikaa tai
halua yrittää etsiä parempia vaihtoehtoja.
Teollisuuden alalla, joka on nuori, nopeatempoinen ja jonka henkilöstövaihtuvuus on
suurta, onkin ensisijaisen tärkeää löytää tapa hyödyntää jo tuotettuja resursseja.
Erityisesti Steve Rabin (Kline 2008a) ja Peter Molyneux (Remo 2009) ovat yleisesti
esitelmöineet tällaisen lähestymistavan puolesta. Rabin on aika ajoin esitelmöinyt myös
tarpeesta nostaa tekoäly pelejä erottavaksi tekijäksi pelaajille sekä sen arvostuksen
puutteesta pelitalojen projektityöskentelyssä.
Yleisesti tekoälyn kehittämisen ongelmaan vaikuttaa, että ratkaisuyritykset ovat
usein tekniikka- tai toimialasidonnaisia, ja näiden tunteminen halutussa laajuudessa on
yksittäisille kehittäjille usein haasteellista. Tekoälyn integroiminen grafiikka- ja
fysiikkavetoisiin jatkuva-aikaisiin simulaatio-ohjelmistoihin (pelimoottoreihin) ei
myöskään yleensä ole helppoa, sillä tekoälyn mutkikkaat rakenteet vaativat
haarautumista sekä aikaulottuvuuden ja kausaalisuuden huomioimista grafiikan tai
fysiikan prosessoinnin kaltaisen maksimaalisen läpisyöttöprosessoinnin ja laskentatehon
sijaan.
Pelien tekoälyn tuottamiseen vaikuttavat myös ei-tekniset näkökulmat, kuten
oikeanlaisen tunnelman luominen tai erilaisten kerronnan elementtien yhdistäminen
juuri oikealla tavalla halutunlaisen vaikutuksen aikaansaamiseksi. Tämän erittäin laajan
ja kulttuurisen tutkimuksen piiriin kuuluvien tulosten tulkitseminen peleihin sopivasti
on erityisen hankalaa jo sen monipolvisuudesta johtuen. Muun muassa Tampereen
yliopistossa on aktiivista pelitutkimusta, ja juuri väitelleen Aki Järvisen (2009) erittäin
1 Johdanto 2
laaja tutkimus jäsentää yhteen viimeisimmän kymmenen vuoden aikana syntynyttä
suunnatonta tutkimusmassaa.
Tavoitteeni on konkreettinen ja järjestelmällinen ohjelmistoon perustuva menetelmä
tuottaa tekoälysisältöä peleihin potentiaalisesti halvemmin ja nopeammin kuin
perinteisemmillä tavoilla. Tutkin tarkemmin pelitekoälyn eri osia ja niiden suhdetta
toisiinsa sekä pelitekoälyn suhdetta pelin tuotantoprosessiin uudelleenkäytettävän
tekoälyn rakentamiseen keskeisimmin vaikuttavien seikkojen osalta. Rakennan
realistisen tekoälytyökalun prototyypin käyttäen erityisesti laaja-alaista ja eri toimialoja
leikkaavaa ongelmaa varten kehitettyä menetelmää ja sen työkalutukea. Prototyypin
rakentamalla voin selvittää, mitä käytännön asioita täytynee ottaa huomioon, ja toimiiko
edellä mainitun menetelmän työkalutuki käytännössä.
Terminologia ei ole vakiintunutta, mutta esitetyn menetelmät keskeiset osat
tunnetaan muun muassa termeillä ”sovellusaluekeskeinen ohjelmistokehitys” ja
”sovellusaluekeskeiset kielet” (TTLRY 2009). Tässä työssä on käytössä termin ”toimiala”
johdannainen, koska se kuvaa menetelmän henkeä paremmin kuin termin ”sovellusalue”
johdannaiset. Lisäksi sana ”alue” viittaa konkreettiseen alueeseen, joten se on myös sikäli
harhaanjohtava.
Aluksi taustoitan luvussa 2 tutkimukseni motivaation kannalta keskeisimmät teol-
lisuuden pelitekoälyyn liittyvät ongelmat. Seuraavaksi käsittelen pelitekoälyn erityis-
piirteitä, minkä jälkeen vertaan sitä muuhun tekoälyyn ja käsittelen yleisellä tasolla niitä
ongelmia, joita pelitekoälyn luomisessa laajemmin aitoon peliin on. Luvun 2
tarkoituksena on paitsi luoda yleiskatsaus pelitekoälyn kenttään yleisesti ja
toteutusongelmien osalta myös pohjustaa luvun 3 teoreettisempaa käsittelyä näiden
ongelmien ratkaisemisen perustaksi.
Luvussa 3 esittelen ohjelmistotekniikassa viime aikoina laajempaan tietoisuuteen
tulleen toimialamallinnuksen teoreettista taustaa laaja-alaisten ongelmien kustannus-
tehokkaaseen ratkaisuun. Pohjustan luvun 4 lyhyellä yhteenvedolla lukujen 2 ja 3
keskeisestä sisällöstä, minkä jälkeen esittelen erään luvussa 3 esitettyyn menetelmään
liittyvän työkalun ja sen aiotun käyttöympäristön sekä rakennan sen avulla ohjelmani
prototyypin. Käsittelen lopuksi luvun 4 lopuksi prototyyppityökaluni joitakin teknisiä
ominaisuuksia niiltä osin kuin ne pelinkehityksen kannalta ovat tärkeitä. Tämän
käsittelyn tarkoituksena on varmistua paitsi siitä, että työkalu on ylipäätään mahdollista
rakentaa, myös siitä, että se on mahdollista saada toimimaan teknisesti kyllin tarkasti ja
ennustettavasti. Olen tähän yhteyteen lisännyt joitakin päätelmiä järjestelmän
toiminnasta ja jatkokehitysmahdollisuuksista niille luontevan esityspaikan vuoksi.
Luvussa 5 pohdin työstä saamiani kokemuksia sekä vertaan luvussa 3 esittämääni
menetelmää ja myöhemmin rakentamaani prototyyppiä muihin vastaavankaltaisiin
tiedossani oleviin. Jotkin johtopäätöksistä ovat ehkä odottamattomiakin, ja pohdin näitä
epämuodollisesti luvussa 6.
2 Videopelien tekoäly
Pelitekoäly on kimara temppuja, algoritmeja, tekniikoita ja menetelmiä yleisestä
tekoälystä, tietokonegrafiikasta, robotiikasta, säätötekniikasta ja muilta tieteenaloilta,
joiden tarkoituksena on tuottaa illuusio älystä ja viihdyttää (Wikipedia 2009a). Tekoäly
on älykkäiden koneiden tiedettä ja erityisesti älykkäiden tietokoneohjelmien
suunnittelua. Tekoäly liittyy tietokoneiden käyttämiseen ihmisälyn ymmärtämiseksi eikä
sen tarvitse rajoittua biologisesti havaittaviin menetelmiin. (McCarthy 2007.)
Videopelien tekoäly on viime vuosien aikana siirtynyt pelinkehityksen keskiöön (vrt.
Nareyek 2004a). Muun muassa hahmojen käyttäytyminen inhimillisesti, halutun
tunnelman luominen erilaisin kerronnan keinoin ja ohjelmallinen sisällöntuotanto ovat
pelitekoälyn erityisvaatimuksia. Juuri sopiva, pelimekaniikkaan tai inhimillisyyteen
liittyvä vajavaisuus (ks. West 2009) erottaa peliteollisuudessa käytetyn tekoälyn
perinteisesti akateemisesti tutkitusta, jossa on päämääränä tuottaa yleensä melko
yksikäsitteinen tulos mahdollisimman suorituskykyisesti.
2.1 Videopelien lyhyt historia ja tekoälykehityksen nykytilanne
Ensimmäinen, vuorovaikutteinen sähköinen peli on tiettävästi ollut Thomas
Goldsmithin ja Estle Mannin ohjussimulaatio vuodelta 1947. Ohjussimulaatiota
seurasivat muun muassa ristinolla vuonna 1952, Tennis for Two 1958, Spacewar! 1961 ja
vihdoin 1971 ensimmäinen, yleinen kolikkopelikone ja tälle peli Galaxy Game. Syksyllä
1972 julkaistiin maailman ensimmäinen kotikäyttöön tarkoitettu videopelilaite
MagnaVox Odyssey ja tälle 12 erilaista peliä. Kiinnostavana yksityiskohtana voidaan
pitää, että näihin aikoihin käytiin myös ensimmäiset patenttioikeudenkäynnit
videopeleihin liittyen ja ensimmäiset videopelien lajityypit syntyivät. (Wikipedia 2009b.)
Videopelit kasvoivat 1980-luvulta lähtien sisällöllisesti yhä suuremmiksi ja
toiminnoiltaan entistä monimutkaisemmiksi. Ensimmäinen peli, jossa voidaan ajatella
olleen tekoälyä, oli Toru Ikawatan suunnittelema ja Namcon valmistama kolikkopeli Pac-
Man vuodelta 1980 (Wikipedia 2009c). Pac-Manin ajatuksena oli ryömittää isoa suuta
pimeässä labyrintissä, syödä mahdollisimman monta pilleriä ja väistellä samalla omaa
hahmoa ”älykkäällä tavalla” jahtaavia haamuja. Aikaisemmissa peleissä ”tekoälyn”
toiminta perustui puhtaasti valmiiksi ohjelmoituun käyttäytymiseen (esimerkiksi
tietokonemaila seuraa palloa), mutta Pac-Manissa kukin haamu teki päätöksensä
yksinkertaiseen tilakoneeseen perustuen.
Esimerkiksi Ian Millington (2006, 7–9) korostaa Pac-Manin merkitystä juuri
pelitekoälyn historian näkökulmasta. Hän mainitsee myös sellaiset klassikot kuin Raren
Goldeneye 007 vuodelta 1997 tai Lionhead Studiosin Peter Molyneuxin Black and White
2 Videopelien tekoäly 4
vuodelta 2001. Nykyhetken kunnianhimoisimmin tekoälyä hyödyntävä peli lienee Will
Wrightin suunnittelema ja Electronic Artsin syyskuussa 2008 julkaisema Spore, jossa
tekoäly simuloi evoluutiota itiöistä galakseihin.
Läheskään kaikissa peleissä ei kuitenkaan yritetä hyödyntää tekoälyä yhtä
kunnianhimoisesti kuin Sporessa, vaan peliala on jakautumassa sen hyödyntämisen
suhteen. Gamasutra uutisoi vuoden 2008 Stanford Universityn isännöimässä Artificial
Intelligence and Interactive Digital Entertainment Conference -tapahtumassa (AIIDE)
Steve Rabinin esitelmöineen tästä jakautumisesta tulevaisuudessa ohjelmallisesti tuotet-
tavasta pelitekoälystä ja yleisemminkin pelinkehityksen haasteista seuraavasti:
[C]osts are rising, risk is greater. CPU power is improving, but we haven't found a
strong AI use for it. Middleware and shared AI architecture are still seeking their
way. Procedural content is becoming even more pervasive, and will continue to
impact both audiences and developers.
But Rabin put forth his own challenge for the future: Despite all this, why is AI still
allowed to suck? Because, in his view, sharp AI is just not required for many games,
and game designers frequently don’t get what AI can do. That was his challenge for
this AIIDE – to show others the potential, and necessity, of game AI, to find the
problems that designers are trying to tackle, and solve them. (Kline 2008a.)
Kustannukset kasvavat, riski on suurempi. Suoritinteho lisääntyy, muttemme ole
löytäneet tehokasta tekoälykäyttöä sille. Väliohjelmistot ja yhteinen
tekoälyarkkitehtuuri tekevät edelleen tuloaan. Proseduraalinen sisältö on yhä
käytetympää ja vaikuttaa sekä yleisöön että kehittäjiin.
Rabin esittikin oman tulevaisuudenhaasteensa: miksi tästä huolimatta tekoäly on
kehnoa? Hänen mukaansa nokkela tekoäly ei ole tarpeen monessakaan pelissä
eivätkä suunnittelijat useasti ymmärrä tekoälyn mahdollisuuksia. Tämä oli hänen
haasteensa täksi AIIDE:ksi – osoittaa muille pelitekoälyn potentiaali ja
välttämättömyys – löytää ne ongelmat, joita [peli]suunnittelijat yrittävät ratkaista
sekä ratkaista ne. (Käännös V. E.)
Tämä on alan keskeisen vaikuttajan mielipide nykyisen pelitekoälyn kehityksen
ongelmista: kustannukset, hyödyntämätön väliohjelmistopotentiaali, hyödyntämätön
mahdollisuus uudelleenkäytettävän tekoälysisällön luomiseksi, kehno tekoäly tai
ylipäänsä epätietoisuus siitä, miten tekoälyä voisi hyödyntää.
Taustalla vaikuttaa tieto siitä, että pelit rikastuvat sisällöllisesti ja vain joissakin
harvoissa, yleensä AAA-luokan peleissä, ohjelmallisen tekoälyn tuottamisen potentiaalia
on hyödynnetty, kuten aiemmin mainitussa Sporessa (AAA-luokan peliksi luokitellaan
yleensä suuren budjetin ja suuren kappalemääräisen myyntiodotuksen pelit). Etenkin,
kun muilla pelinkehityksen osa-alueilla, esimerkiksi grafiikassa, automaattisia
sisällöntuotannon menetelmiä käytetään alati laajemmin ja sisältöä kierrätetään. Peter
Molyneux toteaakin Gamasutran mukaan Game Developers Conferencessa (GDC):
Lionhead also has a structure called "concrete" that allows assets from one game –
say, a tree from Black & White – to take directly into a totally different game – such
as Fable 2.
2 Videopelien tekoäly 5
Further off, Molyneux would like to expand that out to systems like AI, to allow
prototypes to be quickly assembled in a modular fashion. (Remo 2009.)
Lionheadilla on systeemi, “concrete”, jonka avulla resurssit jostain pelistä – vaikkapa
puu Black & Whitestä – voidaan siirtää johonkin toiseen peliin – kuten Fable 2.
Edelleen, Molyneux haluaisi laajentaa tämän järjestelmiin kuten tekoäly voidakseen
nopeasti rakentaa prototyyppejä modulaarisesti. (Käännös V. E.)
Rabinin ja Molyneuxin edellä viittaamat seikat lisäävät kustannuksia. Tekoäly on
laaja ja epäyhtenäinen kenttä, jossa toisistaan eroavat tekniikat ovat jakautuneet toimi-
aloittain eri tarpeiden mukaan, mistä seuraa epätietoisuutta tekoälyn mahdollisuuksista
ja jopa kehnosti sovellettua tekoälyä. Eri tekniikat on siis kehitetty ratkaisemaan juuri
tietynlaisia ongelmia, jolloin ne ovat kehnoja ratkaisemaan toisenlaisia ongelmia, eikä
ole helppoa tuntea tätä ratkaisujen kirjoa tarvittavassa laajuudessa.
Tilannetta hankaloittaa, että videopeleissä käytettävää tekoälyä on alettu tutkia
akateemisesti vasta viime vuosina, joten tieto on edelleen melko hajallaan eikä tieteel-
lisesti koonnettua. Esimerkiksi Togelius (2007) ja Wardrip-Fruin (2007) kirjoittavat1
tähän liittyen blogeissaan UK Research Network on Artificial Intelligence and Video
Game technologies -tutkimusverkoston (2009) perustamiseen ja siihen liittyvään
kommentointiin blogosfäärissä, jossa eräs (Alt ym. 2007) perustamistapahtumassa
mukana ollut peliteollisuuden edustaja purkaa turhautuneisuuttaan, koska tuntee
akateemisten tutkijoiden olevan irrallaan juuri niistä teollisuuden ongelmista, joita he
ovat alkamassa tutkimaan. Alexander Nareyek (2004b) kirjoittaa aiheesta kärkevästi jo
vuonna 2004 huomauttaen, että pelit ovat mahdollisuus tehdä tekoälytutkimuksesta
tulevaisuudessa oleellisempaa sekä jokapäiväisen elämän että ohjelmistoteollisuuden
näkökulmasta.
Tiedon hajanaisuuteen ja Molyneuxin (Remo 2009) mainitsemaan tekoälyn
uudelleen käytettävyyden puutteeseen kytkeytyy teknisen kehityksen nopeus. Haja-
naisuutta lieventävät väliohjelmistot (engl. middleware) ja yleisesti hyväksytyt
tekoälyarkkitehtuurit eivät vielä ole yleistyneet käytössä todennäköisesti siksi, etteivät ne
perinteisesti ole olleet kovin muunneltavia, vaan rakennettu periaatteella ”yksi koko
sopii kaikille”. Tämä johtunee siitä, ettei alalla ole standardoituja rajapintoja peleissä
käytettyjen eri osajärjestelmien välillä. Nopeasti kehittyvällä ja hajanaisella alalla on
hankalaa kehittää tällaisia rajapintoja ja yhteistä näkemystä tarvittavasta perus-
arkkitehtuurista.
Tyypillisesti pelattavuus ja pelilogiikka mielletään samaan lajityyppiin kuuluvia tai
muuten samankaltaisia pelejä erottaviksi tekijöiksi, jotka pelitalot haluavat pitää omassa
hallinnassaan (huomaa West 2009) suuresta muuntelun tarpeesta johtuen. Tämä lisää
painetta tekoälyn väliohjelmaratkaisuihin ja kirjastoihin, joiden on käytännössä tuettava
useanlaisia tapoja integroitua tehokkaasti ohjelmistoon. Tällaisesta räätälöinnistä syntyy
1 Julan Togelius on Sveitsin Dalle Molle Institute for Artificial Intelligencen tutkijatohtori. Noah Wardrip-Fruin on Santa Cruzin University of Californian ohjelmistotieteen laitoksen yliassistentti (assistant professor).
2 Videopelien tekoäly 6
lisätyötä sekä väliohjelmistojen toimittajalle että käyttäjälle. Tämä haluttaneen välttää,
kun ei ole selvää, mitä etua tekoälyn valmisratkaisuista on.
Viime aikoina ongelmakenttä on mutkistunut entisestään, kun esimerkiksi Nvidia ja
AMD ovat esitelleen omien näytönohjaimiensa laskentatehoa hyödyntäviä ratkaisuja
(Hardwidge 2009; Plunkett 2009). Nämä ratkaisut voivat perustua paitsi erilaisille
suoritinarkkitehtuureille myös uusille ohjelmistoratkaisuille kuten OpenCL tai tuloillaan
olevaan Ct-kirjastoon (Feldman 2009), jotka on kehitetty yhtenäistämään heterogeenisiä,
rinnakkaisia prosessointyksiköitä. Videopelien tekoälyn luomista helpotetaan nykyään
jonkin verran työkalutuella, mutta sitä ei hyödynnetä yhtä laajasti pelejä erottavana
tekijänä kuin esimerkiksi grafiikkaa. Tähän lienee syynä, että olemassa olevat ohjelmisto-
ratkaisut kuten kirjastot sitovat teknisesti tietynlaisiin ratkaisuihin kuten peli-
moottoreihin ja työkaluketjuihin, joiden kaupalliset lisenssit voivat olla julkisten, osin
epämääräistenkin tietojen valossa varsin hintavia. Lisäksi nämä ratkaisut eivät
välttämättä ole kyllin joustavia sisällytettäväksi muuhun työkaluketjuun tai ne eivät
tarjoa kaikkea haluttua toiminnallisuutta.
Edellä mainitut ongelmat tekoälyresurssien uudelleenkäytettävyydestä teknisesti
nopeasti muuttuvalla alalla vaatii niin akateemisten tutkijoiden, pelinkehittäjien kuin
väliohjelmistoteollisuudenkin yhteistyötä. Näiden toimijoiden yhteinen näkemys
keskeisesti käytettävistä tekoälyprimitiiveistä ja -arkkitehtuurista onkin mainittu
International Game Developers Associationin Artificial Intelligence Special Interest
Groupin (IGDA AI SIG 2009) ohjelmajulistuksessa tärkeänä tulevaisuuden askeleena.
Julistuksessa todetaan myös, että standardirajapinnan suunnittelu on keskeinen tavoite,
kun tekoälyn abstraktiotasoa nostetaan sekä Rabinin (Kline 2008a) että Molyneuxin
(Remo 2009) esittämää tekoälyresurssien ohjelmallista tuottamista ja uudelleen-
käytettävyyttä lisätään. Myös Hecker (2009) ottaa kantaa juuri tekoälystä uupuviin
primitiiveihin, jollaisista on yhteisymmärrys grafiikassa.
Ensisijainen tavoitteeni on suunnitella tällainen monikäyttöinen ja mahdollisimman
vähän rajoittava yleinen tekoälyrajapinta. Testaan rajapinnan toimivuuden rakentamalla
sitä käyttävän prototyyppisuoritusmallin. Suoritusmallin lähtökohtana on, ettei se rajoita
muun ohjelmiston rakentamista merkittävästi: se on helposti integroitavissa ja on kyllin
suorituskykyinen pelitekoälykäyttöön. Tehokkuus ja mahdollisuus säädellä alustan
resurssienkäyttöä ovat peliohjelman keskeisiä laatuvaatimuksia, joten prototyyppi-
toteutuksen tehokkuuden ennustettava ja luotettava mittaaminen on myös olennainen
tekijä.
Toissijainen suunnittelutavoitteeni on selvittää samalla tekoälyn rakentamisen
työkalutukeen ja resurssien uudelleenkäytettävyyteen liittyviä ongelmia. Rakennan
prototyyppisuoritusmalliin liittyvän työkalutuen, jota käyttämällä voi ratkaista
ensisijaisen ongelman. Työkalun tavoite on toimia mahdollisimman useanlaisessa
ympäristössä, tukea pelitekoälyn kehittämisessä tarvittavaa työtä ja olla päivitettävissä
uusimpien teknologioiden ja kehitysalustojen mukaan. Prototyyppisuoritusmallin ja
työkalun rakentamisen tarkoituksena on selvittää, voiko tällaisen työn tehdä
projektinhallinnallisesti järkevällä panostuksella.
2 Videopelien tekoäly 7
Peliteollisuuden kannalta tällä on merkitystä, koska kuten jäljempänä selviää, suuri
osa tekoälyn tuottamisen kustannuksista on muun ohjelmistoteollisuuden tapaan
työvoimaperäistä. Erityisesti Suomen peliteollisuuden valtiksi on arvioitu alkuperäisten
immateriaalioikeuksien tuottaminen ja siten jo tuotettujen resurssien uudelleen
hyödyntäminen voi olla hankalampaa kuin muutoin. Alan riskiksi on myös arvioitu
työvoimapula samalla, kun kasvuksi on ennustettu 5–11 prosenttia vuosina 2009–2011
(Uudenmaan TE-keskus/SILE-projekti 2008, 7–8). Peliteollisuus arvioitiin myös Suomen
vuoden 2008 suurimmaksi kulttuurin vientialaksi 86,5 miljoonan euron liikevaihdolla
(Hiltunen & Haila 2009). Työvoimaperäisten panostusten tehostetulla hyödyntämisellä
ja siten kustannusten laskemisella on kansantaloudellista merkitystä.
Tarkennan seuraavissa luvuissa jo mainittuja tekoälyn kehittämisen ongelmia. Nämä
taustatiedot määräävät toteutuksen reunaehdot.
2.2 Pelitekoälyn ongelmien yleiskatsaus ja erityispiirteitä
Tekoälyresurssien yleiskäyttöisyyden ja uudelleenkäytön kannalta olisi hyödyllistä,
mikäli olisi olemassa jonkinlainen yleispätevä tietovarasto ja esitystapa (ontologia)
kaikenlaiselle tiedolle, jonka perusteella tekoälyjärjestelmät järkeilisivät halutulla tavalla
yhdistäen näin varsinaiset tekoälyalgoritmit ja niitä soveltavan todellisen maailman
toimialakohtaisen tiedon.
Videopelien tekoäly kuten videopelitkin on laaja käsite eikä sitä ilmeisesti ole
analysoitu ja luokiteltu yleisesti hyväksytysti tai kootusti muun muassa alan nuoruuden
ja laajuuden vuoksi. Yleisesti tekoäly on hajaantunut useihin alialoihin eri tavoitteineen
ja menetelmineen (McCorduck 2004, 419–425) kuten pelitekoälykin. Marvin Minsky
(1992) onkin todennut yleisesti tekoälystä edelleen ajankohtaisesti, että paras tapa
toimivan tekoälyn rakentamiseksi on useanlaisen esitystavan käyttäminen samassa
systeemissä: erilaisia tietorakenteita sekä algoritmeja ja analogioita, joilla on aiemmin
ratkaistu ajankohtaisia ongelmia.
Pääpiirteissään voidaan ajatella, että pelien tekoälyssä yhdistyvät algoritmit ja
interaktiivinen kerronta, jolloin työkalutuen täytyy vähintään olla neutraali näiden
elementtien suhteen ja jopa tukea ei-teknisten, interaktiivisen kerronnan elementtien
sisällyttämistä algoritmisen tekoälyn tuottamiseksi erityisesti, kun tarkoituksena on
tuottaa kerrontaa ohjelmallisesti staattisen sisällön lisäksi.
Valven vuoden 2008 lopulla julkaisema Left 4 Dead (2008) on eräs ensimmäisistä
peleistä, jonka kehityksessä on järjestelmällisesti tällainen lähestymistapa esituotetun
sisällön tai tapauskohtaisen räätälöinnin sijaan. Left 4 Deadissa (2008)
tekoälyjärjestelmä, The Director, säätelee pelitapahtumia ja kerrontaa dynaamisesti
tehden päätöksiä lähinnä musiikkiin, visuaaliseen palautteeseen, vaikeustasoon ja peli-
ohjattujen hahmojen käyttäytymiseen sekä sijoitteluun perustuen. Valven Gabe Newell
(2008) kirjoittaa tästä Edgen kolumnissa ja toteaa tämän olevan ensimmäisiä kaupallisia
askelia kohti ohjelmallisesti tuotettua kerrontaa.
Syy tällaisen sisällöntuotannon varovaiseen käyttämiseen on jo aiemminkin mainittu
projektien kallistuminen ja halu löytää tapoja kustannusten laskemiseksi. Sisällön
2 Videopelien tekoäly 8
tuottaminen käsityönä on kallista. Adam Russell (2008a, 6) toteaakin osuvasti, että
kahdeksan lisäpelitunnin sisällön tuottamiseen käsityönä tarvitaan yhdeksän kuukautta
pidempi kehitysaika ja 30 sisällöntuottajaa enemmän.
Newell (2008) sivuaa kolumnissaan myös projektinhallinnallisia ongelmia
ohjelmoijien ja suunnittelijoiden kesken, kun suunnittelijoilla ei ole tarkkaa kerronnan
yksityiskohtiin ja ohjelmoijien täytyy hallita ohjelmallisesti tuotettavasta älystä seuraavaa
emergenttisyyttä. Emergenssi on muutos, joka ilmenee, kun yksinkertaisista säännöistä
sukeutuu ylemmän tason järjestelmä. Tämä ilmiö on yleensä epätoivottu, koska se on
hallitsematon. Ilmeisesti osa ongelmista liittyy myös siihen, ettei suunnittelijoilla ja
ohjelmoijilla ole orastavasta tutkimustoiminnasta huolimatta vielä yhteistä kieltä
keskinäiseen viestintäänsä tai ettei ole aivan selvää, minkälaisista osatekijöistä ohjelmal-
lisen kerronnan voidaan ajatella koostuvan. Vastaavanlaisesta ongelmasta kirjoittavat jo
Costikyan (1994; sekä 2002), Church (1999) ja myöhemmin pelinsuunnittelun ja
kerronnan yhdistämisen tutkimusongelmista Arsenault (2005).
Sanastoa, kieltä ja luokittelua erilaisten lähestymistapojen tueksi tarjotaan myös
teoksessa Hamlet on the Holodeck (Murray 1998), jossa pelejä eritellään niiden tilan ja
ympäristön mukaan. Muita varteenotettavia tapoja luokitella ovat semioottinen
(Kücklich 2003), toimintojen ja tapahtumien väliset suhteet (Eskelinen 2001) tai
sääntöjen ja haasteiden suhde (Sicart 2008). Russel (2008a, 10–11) kirjoittaa jaottelusta
sosiologian näkökulmasta mainiten Skinnerin radikaalin behaviorismin ja Francisco
Varelan kognition ruumiillistuman teoriat.
Yleisesti tällaista tutkimusta kutsutaan pelitutkimukseksi tai ludologiaksi. Aki
Järvisen (2008) laaja väitös kokoaa ja käsittelee edellä mainittuja asioita tähdäten
käytännön sovelluksiin pelien tuottamisessa ja tutkimisessa. Laveudestaan huolimatta
mainitut käsittelytavat tarjoavat siis sanaston ja tavan käsitellä pelitekoälyn kehittämisen
viestintäongelmaa. Nicholas Caldwell (2004, 42) kirjoittaa ei-tekniseen luokitteluun
liittyen tosin, että pelit ovat niin monimuotoisia ja edustavat alilajityyppeineen niin
monia eri asioita, ettei niiden luokitteleminen, lajittelu tai tyypittäminen ole samaan
tapaan mahdollista kuin vaikkapa elokuvien. Pelejä yhdistää vain niiden tarkoitus
viihdyttää. Tästä huolimatta voidaan todeta, että luokitteleminen eri näkökulmista on
hyödyllistä muun muassa yhteisesti ymmärretyn sanaston löytämiseksi.
Teknisesti, algoritmisesti pelien tyypittämistä voidaan ajatella taulukossa 2-1
esiintyvien tyypillisimpien algoritmisten tekoälyratkaisujen mukaan, kuten niitä
ohjelmistotieteessä nimitetään. Listaus on rakennettu Brian Schwabin (2004, VII–XXV)
teoksen AI Game Programming sisällysluettelon pohjalta täydennettynä viime vuosina
käytetyillä uudemmilla yleistekniikoilla. Tämä tapa tyypittää on algoritmien kannalta
vain yksi monista mahdollisista, mutta hyödyllinen tarkasteltaessa pelejä juuri niiden
ominaisuuksien perusteella. Tämän työn kannalta ei sikäli ole tärkeää tietää kuin
oikeastaan se, että näillä algoritmeilla on toisistaan poikkeavia ominaisuuksia.
Joissain yhteyksissä tällaisista algoritmeista pelien yhteydessä käytetään termiä
peliikka (engl. gamics) (Gamics 2009). Listaus itsessään ei ole sikäli ehdoton, etteivätkö
tietyn lajityypin pelit käyttäisi toisinaan myös muiden lajityyppien tyypillisimpiä
2 Videopelien tekoäly 9
tekniikoita, tai tekniikoita voisi luetella enemmän ja hienojakoisemminkin tai
esimerkiksi tekniikoiden ohjelmalliseen arkkitehtuuriin perustuen.
Taulukko 2-1: Joitakin pelien lajityyppejä ja niissä käytettyjä pelien ratkaisutapoja.
Pelin lajityyppi Ratkaisutavat
Roolipelit Komentosarjat ja tilakoneet.
Seikkailu Komentosarjat, tilakoneet ja sumea logiikka.
Tosiaikaiset strategiat Reitinhaku, tilakoneet, sumeat tilakoneet, suunnittelu- ja vuoronnusalgoritmit ja dataohjaus. Esimerkiksi Rete, Stanford Research Institute Problem Solver (STRIPS) tai hierarchical task network (HTN) tai taaksepäin ketjutetut asiantuntijajärjestelmät (goal-oriented methods).
Räiskintäpelit Tilakoneet, sumeat tilakoneet, komentosarjat, suunnittelu- ja vuoronnusalgoritmit.
Ammuskelupelit Tilakoneet, komentosarjat ja dataohjaus
Urheilupelit Tilakoneet, sumeat tilakoneet ja dataohjaus.
Kilpa-ajopelit Tilakoneet, komentosarjat ja geneettiset algoritmit
Strategiapelit Tilakoneet, alfa-beeta-karsinta, hermo-verkot ja geneettiset algoritmit, mukaan lukien NegaScout, MTD-f ynnä muut vastaavat parannukset.
Taistelupelit Tilakoneet, dataohjaus ja komentosarjat.
Tilakoneet ovat melko yleisesti korvautuneet käyttäytymispuilla, jotka ovat
eräänlaisia päätöspuita, sekä monimutkaisemmilla tilakonemuunnelmilla kuten
hierarkkisilla tai sisäkkäisillä tilakoneilla. Pelien voidaan katsoa alan konferenssien
esitysten ja yleisen keskusten perusteella käyttävän yhä enemmän parviälyä,
tiedonlouhintaa ja evoluutiolaskennan keinoja. Myös proseduraalisten sisällönluonti-
algoritmien ja emergenttisten algoritmien ajatellaan kuuluvan tekoälyohjelmoinnin
piiriin, kuten aiemmin on jo käynyt ilmi. Erityisesti proseduraaliset algoritmit tuovat
yhteen ohjelmallisesti tuotetun grafiikan, tekoälyn ja kerronnan.
Algoritmit ovat myös luonteeltaan erilaisia. Esimerkiksi tilakoneet ja
käyttäytymispuut tuottavat yleensä niiltä odotettavan vastauksen reaaliaikaisesti, kun
taas reitinhaku- ja suunnittelualgoritmit saattavat toimia pelin kannalta hyvinkin hitaasti
muodostaen ongelman silloin, kun pelin immersion kannalta vastaus tarvittaisiin pian.
Teknisesti saattaa olla hankalaa odottaa pitkä- ja lyhytkestoisten algoritmien tuloksia
2 Videopelien tekoäly 10
samassa ohjelmassa erityisesti silloin, kun ne toimivat rinnakkain useampana
ilmentymänä, ja näiden algoritmien tulokset vaikuttavat toistensa toimintaan.
2.3 Uskottavan ja toimivan pelitekoälyn piirteet
Minskynkin (1992) esittämä tapa jaotella tekoälyn toteutus toteutustekniikoin ja
toimialoittain ei rajaa syntyneiden osien sovellusalueen laajuutta. Tällaisesta rajauksesta
on hyötyä pohdittaessa työkalutuen lähtökohtia ja mahdollisia saatavia hyötyjä. Robert
Sternberg (1985, 45) jakaa tässä mielessä älykkyyden kognitiivisiin kokonaisuuksiin
niiden sovellusalan laajuuden perusteella uraauurtavassa, vuonna 1985 ilmestyneessä
kirjassaan Beyond IQ: A Triarchic Theory of Human Intelligence:
Analyyttinen älykkyys tiedon hankkimiseen, arviointiin ja vertailuun.
Luova älykkyys uusien ratkaisujen keksimiseksi.
Käytännöllinen älykkyys opittujen ratkaisujen soveltamiseksi eri käytännön
tilanteissa.
Käytännössä koneet eivät voi ratkaista luovaa älykkyyttä vaativia tehtäviä, vaikka juuri
tämä antaisi pelienkin toimijoille älyn vaikutelman. Jäljelle jäävien vaihtoehtojen
mukaan onkin kaksi keskeistä lähestymistapaa pelitekoälyn rakentamiseen: analyyttinen
älykkyys ja toimialaälykkyys.
Pelien kannalta ensimmäisten tekoälyongelmien 1970- ja 1980-luvuilla voidaan
ajatella keskittyneen tapauskohtaisiin ratkaisuihin, koska ensimmäiset kehitetyt
ratkaisut olivat pääasiassa eri lautapelien, kuten šakin tai Hexin2, pelaamiseen
tarkoitettuja. Arkipäivän esimerkkinä tällaisesta toimialaälykkyydestä ovat vaikkapa
ohjeet auton renkaan vaihtoon – tai yleisemmässä tapauksessa minkä tahansa renkaan
vaihtoon. Jonathan Schaeffer ja Jaap van den Herik (2002) käsittelevät tekoälyä tästä
näkökulmasta juuri lautapeleihin liittyen.
1970- ja 1980-luvuilla useat eri tutkijat toisistaan riippumatta keksivät ja sittemmin
edelleen kehittivät muun muassa alfa-beeta-karsinnan teoriaa peleissä esiintyvien,
tyypillisesti suurien tila-avaruuksien tehokkaampaan läpikäyntiin. Tekoäly laajeni
myöhemmin myös asiantuntija-, teollisuus- ja informaatiojärjestelmiin, jolloin erilaisia
tekniikoita syntyi lisää ja myöhemmin osa tästä kehityksestä onkin otettu eri
muodoissaan käyttöön myös videopeleissä. Kuvassa 2-1 (Reddy 1988) on esitetty joitakin
tekoälyratkaisujen tyypillisiä ominaisuuksia. Videopelit sijoittuvat pääasiassa pulma-,
šakki- ja asiantuntijaryhmiin sikäli kuin ne hyödyntävät perinteisempiä algoritmeja –
vasteaikavaatimusten voidaan kuitenkin ajatella olevan lähempänä tosiaikaa, eli kuvan
2-1 (Reddy 1988) mukaisessa puhe- tai näköluokassa.
Esimerkkinä Sternbergin (1985) mallin mukaisesta analyyttisestä älykkyydestä
voidaan pitää viime vuosina virinneitä aloitteita yleisen pelitekoälyn (General Game
Playing) kehittämiseksi. Tämän lähestymistavan perusajatus on, että sama tekoälytoimija
pystyy tulkitsemaan jonkin pelin säännöt formaalista kuvauksesta ja pelaamaan ilman
2 Paula Kemppi (2008) käsittelee Hex-pelin tekoälyä nasevasti nimetyssä raportissaan Tekoäly
Hex-pelissä.
2 Videopelien tekoäly 11
ihmistä näitä eri pelejä, ja jopa sellaisia pelejä, joita tekoäly ei ole kohdannut ennen
(Genesereth ym. 2005).
Kuva 2-1: Joitakin tekoälyn toimialoja ja niiden ominaisuuksia (Reddy 1988).
Hilmar Finnsson (2007) kuvailee tätä lähestymistapaa yksityiskohtaisemmin
käsitellessään CADIA-Playeria. CADIA-Playerille pelien säännöt syötetään erityisellä
Game Description Language -kielellä (GDL).
Edellisen luvun tyypittämisen mukaan tämäntyyppistä lähestymistapaa voitaneen
käyttää, kun pelit ovat tekoälyresurssien käytön kannalta kyllin lähellä toisiaan ja niistä
voidaan erottaa tarpeelliset osaset. Siten tässä nimenomaisessa tapauksessa useampiakin
lautapelejä pelaava äly voi toimia, kun sille on kerrottu säännöt jollain erityiskielellä
(edellisessä tapauksessa GDL), mutta vielä ei ole tekoälyä, joka voisi itse menes-
tyksekkäästi opiskella mielivaltaisten pelien sääntöjä esimerkiksi lukemalla ohjekirjoja
tai seuraamalla pelejä. Ei ole kehitetty tekoälyä, joka pystyisi analysoimaan mielivaltaisen
toimialan ja toimimaan halutunlaisten tavoitteiden saavuttamiseksi; esimerkiksi
muokkaamaan dynaamisesti vallitsevaa tunnelmaa pelaajan ja pelin vuorovaikutuksen
mukaan pelin tekijän tarkoittamalla tavalla (kuten lienee The Directorinkin tarkoitus).
Pelitekoälyn tarkoitus eroaakin eräällä ratkaisevalla tavalla aiemmin käsitellystä,
akateemisesta tai algoritmisesta tekoälystä: sen on tarkoitus viihdyttää – tai laajemmin
tulkittuna myös opettaa ja simuloida (ks. Serious 2009) aidontuntuisesti.
”Akateemiseen”, mahdollisimman hyvin suoriutuvaan ja ongelmia ratkaisevaan
tekoälyyn erona on, että esimerkiksi ihmispelaajaa ei viihdytä täydellistä3 peliä pelaava
tekoälyvastustaja. Aina täydellisen pelin pelaava tammi-vastustaja tai sekunnin murto-
osassa kuvapisteen tarkkuudella osuva tekoälyrobotti eivät ole viihdyttäviä saati
inhimillisiä. Benjamin Ellinger (2008, 17–18) huomauttaakin, että pelaajille viih-
dyttävämpää on olla tekemisissä inhimillisen ja persoonallisen tekoälytoimijan kanssa.
Pelitekoälyssä huijaaminen on yleensä hyväksyttävää, koska monissa peleissä
tekoälyvastustaja ei voi tehdä tarpeeksi hyviä päätöksiä käyvässä ajassa, ellei sillä ole
3 Ks. Mick Westin (2009) lyhyt artikkeli Intelligent Mistakes: How to Incorporate Stupidity Into
Your AI Code.
2 Videopelien tekoäly 12
käytössään enemmän tietoa kuin pelaajalla. Pelitekoäly voi esimerkiksi tietää, missä
kaikkialla maailmassa muut toimijat ovat, mitä ne ovat tehneet ja mitä aikovat tehdä.
Huijaaminen ei luonnollisesti ole mahdollista tai edes haluttuakaan esimerkiksi
täydellisen informaation peleissä kuten šakissa, kun taas pokerin kaltaisissa epä-
täydellisen tai stokastisen informaation peleissä tämä riippuu toteutustavasta. Pelien
viihdytystarkoitusta ajatellen on kuitenkin tarkoituksenmukaista hyödyntää niin
kutsuttua Eliza-efektiä. Kuten Andew Stern toteaa:
The Eliza effect – the tendency for people to treat programs that respond to them as
if they had more intelligence than they really do […] is one of the most powerful
tools available to the creators of virtual characters. As much as it may aggravate the
hard-core computer scientist, we should not be afraid to take advantage of this.
“Truly alive” versus “The illusion of alive” may ultimately be a meaningless
distinction to the audience. Ninety-nine percent of users probably will not care how
virtual characters are cognitively modeled – the just want to be engaged by the
experience, to be enriched and entertained. (Stern 2002, 353.)
Eliza-efekti – ihmisten taipumus suhtautua ohjelmiin kuin niillä olisi enemmän älyä
kuin onkaan, on yksi tehokkaimmista työkaluista virtuaalihahmojen luojille. Niin
paljon kuin se voikin ärsyttää ohjelmistotieteilijää, tämän hyödyntämistä ei tulisi
pelätä. ”Aidosti elävä” tai ”harhakäsitys elävästä” saattaa loppujen lopuksi olla
merkityksetön ero yleisölle. Yhdeksänkymmentäyhdeksän prosenttia yleisöstä ei
todennäköisesti välitä virtuaalihahmojen kognitiivisesta mallista – he haluavat vain
osallisiksi kokemuksesta, olla viihdytettyjä ja kokemusta rikkaampia. (Käännös V. E.)
Edellä mainitun kahtiajaon akateemisen ongelmia ratkaisevan ja pelien viihdyttävän
tekoälyn välillä ei kuitenkaan tarvitse olla ehdoton. Voi olla täysin suotavaa, että
viihdytystarkoituksessa peli pystyy ratkaisemaan ja reagoimaan älykkäästi eri tilanteisiin
ja ratkaisee tällaisen ongelman esimerkiksi peliin syötetyn asiantuntijaälyn –
asiantuntijajärjestelmän päättelyn – avulla. Edellä mainitun Eliza-efektin alkuperä on
Joseph Weizenbaumin (1966) kehittämässä Eliza-nimisessä keskusteluohjelmassa, josta
edelleen kehitetyillä myöhemmillä versioilla on yritetty esimerkiksi harhauttaa ihmisiä
Turing-testissä.
Alan Turing ehdotti vuonna 1950 testiä, jossa ihminen keskustelee kahden toimijan
kanssa, joista toinen on tietokoneohjelma ja toinen oikea ihminen. Mikäli keskustelija ei
pysty erottamaan näitä toisistaan, on tietokoneälyä pidettävä ihmisen veroisena.
”Peliversio” on esimerkiksi Perthissä, Australiassa, pidetty IEEE Symposium on
Computational Intelligence and Gamesin (IEEE Computational Intelligence Society
2008) järjestelmä kisa, missä 2K Australia (2009) palkitsee 7000 Australian dollarilla
tahon, jonka botti saa ihmispelaajan luulemaan sitä toiseksi ihmiseksi.
2.4 Pelitekoälyn keskeiset toteutusongelmat
Edellä esitetyt yleisesti pelitekoälyn kehitykseen vaikuttavat ongelmat ilmenevät
konkreettisen kehityksen aikana hyvinkin eri tavoin riippuen lukemattomista toteutus-
teknisistä yksityiskohdista ja peliprojektin sidosryhmien vaatimuksista. Sidosryhmien
2 Videopelien tekoäly 13
vaikutussuhteiden kannalta oleellista on tässä yhteydessä karkeasti yksinkertaistaen
todeta, että julkaisija asettaa yleensä julkaisuajankohdan ja päättää joistakin sisältöön
liittyvistä asioista. Julkaisija on yhteydessä pelintekijän tuottajaan (projektipäällikkö),
joka toimii yhteistyössä muun muassa pelinsuunnittelijoiden (suunnittelija) tekoäly-
nohjelmoijien (ohjelmoija) ja grafiikasta (graafikot) vastaavien tahojen kanssa.
Suunnittelijat, ohjelmoijat ja graafikot ovat myös yhteistyössä keskenään. Näiden lisäksi
projektiin kuuluu koko joukko muitakin ohjelmoijia, audiosuunnittelijoita, käsi-
kirjoittajia, laadunvarmistusta, linjaorganisaation toimijoita ja niin edelleen. (Bethke
2003, 39–59.)
Konkreettisen pelitekoälyn tuottamisen kannalta pelimaailman ja -käsikirjoituksen
kirjoittaminen ovat siis pääasiassa kahden eri tavalla roolitetun henkilön hallinnassa:
ohjelmoijan ja suunnittelijan. Yleinen käytäntö on, että ohjelmoija pyrkii tekemään
vaativamman ohjelmoinnin kuten tekoälyn integroinnin muihin pelin osajärjestelmiin,
suorituskykykriittiset osat sekä perusinfrastruktuurin suunnittelijalta tulevien vaati-
musten perusteella. Suunnittelija puolestaan käyttää tätä perusinfrastruktuuria kehit-
täessään jollain skriptikielellä kuten Lualla tai mahdollisesti pelimoottorin mukana
tulevalla kielellä korkeampaa, jonkin pelitilanteen kannalta keskeistä tilannelogiikkaa tai
yleiseen pelimekaniikkaan vaikuttavia toimintoja.
Tämä ei ole ideaalista, koska suunnittelussa tarvitaan nopeaa iterointia oikean
pelimekaniikan ja -tuntuman löytämiseksi (Pfeifer 2008, 29), eikä suunnittelijoiden
ohjelmointitaito useinkaan riitä haluttujen toimintojen aikaansaamiseksi. Tällöin he
tarvitsevat yleensä ohjelmoijan apua, mikä hidastaa muuta ohjelmoijan vastuulla olevaa
kehitystyötä. Ohjelmoijien ja suunnittelijoiden vuorovaikutuksen tärkeydestä ja
iterointinopeudesta ovat eri yhteyksissä esitelmöineet useat henkilöt (Reynolds 2004;
Hutchinson ym. 2009). Tilannetta kärjistää, että teknisten ongelmien tunnistaminen,
ratkaisumallien löytäminen ja ratkaisujen toteutus on yleensä yksittäisten
tekoälyohjelmoijien vastuulla. Ongelmakentän laajuuden huomioiden tämä on jo
teknisesti erittäin haasteellista.
Tästä aiheutuu jätetyötä (ks. Eeva 2006) paitsi suunnittelijalle ja ohjelmoijalle myös
pelitestaajille, ja jätetyöstä syntyy todennäköisesti myös enemmän ohjelmointivirheitä ja
ohjelmiston arkkitehtuurin rapautumista (Russel 2008b, 51). Jätetyö tarkoittaa kaikkea
työtä, jonka tulokset eivät ole sellaisenaan ja täysin seuraavan työvaiheen syötteenä.
Muun muassa Poppendieckien (2003) mukaan kevyet projektimallit ovat välttämät-
tömyys tällaisessa tilanteessa, ja ne ovatkin lisänneet suosiotaan myös peliteollisuudessa.
Mikäli pelimekaniikkaa päästään kokeilemaan jo ennen kuin varsinainen peli on
pelattavissa, saadaan kehityskustannuksissa säästettyä jopa niin, että myöhemmin
voidaan välttää projektin keskeyttäminen ja suuret taloudelliset tappiot. Kun Pac-Manin
kehitys vuonna 1982 maksoi noin 100 000 Yhdysvaltain dollaria (Takatsuki 2007), maksoi
vuonna 2008 ilmestynyt Grand Theft Auto IV Rockstarin tuottaja Leslie Benziesin arvion
mukaan noin sata miljoonaa Yhdysvaltain dollaria (Ivan 2008). On siis helppoa
ymmärtää, miksi jätetyön vähentämisellä (vaikkei kaikki johdukaan tekoälystä) on
merkitystä alati monimutkaisempien pelien kehityksessä kustannussäästöjen aikaan-
saamiseksi.
2 Videopelien tekoäly 14
Pelitekoälyn kehitys liittyy siis kokonaisvaltaiseen suunnitteluun ja on siten projektin
poikkileikkaavien huolenaiheiden risteyspiste – myös liiketoimintavaatimusten osalta.
Liiketoimintavastuut ja ei-teknisten henkilöiden osallistuminen kehitykseen muodosta-
vatkin ohjelmoinnin ohella oman lisähaasteensa. Täten voidaan perustella, että peli-
tekoäly on läheisesti sidoksissa projektin eri sidosryhmien ongelmiin ja ratkaisuihin
näiden omine toimialakohtaisine erityisongelmineen.
Toinen keskeinen ongelma on pelin tekoälytoimijoiden, agenttien, sisäinen vuoro-
vaikutusrajapinta muiden pelimaailman osien kanssa. Näiden toimijoiden tekoälyn ja
esimerkiksi animaatioiden ja fysiikkamoottorin toimintojen yhteensovittaminen ei
yleensä ole aivan suoraviivaista eikä standardoitua. Pelityypistä riippuen tämä on voitu
ratkaista useilla eri tavoilla.
Kuva 2-2: Tekoälyjärjestelmän arkkitehtuuri pelissä Ian Millingtonin mukaan (Millington 2006, 9).
Kuvassa 2-2 on esitetty eräs tekoälyarkkitehtuurin malli Ian Millingtonin (2006, 9)
mukaan. Kuvan keskellä ovat keskeiset tekoälyn ohjelmistototeutuksen osat ja reunoilla
liittymät muihin järjestelmiin siten kuin suoritus yleensä etenee pelin tekoälymoottorin
saadessa suoritinaikaa. Liittyen taulukon 2-1 listaukseen, kuvassa 2-2 ylempänä olevan
strategia-tason algoritmit (esimerkiksi HTN) käyttävät keskimäärin enemmän aikaa
ratkaisun saamiseksi kuin liikkumistason algoritmit (esimerkiksi käyttäytymispuut).
Tällä on merkitystä, koska algoritmien tulokset täytyy jaksottaa pelaajalle annettavaan
palautteeseen sopivaksi. Voi olla esimerkiksi tarpeen varmistaa, että johonkin
fysikaaliseen animaatioon liittyvä algoritmi tuottaa tuloksen oikea-aikaisesti ja yhden-
mukaisesti graafisen palautteen (renderöinnin) kannalta, eli vaikkapa kokonaisen kuvan
viimeistään joka 33. millisekunti.
Erityinen ongelma tekoälytoteutuksessa onkin graafisten osien integrointi ja
tahdistus tekoälyjärjestelmän ja esimerkiksi fysiikan mallinnuksen välillä, kun erilaiset
2 Videopelien tekoäly 15
takaisinkytkentämahdollisuudet (kuvassa 2-2 fysiikkajärjestelmän ajatellaan yleensä
ohjaavan peliä) ja siten animaatioiden keskeyttäminen tai vaihtaminen täytyy ottaa
huomioon. Dan Kline (2008b) havainnollistaa blogissaan kuvan 2-3 mukaisesti
animaatiojärjestelmän kerroksittain järjestettynä. Fysiikkamoottorin ajaman tekoälyn
suhteen on esitetty ajatuksia, että tekoäly ajaisi fysiikan mallinnusta (Champandard
2008). Tai kuten nimimerkki notamac (Tiller 2009) kertoo, suositussa Crysis-pelissä on
erityinen hybridijärjestelmä, jossa hahmot ovat animaatio-ohjattuja (tekoälyohjattuja) tai
fysiikkaohjattuja tilanteen mukaan. Tällä tavoin voidaan välttää ongelmia sellaisissa
tilanteissa, joissa ei haluta käytetyn fysiikkamallinnuksen vaikuttavan tekoälyn
päätöksentekoon esimerkiksi mutkistamalla päätöksentekoa lisäämällä uusia huomioon
otettavia muuttujia.
Kuva 2-3: Pelitekoälyn kerrosarkkitehtuuri Dan Klinen mukaan (Kline 2008b).
Kuvassa 2-3 ylemmällä tasolla toimiva tekoäly valitsee pelin agentille jonkin
toiminnon, kuten kävelyn, ja välittää tarvittavat päätökset alemmille kerroksille
suoritettavaksi. Kirjoitelmassaan Kline (2008b) selvittää esittämäänsä kerros-
arkkitehtuuriin liittyen, miten hankalaa on ohjata esimerkiksi tekoälystä riippuvaa
animaatiota4. Pelit ovatkin käytännössä yleensä hajautettuja, pehmeitä reaali-
aikajärjestelmiä, joiden osien yhteensovittaminen ei ole suoraviivaista etenkään, kun
toiminnan täytyy immersion ylläpitämiseksi olla tahdistettua pelaajan syötteen ja siitä
annetun audiovisuaalisen sekä mahdollisen tuntopalautteen kanssa.
Kolmantena selvänä ongelmana voidaan nähdä pelin tekoälyä rakennettaessa
syntyvien ohjelman eri osien ja toimijoiden vuorovaikutussuhteiden lisääntyminen, jotka
usein sitovat eri osia toistensa sisäiseen toiminnallisuuteen. Esimerkiksi tilakoneisiin
perustuvat ratkaisut sisältävät nopeasti suuren määrän toisteisiakin tiloja eikä suuren
tilamäärän tulkitseminen tarkoituksenmukaisesti ole yksinkertaista. Monien vuoro-
vaikutussuhteiden vuoksi tekoälyratkaisujen uudelleen käyttö on useasti hankalaa.
Kustannusten laskemiseksi täytyisi kuitenkin olla keino käyttää uudelleen aiemmin
kehitettyjä tekoälyalgoritmeja, kuten tilakoneita tai käyttäytymispuita, vain niiden
syötteiden ja tulosten perusteella välittämättä vuorovaikutussuhteista tulevista
riippuvuuksista.
4 Alex Champandard ja Christian Gyrling (2009) esitelmöivät GDC-09:ssä asiasta laajemmin
aiheella Animating in a Complex World: Integrating AI and Animation.
2 Videopelien tekoäly 16
Neljäntenä toteutusongelmana voitaneen ajatella pelien kehittämistä useille eri
alustoille sekä jo kehitettyjen teennösten uudelleen käyttöä näillä alustoilla tai julkaistun
pelin jatko- tai rinnakkaisprojekteissa ja jopa tulevaisuudenkin alustoilla.
Ideaalitapauksessa jo luodut teennökset olisivat käytettävissä sellaisinaan tai halutuin
muutoksin muun muassa eri syötelaitteita ajatellen. Tämä ei ole vaivatonta, sillä jo
konsolit eroavat kehitysalustana laitteistoiltaan ja käyttöjärjestelmiltään toisistaan,
minkä lisäksi PC on omanlaisensa alusta ongelmineen. Esimerkiksi Tim Sweeney (2006)
selvittää asiaa toteamalla, että Gears of War sisältää noin 250 000 riviä C++- ja
skriptikoodia, noin 250 000 riviä C++-koodia Unreal 3 -pelimoottorissa ja riippuvuuksia
muun muassa grafiikka-, ääni-, ikkunointi-, koodekki- ja pakkauskirjastoihin.
Pelit sisältävät julkaistaessa usein myös töksähdyksiä (engl. glitch) ja
ohjelmistovirheitä, jotka joko tekevät pelaamisesta epämiellyttävää tai jopa estävät sen
täysin, eli peli toimii virheellisesti ja käyttöjärjestelmä sulkee sen. Näitä ongelmia
setvitään monilla pelaaja- ja ammattilaisfoorumeillakin eikä esimerkkejä ole hankala
löytää, vaikkei asiasta tutkittua tietoa olekaan. Ongelma on oikeastaan sama kuin
ohjelmistotuotannossa laajemminkin: ohjelmistojen koon kasvaessa myös ohjelmisto-
virheiden määrä lisääntyy ja kokonaisuuden hallitseminen hankaloituu – etenkin, mikäli
jo korjattuja virheitä ei voida hyödyntää ohjelmistojen uudelleenkäytön vähäisyyden
vuoksi.
Ilmiö tunnetaan ohjelmistotekniikassa termillä ohjelmistokriisi (engl. software crisis).
Termin esitti tiettävästi ensimmäisenä Friedrich Bauer (1976) ja laajempaan tietoisuuteen
sen toi Edsger Dijkstra (1972). Pelin- ja tekoälynkehityksen näkökulmasta tulkittuna
kriisin taustalla on pelien monimutkaisuus, odotukset ja muutokset.
3 Tekoälyn mallintaminen ja kieli
Aiemmin esitetyt pelitekoälyn tuottamiseen ja kehittämiseen liittyvät ominaisuudet,
yksityiskohdat ja ongelmat voidaan ylemmällä tasolla tiivistää Adam Russellin
toteamukseen:
As mentioned, the game designers are driving the engineering of AI features through
the representational models they employ to describe AI processes. These models
constrain the AI design in two senses. On one hand, the designers use their own
models as a framework for themselves within which they are able to picture new AI
features. On the other hand, they use these models as a language through which to
express their designs back to the AI programmers. Of course, there will always be a
difference in representation between the designers and the programmers they are
working with. In an ideal world, this difference is only one of details, and the overall
structure remains the same whichever discipline is describing it. Unfortunately, in
practice, this is becoming less and less true as the technical architectures for AI
become more and more sophisticated. (Russell 2008b, 55.)
Kuten mainittua, suunnittelijat ohjaavat tekoälyn ominaisuuksien kehittämistä
tekoälyprosesseja kuvaavilla malleillaan. Nämä mallit rajoittavat suunnittelua
kahdella tavalla. Yhtäältä suunnittelijat käyttävät mallejaan kehyksenään luodakseen
uusia tekoälyominaisuuksia. Toisaalta, he käyttävät näitä malleja kielenä
ilmaistakseen suunnittelunsa edelleen tekoälyohjelmoijille. Tietenkin
suunnittelijoiden ja heidän kanssaan työskentelevien ohjelmoijien välillä on aina
esitystapaero. Ideaalisessa maailmassa tämä ero on vain yksityiskohdissa ja
kokonaisrakenne pysyy samana riippumatta sen esittäjän edustamasta alasta.
Valitettavasti käytännössä tämä on entistä harvemmin totta, koska tekoälyn
tekninen arkkitehtuuri on yhä monimutkaisempi. (Käännös V. E.)
Toisin kuin Russell (2008b, 55) antaa ymmärtää, on olemassa systemaattinen tapa
yhdistää nämä esitystavat. Tätä tapaa voidaan kutsua termillä toimialamallinnus, joka on
aivan viime vuosina noussut yleiseen tietouteen tapana yhdistää toimiala-
asiantuntijoiden – jotka eivät yleensä ole teknisiä asiantuntijoita – tietous
systemaattisesti ohjelmiston tuottamiseksi. Edelliseen lukuun liittyen toimiala työssä on
pelitekoäly, joka on alana nuori kuten seuraavaksi tarkemmin esitetty toimialamallinnus
ohjelmistotekniikan menetelmäkin.
3.1 Minkä ongelman toimialamallinnus ratkaisee
Toimialamallinnuksen voidaan yksinkertaistaen ajatella ratkaisevan toimiala-
asiantuntijan ja ohjelmistoinsinöörin viestintäongelman tarjoamalla yhteisen
toimialakielen (kielioppeineen ja sanastoineen). Toimialamallinnus on siten yhtenäinen
3 Tekoälyn mallintaminen ja kieli 18
tapa viestiä pelinsuunnittelijan ja tekoälyohjelmoijan välillä, ja se kuvaa yhteisen kielen
tekniseen toteutukseen. Tämä vaikuttaa osaltaan rapautuvan ohjelmiston laatu-
ongelmaan, joka seuraa usein riittämättömästä tai epätarkasta viestinnästä ja monista
pienistä muutoksista ohjelmistoon nopeassa aikataulussa. Ohjelmiston laatua voidaan
ajatella parantavan myös, että toimialamallinnus on systemaattisempi menetelmä
ominaisuuksien ja toimintojen lisäämiseksi tähän yhteiseen kieleen. Tällöin myös
tarpeettomien ominaisuuksien lisääminen (engl. feature creep) vähenee – samoin
helpottuu tarpeettomien ominaisuuksien löytäminen ja poistaminen.
Pelien tekoälyn tapauksessa tämä tarkoittaa, että erilaiset protokolla-, tosiaika-,
rajapinta- ja toimintovaatimukset voidaan kytkeä tekoälyn toimialavaatimuksiin
määritellysti ja systemaattisesti. Myös eri toimialavaatimukset voidaan yhdistää toisiinsa
systemaattisesti; tällä tavoin voidaan yhdistää tarvittavin osin eri tekoälytekniikoita
toisiinsa. Cook ym. (2007, 10) luetteloivat toimialamallinnuksen ominaispiirteitä (vrt.
myös verkosta löytyvä Facts and Fallacies -lista Glass 2003) pääosin seuraavasti:
Toimialakielellä työskentely vähentää toimialavirheitä toisin kuin yleisen
ohjelmointikielen käyttäminen.
Suunnittelu on projektin asianosaisille saavutettavampaa, kun
toteutusteknologioiden sijaan viestitään toimialakäsittein.
Toimialamallin oikeellisuus voidaan tarkistaa ongelma- eli toimialatasolla, jolloin
virheet toimialakohtaisen ongelman esittämisessä tai ymmärtämisessä voidaan
korjata aiemmin.
Malleja voidaan simuloida tai tutkia välittömästi ja saada näin tietoa ratkaisun
käyvyydestä jo ennen varsinaisen ratkaisun rakentamista.
Toimialamallia voidaan käyttää heterogeenisten teknologioiden sidostamiseen,
jolloin asiantuntijatyön tarve samankaltaisina toistuvissa tehtävissä vähenee.
Esimerkiksi tällaisesta on grafiikan ja erilaisten skriptausteknologioiden
sovittamisessa peliin tai peleihin, jopa eri alustoilla.
Malleista voidaan tuottaa toisia malleja tai niiden avulla voidaan konfiguroida
toisia järjestelmiä tai tuotteita esimerkiksi velhoilla.
Toimialamallin (formaalia) rajapintaa käyttäen toimialateennöksiä voidaan
manipuloida ja lisätä täten ohjelmistokehityksen tehokkuutta.
Malleista tuottuvat teennökset voivat olla paitsi teknisiä toteutusteennöksiä
myös dokumentaatiota, määräyksiä, suunnitelmia, sopimuksia ja niin edelleen.
Kun jokin toimialaongelma on mallinnettu, on helpompi vuorovaikuttaa muiden
toimialojen kesken, lisätä toimialakäsitteitä, tuottaa erilaisia teennöksiä ja niin
edelleen.
Toimialamallin avulla on mahdollista linkittyä ja siirtyä toisille toimialoille sekä
laajentaa siten luontaisesti markkina-aluetta ja markkinoillepääsynopeutta.
3 Tekoälyn mallintaminen ja kieli 19
3.2 Mitä ovat toimialamallinnus ja -kielet
Toimialamallinnusta ja -kieliä voidaan ajatella siltana projektivaatimusten
(liiketoimintavaatimusten) ja toisaalta ohjelmiston teknisten vaatimusten välillä.
Pelitekoälyn kannalta tämä tarkoittaa, että jokin ohjelma kokoaa pelin tekoälyyn
vaikuttavat tekijät saman käsitteistön piiriin ja määrittää suhteen vaatimuksista
toteutukseen. Toisien sanoen suunnittelijat, graafikot ja ohjelmoijat saavat yhteisen
kielen, joka toimii keskustelukanavana paitsi yhdessä tapauksessa myös alalla yleisesti;
toimialamallinnus kokoaa yhteen tuoteperheiden teennökset ja ei-tekniset
projektivaatimukset.
Toimialamallinnus ohjelmistotekniikassa tarkoittaa nimensä mukaisesti jonkin
rajatun alan ohjelmallista mallintamista tätä alaa varten räätälöidyllä kielellä ja
termistöllä – eli mallintamista alan omalla käsitteistöllä, merkinnöillä ja tavoilla.
Käyttäjän näkökulmasta toimialamallinnus työkaluna on siten korkeammalla tasolla
kuin itse prosessin tuotteena syntyvä, ongelman ratkaiseva ohjelmisto. Edellinen on
kirjattu alan pääsivustolla, DSM Forumilla, seuraavasti:
Domain-Specific Modeling raises the level of abstraction beyond programming by
specifying the solution directly using domain concepts (DSM Forum 2009).
Toimialamallinnus nostaa abstraktiotason yli ohjelmoinnin määrittämällä ratkaisun
suoraan toimialakäsittein. (Käännös V. E.)
Termistö ja käsitteistö alalla ovat vielä jonkin verran muotoutumassa, mutta juuri
annettu on yleisen hengen mukainen. Asiasta kirjoittavat muun muassa Arturo Sánchez-
Ruíz ym. (2007) artikkelissaan Domain-Specific Software Development Terminology: Do
We All Speak the Same Language? Sama asia on esitetty kuvassa 3-1 (Kelly & Tolvanen
2008, 16). Kuvan ajatus on suoraan toimialakuvauksesta tuotettava ohjelmakoodi.
Ongelmaa ei siis kuvata erikseen toteutusdokumentaatiota varten, jonka perusteella
tuotetaan ohjelmakoodia ongelman ratkaisuksi, vaan kuvaus itsessään toimii kuin
ongelman ratkaiseva ohjelmakoodi. Toimialamallista tuotetut teennökset voivat olla
ohjelmakoodin lisäksi kuvauksia dataohjattuun suoritukseen tai esimerkiksi
dokumentaatioteennöksiä suunnittelu- ja projektinhallintaprosessien ohjaamiseksi – eli
kokonainen projektitoimitus. Teennökset mallista tuotetaan erityisillä generaattoreilla,
jotka on kehitetty juuri mallia ja sen kohde toimialaa varten.
Kuten kuvasta 3-1 (Kelly & Tolvanen 2008, 16) ilmenee, toimialamallinnus ei tarkoita
(uutta) UML-teknologiaa tai vain tapaa kääntää UML-kaavioista toimivia ohjelmia
erilaisten mallimuunnosten avulla. Toimialamallinnus ei ole myöskään vain tapa
dokumentoida ohjelmia, vaan se on järjestelmällinen tapa rakentaa ohjelmia jonkin alan
käsittein tai laajemmin tulkittuna tapa järjestää ohjelmistoprosessi toimialakäsittein.
3 Tekoälyn mallintaminen ja kieli 20
Kuva 3-1: Toimialamallinnus sulkee kuilun konkreettisen ratkaisun ja sen idean välillä (Kelly &
Tolvanen 2008, 16).
Kuvasta saattaa havaita, että toimialamallinnuksessa malli on sekä dokumentaatio
järjestelmästä että toimiva ohjelmiston osa. Tästä on etuna, että malli kuvaa tarkasti
ohjelmiston toimialakäsittein, mikä tarkoittaa myös, että projektin ei-tekniset henkilöt
kuten suunnittelijat voivat ilman UML- tai ohjelmisto-osaamista kommentoida tai
rakentaa järjestelmää omaan toimialaosaamiseensa nojaten.
Toimialamallinnusta voi siis ajatella siten, ettei se ole tapa automatisoida tai pitää
ajan tasalla dokumentaatiota, vaan malli itsessään on korkeamman käsitetasonsa vuoksi
yhtä paljon dokumentaatio järjestelmästä kuin toimiva ohjelman osakin. Usein
toimialamallinnus esitetäänkin juuri tapana tuottaa mallista toimivia ja sellaisenaan
käytettäviä kokonaisuuksia. Esimerkiksi UML-kaavioiden ja OMG:n Model-Driven
Architecturen tapauksissa edellinen ei ole yleisesti mahdollista suoraan edes
erityiskäytänteiden avulla (Kelly & Tolvanen 2008, 55). Toimialamallinnus ei tarkoita
myöskään vain vaiheittain, dialogivetoisesti toimivaa velhoa, joka kyselee askel askeleelta
eri vaihtoehdot, vaikka se voikin olla eräs käytännön tavoista toteuttaa jokin toiminto.
Yksinkertaisimmillaan kyse on kuvan 3-2 tapaisesta tilanteesta, kuten Bran Selic5
(2006) esittää. Kuvassa on kaksi komponenttia, jotka on kytketty toisiinsa tuottaja-
kuluttaja-mallin mukaisesti, ja näistä komponenteista on tuotettu ohjelmakoodia. Pelien
tapauksessa vastaaviksi työkaluiksi voitaisiin tulkita esimerkiksi tilakone-editori. Mikäli
kyse ei kuitenkaan ole esimerkiksi tilakoneiden mallinnuksesta, toimialamallit ovat
yleensä korkeammalla tasolla.
5 Bran Selic, silloinen IBM Distinguished Engineer.
3 Tekoälyn mallintaminen ja kieli 21
Kuva 3-2: Koodi ja sen toimiala-esitys (Selic 2006).
Monimutkaisimmillaan toimialamalli ja -kieli voivat kuvata jopa kokonaista
tuotelinjoja, kuten Frank van der Linden ym. toteavat:
A particularly interesting area is Domain-Specific Languages (DSLs). In some sense,
they can be regarded as an extreme form of product lines. The core idea of a domain-
specific languages approach is to describe the variability of a product line based on a
specifically developed high-level language. Commonalities are not made explicit in
the language. They are treated as part of the domain. (Linden ym. 2007, 309.)
Erityisesti kiinnostava kenttä on toimialakielet. Eräässä mielessä niitä voidaan pitää
tuotelinjojen äärimmäisenä muotona. Toimialakielten ydinajatuksena on kuvata
tuotelinjan vaihtelevuus erityisesti kehitetyllä korkeamman tason kielellä. Yhtäläisiä
piirteitä ei esitetä kielessä, vaan niitä käytetään toimialan osana. (Käännös V. E.)
Tuotelinjojen hyvät puolet tulevatkin esiin myös toimialamallinnuksessa ja yleensä
niihin siirtymisen motivaationa ovat taloudelliset syyt. Suuren mittakaavan järjestel-
mällinen resurssien uudelleenkäyttö laskee kustannuksia, nopeuttaa markkinoille
pääsyä, lisää yhteensopivuutta eri versioiden välillä ja parantaa tuotteiden laatua – tämän
rinnalla yleensä ylläpitokustannuksetkin laskevat merkittävästi. (Linden ym. 2007, 3–4.)
3 Tekoälyn mallintaminen ja kieli 22
Kuva 3-3: Tuotelinja-arkkitehtuurin kustannuksista (Linden ym. 2007, 4).
Kuva 3-3 (Linden ym. 2007, 4) havainnollistaa tuotelinja-arkkitehtuurin kehittämisen
kustannuksia tavanomaisempaan tuotekehitykseen verrattuna. Pelien ja tekoälyn
kustannukset saattavat olla varsin suuria, mikä johtuu suuresta käsityöosuudesta kuten
Jack Greenfield ja Keith Short ohjelmistokustannuksia nimittävät ja kutsuvatkin tuote-
linja-arkkitehtuureja ja toimialamallinnusta ohjelmistotuotannon teollistamiseksi
(Greenfield & Short 2004, 155). Kelly ja Tolvanen (2008, 22–24) toteavat useisiin lähteisiin
viitaten myös tuottavuuden kasvan enemmän kuin UML-pohjaisten menetelmien 0–35
prosenttia. Kierburtz ym. (1996) väittävät erään tutkimukseensa kohdalla, että toimiala-
menetelmät ovat keskimäärin 300–1000 prosenttia tuottavampia verrattuna perinteiseen
ohjelmointiin, jopa 99 prosentin luotettavuustasolla. Täysin puolueettomia tutkimuksia
puolesta tai vastaan on hankala löytää, mutta Paul Clements kertoo kirjan Software
Product Lines in Action esipuheessa tutkimuskokemukseensa perustuen tuotelinja-
arkkitehtuurien jopa kertaluokkia tehokkaammista projektituloksista (Linden ym. 2007,
V).
Lupaukset jopa useiden satojen prosenttien tuottavuuden noususta voivat tuntua
epäuskottavilta. Hyppäys on samaa luokkaa kuin siirryttäessä assembly-kielistä nykyään
laajasti käytettyihin kolmannen sukupolven kieliin. Jokapäiväinen ja intuitiivinen
esimerkki toimialakielestä ja mallinnuksesta voisi olla vaikkapa World Wide Web ja
yleisesti käytetty HTML-merkkaus. Tällöin toimiala on vaikkapa esityksen tuottaminen
heterogeeniseen ympäristöön, toimialakieli HTML-merkkaus ja erilaiset HTML-työkalut
kielen manipulointiin tarkoitettuja editoreita.
3 Tekoälyn mallintaminen ja kieli 23
Toisaalta toimialamallinnus sisältää myös joitakin kielteisiä elementtejä. Tällaisia
voivat olla työkalutuen vajavaisuudet ja hankaluus mallinnettavan alan kyllin tarkassa
määrityksessä. Lisäksi kielen kehittäminen ja teennösten tuottaminen kohdealustoille
vaatii paitsi laitteisto- ja ohjelmistoarkkitehtuurin tuntemusta, myös organisaation tuen
kehitettäessä erilaisia malleja. Mallien ja kielten kehittäminen on ilmeisen aikaa vievää ja
onkin jopa todennäköistä, että vaikka organisaatiossa on tarpeeksi taitavia ohjelmisto-
kehittäjiä ja toimiala-asiantuntijoita, taloudellinen panostaminen ei ole mahdollista.
3.3 Toimialamallin ja -kielen rakentaminen yleisesti
Toimialamallinnus koostuu kolmesta osasta: toimialan määrittämisestä sekä
toimialamallin ja -kielen kehittämisestä. Teknisesti toimialamallinnuksen ja siihen
liittyvän ohjelmistokehityksen voidaan ajatella jakautuvan seuraavasti: kirjastonkehittäjä
työskentelee kohdealustaan liittyvien toteutusyksityiskohtien parissa, työkalukehittäjä
toimialatyökalujen (esimerkiksi editori) parissa ja tuotekehittäjät tuotteen parissa
esimerkiksi rakentamalla lähdekoodigeneraattoreita malleista muihin olemassa oleviin
ohjelmistoihin tai alustan kirjastoihin.
Varsinaisesti toimialamallin suunnittelevat kielisuunnittelijat. Tästä vaiheesta
syntyviä teennöksiä kutsutaan myös metamalleiksi tai metakieliksi, jotka voidaan
mieltää eräällä tavalla toimialakielten syntaksiksi. Roolituksessa kaikille osa-alueille ei
tarvitse olla eikä yleensä olekaan eri kehittäjää.
3.3.1 Toimialakieli
Toimialakieli voidaan määrittää usealla eri tavalla. Tämän työn kannalta osuva on
seuraava määritys:
A Domain-Specific Language is a custom language that targets a small problem
domain, which it describes and validates in terms native to the problem domain
(Cook ym. 2007, 11).
Toimialakieli on räätälöity kieli jonkin suppean ongelma-alueen kuvailemiseen ja
oikeellisuuden tarkistamiseen toimialan termistöä käyttäen. (Käännös V. E.)
Samansuuntaisen määrityksen esittävät myös Tomaž Kosar ym. (2008). Lisäksi toimiala-
kieliä voidaan luonnehtia neljännen sukupolven kieliksi (Deursen ym. 2000). Neljännen
sukupolven kielinä voidaan pitää kieliä, jotka on kehitetty ratkaisemaan joitakin
tietynlaisia ongelmia. Yleensä nämä neljännen sukupolven kielet ovat horisontaalisia.
Horisontaalisuus tarkoittaa, että kieli on kehitetty ratkaisemaan tietynlaisia teknisiä
ongelmia riippumatta sovellustyypistä. Toinen yleisesti käytetty luokittelutapa on
vertikaalisuus, jonka mukaan voidaan luokitella kielet, jotka on kehitetty ratkaisemaan
liiketoimintalähtöisiä ongelmia, ei teknologiaan liittyviä. (Kleppe 2009, 35.)
Tämän työn kannalta voidaan yleistäen ajatella, että sekä horisontaaliselle ja
vertikaaliselle toimialakielelle määritellään kielen syntaksi, semantiikka ja formaalius.
Syntaksi määrittelee ja kuvaa kielen eri elementit, niiden väliset suhteet ja säännöt
3 Tekoälyn mallintaminen ja kieli 24
niiden liittämiseksi toisiinsa, siis kieliopin. Syntaksin voidaan ajatella esittävän myös
kielen esitystavan – näistä käytetään myös nimitystä abstrakti ja konkreettinen syntaksi.
(Leppänen 2005, 96.) Konkreettisia syntakseja voi kielellä olla useita, esimerkiksi
jonkinlainen graafinen ja tekstuaalinen erikseen sekä kielen esittämiseen että
tallentamiseen. Abstrakteja syntakseja on vain yksi. (Kleppe 2009, 39–59.)
Kielen semantiikka on kielen symbolien suhde niiden kuvaamiin kohteisiin,
kuvaus kielen tarkoituksesta. Ehkä neljä yleisintä tapaa kuvata kielen
semantiikka ovat:
Denotationaalinen semantiikka, jossa rakennetaan kielen osista matemaattisia
objekteja kielten rakenteiden kuvaamiseksi ja liittämiseksi toisiinsa.
Pragmaattinen, jossa yleensä annetaan referenssitoteutus ja pidetään sitä kielen
kuvauksena.
Translationaalinen, joka kääntää kielen teennöksen toiselle kielelle (ehkä
paremmin ymmärretylle).
Operationaalinen, jossa kuvataan kielen teennöksen suoritus askel askeleelta
esimerkiksi tilakoneen avulla.
Näistä käytetyimmät lienevät translationaalinen ja operationaalinen. (Kleppe
2009, 134–148.)
Kielet voidaan formaaliutensa mukaan jakaa luonnollisiin kieliin, puoliformaaleihin
kieliin ja formaaleihin kieliin. Luonnollisia kieliä voidaan määrittää monella tavalla,
mutta ne eivät ole puoliformaaleja eivätkä formaaleja, vaan kieliä kuten suomi. Formaalit
kielet ovat kieliä, joilla on täsmällisesti määritetty semantiikka ja syntaksi, kun
puoliformaaleilla kielillä on pelkästään täsmällisesti määritetty syntaksi. (Leppänen 2005,
96–97.)
Kielellä kirjoitetut ohjelmat voivat joko sellaisenaan olla suoritettavissa (esimerkiksi
simuloitavissa tai tulkattavissa) tai se tuottaa ohjelmakoodia kääntäjälle. Deursen ym.
(2002) määrittävät ajettavuuden välttämättömäksi toimialakielen ominaisuudeksi, kun
taas David Wile (2001) korostaa nimenomaan ajamattomien kielten tärkeyttä. Deursenin
määritys tarkoittaa kieliä kuten Prolog (1999) tai Ruby (2009), joiden joustavan tyyppi-
järjestelmän vuoksi kieliin voidaan metaohjelmoimalla luoda uusia, kulloistakin
toimialaa tukevia kielellisiä käsitteitä. Wilen määritys pitää sisällään myös sellaiset
kielet, jotka määritellään esimerkiksi graafisella kielellä, ja joista tuotetaan edelleen
jonkin toisen kielen kääntäjälle ohjelmakoodia.
Historiallisesti toimialakielten kaltaisista kielistä voidaan katsoa kirjoitetun jo, kun
Jean Sammet mainitsi sovellussuuntautuneet kielet vuonna 1969, Richard Wexelblat
erikoiskielet vuonna 1981, James Martin sovelluskielet vuonna 1985, Thomas Bergin ja
Richard Gibson erikoistuneet kielet vuonna 1996 ja Bonnie Nardi työkohtaiset kielet
vuonna 1993 (Mernik ym. 2007, 317).
3.3.2 Toimiala
Ohjelmistoteknisesti toimialalla tarkoitetaan ongelmanratkaisualuetta, jonka käsitteet
rajaavat ja määrittävät ratkaisualueen (Sánchez-Ruíz ym. 2007, 5). Pelien kannalta
3 Tekoälyn mallintaminen ja kieli 25
mielenkiintoisia toimialamäärittelyjä voisivat olla André Furtadon ja André Santosin
(2006) määritys kokonaisten pelien tekemiseen tai Pablo Moreno-Gerin ym. (2009)
toimialamääritys seikkailujen kirjoittamiseen.
Furtadon ja Santosin (2006) toimiala, kokonainen peli, lienee liian laaja käsiteltäväksi
kyllin laajasti yhdessä mallissa, mutta käypä esimerkki kiinnostuneille muun muassa
kielensä graafisuuden vuoksi. Moreno-Gerin ym. (2009) paperi keskittyy adaptiivisen,
opetuspelin määrittelyyn pelinkirjoittajan näkökulmasta ottaen huomioon muun muassa
ajankäytön. Määrittelyn tuloksena syntyvästä mallista käännetään tilakoneisiin
perustuva ohjelma. Aikaisemmin esitettyyn suhteutettuna tällaisesta mallista ei
välttämättä tarvitse kääntää koko ohjelmaa, vaan suurempaan peliin upotettava
kokonaisuus. Tämä on eräs tapa rakentaa ja yhdistää kerronnan elementtejä muuhun
peliohjelmistoon.
On ollut pyrkimyksiä käyttää hyödyksi myös joitakin yleisempiä toimialamäärityksiä
ja niiden kieliä. Esimerkiksi Planning Domain Definition Language (PDDL 2009) on
tällainen kieli, jolla voidaan kuvata suunnittelutoimialan ongelmia omalla erityis-
kielellään. Karkeasti tiivistäen PDDL-kielessä kuvataan predikaatein mallinnettavaa
maailmaa sekä sen toimintoja esiehtoineen. Kielten kuten PDDL käyttö peleissä on
kuitenkin jäänyt vähäiseksi, koska jonkin pelimaailman riittävä mallintaminen
predikaatein ja työkalutuen rakentaminen on resursseja kuluttavaa. Jeff Orkin (2004)
raportoi PDDL-mallinnuksta ja sen ongelmista työskennellessään Monolith Studiosilla
(peli lienee juuri tekoälynsä vuoksi suosittu F.E.A.R.).
3.3.3 Toimialamalli
Mallin määritelmästä ei ilmeisesti ole toimialamallinnuksen yhteydessä täyttä yhteis-
ymmärrystä; Mauri Leppänen (2005, 279) määrittää väitöskirjassaan mallin olevan keino
saada tietoa oleellisista asioista. Samansuuntainen, mutta yksityiskohtaisempi on
Eckhard Falkenbergin ym. (1998, 55) määritelmä: malli on tarkoituksenmukaisesti
abstrahoitu, selkeä, tarkka ja yksikäsitteinen näkemys. Mallinnus on sarja toimenpiteitä,
joilla määritellään toimialan käsitteet esitettäväksi mallissa toimialan käsitteistöä ja
termistöä käyttäen. Tämän työn kannalta mallin voidaan määrittää sisältävän kielen
käsitteet, niiden ominaisuudet, suhteet, kielen sisäiset eheyssäännöt, graafisen
esitystavan, muun tarpeiston kuten käyttöjärjestelmä- ja kirjastopalvelut sekä
dokumentoinnin. Hyvän mallin määritelmä on epäselvä, mutta sillä voidaan katsoa
olevan kolme ominaisuutta:
Abstraktio: ilmaisuvoimaa ongelma-alan kuvailemiseksi.
Mallin johdonmukaisuus: mallien pitäminen yhdenmukaisina ja käytettävinä,
käytön opastus.
Tuki generaattoreille: malleista täytyisi olla mahdollista tuottaa haluttuja
teennöksiä, tyypillisesti ohjelmakoodia. (Kelly & Tolvanen 2008, 262.)
Stahl & Völter (2006, 15) nivovat edellä esitetyn yhteen kuvan 3-4 tavalla.
3 Tekoälyn mallintaminen ja kieli 26
Kuva 3-4: Toimialamallinnuksen peruslähtökohdat (Stahl & Völter 2006, 15).
Kuvassa on esitetty yleisemminkin toimialamallinnuspohjaista ohjelmistokehitys-
prosessia. Yleensä on olemassa jonkinlainen referenssitoteutus, josta tunnistetaan
toisteiset sekä itse toimialaan liittyvä toiminnallisuus että teknisiin vaatimuksiin liittyvät
osat. Osa tästä on geneeristä ohjelmakoodia, joka liittyy johonkin ohjelmistokehykseen,
voidaan muokata sellaiseksi tai se voidaan käyttää kirjastopalveluina. Toimialaan liittyvät
osat voidaan tuottaa muihin osiin liitettäväksi lähdekoodigeneraattoreilla. Toimiala-
kohtaiset osat riippuvat melko paljon siitä, mallinnetaanko horisontaalisesti vai
vertikaalisesti – vai kummallakin tavalla.
4 Toimialatyökalu Vipunen ja toimialakieli Luote
Luvussa selvitetään aluksi toimialakielen ja sen editorin rakentamisen yleisesti edelliseen
lukuun pohjautuen. Tämän jälkeen esitellään käytetyt työkalut ja yleiset suunnittelu-
päätökset. Prototyyppityökalun nimi on Vipunen (Wikipedia 2009d). Vipusella mani-
puloidaan tekoälykieli Luotteen (Wikipedia 2009e) metamallia ja tuotetaan käännettävää
tekoälykoodia.
4.1 Luotteen suunnittelulähtökohdat
Pelitekoäly on laaja ja hajanainen sovellusalue erilaisine tarpeineen ja monine
ratkaisuineen. Toimialamallinnus on järjestelmällinen tapa mallintaa rajattuja
kokonaisuuksia sekä yhdistää niitä toisiinsa.
On tarkoituksetonta, että suunnittelijat hahmottelevat toimintoja ja kirjoittavat
näistä kuvaukset dokumentaatioon luonnollisella kielellä, minkä jälkeen ohjelmoijat
toteuttavat nämä toiminnot. Tästä aiheutuu hukkatyötä ja siten pidempiä kehitysaikoja
ja suurempia projektikustannuksia, koska standardoidut ja hyväksi havaitut ratkaisut
eivät ole suoraan hyödynnettävissä eivätkä suunnittelijat voi oitis testata toimintojaan
aidossa ympäristössä. Monimuotoisten tarpeiden vuoksi ei ole myöskään mahdollista
aavistaa ennalta tarvittavia toimintoja. Tulisi myös olla mahdollista hyödyntää helposti
ohjelmoijan tekemiä uusia toimintoja toimialakielessäkin siten, että ne olisivat
suunnittelijoiden käytössä kielen elementteinä eivätkä vain ohjelmakoodissa.
Nopeassa toimialakielen kehitysrytmissä uusia ominaisuuksia lisättäessä kielen
käyttäjiltä saattaa tulla kysymyksiä odottamattomista toiminnoista tai suoranaisista
ohjelmavirheistä (ohjelmointivirheistä), joita ei ole joko huomattu tai kaikissa
tapauksissa edes mahdollista poistaa kielen syntaksin ja toimialakohtaisin semanttisin
tarkistuksin. Mikäli kehitetyn kielen rakenteet vastaavat toimialakielestä tuotettujen
ohjelmistoteennösten rakennetta, ohjelmoijat voivat verrata monimutkaisiakin kielen
rakenteita syntyvän ohjelmakoodin rakenteisiin ongelmien selvittämiseksi. Toisaalta,
toimialakielen täytyy toimia kielen toimiala-asiantuntijoiden käsittein.
Toimialakielestä tuotetun ratkaisun täytyy olla myös käytössä riittävän tehokas, mikä
tarkoittaa valmiutta rinnakkaisprosessointiin. Nykyään laajasti saatavilla olevat laitteistot
ovat moniytimisiä ja niiden tehokas käyttö vaatii rinnakkaisprosessointia. Vaikka rinnak-
kaisuus ei kielen käyttäjälle näykään, aiheutuu siitä kuitenkin ongelmia ohjelman
virheiden löytämiseen, poistamiseen ja esimerkiksi erillisten toimintojen kausaalisuuden
varmistamiseen. Liika rinnakkaisuus myös hidastaa ohjelman suoritusta sen nopeut-
tamisen sijaan. Ohjelmoijien ja ohjelmarakenteen pakottaminen tiettyyn rinnakkais-
prosessoinnin malliin ei myöskään ole mahdollista. Tästä seuraisi todennäköisesti
4 Toimialatyökalu Vipunen ja toimialakieli Luote 28
ohjelmistokehittäjien turhautumista, piileviä rinnakkaisvirheitä ja suorituskykyongelmia,
koska kaikki tehtävät kehitysratkaisut täytyisi tehdä rinnakkaismallin kannalta
oikeellisesti.
Teknisen ratkaisun täytyy myös olla tarpeeksi avoin salliakseen luvussa 2 esitettyihin
ongelmiin kehitetyt (ja kehitettävät) ratkaisutavat. Ratkaisun täytyy sallia erilaisten
algoritmien ja tietorakenteiden toiminta sekä tukea takaisinkytkennän tapaisia
rakenteita. Tämä tarkoittaa, että on voitava mitata aikaa ja toimia sen mukaan
(esimerkiksi toiminto voidaan suorittaa korkeintaan jonkin kuluneen ajan jälkeen),
keskeyttää jokin toiminta ja muistaa edellisiä tapahtumia samalla, kun tulevaisuuden
toiminnot ovat suunniteltavina. Tällaiset vaatimukset liittyvät muun muassa animaa-
tioiden tahdistukseen fysiikkajärjestelmän kanssa ja siten toiminnan todenmukaisuuteen
sekä eri toimintojen välillä mahdollisesti ilmenevän hystereesin eliminoimiseen. Tässä
työssä kahden eri tilan välillä tapahtuvat ei-toivottu siirtymä tapahtuu, kun uuden tilan
siirtymäehto täyttyy heti siirtymän jälkeen ja tapahtuu siirtymä takaisin edelliseen tilaan.
Huomioiden edellä esitetyt rajoitukset, Luotteen tarkoitus on olla yksinkertainen,
graafinen prototyyppikieli tekoälyn toimialamallien rakentamiseen. Vipunen on editori
tämän kielen metamallin manipulointiin ja tuottamiseen.
4.2 Microsoft DSL Tools ja XNA's Not Acronymed (XNA)
Tekoälytyökalun rakentamiseen on käytetty Microsoft DSL Tools -työkalua (2007). DSL
Tools on osa Visual Studio 2008 Software Development Kit:ia (SDK) (VS2008 2009) ja
työssä käytetty versio on tätä kirjoitettaessa uusin, 1.1. Tämä SDK vaatii vähintään Visual
Studio 2008 Standard -version tai laajemman, ja opiskelijat voivat saada ilmaisen
Professional-version Microsoftin (2009a) ylläpitämästä DreamSpark-palvelusta. .NET-
kehyksen versio on 3.5 SP1 (2009). On olemassa muitakin toimialatyökalujen raken-
tamiseen tarkoitettuja työkaluja kuten MetaCasen (2009) MetaEdit+ tai Eclipse
Foundationin Generic Eclipse Modeling System (GEMS 2009), mutta Microsoft DSL
Tools integroituu suoraan Visual Studioon ja Microsoftin .NET-kehykseen, joten se
soveltuu hyvin prototyyppitoteutuksen tekemiseen.
Toimialani kohdealusta on XNA 3.0:n (2009), koska se sisältää täyden pelinkehitys-
ympäristön, on integroitu jo Visual Studio 2008 -ympäristöön ja siten siis saavutettavissa
DSL Tools -ympäristöstä monin tavoin. XNA:n SDK on saatavissa ilmaiseksi Microsoftin
ylläpitämiltä sivustoilta. XNA on Microsoftin .NET 2.0 Compact Frameworkiin (2009)
perustuva ohjelmistokehys, jonka varaan voi tehdä niin Windows- kuin Xbox 360 -
konsoliohjelmiakin samaan ohjelmakoodiin perustuen. XNA sisältää myös oheisohjelmia
ja -kirjastoja muun muassa grafiikkaresurssien ja äänimaailman luomiseen.
4.3 Microsoft DSL Toolsin rakenne ja toiminta
Konkreettisesti metamallin rakennusympäristö jakautuu kahteen projektiin: kielen
määritykseen (yleensä nimeltään Dsl) ja toimialaprojektiin (yleensä nimeltään
DslPackage). Näistä ensimmäinen, Dsl, sisältää kielen määrittämisen, kuten käsiteltävän
4 Toimialatyökalu Vipunen ja toimialakieli Luote 29
syntaksin ja rajoitteiden määrittämisen. Jälkimmäinen, DslPackage, sisältää tarvittavat
komponentit toimialaratkaisun asentamiseksi osaksi Visual Studio -asennusta tai omaksi
jakelukseen Visual Studio mukaan lukien. Toisin sanoen DSL Toolsilla kehitetyt
toimialaratkaisut vaativat Visual Studion toimiakseen.
Kuva 4-1: Tyypillinen toimialamallin kehityskiertokulku (Microsoft 2009b).
Kuvassa 4-1 (Microsoft 2009b) on esitetty tyypillinen kehityskierto toimialaratkaisulle
DSL Toolsin tapauksessa, kun tarvittava toimialarajaus on jo tehty. Se voidaan määrittää
tiivistetysti myös näin:
1. Luodaan projekti velhon avulla.
2. Määritetään toimialakielen metamalli (käyttäen metametakieltä): syntaksi,
rajoitteet ja muu tarvittava.
3. Tuotetaan työkalun (eli räätälöidyn Visual Studio -editorin) luova lähdekoodi
toimialamallista (tt-tiedostoista).
4. Ratkaisun testaaminen ja tarkastaminen (F5, Debug) käynnistämällä tätä varten
väliaikainen Visual Studio -ilmentymä.
5. Asennuspaketin (MSI6) luominen ja valmiin ohjelman, eli Vipusen, jakelu.
Kuvassa 4-1 (Microsoft 2009b) mainitaan tt-tiedostot, jotka ovat erityisiä T4-työkalun
(Text Template Transformation Toolkit) (T4 2007) tiedostoja. T4 on Visual Studio
2008:aan integroitu muunnoskieli, joka muuntaa saamansa syötteen toiseen muotoon.
Metamallien suunnittelussa ei riitäkään, että suunnitellaan syntaksi ja sen esitystapa,
vaan on myös tiedettävä, millaisia teennöksiä mallista tuotetaan. Tämä tapahtuu
6 Microsoft Installer -asennuspaketti. Tiedostopääte on vielä sama, mutta nimi Windows Installer.
4 Toimialatyökalu Vipunen ja toimialakieli Luote 30
luomalla T4-tiedostoja eri tehtäviä varten ja määrittämällä, mitkä mallin osat DSL Tools
syöttää näihin tiedostoihin tarvittavia prosessointitoimenpiteitä varten. Erittäin
yksinkertaistetusti, metamallit (tai niiden graafit) voidaan syöttää erityiseen
prosessointijärjestelmään muunnoksia varten.
T4 on oma prosessointikielensä, johon voidaan sisällyttää myös tavallisen
ohjelmointikielen lähdekoodia. DSL Tools sisältää tässä suhteessa kuitenkin erään
rajoituksen: yksi metamallin osa voidaan prosessoida vain yhdellä tt-tiedostolla ja siitä
voidaan tuottaa vain yksi teennös.
Kuvan 4-1 (Microsoft 2009b) DSL-tiedosto sisältää toimialamallin määrityksen.
Testauskäyttöön käynnistetty Visual Studio -ilmentymä sisältää edellä mainitut tt-
tiedostot, joilla toimialamallista voi testiajossa tulostaa erilaisia teennöksiä. DSL Tools
pakkaa nämä tiedostot mukaan varsinaiseen toimialaohjelmaan edellä luetellussa
vaiheessa 5, kun ohjelmasta luodaan asennuspaketti. Asennuspaketti huolehtii edelleen
toimialaohjelman ja sen toimintojen oikeellisesta rekisteröinnistä asennettavaan
järjestelmään, mutta tämä ei ole enää oleellista työn kannalta muuten kuin, että tämä
integroituvuus Microsoftin eri tuotteiden ja järjestelmien välillä luonnollisesti tekee
ratkaisun toteuttamisesta yksinkertaisempaa.
4.4 Mallin määrittäminen DSL Toolsilla
DSL Tools -editori itsessään on rakennettu samalla metametakielellä, jota on käytetty
Vipunen-editorin ja Luotteenkin määrittämiseen. Tämä on käytännössä sama asia kuin
kääntäjä, joka kääntää oman lähdekoodinsa. Tästä metamallista käännetään editori, jolla
voidaan muokata metamallissa määritetyn kielen konkreettista syntaksia. Visual Studio
-pohjaisen editorin ulkoasu ja toiminnallisuus ovat muokattavissa.
Kuvassa 4-2 on esitetty metamalli kielimäärityksen syntaksista esimerkkinä Luote-
kieli. Kuvasta voidaan havaita, että se on jaettu kahteen osaan, missä vasemmalla
puolella määritetään edellisessä luvussa mainittu kielen abstrakti syntaksi ja oikealla
puolella kielen graafinen ulkoasu, eli konkreettinen syntaksi. Kuvassa toimialamallin
käsitteet on esitetty sinisellä värillä ja niiden väliset suhteen keltaisella värillä. Elementit
itsessään otetaan käyttöön raahaamalla ne kuvan 4-3 esittämästä valikosta erityiselle
suunnittelualustalle.
Luote-kielen määritys koostuu State-luokista, joita yhdistävät toisiinsa
StateTransition-luokkien määritykset. Jokaiseen Stateen kuuluu myös Command-luokkia,
jotka määrittävät State-luokkien toimintoja. Kuvan 4-2 lukumääräsuhteissa State-
luokkien välillä on nolla tai useampia yhteyksiä ja jokaisessa tilassa voi olla nolla tai
useampia Command-olioita. Lisäksi State- ja StateTransition-luokilla on rajoituksia ja
lisämääreitä. Selvitän luokkien ajonaikaisen merkityksen kohdassa luvussa 5 Määritykset
itsessään tallennetaan oletusarvoisesti kahteen eri XML-tiedostoon (elementtien väliset
suhteen ja graafinen esitystapa) DSL Toolsin tallennus-skeeman mukaisesti, mutta
tallennustoimintoa voi räätälöidä mielivaltaisesti.
4 Toimialatyökalu Vipunen ja toimialakieli Luote 31
Kuva 4-2: Luote-kielen metamalli.
4 Toimialatyökalu Vipunen ja toimialakieli Luote 32
Vasemmalla olevaan abstraktiin syntaksiin kuuluu tarkemmin toimialaluokkien
(Domain Class) määrittäminen sekä näiden välisten suhteiden (Relationship)
määrittäminen. Kuvassa oikeassa ylälaidassa näkyvä StateMachineModel on mallin
juuriluokka, jollainen kullakin mallilla on välttämättä oltava. Metamallin luokat esittävät
toimialamallin erilaisia käsitteitä ja DSL Toolsin näille kiinteästi määrittämiä
ominaisuuksia. Näitä ominaisuuksia voi määrittää ja muokata valitsemalla tällaisen
luokan, jolloin yleensä saa valikon eri vaihtoehdoista. Määritettävät vaihtoehdot
sisältävät erilaisia yleiskäyttöisiä rajoitteita ja ohjausrakenteita kuten esimerkiksi
lukumääräsuhteita ja polkuja eri mallielementtien välillä. Malliluokkiin on mahdollista
liittää muitakin ominaisuuksia ohjelmoimalla niitä jollain yleiskäyttöisellä
ohjelmointikielellä kuten C#:lla (ECMA-334 2006).
Elementtien välillä voi olla kolmenlaisia suhteita: koostesuhteita, viitesuhteita ja
periytymissuhteita. Suhteen tyyppi määrittää sen määrittämien mallin osien
käyttäytymisen muun muassa päivitys- ja tarkistusoperaatioiden yhteydessä, esimerkiksi
poistettaessa tai lisättäessä malliluokkia tai muutettaessa näiden keskinäisiin suhteisiin
vaikuttavia ominaisuuksia. Nämä tarkoittavat oikeastaan samaa kuin missä tahansa
oliosuuntautuneessa ohjelmointikielessäkin: koostesuhteessa jokin toimialakäsite
sisältyy koosteena toiseen, viittaussuhteessa se on olemassa myös itsenäisenä ja
periytymissuhteessa se perii yliluokkansa. Näille suhteille voidaan myös määritellä
erilaisia sääntöjä, kuten esimerkiksi periytymissuhteessa voidaan kieltää edelleen
periyttäminen tai tehdä luokasta puhdas kantaluokka (abstract class).
Kuva 4-3: DSL Toolsin metakielen rakentamisessa käytetty työkaluvalikko.
4 Toimialatyökalu Vipunen ja toimialakieli Luote 33
Geometry Shape. Yksinkertainen geometrinen muoto, joita löytyy
esimääritettyinä muun muassa neliö, suorakaide, ympyrä ja ellipsi. Neliölle ja
suorakaiteelle voidaan määrittää myös pyöristetyt kulmat.
Compartment Shape. Tämä on ”osastokuva”, jossa voidaan esittää yhdessä tai
useammassa osastossa luetteloita, esimerkiksi luokkakaavion tapauksessa
muuttujia.
Image Shape. Jokin toimialamallia esittävä kuva.
Connector. Tämä esittää toimialalementtejä yhdistävää graafista elementtiä.
Yleensä ohut viiva, jonka päässä on nuoli.
Port Shape. Toimiala-elementeille voidaan määrittää portteja, joihin voidaan
yhdistää esimerkiksi edellisessä kohdassa mainittuja Connector-elementtejä
(vrt. elektroniikan komponentit).
Swimlane. Tällä malli voidaan jakaa ohuella viivalla useampaan osaan, kuten
esimerkiksi DSL Tools tekee jakaessaan abstraktin ja konkreettisen syntaksin
määritykset omiin puoliinsa.
Diagram Element Map. Yhdistää abstraktin ja konkreettisen syntaksin luokat
toisiinsa.
Kuten kuvasta 4-3 voi havaita, konkreettisen syntaksin ilmenemismuotoja on useita.
Kuvassa 4-4 on esimerkki yhdestä toimialaluokasta (State) ja sen määrittävästä
konkreettisesta syntaksista (StateShape, yhdistetty vaaleansinisellä viivalla). Seuraavassa
on esitelty kuvan 4-3 työkaluvalikossa näkyviä konkreettisen syntaksin muotoja.
Luonnollisesti kaikille muodoille on mahdollista määrittää erilaisia arvoja kuten viivojen
väri, leveys ja toisiinsa upotettujen elementtien sijainti.
Kuva 4-4: Toimialaluokka ja sen konkreettinen syntaksi.
4.5 Luotteen konkreettinen syntaksi
Kuvassa 4-5 on Luotteen metamallin (kuva 4-2) mukaisen määritelmän mukainen eräs
kielen ilmentymä, eli eräs tapaus kielen konkreettisesta syntaksista. Vasemmalla työkalu-
valikossa on DSL Toolsin automaattisesti metamallin määritelmästä luoma työkalupalkki
4 Toimialatyökalu Vipunen ja toimialakieli Luote 34
kielen käsittelyyn. Editorissa kukin graafi on omassa välilehdessään (kuten Visual
Studiossa tavallisesti).
Kuvassa State1, State2 ja State3 esittävät kuvan 4-4 State-luokan konkreettisen
syntaksin ilmentymiä, jotka on määritetty StateShape:n perusteella. Työkalupalkissa
nämä elementit ovat nimellä State Element. Tässä työstä näistä käytetään sanaa ”tila”,
mutta näitä ei pidä sekoittaa tavanomaisiin tilakoneiden tiloihin, koska ne eivät suoraan
vastaa ainakaan yleisesti tunnettujen tilakoneformalismien tilan määritelmää. Vipunen
valvoo, että kullakin tilalla on yhdessä diagrammissa ainutkertainen nimi. Tämä on
tärkeää, sillä tuotettavassa ohjelmakoodissa näiden avulla tunnistetaan editorissa
näkyvät tilat. Nämä tilat ovat vuorovaikutusrajapinta muuhun ohjelmaan siten, että
Vipusen tuottama järjestelmä kytketään muuhun pelin ohjelmakoodiin näiden tilojen
avulla. Kyseinen kieli tuottaa liitteen C mukaisen ohjelmalistauksen – kuvassa ei näy,
että graafin nimi on Vipunen, kuten editorinkin.
Kuva 4-5: Vipunen-editorin muokkausalue ja esimerkki Luote-kielestä.
Kuvan State1:n vasemman yläkulman musta umpiympyrä tarkoittaa aloitustilaa (joko
on tai ei, liitteessä C StartState). Aloitustiloja voi olla vain yksi kutakin graafia kohden, ja
Vipunen valvoo tätä rajoitusta. State2:n plus-määre tarkoittaa tilaa, joka on aina
aktiivinen. Kunkin tilan aktiivisuusaste (liitteessä C aina aktiivinen on AlwaysActive ja
tavallinen None) on ilman eri määritystä oletusarvoisesti tavallinen. Aktiivisuusasteet
ovat toisensa poissulkevia – myös aloitustila voi olla aina aktiivinen. Määreet voi antaa
elementeille avaamalla niiden kohdalla pikavalikon. Myös graafisten elementtien
väritystä voi vaihtaa pikavalikosta. Värien muutoksia voi käyttää esimerkiksi tilojen
visuaaliseen ryhmittelyyn. State-elementit liitetään toisiinsa State Transition -työkalulla
(kuvan 4-2 StateTransition). Tilasiirtymät esitetään kuvassa Transitions-valikossa
4 Toimialatyökalu Vipunen ja toimialakieli Luote 35
kussakin State-elementissä, mikäli se on siirtymän lähtötila. Nämä siirtymät voidaan
käsittää Luote-kielessä samoin kuin tilasiirtymät tilakoneissakin.
Editorin työkalupakissa ei näy tilojen Commands-osioon lisättäviä Command-olioita
(kuvan 4-2 metamallin Command). Kuhunkin Command-olioon liittyy liipaisin, joka
laukaisee siihen liittyvät Command-oliot ajettaviksi liipaisuehtojen täyttyessä –
liipaisimia ei ole myöskään mallinnettu metamallissa. Nämä on toteutettu Luote-kielestä
tuotettuun ohjelmakoodiin, muttei graafiseen kieleen. Syynä ovat DSL Tools -kielen
käytännön rajoitukset (esimerkiksi graafisten elementtien luominen sisäkkäin täytyy
toteuttaa piirtämällä kontrolli itse) ja realistisen aikataulun mukaan toimiminen. Mikäli
tämä ominaisuus olisi suoraan Luotteen graafisessa kielessä, sen syntaksi voisi olla
tekstuaalisesti esitettynä riveittäin Commands-osiossa (ks. kuva 4-5) ”Liipaisin:
Komento” (esimerkiksi ”Lähestyvä vaara: Pakene”). Sääntöjä voisi olla mahdollista
ketjuttaa myös esimerkiksi ”Liipaisin1: Komento1, Komento2; Liipaisin2: Komento1,
Komento3” ja niin edelleen.
4.6 DSL Toolsin kielen oikeellisuustarkistukset
Metamalliin tehtävillä oikeellisuustarkistuksilla ohjataan kielen oikeaan käyttöön ja
pyritään siten syntyvien teennösten virheettömyyteen. Tämän varmistamiseksi DSL
Tools rakentaa oletusarvoisesti tietovaraston, johon Luote-kielen käyttäjän Vipunen-
editorissa tekemät muutokset tallennetuvat transaktionaalisesti. Muutokset voidaan
tarkistaa erilaisiin rajoitteisiin perustuen ja hylätä tai hyväksyä ennen tai jälkeen
tallennuksen sekä niistä voidaan antaa käyttäjäpalautetta. Rajoitteita on käytännössä
kahdenlaisia, kovia (hard constraints) ja pehmeitä (soft contraints).
Kovat rajoitteet tarkoittavat esimerkiksi metamallissa esitettyjä lukumääräsuhteita
tai nimeämistä koskevia rajoituksia, joita ei missään tapauksessa voi rikkoa. Tällöin
editori voi esimerkiksi automaattisesti estää kahden elementin yhdistämisen ja näyttää
ennalta tilannetta varten ohjelmoidun ohjeviestin. Editori voi myös nimetä jonkin
elementin uudestaan siten, että sen nimi on aina ainutkertainen.
Pehmeät rajoitteet voivat olla hetkellisesti poissa voimasta, mutteivät esimerkiksi
tallennettaessa tai ainakaan teennösten tuottamisten aikana. Tällöin rikkoutuvien
ehtojen syystä voidaan antaa palaute ja korjausehdotus. Keskimäärin pehmeät rajoitteet
ovat järkevämpiä, sillä niiden avulla editoitavaan sovelluskoodiin voidaan tehdä
muutoksia, jotka rikkovat kielen eheyssääntöjä hetkellisesti.
5 Luotteella tuotetun ohjelmiston toiminta
Luvussa käsitellään Luote-kielen ohjelmakoodin rakennetta ja suorituskyky-
ominaisuuksia. Vipunen tuottaa Luotteesta ohjelmakoodia, joka voidaan liittää minkä
tahansa ohjelman rakenteisiin takaisinkutsufunktioilla. Näin Luotteen ajonaikainen
järjestelmä voi kontrolloida ulkopuolelta tulevia syötteitä ja tekoälysuunnittelija voi
muokata Vipusella mallia muuttaen automaattisesti tuotettavaa ohjelmakoodia ilman,
että ohjelmoijan muutokset häviävät.
5.1 Luote-kielen ajoympäristö
Ensimmäinen kahdesta Luote-kielen ajoympäristön perustoiminta-ajatuksista on, ettei
sen käyttäminen ja integrointi sido mihinkään tiettyyn ohjelmointikieleen, se ei vaadi
mittavia muutoksia muuhun ohjelmaan tai ohjelmoijan tekemiä muutoksia automaat-
tisesti tuotettuun lähdekoodiin. Vipunen muuntaa piirretyt Luote-kielen graafit –
epäformaalisti tilakoneet – ohjelmakoodiksi, jotka integroidaan muuhun ohjelmaan
takaisinkutsufunktioiden avulla siten, että tila on takaisinkutsufunktion nielu kutsujan
ollessa sen lähde (eli tilaan integroitu pelin osa).
Ohjelmalistaus 5-1 on esimerkki tällaisesta sidonnasta. Siinä tilaan State2 lisätään
tunnuksella SomeBinding nieluna toimiva liipaisinolio SomeTrigger ja sen vartioima
komento RandomCommand, joka sidotaan lähteenä toimivan olion testObject
määreeseen (eli tässä tapauksessa .NET:n ja C#:n property, mutta muissa kielissä jokin
muu tapahtumalähde) Source. Id 1 on sidonnan tunnus, ja samaan nieluun voidaan tällä
tunnuksella liittää useita lähteitä.
Ohjelmalistaus 5-1: Luotteen liittäminen muuhun ohjelmaan takaisinkutsufunktiolla.
Tällainen integrointi vastaa laajennettavuutta avoin-suljettu-periaatteen (Meyer
1997) hengen mukaisesti mieluummin sisällyttämällä kuin periyttämällä. Tämä näkyy
machine["State2"].BindingManager.AddCommandBinding("SomeBinding",
new RandomCommand{}, new SomeTrigger{});
var b = machine["State2"].BindingManager.
TryGetCommandBinding("SomeBinding");
b.AddBindings(new[]
{
new BindingArgument(testObject, "Source", "Id 1")
});
5 Luotteella tuotetun ohjelmiston toiminta 37
siten, että lähteen tai nielun muutokset eivät vaikuta toisiinsa niin kauan kun
takaisinkutsurajapinta pysyy samanlaisena ja kaikki vuorovaikutus on rajattu vain siihen.
Luotteen vuorovaikutuksen perusajatuksena on siis erillään hallinnoitu tilakone, joka
ryhmittää ja rajaa pelin toimijoiden ja Luotteen välisen rajapinnan.
Loogisen järjestelmän kannalta lähteitä voi olla rajoittamaton määrä ja näiden
lähteiden muutosta vartioivat nieluissa liipaisimet, jotka suorittavat niihin liitetyt
komennot liipaisuehtojen täyttyessä. Tehokkuuden lisäämiseksi tieto lähteiden
muutoksista välitetään liipaisimille laskettavaksi vain kun liipaisimien isäntätila on
aktiivinen (koodilistauksen 5-1 tapauksessa isäntätila on State2). Isäntätila toimii siis
paitsi liipaisimien ja niihin liitettyjen komentojen organisoijana myös suodattimena.
Kuva 5-6 havainnollistaa tilannetta. Kuvassa johonkin pelin toimijaan (esimerkiksi
tietokoneohjattu hahmo) on liitetty tilakone, jossa tila Nuku on aktiivinen, tila Juokse
inaktiivinen ja aina aktiivinen tila on Kavahda.
Kuva 5-6: Havaintokuva toimijaan liitetystä tilakoneesta ja signaaleista.
Signaalit Juokse-tilaan eivät etene liipaisimille laskentaan. Nuku-tila ei käsittele
lainkaan ulkopuolelta tulevia signaaleja. Kavahda-tila sen sijaan on aina aktiivinen ja saa
signaalin toisesta hahmosta (signaalin välittäjän ei tarvitse olla tämä lähestyvä hahmo).
5 Luotteella tuotetun ohjelmiston toiminta 38
Kavahda-tilalla voi olla useita liipaisimia, jotka kaikki vastaanottavat tulevan signaalin ja
joista jokainen reagoi eri tavalla tässä tapauksessa esimerkiksi lähestyvän hahmon tyypin
perusteella. Tällöin yksi liipaisin voi aloittaa esimerkiksi joko toiminnon pelota pieni
agentti pois tai juokse isoa agenttia pakoon, tai yksi liipaisin voi aloittaa vain yhden
toiminnon. Liipaisimien aloittama toiminto suoritetaan siten, että liipaisin laukaisee
toiminnon Luotteen ajonaikaiseen järjestelmään suoritettavaksi. Tämä toiminto on
käytännössä funktio-objekti, funktori, joka lisätään jonoon. Kukin funktori poistetaan
jonosta vuorollaan ja sen toiminto suoritetaan.
Myös tilasiirtymät laukaistaan samalla tavalla. Vipunen kirjoittaa tilasiirtymistä
automaattisesti liipaisimet ja tilasiirtymän tekevien olioiden ohjelmakoodin sillä
piirrettyjen graafien perusteella. Kunkin tilasiirtymän yhteydessä on mahdollista myös
ajaa tilasta poistumiseen ja tilaan siirtymiseen liittyviä takaisinkutsufunktioita. Nämä
funktiot ajetaan käänteisesti tallennusjärjestyksensä suhteen, eli pinojärjestyksessä
(LIFO), järjestelmän säiealtaassa Luotteen ulkopuolella. Valitulla suoritusjärjestyksellä ei
sinänsä ole merkitystä, mutta viimeksi lisätyllä alkiolla on suurempi todennäköisyys
sijaita edelleen välimuistissa, pino on helppoa toteuttaa ja sen suoritusmalli on verrattain
selkeä. Toinen luonteva vaihtoehto olisi jonojärjestys (FIFO).
Luotteen ajoympäristön perustoiminta-ajatus on, että sen tilat ja liipaisinrajapinta
toimivat ikään kuin muuntimena muun ohjelman ja Luotteen edustaman
tekoälyjärjestelmän välillä. Tässä rajapinnassa ohjelman jatkuva-aikaiset toiminnot
diskretisoidaan siten, että liipaistujen komentojen suoritusjärjestys säilytetään.
Komennot suoritetaan liipaisimien laukeamisjärjestyksessä. Toisin sanoen Luotteeseen
liitettyjen peliohjelman osien toimintojen kausaalisuus säilytetään ja varmistetaan
lähtien liipaisusta jatkuen kunkin komennon suoritukseen.
Rakenne varmistaa, että luvussa 2 esitetyt algoritmiset ongelmat voidaan ratkaista
liittämällä ne vaikkapa osaksi komentoja tai ne voivat toimia taustalla lisäten komentoja
jonoon (aivan kuten liipaisimetkin). Lisäksi aina aktiiviset tilat mahdollistavat rakenteen,
missä sen hetkisestä aktiivisesta tilasta riippumatta voidaan aina vastata tilanteisiin,
jotka vaativat välitöntä huomiota ilman, että jokaisesta tilasta täytyy erikseen tehdä tätä
varten siirtymä (kuten kuvan 5-6 Kavahda). Takaisinkytkennän tapaiset rakenteet
toteutuvat, kun tapahtumat aiheuttavat uusia tapahtumia, joita vastaanottavat tilat ja
liipaisimet prosessoivat lisäten uusia komentoja ajoon Luotteeseen tai kun tilasiirtymät
lisäävät toimintoja ajoon tai poistavat toimintoja ajosta. Esimerkiksi animaatiot voidaan
käynnistää siirryttäessä tiloihin, jolloin ne suoritetaan joko loppuun tai ne voidaan
lopettaa kesken, mikäli niihin kuuluva tila deaktivoituu. Nämä animaatiot ovat
takaisinkutsurakenteen ansiosta eriytetty selkeästi itse tilakonelogiikasta.
Hystereesi voidaan välttää esimerkiksi siten, että komento kirjoittaa
suoritusajankohtansa muistiin, ettei liipaisin aja uudestaan samaa komentoa ennen kuin
kynnysaika ole kulunut. Tällöin voidaan helposti välttää tilanne, jossa kahden tai
useamman tilasiirtymän väliset ehdot täyttyisivät vuoronperään ja aiheuttaisivat
epätoivottua edestakaista siirtymistä näiden välillä.
5 Luotteella tuotetun ohjelmiston toiminta 39
5.2 Staattinen luokkamalli
Luote-kielen staattinen luokkamalli eli aina tuotettava perusinfrastruktuurikoodi on
melko yksinkertainen, kuten kuvasta 5-7 on havaittavissa.
Kuva 5-7: Luote-kielestä tuotetun ajonaikaisen rakenteen luokkakaavio.
Luokkakaaviossa on esitetty toiminnan kannalta 11 tärkeintä luokkaa, joiden osuuden
toiminnallisuudesta käyn läpi tarkemmin seuraavissa alaluvuissa. Luokkakaavioon ei ole
merkitty joitakin pieniä apuluokkia kuten erilaisia tapahtumia.
5.2.1 Signaalien lähteiden ja nielujen sitominen
LuoteObject kuvan 5-7 ylälaidassa on yliluokka kaikille signaalilähteinä toimiville
luokille. Tämä ei ole välttämätöntä, mutta LuoteObject toteuttaa .NET-rajapinnan
INotifyPropertyChanged:in (2009) ja sisältää signaalilähteiden sidontaan liittyvää yleistä
helppokäyttöisyystoiminnallisuutta. INotifyPropertyChanged (2009) on .NET-kehyksen
täydessä versiossa tavanomainen rajapinta objektien keskinäisen sidonnan
5 Luotteella tuotetun ohjelmiston toiminta 40
toteuttamiseksi ja on valmiina käytettäväksi yleisimmille toiminnoille. Luotteen
signaalilähteet ja -nielut ovat tällainen sidontatoiminnallisuus.
XNA-alusta ei sisällä objektien sidontaominaisuuksia, joten näiden toteuttaminen
Luote-kieleen oli välttämätöntä. Samalla oli ratkaistava myös roikkuvista muistiviitteistä
aiheutuva sidontaongelma, jossa pitkäikäisten olioiden viittaus lyhytikäisiin estää näiden
roskienkeruun. Tämä saattaa myös olla syy, miksi sidontatoiminnallisuutta ei ole
toteutettu .NET:in XNA-versiossa: Erityisesti konsolijärjestelmässä muistia on rajallisesti
ja objektien sidonta saattaa nopeasti kuluttaa suuren määrän muistia.
Roskienkeruujärjestelmän toiminta saattaa hetkellisesti vaatia runsaastikin prosessointi-
resursseja.
Roikkuvien viitteiden ongelmaan tunnetaan ratkaisu epävirallisella termillä heikot
delegaatit (engl. weak delegates)7 (Schechter 2004), jonka muunnelmaan osa
Luotteestakin tuotetun ohjelmakoodin toiminnallisuudesta perustuu. Ongelma ei sikäli
ole erityisen laajalti tunnettu, koska varsinkaan normaalissa työpöytä- tai
palvelinohjelmistokäytössä roikkuvilla viitteillä ei juuri milloinkaan ole käytännön
merkitystä. Tämä on myös esimerkki toimialamallinnuksen eduista: hankalahko
ongelma ratkaistaan ja on ratkaistu tulevaisuudessakin ilman, että esimerkiksi
kokemattomampien kehittäjien täytyy miettiä asiaa uudestaan (mikäli ovat alun
alkaenkaan tietoisia ongelmasta!).
BindingManager on Julkisivu-suunnittelumalli (engl. Façade) (Bishop 2008, 93–99)
kunkin tilan signaalinielujen hallintaan. Kuten kuvasta 5-7 on havaittavissa, tarjoaa
BindingManager rajapinnan erityisesti sidontojen lisäämiseen ja poistamiseen. Kukin tila
sisältää yhden BindingManager-ilmentymän ja kullakin BindingManager-ilmentymällä on
viite sen sisältävään tilaan. Prototyyppitoteutuksen tapauksessa sidonta tarkoittaa jonkin
pelin (LuoteObject:sta periytetyn) objektin rajapinnan määreestä BindingManager:iin
tehtyä liitosta ainutkertaisella tunnuksella siten, että muutos lähdeominaisuudessa
välittyy sidontaan (kuten tavanomaisessakin .NET-sidonnassa). Kutakin uutta sidontaa
varten BindingManager luo uuden BindingSet-ilmentymän. Uusi sidonta tehdään silloin,
kun sidonnan yhteydessä käytetään sidottavan tilan BindingManager:lle tuntematonta
tunnusta. Tämä tarkoittaa myös, että yhdellä tunnuksella on yksi liipaisin.
Kuhunkin nieluun voidaan liittää liipaisimia, ITrigger-rajapinnasta periytettyjä
vahtifunktioita. Käytännön merkitys on, että näin tiloihin voidaan liittää dynaamisesti
uusia funktiota suoritettaviksi tietyin ehdoin, toisin sanoen, ITrigger-rajapinnasta
periytettyjen olioiden voidaan ajatella toteuttavan Strategia-mallin (engl. Strategy)
(Bishop 2008, 139–148) dynaamisen version, eli Tila-mallin (engl. State) (Bishop 2008,
148–158). Vipunen luo editorissa piirretyille siirtymille niiden nimien perusteella
sidontanielut automaattisesti. Ohjelmoija voi liittää nämä pelimaailmaan kunkin tilan
TryGetTransitionBinding-funktiota käyttämällä joko staattisesti tai dynaamisesti. Funktio
toimii .NET:n nimeämiskäytännön mukaisesti yrittäen palauttaa parametrina annetun
siirtymäkomennon BindingSet-olion, johon voidaan lisätä liipaisimet ja komennot.
7 WPF:ssä ja siten .NET:in versiosta 3.0 eteenpäin on vastaava WeakEvent-mallinsa (Microsoft
2009c). Tämä ei kuitenkaan vielä ole XNA:ssa.
5 Luotteella tuotetun ohjelmiston toiminta 41
5.2.2 Vuorovaikutuksen rakenne
State-luokkia käytetään signaalinielujen (BindingSet) ja niihin sidottujen liipaisimien
(ITrigger) ja komentojen (Command) organisoimiseen. Kunkin tilan sidonnat tarkistavat
BindingManager-säiliönsä kautta tilansa aktiivisuuden eivätkä välitä signaaleja
liipaisimille, mikäli tila ei ole aktiivinen. Kun tila on aktiivinen ja signaali välitetään
liipaisimelle, laskee tämä liipaisin signaalien arvoihin perustuen totuusarvon. Jos
laskenta tuottaa arvon TOSI, lähetetään liipaisimeen liitetyt komennot StateMachine-
luokan suoritettaviksi. State-luokat voivat sisältää myös suoritettavaa ohjelmakoodia
kutsuttavaksi tilasiirtymien yhteydessä: tiloihin voidaan lisätä erityisiä takaisinkutsu-
funktioita kutsuttaviksi siirryttäessä tiloihin ja tiloista. Kutsusekvenssin on esitetty
seuraavassa kohdassa yksityiskohtaisesti (kuva 5-8).
Command-luokka on kaikkien ajettavien komentojen kantaluokka. Komennot ovat
mitä tahansa (pelin) toimintoja, joita ohjelmoijat ovat periyttäneet Command-luokasta ja
lisänneet Vipunen-editoriin suunnittelijoiden käytettäväksi, eli aiemmin mainittuja
funktoreita toimintojen suorittamiseksi. TransitionCommand on yksi Luotteen perus-
luokista, ja josta Vipunen luo automaattisesti ilmentymät tuottaessaan ohjelmakoodia
suunnittelijoiden piirtämien tilakoneiden tilasiirtymille.
TransitionCommand sisältää tarvittavan toiminnallisuuden tilasiirtymän oikeelliseen
suoritukseen. Liipaisimilla ei ole muita vaatimuksia kuin toteuttaa rajapinnan ITrigger
Trigger-totuusarvofunktio. Ne voivat siis käytännössä esimerkiksi varastoida historia-
dataa, käyttää ajastimia tai jopa kutsua ohjelman muita osia suorituksensa aikana.
StateMachine-luokalla on keskeinen tehtävä kaiken Luote-kielen ajonaikaisessa
mallissa olevan toiminnallisuuden toteuttamisessa. StateMachine käyttää omassa
komentoja suorittavassa säikeessään kaikille yhteistä, staattista ja vapaakäyntistä (engl.
re-entrant) CommandQueue-luokkaa, johon StateMachine käytännössä lisää
suoritettavat komennot taaten näin omalta osaltaan suoritettavien komentojen suoritus-
järjestyksen säilymisen lisäysjärjestyksessä vähäisellä ylimääräisellä prosessoinnilla.
StateMachine on myös säiliöluokka kaikille tiloille toimien niille näin yhteisenä
rajapintana. Kustakin Vipusessa piirretystä graafista tuotetaan täsmälleen yksi
StateMachine-luokan ilmentymä.
StateMachine kutsuu CommanQueue:n Deque-funktiota poistaakseen sieltä
seuraavan komennon. Mikäli puskuri on tyhjä, estää CommandQueue kutsujan
toiminnan nukuttamalla tämän, kunnes puskurissa on jälleen objekti. Käytännössä siis
komennot suoritetaan sarjassa niin nopeasti kuin mahdollista eikä muuten kuluteta
lainkaan resursseja.
CommandQueue ei ole yksinkertaisuudestaan huolimatta triviaali. Se on puskurointi-
ratkaisu tuottaja-kuluttaja-ongelmaan yleisesti ja komentojen järjestyksen ja siten
kausaalisuussuhteiden säilyttäminen erityisesti. Huomioitavaa on, että CommanQueue:n
puskuri on käytännössä vain käyttöjärjestelmän ohjelmalle antaman virtuaalimuistin
määrän rajoittama eikä kiinteä. Ratkaisussa on oleellista lukituksen tapahtuminen täysin
hallinnoidussa ohjelmakoodissa ilman, että kutsutaan Windows-ytimen palveluita .NET-
virtuaalikoneen ja käyttäjätilan ulkopuolelta. .NET-virtuaalikone toimii omassa
5 Luotteella tuotetun ohjelmiston toiminta 42
prosessiaan8, joten kutsut sen ulkopuolelle aiheuttavat ylimääräisiä kontekstinvaihtoja.
Erityisesti kutsut käyttöjärjestelmän ytimen lukitusrutiineihin ja etuoikeutettuun tilaan
aiheuttaa monia kontekstinvaihtoja, ylimääräistä muistinvarausta, kopiointia ja muuta
resurssienkäyttöä.
5.3 Vuorovaikutusten suoritussekvenssi
Luotteen tekoälyjärjestelmässä kaikki komennot kulkevat saman suorituspolun, mutta
järjestelmän sisäisen toiminnan kannalta ja rinnakkaisuudesta johtuen monimutkaisin
on tilasiirtymän suorittaminen, joka sisältää joitakin lisätoimenpiteitä tavanomaisen
komennon suorittamisen lisäksi. Kuvassa 5-8 näkyy jo edellisissäkin luvuissa mainittu
komentojen suorittamisen tapahtumasekvenssikaavio.
Kuva 5-8: Luotteen komentojen suorittaminen.
Komennon suorittamisen voidaan katsoa alkavan, kun jonkin sidotun ominaisuuden
arvo vaihtuu, jolloin kutsun jälkeen tapahtuu automaattinen takaisinkutsu edellisessä
luvussa mainittuun BindingSet-sidontaan. Mikäli tämä BindingSet on jonkin toisen
8 Windowsissa vuoronnettavat yksiköt ovat säikeitä, jotka vain perivät prosesseilta ominaisuuksia
kuten tietoturvakontekstin (About Processes and Threads 2009).
:LuoteObject : BindingSet : StateMachine
«precondition»
{BindingSet host state
IsActive = true
AND
BindingSet Trigger = true}
PropertyChanged
commandQueue : CommandQueue
Enqueue(command)
CommandLoop
ref
QueueCommand(command)
par
5 Luotteella tuotetun ohjelmiston toiminta 43
LuoteObject-ilmentymän muuttujana, voidaan myös ajatella kutsun tapahtuvan kahden
LuoteObject-ilmentymän välillä – LuoteObject voi olla toinen toimija tai sama objekti
itse. Se voi olla myös koko maailman tilaa ylläpitävä tietokanta, johon sidotuille
objekteille se lähettää päivityksen (kuten aiemmin mainittuun Kavahda-tilaan)
esimerkiksi kaikista objekteista, joiden lähestymisvektori (suunta, nopeus ja sijainti)
täyttävät annetut kriteerit.
PropertyChanged-kutsun jälkeen tarkistetaan säiliötilan (State) aktiivisuus ja tämän
jälkeen lasketaan liipaisinfunktio. Mikäli isäntätila ei ole aktiivinen, jätetään liipaisinkin
laskematta. Vasta isäntätilan aktiivisuuden ja liipaisimen laskun jälkeen BindingSet lisää
kunkin liipaisimeen liitetyn komennon StateMachine-luokan jonoon kutsulla
QueueCommand. Suoritus on rinnakkainen Luotteen ajonaikaisen komentosilmukan
(kuvan 5-8 CommandLoop) suorituksen kanssa.
CommandQueue (ks. kuva 5-8) takaa lisättyjen komentojen poistamisen
lisäämisjärjestyksessä (FIFO-järjestys). Vaikka pelissä käytettäisiin useitakin rinnakkaisia
säikeitä ja siten eri liipaisimet laukeaisivat yhtäaikaisesti, komentojen suoritus-
järjestyksen kannalta ratkaisevaa on, mikä niistä on lisätty jonoon ensimmäisenä (mikäli
järjestys haluttaisiin säilyttää signaalin vastaanottamisesta asti, täytyisi liipaisinfunktiot
asettaa samanlaiseen puskuriin kuin komennotkin).
Tästä puskuroinnista ja säikeiden erillisyydestä seuraa, että pelissä voidaan vapaasti
käyttää yhtäaikaisia säikeitä ilman järjestelmästä johtuvia rinnakkais- tai kausaalisuus-
virheitä: komennot ovat puskurissa lisäämisjärjestyksessä, joka on myös aikajärjestys, ja
niiden suorittamisesta syntyvät uudet komennot lisätään puskuriin vasta edellisten, niitä
ennen tapahtuneiden, jälkeen suoritettavaksi.
Suoritettavien kannalta on tärkeää, että toimijat liittävät itsensä takaisinkutsuilla
kaikkiin toisiinsa vaikuttaviin toimintoihin. Muutoin monen toimijan tapauksessa voi
tapahtua niin, että toisaalla tapahtunut vuorovaikutus voi välillisesti aiheuttaa
virheellistä toiminnallisuutta. Tämä tarkoittaa esimerkiksi tilannetta, jossa:
1. On aloitettu jokin toiminto vasteena tapahtumaan (siirryttäessä tilaan).
2. Tämä toiminto on tarkoitus lopettaa tilan deaktivoituessa.
3. Tilan deaktivoitumista ei tapahdu, koska tilan deaktivoivaa signaalia ei ole
sidottu joko suoraan tilaan itseensä tai yhteenkään tilaan tai liipaisimeen, joka
voisi välillisesti deativoida aktiivisen tilan.
Pitkäkestoisten komentojen suorittaminen on potentiaalinen ongelma, sillä
komennot suoritetaan yksitellen yhdessä säikeessä (ne eivät siis voi ohittaa toisiaan edes
järjestelmän riistäessä CommandQueuen suoritusvuoron), jolloin pitkäkestoisten
komento suorittaminen saattaa hidastaa koko pelin tekoälyn suorittamista
hallitsemattomasti. Tällainen komento voitaisiin suorittaa toisessa säikeessä (komento
itse voi tehdä sen), mutta silloin sen täytyisi eksplisiittisesti varmistaa kausaalinen eheys
koko järjestelmän laajuisesti. Käytännössä tämä ei liene mahdollista.
Eräs keino olisi profiloida ohjelmakoodi ja olla käyttämättä liian hitaita toimintoja.
Kuten luvussa 2 kuitenkin kävi ilmi, osa tärkeistä ja tarvittavista algoritmeista saattaa
laskea tarvittavia tuloksia pelitapahtumien mittakaavassa liian pitkään. Toinen keino
lieventää ongelmaa olisi uusi, erillinen jono erityisen pitkäkestoisille komennoille.
5 Luotteella tuotetun ohjelmiston toiminta 44
Tällöin täytyy kuitenkin varmistaa esimerkiksi lukituksin tai ylimääräisin kopioin,
etteivät tällaisen algoritmin laskennassaan käyttämien parametrien arvot vaihdu kesken
laskennan ja että algoritmi itse päivittää jaetun tilan transaktionaalisesti virheellisten
tulosten välttämiseksi. Tällaisesta ei kuitenkaan ole Luotteessa ole tällä hetkellä otettu
huomioon.
Kuva 5-9: Luotteen ajonaikainen komentosilmukka.
Kuvassa 5-9 on tilan vaihtamisen vaiheet, eli yhden TransitionCommand-komennon
suorittaminen. Ensimmäiseksi StateMachine purkaa CommandQueue-jonosta komennon
ja tarkistaa, että komennon laukaissut säiliötila on aktiivinen, ja että sen identiteetti on
sama kuin liipaisimen lauetessa ja komentoa jonoon lisättäessä. Identiteetti on 32-
bittinen näennäissatunnaisluku, jonka kukin tila arpoo itselleen aktivoituessaan.
Tarkistustoimenpiteet ovat välttämättömiä, koska alun perin laskettaessa liipaisimen
arvoa ja lisättäessä komentoa jonoon ei voida tietää, mikäli jokin jo jonossa oleva,
suoritustaan vielä odottava komento vaihtaa aktiivisen tilan toiseksi, jolloin sen jälkeen
saman tilan kautta lisättyjä komentoja ei pidä ajaa.
: StateMachine commandQueue : CommandQueue
command := Dequeue(): Command
command : TransitionCommand
command.Execute()
ChangeState(source, destination)
source : State destination : State
OnExit()
ChangeState
OnEnter()
Deactivate
Activate()
«precondition»
{Host State
(launch state)IsActive = true AND
command.
OwnerStateIdentity =
command.OwnerState.
CurrentIdentity}
CommandLoop
5 Luotteella tuotetun ohjelmiston toiminta 45
Tarkemmin jaoteltuna ongelma syntyy, kun:
1. Jonossa on suorittamattomia komentoja, joiden joukossa on tilan deaktivoiva
tilansiirtokomento.
2. Jossain välissä tämän deaktivoivan komennon jälkeen jonossa seuraa toinen
komento, joka aktivoisi tilan jälleen.
3. Jonoon lisätään komentoja ennen kuin deaktivoiva komento on ajettu, jolloin siis
komentojen lisäämistä ei estetä lisäämisvaiheessa. Nämä komennot seuraavat
deaktivoivan komennon jälkeistä, aktivoivaa komentoa.
4. Nyt vaikka aktiivinen tila vaihtuu ja viimeisenä lisättyä komentoa ei pitäisi ajaa,
toinen tilansiirtymäkomento aktivoi tilan jälleen, jolloin komentoa suoritettaessa
tehtävä tilan aktiivisuustarkistus ei ole riittävä. On siis tarkistettava, että tilan
identiteetti on sama kuin mihin komento on alun perin liitetty. Tämä on
seurausta siitä, että tilan tekemä suodatus signaalilähteelle on vain suorituskykyä
lisäävä suodatus eikä suinkaan vielä varmista kausaalista oikeellisuutta.
Varsinainen komennon suorittaminen tapahtuu kutsussa command.Execute, jossa
voidaan suorittaa mitä tahansa ohjelmakoodia. Normaalin komennon suorittaminen
loppuu tämän kutsun jälkeen ja silmukka purkaa jonosta jälleen yhden komennon
suoritettavaksi. Juuri tämän Execute-kutsun täytyy käytännössä olla mahdollisimman
nopea. Muutoin komentosilmukan läpisyöttö hidastuu ja se vaikuttaa koko pelin
tekoälyn suoritustehoon. Komentojen Execute-funktiot eivät myöskään saa vuotaa
poikkeuksia. Tämä pysäyttäisi koko järjestelmän tekoälyn suorituksen.
Tilasiirron tekevän TransitionCommand:in tapauksessa komento kutsuu
StateMachine:n ChangeState-funktiota. Tämän funktiokutsun aikana on käytännössä
vain kaksi asynkronista kutsua ja lukolla suojattu sijoitus, joka päivittää StateMachine:n
ylläpitämän tiedon aktiivisesta tilasta. Lukkosuojaus ei ole tehokkain ratkaisu, koska
lukuja on enemmän kuin kirjoituksia. XNA 3.0 ei kuitenkaan toteuta kevyt-
rakenteisempia luku- ja kirjoituslukkoja kuten ReaderWriterLockSlim (2009) eikä
muistiseinän (engl. memory barrier) käyttö auttaisi. Muistivallin käyttäminen kyllä
estäisi kääntäjää järjestämästä käskyjä uudelleen, muttei päivittäisi muuttujan
viimeisintä tilaa muiden suorittimien välimuistiin. Muistivallin ja volatile-määreen
(VolatileRead 2009; VolatileWrite 2009) käyttö on oikeastaan sama kuin vain hallitussa
ohjelmakoodissa tapahtuva lukitus.
OnExit kutsuu senhetkisen aktiivisen tilan poistumistilannetta varten tallennettuja
takaisinkutsufunktiota pinojärjestyksessä (LIFO, viimeksi lisätty ensin) taustasäikeessä.
Kutsut tapahtuvat taustasäikeessä, koska takaisinkutsufunktioiden ajoaika on
potentiaalisesti pitkä. Näiden funktioiden kutsu ei saa olla riippuvainen komennon
säiliötilan aktiivisuudesta, sillä .NET-kehys ei takaa taustasäikeen suorituksen
järjestyksestä tai vuoronnuksesta mitään, ja erittäin todennäköisesti tila vaihtuu
aktiivisesta inaktiiviseksi ennen kuin pino on kokonaisuudessaan kutsuttu.
OnEnter-funktiotioita kutsutaan samoin kuin OnExit-funktiota. Koska kummatkin
kutsut tehdään taustasäikeessä, Luote ei takaa OnExit- ja OnEnter-funktioiden
kutsujärjestyksestä kuin kummankin pinojärjestyksen. Nämä pinokutsut voidaan
suorittaa pinojen kesken missä tahansa järjestyksessä. Suoritusmallina on .NET:n
5 Luotteella tuotetun ohjelmiston toiminta 46
säieallas (ThreadPool 2009) ja taustasäikeet, koska yhtäaikaisia potentiaalisia
tilanvaihtoja on useita. Tällöin säikeistetyssä ajoympäristössä kulloinenkin käyttö-
järjestelmän versio huolehtii keskimäärin optimaalisimmasta kuormasta vasteaikojen
suhteen, vaikkei läpisyöttö olisikaan optimaalinen. Erityisesti, koska yhtä aikaa suori-
tettavia kutsuja voi olla useita ja siten vuoronnettavia säikeitä jopa liikaa tehokkaaseen
toimintaan ja OnEnter- ja OnExit-pinoihin tallennetut funktiot voivat olla mielivaltaista
ohjelmakoodia: esimerkiksi funktoreita tai takaisinkutsuja ne lähettäneeseen toimijaan
sisältäen pitkäkestoisempaakin toiminnallisuutta.
5.4 Suorituskyky ja ajonaikainen käyttäytyminen
Käytännössä suurimmat suorituskykyyn ja käyttäytymiseen vaikuttavat tekijät ovat
StateMachine-luokan komentosilmukan läpisyöttöteho ja tasaisuus. Läpisyöttötehon ja
tasaisuuden mittaaminen kyllin yleispätevästi ja tarkasti on kuitenkin hankalaa ja monen
suoritinelementin tapauksessa jopa liki mahdotonta. Suorituselementti (Processing
Element, PE) voi tarkoittaa joko yksittäisiä tietokoneita, fyysisiä suorittimia, suoritin-
ytimiä, laitteistosäikeitä kuten Intelin Hyper-Threading tai vastaavia. Tätä määritelmää
käytetään myös teoksessa Patterns for Parallel Programming (Mattson ym. 2005, 17).
Koska Luote-järjestelmä toimii sekä PC- että Xbox-alustalla, voidaan sen
kohdesuoritusympäristöksi katsoa ainakin moniydin-x86- ja PowerPC-suorittimet
(Xbox) sekä .NET-kehys x86-arkkitehtuurilla ja .NET Compact Framework -versio Xbox-
arkkitehtuurilla (PowerPC). Testauksessa Xbox-ympäristö on kuitenkin jätetty
huomiotta.
5.4.1 Suorituskykyyn vaikuttavat yleistekijät
Suorituskyvyn ja tasaisuuden mittaaminen muuten kuin karkeasti suuntaa-antavasti on
jo yleisesti tutkimusongelmia itsessään, mutta näiden ominaisuuksien mittaaminen edes
karkeasti antaa osviittaa suorituskyvystä ja järjestelmän toimivuudesta. Näiden
ongelmien ratkaisuhahmotelmat osoittavat myös, miten Luotetta voisi analysoida
tarkemmin ja mitä analyysit todennäköisesti paljastaisivat.
Luotteen suorituskykyä, ajonaikaista käyttäytymistä ja joitakin helpommin
selvitettäviä laatutekijöitä mitattiin kahdella x86-testikoneella, joista toinen on
kokeiluluonteisesti yksiytiminen. Testilaitteistojen oleelliset kokoonpanotiedot on
esitetty liitteessä A. Tavallisimmat PC-moniydinlaitteistot perustuvat tällä hetkellä x86-
käskykantaan, jaettuun välimuistiin ja enenevissä määrin myös NUMA-arkkitehtuuriin9
(AMD-suorittimet yleisesti ja Intelin uusimmat).
Karkeasti NUMA tarkoittaa, että kukin suoritin voi osoittaa päämuistia yhtäläisesti,
mutta jotkin muistiblokit ovat nopeammin saavutettavissa joiltain suoritinelementeiltä
kuin toisilta. Tämän epäsuhdan lieventämiseksi kullakin suoritinelementillä on
9 Yhtenäisen välimuistin erillinen muistipääsy ((cache coherent) non-uniform memory access,
NUMA).
5 Luotteella tuotetun ohjelmiston toiminta 47
välimuistia ja protokolla näiden välimuistien yhteisen tilan pitämiseksi yhtenäisenä.
(Mattson ym. 2005, 10.) Myös yleisesti tunnettu seikka on, että suorittimen yhteydessä
oleva muisti on nopeampaa kuin päämuisti, ja että suorittimen ja päämuistin rajapinta
on suorituksen pullonkaula; eli on olemassa epäsuhta suorittimen nopeuden ja sen kyvyn
käyttää muistia sekä muistijärjestelmän toimintanopeuden välillä. Tästä moni-
mutkaistumisesta aiheutuu ongelmia sekä välimuistien että päämuistin keskinäisessä
synkronoinnissa ja rajapinnan kaistaleveyden riittävyydessä. Ilmiö tunnetaan myös
termillä muistivalli (engl. memory wall tai memory fence).
Kuva 5-10: Moniydinkoneiden suoritusteho eri ytimien lukumäärällä (Sandia National Laboratories 2009).
Muun muassa Sandia National Laboratoriesin rinnakkaislaskennan yksikkö on
tutkinut tätä ongelmaa simuloimalla suoritusaikaa erilaisilla laitteistoilla ja eri
suoritinytimien lukumäärällä ja suurilla datajoukoilla keskeisiä suurteholaskennan
algoritmeja ja menetelmiä käyttäen. Kuvassa 5-10 (Sandia National Laboratories 2009)
x86-järjestelmiä on merkitty sinisellä viivalla (”Conventional”), joka nousee jyrkiten
lopussa. Kuvasta on havaittavissa merkittävä nopeutuminen välillä 2-4 ydintä ja
vähemmän merkittävä välillä 4-8 ydintä, 16 ytimen suoritusteho on enää noin 2 ytimen
luokkaa ja tämän jälkeen on havaittavissa jopa merkittävää hidastumista.
Käytännössä edellisen kaltainen hidastuminen johtuu muistin ja suorittimien välisen
väylän ruuhkautumisesta ja tarvittavasta ylimääräisestä työstä välimuistien
5 Luotteella tuotetun ohjelmiston toiminta 48
synkronoimiseksi. Ilmiö tunnetaan myös epävirallisella termillä superlineaarinen
hidastuminen, vastakohtana superlineaariselle nopeutumiselle. Sandian vertailu ei ole
aivan kiistaton, koska siinä on ilmeisesti oletettu olevan suuri joukko suoritinelementtejä
samassa suoritinkannassa jopa ilman HyperTransport- tai QuickPath-ominaisuuksia
(Friedman 2009a; Friedman 2009b; Gunther 2009).
Eri muistien tahdistamisen lisäksi ongelma johtuu myös siitä, että vaikka
suoritinytimillä on yleensä omaa välimuistia (esimerkiksi L1- ja L2-taso), ne myös jakavat
jonkin välimuistin tason (esimerkiksi L3-tason). Koska välimuistin määrä ei käytännössä
kertaudu ytimien lukumäärän mukaan, on jokaisella ytimellä vähemmän muistia
käytettävissään. Tästä seuraava ilmiö tunnetaan termeillä käsky- ja datahudit (engl.
cache data miss ja cache instruction miss), joissa välimuistista puuttuva data täytyy
hakea päämuistista. Tilannetta hankaloittaa, että muun muassa Intelin uusimmissa
suorittimissa on jälleen käytössä suoritintason säikeet (HyperThreading), jolloin
välimuistin määrä jokaista suoritinelementtiä kohden on edelleen vähäisempi. Muistin
määrällä, kiintolevy mukaan lukien, on vähemmän vaikutusta. Muistin nopeus on
jonkinasteinen tekijä, koska muistiväylän ja muistin nopeudet ovat sidoksissa toisiinsa.
Muistivallin madaltamiseen ei nykyisissä yleisesti käytössä olevissa arkkitehtuureissa
juuri ole mahdollisuutta. Käytännössä tämä tarkoittaa, että suoritus on ensin optimoi-
tava yhden säikeen tapauksessa. Tietorakenteet täytyy valita siten, ettei prosessoitava
data sijaitse useamman suorittimen välimuistissa, ettei se kuluta suorituksen kannalta
tarpeettomasti tilaa ja ettei tietorakenteiden välillä esiinny näennäisjakamista.
Tämän jälkeen voidaan selvittää, onko suoritusmallin teho riippuvainen muisti-
rajapinnan nopeudesta vai datan prosessoinnin tehokkuudesta. Jos ohjelma odottaa
datan siirtoa keskusmuistista suorittimeen pystyen käsittelemään kaiken, ongelma
suurenee useamman ytimen tapauksessa. Toisin sanoen, useammalla säikeellä
prosessointi verrattuna yhteen säikeeseen vain hidastaa käsittelyä, mikäli sovellus on
muistivallin rajoittama. Tätä ajatellen Luotteenkin komentojen läpisyöttösilmukka
(CommandQueue) on suunniteltu aluksi yksisäikeiseksi.
5.4.2 Luotteen nopeusmittaukset ja profilointi
Edellisessä luvussa kuvatut ongelmat koskevat myös Luote-järjestelmää, kun suoritin-
elementtejä on käytössä useita tai suorittimien välimuistiin siirrettävät datamäärät ovat
suuria. Tällöin esimerkiksi komentojen ja liipaisimien ei tulisi siirtää tai sisältää suuria
määriä dataa, tai ainakin niiden pitäisi välttää jakautumista useamman suorittimen
välimuistiin.
Toisaalta suoritinarkkitehtuurinkaan tunteminen ei välttämättä vielä takaa kuorman
tasaista jakautumista suorituselementeille ja siten läpisyöttötehon maksimaalisuutta tai
ennustettavuutta (tasaisuutta). Vaikka Luotteen tietorakenteet voidaan suunnitella
esimerkiksi profiloijan avulla siten, että samassa paikassa käytettävä data päätyy
oikeellisesti kunkin suorittimen samaan välimuistin lohkoon (datan paikallisuus ja
näennäisjakamisen estäminen) ja suoritettavan säikeen affiniteetti voidaan asettaa
jollekin tietylle suoritinelementille, käyttöjärjestelmä on kuitenkin yleensä edelleen
5 Luotteella tuotetun ohjelmiston toiminta 49
vapaa vuorontamaan säikeitä sekä jakamaan resursseja järjestelmän kannalta parhaalla
tavalla. Luotteen tapauksessa tällaista järjestelmän puolesta tapahtuvaa viemistä eri
suoritinelementeille tapahtuu erityisesti OnExit- ja OnEnter-funktiossa, koska ne
suoritetaan säiealtaassa.
Näiden asioiden tutkiminen panostamatta testiprojektiin ei kuitenkaan ollut tämän
työn puitteissa mahdollista, koska tutkiminen vaatisi useamman suoritusalustan eri
laitteisto- ja käyttöjärjestelmävaihtoehtoineen sekä oikean pelin. Pelien aiheuttama
kuorma voi olla lajityypistä ja käytetyistä ratkaisuista riippuen hyvin erilainen.
Käytännössä testauskustannukset olisivat siis suuret ja testausaika pidempi.
Muun muassa Thomas Scogland ym. (2008; ks. myös Friedman 2008) tutkivat eri
suoritinytimien välistä kuorman asymmetrisyyttä käytännön järjestelmissä
esimerkkinään I/O-toiminnot suhteessa muuhun järjestelmään. He raportoivat jopa 10–
15 prosentin tehonlisäyksestä yksinkertaisella, käyttöjärjestelmän lisäksi toimivalla
kuormantasauskirjastolla, joka pyrkii optimoimaan prosessien affiniteetin eri
suoritinelementeille. Scogland ym. (2008) viittaavat myös aiempiin tutkimuksiinsa, joissa
on todettu, ettei suorituselementtien symmetrisyys keskimäärin takaa symmetristä
suoritustehoa näiden elementtien kesken. Tämä riippuu huomattavasti muun muassa
käyttöjärjestelmän NUMA-tuesta (ks. Windows-järjestelmissä Microsoft 2009d).
Toisaalta kun edellä mainitut yleiset seikat ovat tiedossa, voidaan suuntaa antavasti
tutkia esimerkiksi muistin kulutusta, eri osajärjestelmien välistä ajankäyttöä ja
läpisyötön tasaisuutta sekä tehoa: esimerkiksi montako komentoa sekunnissa Luote
kykenee käsittelemään ennen kuin puskuri alkaa kasvaa komentojen jäädessä
pidemmäksi ajaksi käsittelemättä. Tämä tarkoittaa esimerkiksi jonkin algoritmisen
simulaation mittaamista ilman koko todellisen sovelluksen suoritustehon mittaamista.
Tällaista toimintamallia kutsutaan muun muassa suurteholaskennassa ytimen
mittaamiseksi (engl. kernel benchmarking eikä nimenomaan application benchmarking)
(mm. Sayeed ym. 2008). Tällainen mittaus on yleensä helppo rakentaa etenkin
toimialamallinnuksen tapauksessa – sovelluskohtaisin olettamuksin mittaustuloksia
voidaan myös tarkentaa. Esitän myöhemmin dataa myös erittäin yksinkertaisesta pelin
kaltaisesta tilanteesta.
Läpisyötön tehoa ja tasaisuutta suhteessa komentojen lukumäärään voidaan arvioida
karkeasti liitteen B mukaisella testiohjelmalla. Ohjelma lisää Luotteen jonoon sata tyhjää
käskyä (NullCommand) kuudessa sarjassa viivästyksillä 0 ms, 10 ms, 20 ms, 30 ms, 40 ms
ja 50 ja ms kolmessa eri jaksossa. Ensimmäisellä kerralla kaikki kuusi sarjaa lisätään ja
suoritetaan täydellä nopeudella (taulukossa 5-1 ”normaali”). Toisessa jaksossa lisäykset
tehdään noin puolitoistakertaisella nopeudella viivästysaikaan verrattuna, suhteessa 3:2
(taulukossa ”puoliviive”) ja viimeisessä jaksossa suhteessa 1:1 (taulukossa ”täysviive”).
Ajat on mitattu StopWatch-luokan10 (2009) palvelulla. Kun StateMachine kutsuu
komentoa, NullCommand.Execute kutsuu Thread.Sleep-funktiota (2009) simuloiden näin
funktion kutsussa kuluvaa, viivytettyä aikaa, joten commandLoop nukkuu noin vähintään
10
StopWatch-luokan tarkkuus ja resoluutio ovat laitteistoriippuvaisia eivätkä kovin tarkkoja, mutta se on tarkin .NET-kehyksen tarjoama, yleisesti käytössä oleva tapa ilman Windows-ytimen Performance Counter -palvelujen (2009) käyttöä.
5 Luotteella tuotetun ohjelmiston toiminta 50
tämän ajan. Mittausdataa ei ole näkyvissä tai liitteenä analyysissä sen runsauden vuoksi,
mutta taulukossa 5-1 on siitä johdettuja tunnuslukuja.
Taulukko 5-1: Luotteen läpisyötön mittausdataa.
Ensimmäiseksi voidaan havaita, että sarjojen huipukkuus ja vinous ovat suuret, kun
komennot eivät lisää viivettä Luotteen komentosilmukan suoritukseen. Varsinaisen
datan ja lähdekoodin perusteella tämän voidaan päätellä johtuvan Luotteen
CommandQueue-puskurin muistinvarauksen aiheuttamasta hienoisesta viiveestä
lisättäessä ensimmäistä komentoa, koska komentopuskurin käyttämä aika lasketaan
myös mukaan sarjakohtaiseen suoritusaikaan. Tästä voidaan edelleen päätellä, että
suorituksen tasaisuuden kannalta on otollista säätää komentopuskurin koko
keskimääräisen ajonaikaisen maksimikoon mukaiseksi muistinvarauksesta johtuvan
värinäefektin välttämiseksi.
Keskihajonta kasvaa tasaisesti normaali- ja puoliviivesuorituksessa. Tämä johtuu
siitä, että kumuloituva viive alkaa ensimmäisen komennon kohdalta nollasta, mutta
kasvaa tasaisesti ollen 100. komennon suorituksen loppuessa suurin. Varsinaisessa
testidatassa tämä näkyy komentokohtaisesti kunkin komennon viipymisenä puskurissa
kauemmin kuin sitä ennen lisätyt – eli puskuriin kertyy komentoja nopeammin kuin
normaali puoliviive täysviive normaali puoliviive täysviive
0 ms 100 100 100 79,5449 75,0284 100
10 ms -1,1988 -1,189 31,2749 -1,1998 -1,1921 47,4177
20 ms -1,1988 -1,3042 21,3971 -1,1998 -1,1998 -2,026
30 ms -1,2015 -1,2354 56,6901 -1,1972 -1,2 0,1885
40 ms -1,2012 -1,1996 39,2468 -1,1992 -1,2002 -0,9333
50 ms -1,1997 -1,1996 12,8065 -1,2 -1,1999 15,8958
0 ms 10 10 10 8,6114 7,814 10
10 ms 0,0008 0,0137 5,4439 -0,0002 0,0006 6,962
20 ms -0,001 0,0456 4,5435 -0,0004 0,0001 0,1221
30 ms 0,0004 0,0086 6,3333 -0,0025 -0,0003 0,5525
40 ms -0,0017 -0,0055 5,9322 -0,0016 -0,0001 -0,1483
50 ms 0,0015 0,0012 3,5065 0 -0,0013 4,1926
0 ms 0,5 1 1 0,5257 0,5411 0,5
10 ms 311,6579 142,0026 0,4606 311,5517 140,7864 0,1407
20 ms 595,1787 311,3854 2,4955 594,8641 283,3104 1,0032
30 ms 878,9355 429,3355 0,7017 878,9809 424,9785 0,4777
40 ms 1163,441 564,134 3,6221 1162,2222 0 0,5505
50 ms 1471,5639 735,9115 0,3333 1473,1615 736,6662 0,219
0 ms 0,0208 10 10 0,1288 0,1349 0,1639
10 ms 0,574 0,5673 0,0456 0,5759 0,5611 0,014
20 ms 0,5734 0,5881 0,1213 0,5748 0,5628 0,0479
30 ms 0,5749 0,5699 0,0234 0,5734 0,563 0,0158
40 ms 0,5748 0,5623 0,0895 0,5745 0,5631 0,0136
50 ms 0,5737 0,5636 0,0067 0,5746 0,5634 0,0044
Testikone BH
uip
ukk
uu
sV
ino
us
Kes
kih
ajo
nta
Var
iaat
ioke
rro
inTestikone A
5 Luotteella tuotetun ohjelmiston toiminta 51
niitä suoritetaan. Mitä suurempi on komennon suoritusviive, sitä suurempi on myös
koko sadan komennon sarjan keskihajonta.
Keskihajonta on myös suurin kummallakin testikoneella, kun komennot lisätään
puskuriin mahdollisimman nopeasti. Kummallakin testikoneella keskihajonta puolittuu,
kun komennon lisäämisen jälkeen odotetaan noin puolet edellisen komennon suori-
tukseen kuluneesta ajasta. Keskihajontaa suoritusajoissa ei esiinny käytännössä lainkaan,
kunhan ennen seuraavan komennon lisäämistä on odotettu edellisen suoritus.
Nämä olivat suoran puskuria iteroivan silmukan tapauksessa melko odotettuja
tuloksia, mutta on huomattavaa, että kahden ja yhden ytimen välillä ei suoritusajassa ole
eroa normaali- ja puolinopeustesteissä. Raakadatassa yksittäisten komentojen
suoritusajat ovat liki samat, joten suoritusta dominoi selvästi yksittäisten komentojen
suorituksesta syntyvä viive. Johtopäätöksenä voidaan esittää, ettei tässä tapauksessa
useammasta suoritinelementistä ole hyötyä.
Tämän testin tapauksessa kannattaa kuitenkin huomata myös, että yksittäisten
suoritinelementtien kellotaajuus on lähellä toisiaan, mutta ydintä kohden käytettävissä
olevan välimuistin määrä on yksiytimisen koneen eduksi. Joko tämän testin tapauksessa
välimuistin määrällä ei ole ratkaisevaa merkitystä tai ero tasoittuu kaksiytimisen
suorittimen hivenen suuremman kellotaajuuden ansiosta. Oma merkityksensä on myös
suorittimen käskykannalla, jota .NET-kehyksen JIT-arkkitehtuuri voi käyttää uudempien
suorittimien tapauksessa paremmin hyödykseen.
Variaatiokertoimen11 arvot ovat melko tasaisesti 50 prosenttia eri jaksojen kesken
huomioimatta täyden viiveen jaksoja. Yhdessä edellisten kappaleiden ja varsinaisen
raakadatan perusteella suoritusajan voidaan päätellä kasvavan melko tasaisesti, koska
suoritusaika kasvaa ja hajonta on tasaista keskiarvon suhteen. Täyden viiveen sarjoissa
todellinen data näyttää, että komennon puskurissaolo- ja suoritusaika on lähes
poikkeuksetta sama kuin yksittäisen komennon viiveen aika. Tätä havaintoa tukee myös
variaatiokertoimen suhteellisen pieni, muutamien prosenttiyksiköiden, poikkeama. Eli
edellinen komento on suoritettu juuri ennen kuin seuraava lisätään puskuriin, jolloin sen
ei tarvitse odottaa suoritusvuoroaan.
Lisäksi huipukkuudesta, keskihajonnasta ja variaatiokertoimesta voidaan päätellä,
että mikäli puskuriin lisätään komentoja korkeintaan niiden suoritukseen kuluvalla
nopeudella, niiden keskimääräinen puskurissaoloaika on muuttumaton. Eli puskuri ja
tarkistustoiminnallisuus ei itsessään lisää merkittävästi (satunnaista) kuormaa
varsinaisen suorituksen lisäksi (eli ei myöskään tehdä kutsuja käyttöjärjestelmän
ytimeen). Tässä testissä ei testattu satunnaisia komentojen testausaikoja, joilla komento-
puskuri esimerkiksi täyttyisi ja tyhjenisi satunnaisesti. Puskurin kasvun värinät-
tömyydestä voidaan kuitenkin päätellä, ettei ainakaan kasvun pitäisi aiheuttaa
odottamatonta epävakautta.
Nämä suoritusaikatestit eivät vielä itsessään kerro, mihin ohjelman osiin suoritusaika
kuluu, eikä testiohjelma testannut suoritusta aidossa ympäristössä. Tätä varten on testi-
11 ”Variaatiokerroin määrittää havaintoarvojen suhteellisen hajonnan ja se ilmoitetaan tavallisesti
prosentteina. Variaatiokerroin (%) osoittaa siis kuinka monta prosenttia havaintoarvojen keskihajonta on havaintoarvojen keskiarvosta.” (Tilastokeskus 2009).
5 Luotteella tuotetun ohjelmiston toiminta 52
ohjelma, jossa on kolme tilaa. Pallo liikkuu ohjelmassa satunnaiseen suuntaan ja
törmätessään reunaan siirtyy tilaan HIT ja tulostaa OnEnter-takaisinkutsu-funktiossa
siirtymästä tiedon (”Ball transitioned to HIT state”) ruudulle. Samoin pallo tulostaa
siirtyessään NORMAL-tilaan (”Ball transitioned to NORMAL state”). Lisäksi demo-
ohjelma lähettää pallon osuessa kuvan seinämään RandomCommand-komennon, joka
tulostaa tekstin ”Random command fired!”. Kuva 5-11 on ruudunkaappaus testi-
ohjelmasta.
Kuva 5-11: Luote demo -ohjelma resurssienkulutuksen jakautumisen mittaamiseksi.
Profilointi tehtiin JetBrainsin dotTrace 3.1 -kokeiluversiolla. Koska tilastollisen datan
koostaminen tästä profilointidatasta on hankalaa eikä välttämättä mielekästäkään on
kuvassa 5-12 esitetty tyypillinen tulos suorittimen käytöstä kahden minuutin testistä
kahden ytimen suorittimella (ks. liitteen A testikone B).
5 Luotteella tuotetun ohjelmiston toiminta 53
Kuva 5-12: Tyypillinen Luote-demon profilointiajon tulos.
5 Luotteella tuotetun ohjelmiston toiminta 54
Kuvasta on havaittavissa suurimmat ajankäyttäjät säikeittäin. Demo-ohjelman
tapauksessa se on CommandQueue, koska se on aina aktiivinen. Profilointidatasta on
nähtävissä, että säie nukkuu suurimman osan ajasta (5792 ms 7782 ms:sta) odottaen
lisättäviä komentoja. Seuraavaksi eniten aikaa vie MoveCommand-komennon palloa
liikuttava Execute-funktio. Tämä funktio simuloi myös 10 ms:n viivettä
”pelitapahtumina”, jottei pallo liikkuisi liian nopeasti. Muistinkulutuksen osalta Luote on
hyvin vaatimaton, joskin tarkkoja lukuja on hankala saada edes dotTracen
muistiprofiloinnilla. Profiloijadatasta ei käy ilmi, mutta Execute-kutsuja tehtiin
tyypillisen ajon aikana noin 5500–6500 – eli näin monta kertaa pallo keskimäärin liikahti
(noin 18–21 ms välein) kahden minuutin testiajon aikana.
Etenkin sovellettaessa Luotetta useisiin eri ympäristöihin, joissa on tuntematon
määrä jaetun välimuistin suorittimia, olisi oleellista arvioida suorituskykyä myös ilman
simulointia ja varsinaista laitteistoa. Suurin suorituskykyyn vaikuttava tekijä on
todennäköisesti jo aiemminkin todettu muistihierarkia ja muistiväylän riittävyys, ellei
pelikohtaisesti esimerkiksi liipaisinten tai komentojen suorittaminen sisällä raskasta
laskentaa välimuistiin mahtuvalla datalla. Tämä on kuitenkin epätodennäköistä.
6 Tulokset ja päätelmät
Toimialamallinnus vaikuttaa toimivalta tavalta kuvata toimialatieto ja -tavoitteet
ohjelmistoratkaisuiksi. DSL Tools oli kuitenkin toteutustyökaluna jonkin verran
keskeneräinen. Työssä esitetty ratkaisu sisältää piirteitä, joissa jatkuva-aikainen
simulaatio käännetään rajapinnan avulla diskreeteiksi viesteiksi hallittavampien
käsittelyominaisuuksien saamiseksi. Lisäksi vaikuttaa siltä kuin alemman tason
toimialaratkaisut kannattaisi kuvata jollain hyvin määritellyllä, alemman tason tekoälyn
kuvaamiseen soveltuvalla kielellä ja tehdä graafinen kieli hyödyntäen tällaista kieltä.
Toisin sanoen vaikuttaa siltä, että kannattaisi ratkaista joitakin horisontaalisia ongelmia
omalla kielellään ja rakentaa tämän abstraktion päälle vertikaalinen kieli.
6.1 Luotteen arviointi
Toimialakielten arviointiin on kehitetty joitakin menetelmiä. Muun muassa Paige
ym. (2000) kuvaavat yhdeksän arvioinnin periaatetta, jotka on esitetty ja selitetty
taulukossa 6-1. Arviointi on kuitenkin hankalaa, koska Luote on prototyyppitoteutus
mahdollisuuden, työmäärän ja esiin nousevien ongelmien kartoittamiseksi eikä sen ole
varsinaisesti ollut tarkoituskaan olla tuotantokäyttöön tarkoitettu kieli.
Myös Haugen ja Mohageghi (2007) kirjoittavat tärkeistä ominaisuuksista
toimialakielelle. He näkevät tärkeiksi asioiksi muun muassa kielen visuaalisen
käytettävyyden sekä semanttisen formaaliuden. Kielen visuaalinen ilmaisuvoima on
tarkoitukseensa soveltuva prototyyppimielessä, koska kieli luottaa tässä suhteessa
maallikoillekin melko tuttuun ”pallukat ja nuolet”-esitykseen eikä ole järin korkealla
tasolla. Kielen ei voida kuitenkaan katsoa olevan sopiva korkeamman tason käsitteiden
esittämiseen, koska se tukee huonosti esimerkiksi käsitteiden koostamista laajemmiksi
käsitteiksi ilman, että ohjelmoija tekee tämän koostamisen ja tulos liitetään sellaisenaan
elementtinä kieleen.
Kieli on hyvin formaali, koska sen suoritusmalli nojaa erityisiin vahteihin ja
komentoihin, jotka voidaan nostaa ohjelmakoodista sellaisenaan käytettäväksi editoriin.
Suoritusmalli on yhtä formaali kuin lähdekoodin standardin antama määritelmä, joten
tässä mielessä Luotetta voidaan pitää translationaalisena kielenä. Näin voidaan ajatella,
että suurin ongelma on käytännössä dokumentoida kunkin komennon ja vahdin
toiminta siten, että suunnittelija ymmärtää sen.
6 Tulokset ja päätelmät 56
Taulukko 6-1: Yhdeksän ominaisuutta toimialakielen arviointiin.
Ominaisuus Luote
Yksinkertaisuus: kieli ei sisällä
tarpeetonta monimutkaisuutta.
Luote ei sisällä tarpeetonta
monimutkaisuutta. Tämä johtuu myös
siitä, ettei abstraktiotaso ole erityisen
korkea ja kielessä on vähän elementtejä.
Yksikäsitteisyys: kieli ei sisällä
päällekkäisiä ominaisuuksia.
Kieli ei sisällä päällekkäisiä ominaisuuksia.
Yhteneväisyys: kielen ominaisuudet
tukevat toisiaan tavoitteen
saavuttamiseksi.
Kielen ominaisuudet tukevat toisiaan
tavoitteiden saavuttamiseksi. Toisaalta,
Luote on melko matalan tason
horisontaalinen kieli.
Palautuvuus: muutokset tuotettuun
ohjelmakoodiin heijastuvat myös malliin.
Vipunen ei huomioi millään tavalla
ohjelmakoodiin tehtyjä muutoksia. Luote
on suunniteltu siten, että se
vuorovaikuttaa muun ohjelmiston kanssa
sidontojen välityksellä (takaisinkutsuilla).
Teoriassa on kuitenkin mahdollista, että
Vipunen lukee kielirajapintojen avulla
projektin lähdekoodin ja tarkkailee
muutoksia esimerkiksi sidontoihin.
Skaalautuvuus: yhtä lailla sekä pieniä
että suuria järjestelmiä voidaan
suunnitella.
Erittäin suurissa järjestelmissä
skaalautuvuus kärsii, koska Luote on
melko matalan tason vertikaalinen kieli.
Tuettavuus: kieli on käytettävä sekä
ihmisille että työkaluille.
Vaatimus toteutuu.
Luotettavuus: kieli kannustaa tekemään
luotettavia ohjelmistoja.
Vaatimus toteutuu
Ytimekkyys: mallit ovat ytimekkäitä. Vaatimus toteutuu.
6.2 Käytännön kokemuksia ja huomioitavaa
Toimialatyökalun rakentaminen on melko työlästä huolimatta siihen tarkoitettujen
työkalujen käytöstä. On kuitenkin selvää, että editorin tuottaminen automaattisesti on
nopeampaa kuin sellaisen tekeminen itse. On myös kiistatta selvää, että toimialan
sisäisen metamallin rakentaminen siihen tarkoitetulla työkalulla on nopeampaa,
selkeämpää ja ylläpidettävämpää kuin vastaavan rakentaminen itse tai toimimalla
ohjelman rakenteeseen rakentuvan, implisiittisen toimialamallin kanssa. On myös
todennäköistä, että eri toimialamallien yhdistäminen yleisesti hyväksyttyjen esitys-
6 Tulokset ja päätelmät 57
tapojen (mm. skeeman määritykset) ja työkalun avulla on tuottavampaa kuin yhdistää
eri esitystapoja, joiden metamalleilla ei ole rakenteellista yhteensopivuutta.
Vaikuttaa myös siltä kuin alemman tason toiminnallisuus kannattaisi rakentaa
tekstuaalisesti eikä graafisesti. Monet pienet yksityiskohdat soveltuvat paremmin
tekstuaaliseen esitykseen graafinen esityksen ollessa parempi laajojen kokonaisuuksien
käsittelyyn. Vastaavanlaisessa työssä kannattanee keskittyä rajaamaan hyvin muun
ohjelmiston ja toimialamallinnuksesta tuotettavien teennösten rajapinta sekä aivan
konkreettisen ohjelmakoodin että myös rajapintasopimusten ja toimintamallien tasolla.
Pohdin näitä vuorovaikutussuhteita työssäni erityisesti rinnakkaisen suoritusmallin
näkökulmasta päätyen aiemmin kuvattuun tilojen, liipaisimien, komentojen ja jonon
avulla tapahtuvaan vuorovaikutukseen. Vaikka rinnakkaisuus on hallittavissa, sen
lisääminen automaattisesti ja tehokkaasti etenkin uusien suoritusresurssien tullessa on
edelleen hankalaa käsityötä. Lisäksi suoritusmalli ja rajapintasopimukset ovat melko
implisiittisiä, vaikkakin helposti integroituvia.
Toimialamallin vaativimman työn pitäisi olla sen määrittäminen, ei sen käyttämiseen
tarkoitetun työkalun rakentaminen. DSL Tools, oli melko kankea ja rajoittunut.
Esimerkiksi kielen graafista ulkoasua ajatellen, sisäkkäisten elementtien tuki on rajattu
kahteen elementtiin eikä tässäkään työssä tilojen graafiseen esitykseen käytetyissä
CompartmentShape-luokissa ole lainkaan tukea sisäkkäisille elementeille. Tällöin ei ollut
muun muassa mahdollista listata liipaisimia tilojen sisään ja näiden liipaisimien sisään
niiden komentoja, vaan ainoaksi vaihtoehdoksi olisi jäänyt tekstuaalinen syntaksi.
DSL Toolsin ongelma on, että se on rakennettu Visual Studio 2008:n COM-kerroksen
päälle, joka itsessään on laajennusarkkitehtuuri Visual Studion ydintoiminnallisuuden
ympärille. Oman laajennuksen, tässä tapauksessa Vipusen, tekeminen laajennuksen
päälle on suhteettoman vaikeaa. Ongelma on yleisesti tunnustettu DSL Toolsin
tapauksessa. Edelleen merkittäviä ongelmia syntyy myös mallista tuotettavista
teennöksistä. Metamallin syöttäminen T4-prosessointikielelle ei ole erityisen joustavaa,
vaikka T4 itsessään on melko selkeä ja joustava. Nämä ongelmat luovat ongelman
rajapintojen käytettävyyden kannalta jyrkentäen oppimiskäyrää ja lisäten siten
huomattavastikin kehityskustannuksia.
Edellä mainitut ongelmat ovat sikäli tärkeitä, että ne vaikuttavat myös syntyvän
kielen ja toimialamallin suunnitteluun – niihin ei jää kylliksi aikaa. Yleensä projektin
reunaehdot asettavat rajoitteita kustannuksille ja henkilöstön käytölle. Siten DSL Toolsin
tapauksessa juuri ne seikat, joita sen pitäisi ratkaista, aiheuttavat ehkä liiankin suuria
ongelmia. Luotteen ja Vipusen tapauksessa editorin tekemiseen meni selvästi kauemmin
kuin itse järjestelmän suunnitteluun, huomioiden monipuolisen toiminnan
(rinnakkaisuus, virheiden jäljitettävyys, erityyppisien tekoälyn standardialgoritmien
käyttämisen huomioiminen, testaus ja niin edelleen), tehokkuuden ja laajennus-
vaatimukset.
Erityisesti editorin tekemisen yhteydessä oli ratkottava tai kierrettävä kiusallisia
ongelmia. Tässä olivat suurena apuna Microsoftin ohjelmistokehitysfoorumit. Kuitenkin
pelkästään editorin tekemiseen kului aikaa noin kolmen viikon työpanoksen verran.
6 Tulokset ja päätelmät 58
Tämä on saavutettuun tulokseen nähden melko paljon, koska editorikehyksen olisi
periaatteessa pitänyt suoraan tukea kaikkea suunnittelemaani toiminnallisuutta.
Joulukuussa 2008 ilmenikin, että Microsoft kohdistaa DSL Tools -kehityksen
tarkemmin muun muassa Visual Studio Team Architectin toimintoihin (Kent 2008) ja
korvaa alkuvaiheessa erityisesti tekstuaalisten toimialakielten kehityksen Oslo-alustalla
(Microsoft 2009e), joka ilmeisesti on paremmin suunniteltu eikä kärsi (kaikista) samoista
ongelmista (Short 2008). Visual Studio 2008:n COM-kehyksen laajentamisesta johtuvien
ongelmien voidaan ajatella helpottuvan Visual Studio 2010:n perustamisesta Managed
Extensibility Frameworkin (MEF) käyttöön, jolloin kehitystyö tapahtuu .NET-kirjastojen
eikä COM-laajennosten avulla. Visual Studio 2010 hyödyntää myös Windows
Presentation Foundationin (WPF) käyttöliittymäparadigmaa, jota yleisesti pidetään
joustavana ja monipuolisena teknologiana.
6.3 Välittömät lisäominaisuudet
Luotteen rakenteellinen ratkaisun toimivuus ei rajoitu vain C#-kieleen tai JIT-
käännökseen, vaan sama rakenne toimii myös tuotettaessa C++-koodia. Tällöin ratkaisu
perustuisi todennäköisesti joko libsigc++-kirjastoon (Cumming ym. 2009), Boost.Signals-
kirjastoon (Gregor 2004) tai erittäin tehokkaana pidettyyn Impossibly Fast Delegates
-tyyliseen (Ryazanov 2005) ratkaisuun.
Binäärikoodiksi kääntäminen on käytännön välttämättömyys, koska esimerkiksi
konsolialustoilla virtuaalikoneiden käyttämisen esteenä ovat ilmeiset resurssiongelmat.
Toisaalta, peleissä on tarve erillisen muistinhallinta- ja I/O-rutiinien toteuttamiselle ja
näiden liittämiselle väliohjelmistoihin. Tämä on yleensä helpompaa C++-koodin
tapauksessa, koska lähes kaikki väliohjelmistot on toteutettu C++:lla. Samalla on
mahdollista toteuttaa tehokkaita optimointeja. Toisaalta, käännettävän ohjelmakoodin
tuottamisesta valmiiden kirjastojen sijaan on etuna, että symbolikonfliktien
säieturvallisuuden, muistinhallinnan12 ja laajennettavuuden toteuttaminen on
helpompaa. Nykyiset C++-kääntäjät myös optimoivat kääntämänsä lähdekoodin
tehokkaasti.
6.4 Muut vastaavat projektit tai tuotteet
Toimialamallinnuksen työkaluja tarjoavat muutkin tahot kuin Microsoft. Esimerkiksi
yleiseen ohjelmistokehitykseen työkaluja tarjoavat jyväskyläläinen MetaCase (MetaCase
2009) (MetaEdit+) ja Eclipse Foundationin Generic Eclipse Modeling System (GEMS
2009). Työni kannalta olisi ollut kiintoisaa verrata tekemiäni ratkaisuja saman toimialan
SpirOpsin (2009) tai Xaitmentin (2009) tuotteisiin. Näiden lisäksi erittäin käytetty
työkalu on Autodeskin (2009a) Kynapse, joka integroituu myös muihin Autodeskin
tuotteisiin, kuten Mayaan (Autodesk 2009b). Julkaisin työstäni myös kehitysversion AI
12
Jokainen enemmän C++-ohjelmointia tekevä on varmaan törmännyt näihin ongelmiin, etenkin eri prosesseissa tai säikeissä tapahtuvan muistin varaamisen ja vapauttamisen ongelmaan.
6 Tulokset ja päätelmät 59
Game Developer’s -foorumilla (Eeva 2008) kerätäkseni palautetta ja mahdollisia
vertailuja näihin muihin tuotteisiin. Valitettavasti en saanut palautetta, mutta kiintoisia
keskusteluja toimialamallinnuksesta ja erilaisten psykologisten mallien käyttämisestä
kuitenkin.
SpirOpsin tai Xaitmentin tuotteista on kuitenkin saatavilla vain niukasti materiaalia
vertailua varten (ehkäpä syynä on yritysten nuoruus). Xaitment tarjoaa työkalunsa
ilmaiseksi ei-kaupalliseen käyttöön, mutta aikataulullisista syistä en voinut tehdä
vertailua. Kummatkin näistä tuotteista ovat kuitenkin tuoteperheitä, jotka sisältävät
erilliset työkalut tekoälyn eri osa-alueille. Tästä on mahdollista päätellä ainakin, että
nämä editorit mallintavat jotain tekoälyn osa-aluetta eivätkä siten ole monoliittisia
järjestelmiä.
Edellä mainituista seikoista ei kuitenkaan käy ilmi, onko työkalut rakennettu
erityisellä toimialatyökalulla. Ei ole myöskään mahdollista päätellä, käyttävätkö nämä
työkalut jotain eksplisiittistä metamallia tekoälyn esittämiseksi eri editorien ja
työkalujen kesken, jolloin kukin editori olisi vain omanlaisensa näkymä tähän tietoon.
On kuitenkin todennäköistä, että nämä tuotteet perustuvat erilaisiin kirjastoratkaisuihin
ja näiden integrointiin eikä varsinaisen lähdekoodin tuottamiseen ja kääntämiseen
kohdeprojektin osana.
Samanaikaisesti tämän työn kanssa julkaisi Gamasutra John Krajewski’n (2009)
artikkelin Creating All Humans: A Data-Driven AI Framework for Open Game Worlds.
Artikkeli kertoo Pandemic Studiosin ja Toy Headquartersin vuonna 2006 julkaiseman
Destroy All Humans! 2 -pelin (DAH2) tekoälyn kehittämisestä. Artikkelissa kirjoitetaan
Pandemic Studiosin pyrkineen ratkaisemaan ongelman, jota tässäkin työssä on pyritty
ratkaisemaan: luoda helposti avoimeen maailmaan agenteille aidontuntuisia ja
laajennettavia käyttäytymismalleja. Toki tavoitteena on varmasti ollut alentaa kokonais-
projektikustannuksiakin, mutta artikkelissa ei ainakaan mainita laajempia toimiala-
mallinnukselle ominaisia tavoitteita tai piirteitä.
Karkealla tasolla Pandemic Studiosin DAH2:n ratkaisu on ajonaikainen dataohjaus,
missä käyttäytymissäännöt ladataan pelin toimijoille tulkittavaksi (emt.). Ero
Luotteeseen on, että Luote tuottaa nimenomaan käännettävää lähdekoodia (mikään ei
tosin estä luomasta ohjelmakoodia datan lukemiseksi). Myös tässä ratkaisussa käytetään
erityisiä esiehtoja Luotteen liipaisimien tapaan, joiden täytyy olla voimassa ennen kuin
varsinaisia toimintoja suoritetaan (emt.). Toteutus on kuitenkin melko erilainen.
DAH2:n toiminnot ovat riippumattomia superyksiköitä, jotka tietävät milloin ne
aktivoituvat ja toimivat, milloin ne lakkaavat toimimasta, mikä ne voi keskeyttää ja mitä
tapahtuu niiden aktivoituessa tai deaktivoituessa. Toiminnot on ratkaisussa järjestetty
puugraafeiksi, joiden osia voi myös korvata ajonaikaisesti ja joissa ylemmän tason solmut
voivat kutsua alemman tason toimintoja priorisoidussa järjestyksessä. Artikkelissa
korostetaan mahdollisuutta valita joitakin toimintoja myös satunnaisesti tai suoritus
joko sarjallisesti tai rinnakkain. (Emt.)
Tältä osin DAH2:n ratkaisu eroaa tässä työssä esitetystä, jossa toimintoja ei voi
muuttaa ajonaikaisesti, korkeintaan vaihtaa toisiin. Toisaalta, komennot ja liipaisimet
voivat vaihtaa sisäistä toteutustaan tai ketjuttaa toimintoja osista; liipaisimet voivat
6 Tulokset ja päätelmät 60
vaihtaa tai ketjuttaa liipaisuehtojaan tai komennot voivat vaihtaa sisäistä toteutustaan.
Myös suoritettavia toimintoja voi valita ajonaikaisesti, mutta mikäli valinta halutaan
tehdä priorisoidusti, käytännössä tällaisia tilanteita varten joudutaan tekemään aina
omanlaisensa liipaisin. Liipaisin voi olla myös dataohjattu.
Muut toiminnot voidaan Luotteessa toteuttaa kutsumalla liipaisimista ja
komennoista mitä tahansa ohjelmakoodia aivan normaalisti. Toiminto voidaan
keskeyttää esimerkiksi toiminnolla, jonka on erityisesti tehty keskeyttämään muita
toimintoja. Toiminnot voivat myös valvoa itse suorituksensa aikana niiden mahdollisia
keskeytysehtoja tai suorittaa muiden toimintojen keskeytyksen omien toimintojensa
ohessa. Koska kaikki tekoälysuoritus käytännössä tapahtuu hyvin määritetyssä
ympäristössä, CommandQueue-jonossa ja StateMachine-luokassa, komentojen voidaan
jopa antaa tehdä hakuja tähän jonoon. Satunnaisuus ja rinnakkaistoiminnallisuus ovat
myös helppoja toteuttaa.
Työssä esitettyä prototyyppiratkaisua voidaan pitää kattavampana ja tehokkaampana
kuin DAH2:ta toiminnallisesti samaan tarkoitukseen luotua. Krajewski’n (emt.)
artikkelista voi päätellä, etteivät toimialatyökalut olleet kyllin tunnettuja eivätkä
käytettyjä vielä vuonna 2006 tai aiemmin, jolloin DAH2:ssa käytettyä ratkaisua
todennäköisesti jo luotiin. Tämän voi päätellä siitä, ettei artikkelissa ainakaan mainita
mitään ongelman mallinnuksesta työkaluja käyttäen tai työkalutuen käyttämisestä
muutoinkaan esimerkiksi editorien tekemiseen mallin pohjalta. Teknisin perustein
kaiken DAH2:n toiminnallisuuden voi suorittaa myös Luotteessa – ja toisinpäin, mutta
ainakin artikkelissa (emt.) annettujen tietojen perusteella vaikuttaa siltä, että DAH2:n
ratkaisu on tehottomampi datan ajonaikaisen tulkkauksen vuoksi ja Luotteeseen
verrattavien ominaisuuksien luonti on vaivalloisempaa kuin lisätä Luotteeseen DAH2:n
toiminnot. DAH2:n suorituskyvystä ei kuitenkaan ole julkista tietoa.
Erityisesti DAH2:n tapa rakentaa toiminnallisuus melko puhtaasti hierarkkisten
tilakoneiden varaan toiminnallisesti vaikuttaa hankalammalta kuin Luotteen tapa
käyttää ”tiloja” vain hallittuna ja hyvin rajattuna kosketuspintana muuhun sovellukseen.
Lisäksi Luotteen suoritusmalli vaikuttaa paremmin rajatulta ja helpommin
laajennettavalta. Erityisesti vaikuttaa siltä kuin Luotetta olisi helpompi päivittää uusien
ominaisuuksien osalta ennustettavammin ja rajatummin sekä analysoida muutoksia
hallitummin. Tällaisen päätelmän voi tehdä siitä, että DAH2:n ratkaisussa tilakoneet
sisältävät toiminnallisuutta, jolloin sen laajentaminen on hankalaa useiden
riippuvuuksien vuoksi. Ongelmana voidaan ajatella olevan myös tapa toimia
tilakoneiden varassa, jolloin todennäköisesti seuraa suuren tilamäärän syntyminen ja
tästä johtuva hankala hallittavuus.
6.5 Päätelmät
Pelinkehityksessä on tarpeen huomioida niin immersiivisen tarinan välittäminen
yleisölle kuin sen tuottaminen teknisestikin, taloudellisella tavalla. Tekoälyn ja tarinan
tuottaminen on monisyinen ongelma, johon on kaksi selkeää pääsyytä: videopelien
tekoälyn kerronnallisille elementeille ei ole selkeää termistöä ja teknisesti tekoälyn
6 Tulokset ja päätelmät 61
tuottaminen on tällä hetkellä joukko tapauskohtaisia, yksittäisiä tarpeita varten
sovellettuja tekniikoita. Videopelien termistön ja yhteisen kielen puute ei helpota ei-
teknisten tavoitteiden viestimistä tekoälyohjelmoijille ja siten niiden toteuttamista
ohjelmallisesti. Erityisesti tekoälyn ja kerronnan tuottaminen ohjelmallisesti on
hankalaa. Kielen ja termistön ongelma on odotettavissa, koska tekoälyn sovelluskohteet
ovat kaikilla elämän aloilla, joilta pelitkin saavat vaikutteensa.
Teknisesti vaikuttaa siltä kuin yleisesti peleissä olisi joukko itsenäisiä toimijoita,
joiden täytyy viestiä keskenään ja yleisesti pelin muiden alijärjestelmien kanssa. Tässä
viestinnässä on oleellista huomioida viestien aikajärjestys, viestijöiden ehkä
epätäydellinen tilannekuva niiden ympäristöstä sekä rajallinen aika vasteen tuot-
tamiseksi vastaanotettuihin viesteihin. Aikarajoitteesta johtuen toiminnan on oltava
suorituskykyistä ja pystyttävä tarvittaessa tuottamaan käyttökelpoisia osatuloksia.
Toiminta saattaa olla myös tarpeen perua tai vaihtaa toisenlaiseen.
Toimialamallinnus on ohjelmistoteollisuudessa yhä käytetympi menetelmä toimiala-
asiantuntijoiden erityistiedon järjestelmälliseen viestintään ohjelmistosuunnittelijoille, ja
tämän tiedon kuvaamiseksi edelleen ohjelmistoteennöksiksi. Toimialamallinnus
vaikuttaa myös menetelmältä, jolla voi kuvata ja yhdistää eri toimialojen rakenteita
toisiinsa – sen menetelmin voi yhdistää hallitusti (ja ilmeisen kustannustehokkaasti)
heterogeenisiä käsitteitä ja järjestelmiä. Nämä mallinnusmenetelmät vaikuttavat siis
toimivalta tavalta koontaa järjestelmällisesti pelitekoälyn käsitteistöä ja kuvata näitä
käsitteitä hallitusti ohjelmistoteennöksiksi.
Prototyyppijärjestelmän selvästi ratkaisua vaativa ongelma oli pelin eri toimijoiden
viestiminen keskenään (samanaikaisesti ja rinnakkaisesti) sekä pelin muiden osa-
järjestelmien kanssa aikaulottuvuus, kausaalisuus, huomioiden. Samanlaisesta
huomiosta kirjoittavat myös White ym. (2007) ja esittelevät yksinkertaisen kielen pelien
tekoälyhahmojen ohjaamiseen siten, että pelin sisäistä tilaa ylläpidetään tietokannassa.
He esittelevät samankaltaisen kehitysprosessin ohjelmoijien ja tekoälyn suunnit-
telijoiden välillä kuin Luotteen ja Vipusenkin suunnittelun lähtökohtana oli ja
päättelevät, että koska tietokantajärjestelmät on suunniteltu skaalautumaan, ne voivat
myös suorituskykyisesti tukea suurta määrää dataohjattuja hahmoja. Samalla tietokanta
ratkaisee ongelman jaettujen muuttujien yhtäaikaisen päivittämisen aiheuttamasta
epäyhtenäisestä tilasta. Ajatus on hyvä, muttei ota juuri kantaa tapahtumista seuraavien
tapahtumien vaikutuksiin, vaan käsittelee lähes ainoastaan datamuuttujien päivitystä
moniajoympäristössä.
Tällaiset tarpeet viittaavat myös moniagenttijärjestelmien parissa tehtävään
tutkimukseen. Akateemisesti tutkitut agenttijärjestelmät eivät ole kuitenkaan saaneet
peliteollisuudessa juuri sijaa. Mitään yleistä syytä tähän ei ole helposti havaittavissa.
Todennäköisimpiä syitä lienevät tutkimuksen keskittyminen melko vahvasti akatemiaan,
tuotettujen järjestelmien teoreettisuus ilman realistista käytännön toteutusta13 sekä
agenttijärjestelmien käytännön integroinnin vaikeus peliprojektien työkaluketjuun, kun
13
Kuten esimerkiksi teoreettisten ominaisuuksiensa takia suositussa BDI-arkkitehtuurissa ja AgentSpeak-toteutuksessa (Rao 1996), tosin yksinkertaisiin peleihin on sovelluksia, esimerkiksi Wumpukseen (Nowaczyk 2006).
6 Tulokset ja päätelmät 62
ne eivät myöskään todennäköisesti ole kyllin suorituskykyisiä (ylipäänsä muut kuin C++-
toteutukset ovat ongelmallisia). Erityisen visaiselta vaikuttaa pelitekoälyn toimiala-
ongelmien kuten tunteiden ja ”epävarmuuden” mallintaminen nykyisillä agenttikielillä.
Vipusen ja Luotteen tapaiset työkalut vaikuttavat päteviltä tavoilta lievittää ongelmaa
kuvaamalla korkeamman tason pelitekoälyn toimialakäsitteitä tapauskohtaisesti
esimerkiksi juuri agenttikieliin.
Toimiva ja Luotettakin muistuttava ratkaisu voisi olla hiljattain kehitetty Knowledge-
Goals-Plan-agenttijärjestelmä (KGP) (Kakas ym. 2008). KGP on abduktiiviseen
logiikkaan perustuva, modulaarinen, dynaamiseen ympäristöön kehitetty arkkitehtuuri,
jossa agenteille voi määrittää proaktiivisia ja reaktiivisia toimintoja. Abduktiivista
päätöksentekoa voi kuvata parhaan johtopäätöksen logiikaksi, jossa määritetystä
joukosta valitaan erilaisin rajoite-ehdoin toiminto epätäydellisen tiedon perusteella.
Järjestelmä on suunniteltu erityisesti dynaamisiin vuorovaikutustilanteisiin, joissa
agentit ovat määriteltyjen antureidensa avulla vuorovaikutussuhteessa toistensa ja
ympäristön kanssa. Yleisesti tutkittujen ja toteutettujen huomioi-suunnittele-toimi-
mallien (kuten BDI) sijaan KGP-mallissa on syntetisoitu useita laskennallisen logiikan
menetelmiä formaalisiksi, syklisiksi agenttien ylemmän tason toiminnoiksi seuraavasti:
huomioi, määrittele tavoite uudelleen, suunnittele, toimi;
huomioi, suunnittele, luotaa esiehdot, toimi;
huomioi, suunnittele, toimi, suunnittele, toimi. (Emt.)
Tämä muistuttaa Luotetta siten, että Luote huomioi ympäristön muutoksia
(signaalit), joiden perusteella liipaisimet ja komennot voivat reagoida esimerkiksi
aloittamalla suunnittelun tulevaa toimintaa varten tai tarvittaessa toimimalla
reaktiivisesti (erityisesti aina aktiiviset tilat). On erityisen huomattavaa, että
agenttikielten, kuten KGP:nkin, toimintojen kuvaamiseen käytetty kieli on toimialakieli.
Eräs abduktiiviseen logiikaan perustuva agenttijärjestelmä on CIFF, joka perustuu
laajentamalla Prolog-tulkkia muun muassa kyvyllä ymmärtää rajoitepredikaatteja
(Endriss ym. 2004). Tässäkin työssä kuvatun järjestelmän hengessä tällainen voidaan
rakentaa esimerkiksi kuvaamalla pelikoodin käsitteitä, kuten funktioita ja muuttujia,
Prologin atomeihin ja predikaatteihin. Alemman tason tekoälyprimitiivit voisi tällöin
ohjelmoida abduktiivisuutta tukevalla Prolog-koodilla uudelleen käytettäviin
moduuleihin, joihin puolestaan voisi kuvata pelitoimialan käsitteitä. Näin saavutettaisiin
joustavuutta Prolog-koodin käytön suhteen eri alustoilla esimerkiksi kirjastona tai
käännettävänä ja optimoitavana ohjelmakoodina. Prolog-moduuleja olisi myös helpompi
käyttää uudelleen, koska niiden liittäminen järjestelmiin ei todennäköisesti vaatisi
muuta kuin, että eri pelit noudattavat näiden moduulien rajapintasopimuksia, siis
liittävät predikaatteihin ja atomeihin oikeanlaiset peliohjelman rakenteet.
Pelin toimijoiden, agenttien, välinen viestintä ei kuitenkaan ratkaise kaikkia teknisiä
ongelmia. KGP:hen perustuva arkkitehtuuri14 vaikuttaa käytännölliseltä tavalta kuvata
järjestelmällisesti tekoälyn toimialakäsitteitä toimiviksi ohjelmistojärjestelmiksi. Se ei
14
Abduktiivisen logiikkaohjelmoinnin perusteoriaa on myös jo laajennettu (mm. Denecker & Eugenia 2007, 333).
6 Tulokset ja päätelmät 63
kuitenkaan ota kantaa muihin pelien osajärjestelmiin, kuten fysiikan ja grafiikan tuot-
tamiseen ja näiden järjestelmien kanssa viestimisen arkkitehtuuriin, jossa erityisesti
tietynmittaisten aika-askeleiden hallinta ja suorituksen tehokkuus ovat oleellisia
tekijöitä.
Nämä vaatimukset viittaavat diskreetteihin tapahtumasimulaatioihin ja niiden
parissa tehtävään tutkimukseen (huomaa tekoälyn ja simulaation yhdistäminen, System
for Parallel Agent Discrete Event Simulation (Riley 2003) (SPADES). Diskreeteistä
tapahtumasimulaatioista on jo olemassa olevaa tutkimusta soveltamisesta eri toimialoilla
ja tätä tietoa yhdistelemällä voisi olla mahdollista kehittää pelitekoälyynkin soveltuva
alusta. Oleellisilta vaikuttavat järjestelmät, joissa on pyritty ratkaisemaan jatkuva- ja
diskreettiaikaisen järjestelmien välinen vuorovaikutusongelma – Luotteenkin
suunnittelussa erityisesti vaikuttanut ongelma (vrt. tilarajapinta ja takaisinkutsut).
Pelien tekemistä diskreettien simulaatioiden näkökulmasta ei ilmeisesti ole juuri
tutkittu. Asiaa ehkä parhaiten (ja ainoastaan) peligrafiikan näkökulmasta ovat käsitelleet
García ym. (2004) sekä García ja Mollá (2006) prototyyppijärjestelmässään Game
Discrete Event Simulation Kernel (GDESK).
7 Yhteenveto
Päätavoitteeni oli kehittää IGDA AI SIG:n ohjelmajulistuksen mukainen yleiskäyttöinen
rajapinta pelitekoälyn vuorovaikutusrajapinnan standardoimiseksi muihin pelin
osajärjestelmiin. Tavoite oli yhtä hyvin määritelty integraatio kuin mikä on nykyisillä
grafiikkajärjestelmilläkin (sekä grafiikkaresurssien työkaluketjuilla). Perimmäinen syy
integraatiorajapinnan kehittämiseen on projektikustannusten vähentäminen. Tavoitteen
toteutuminen alkoi muuntamalla ongelman asettelu perinteisimmistä rajapinnoista,
kirjastoista ja väliohjelmistoista ajatukseen pelien tekoälyyn yleisesti soveltuvasta
metamallista, josta voisi tuottaa tarvittavan ohjelmakoodin. Tällä tavoin olisi mahdollista
myös säilyttää olemassa olevia, jo kehitettyjä ohjelmistoteennöksiä.
On ilmeistä, että tällaisen rajapinnan rakentamiseksi pelitekoälyn käsittelyyn on
luotava yhteisesti ymmärretty termistö. Pelitekoäly kuten tekoälykin on laaja ja osin
fakkiutunutkin ala eikä ole selvää, onko tällainen mahdollista – edes toimialan laajuuden
perusteella. Syntynyt käsitteistö täytyisi edelleen pystyä kuvaamaan yleisesti toimiviksi
ohjelmistoteennöksiksi, käännettäväksi ohjelmakoodiksi.
Toimialamallinnus on hiljattain enemmän näkyvyyttä saanut järjestelmällinen tapa
paitsi koontaa jonkin toimialan käsitteistöä, myös kuvata tämä käsitteistö
automaattisesti tuotetuksi ohjelmakoodiksi, jolloin tutkimusten mukaan tuottavuus on
lisääntynyt jopa sadoilla prosenteilla. Koska pelitekoälyn käsitteistö tarvitsee paitsi
koontamista myös kuvaamista käsitteistöstä ohjelmakoodiksi, toimialamallinnus sopii
myös pelitekoälyn järjestelmälliseen kehittämiseen ja siten kustannusten alentamiseen.
Työn tulokset tukevat näitä muilta toimialoilta saatuja johtopäätöksiä termistön
koontamisesta. Tulokset osoittavat myös alustavasti, että toimialamallinnuksella voi
tuottaa yleisesti toimivaa ohjelmakoodia tekoälyn tuottamiseksi peleissä. Työn
teknisyydestä johtuen termistön koontamisen tutkiminen oli kuitenkin rajoittunut
lähinnä huomioimaan viime aikojen tutkimustulokset ja hyödyntämään niitä tekoälyyn
liittyvän ohjelmakoodin tuottamisessa.
Teknisesti tulokset osoittavat, että pelitekoälyn teknisiä haasteita olisi hedelmällistä
tutkia diskreettien tapahtumasimulaattoreiden ja agenttiarkkitehtuurien (erityisesti
KGP:n) yhdistämisen näkökulmasta. Pelitekoälyn näkökulmasta keskeisiä ovat useat
keskenään toimivat viestijät, joiden toimien oikeellisuudelle on oleellista niiden viestien
kausaalisuussuhteiden säilyminen ja prosessointinopeus. Diskreettien tapahtuma-
simulaattoreiden tutkimus on tuottanut runsaasti tietoa tällaisista järjestelmistä.
Edelleen on selvää, että pelin toimijoiden viestintä täytyy ilmaista jotenkin formaalisti ja
ohjelmoitavasti, mukaan lukien ajallinen ulottuvuus. Tällaisesta viestinnän ajallisen
ulottuvuuden formalisoinnista on runsaasti tutkimustietoa erilaisten agenttijärjestelmien
yhteydessä, kuten abduktiivisesta logiikkaohjelmoinnista.
7 Yhteenveto 65
Pelitekoälyn rajapinta- ja termistöongelmaa ratkottiin toimialamallinnuksen hengen
mukaisesti yleisesti luomalla Luote-kielen ja määrittelemällä sen ajonaikaiset rakenteet.
Päätyminen tästä näkökulmasta diskreettien tapahtumien simulointiin ja agenttikieliin
vahvistaa viittaa niiden keskeisyyteen ongelman laajamittaisen teknisen ratkaisuperustan
luomisessa. Toimialamallinnuksen lisä vaikuttaisi olevan toimialakäsitteiden
koontaminen, formalisointi ja kuvaaminen agenttikielten rakenteisiin, jotka toimivat
simulointijärjestelmässä. Työni kuvaa myös eräänlaisen rajapinnan muun peli-
ohjelmiston jatkuva-aikaisen simulaation kääntämiseksi diskreettiaikaiseksi.
Tähän liittyvää tutkimusta ei ole vielä juuri olemassa. GDESK on järjestelmä, jonka
yhteydessä on tutkittu nimenomaan diskreettiaikaisen simulaation ja pelien
yhdistämistä grafiikan näkökulmasta. SPADES on järjestelmä vuorovaikutuksen
tutkimiseen diskreetissä tapahtumajärjestelmässä, muttei peleissä. Toimialamallinnus
tässä yhteydessä voi tarkoittaa paitsi ei-teknisten tekoälykäsitteiden kuvaamista
tällaiseen järjestelmään myös tapaa yhdistää erilaisia järjestelmiä hallitusti hyvin
määritellyn metamallin avulla. Tällä tavoin eri toimialojen simulaatiotietous olisi
mahdollista levittää peleihin (miksei myös yleisesti simulaatioiden välillä).
Jatkotutkimusaiheita voisivatkin olla pelien kerronnan elementtien koontaminen
puoliformaalisti siten, että tekoälysuunnittelija voi kuvata ne tapauskohtaisesti
formaalille agenttikielelle, joka edelleen toimii pelin tekoälyjärjestelmässä, joka voisi olla
peliympäristöön sovitettu diskreetti tapahtumasimulaattori. Tämä vaatii paitsi teknisesti
diskreettien simulaatiojärjestelmien ja agenttikielien myös pelien kerronnallisten
elementtien tutkimusta. Toisaalta, peleissä saatetaan käyttää useanlaisia alisimulaatioita
esimerkiksi talouden alalta. Tällaisten simulaatioiden sovittaminen yhteen saattaisi olla
myös toimialamallinnuksen tutkimuskohde. Kauaskantoisena seurauksena voisi, että
parhaat metamallit, niiden generaattorit ja oheisohjelmistot leviävät joko kaupallisesti
tai muuten laajempaan käyttöön ja alan yhteinen sanasto kehittyy ja formalisoituu.
Lähteet
.NET 3.5 SP1 (2009). Microsoft .NET Framework 3.5 Service Pack 1.
http://www.microsoft.com/downloads/details.aspx?FamilyID=ab99342f-5d1a-413d-8319-
81da479ab0d7&displaylang=en, viitattu 27.7.2009.
.NET Compact Framework 2.0 (2009). .NET Compact Framework 2.0 Service Pack 2
Redistributable. http://www.microsoft.com/downloads/details.aspx?familyid=aea55f2f-
07b5-4a8c-8a44-b4e1b196d5c0&displaylang=en, viitattu 27.7.2009.
2K Australia (2009). The 2K BotPrize. http://www.botprize.org/, viitattu 14.4.2009.
About Processes and Threads (2009). About Processes and Threads.
http://msdn.microsoft.com/en-us/library/ms681917%28VS.85%29.aspx, viitattu
29.9.2009.
Alt, Gregg; Dill, Kevin; Isla, Damiàn; Orkin, Jeff; Russel, Adam; Tozour, Paul & Zubek,
Rob (2007). Thoughts on Industry / Academic collaboration.
http://www.ai-blog.net/archives/000135.html, viitattu 14.4.2009.
Arsenault, Dominic (2005). Abstract of Dynamic Range: When Game Design and
Narratives Unite. http://www.digra.org/dl/db/06278.28202.pdf, viitattu 14.4.2009.
Artificial Intelligence and Games Research Network (2009). Artificial Intelligence and
Games Research Network. http://www.aigamesnetwork.org/, viitattu 14.4.2009.
Autodesk (2009a). Autodesk Kynapse.
http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=11661833, viitattu
14.4.2009.
Autodesk (2009b). Autodesk Maya.
http://usa.autodesk.com/adsk/servlet/index?id=7635018&siteID=123112, viitattu
14.4.2009.
Bauer, Friedrich Ludwig (1976). Programming as an evolutionary process. Teoksessa
International Conference on Software Engineering: Proceedings of the 2nd international
conference on Software engineering, s. 223–234. Los Alamitos: IEEE Computer Society
Press.
Bethke, Erik (2003). Game Development and Production. Plano: Wordware Publishing.
Bishop, Judith (2008). C# 3.0 Design Patterns. Sebastopol: O’Reilly Media.
Lähteet 67
Caldwell, Nicholas (2004). Theoretical frameworks for analyzing turn-based computer
strategy games. Media International Australia Incorporating Culture and Policy (110), s.
42–51.
Champandard, Alex J. (2008). Who Put Physics In Charge?
http://forums.aigamedev.com/showthread.php?t=1640, viitattu 14.4.2009.
Champandard, Alex J. & Gyrling, Christian (2009). Animating in a Complex World:
Integrating AI and Animation.
http://aigamedev.com/coverage/gdc09-slides-highlights#session3, viitattu 14.4.2009.
Church, Doug (1999). Formal Abstract Design Tools.
http://www.gamasutra.com/features/19990716/design_tools_01.htm, viitattu 14.4.2009.
Cook, Steve; Jones, Gareth; Kent, Stuart & Wills, Alan Cameron (2007). Domain-Specific
Development with Visual Studio DSL Tools. Boston: Pearson Education.
Costikyan, Greg (1994). I Have No Words & I Must Design.
http://www.costik.com/nowords.html, viitattu 14.4.2009.
Costikyan, Greg (2002). I Have No Words & I Must Design: Toward a Critical Vocabulary
for Games. http://www.costik.com/nowords2002.pdf, viitattu 14.4.2009.
Cumming, Murray; Schulze, Martin; Pulkkinen, Tero & Nelson, Karl (2009). libsigc++ -
The Typesafe Callback Framework for C++. http://libsigc.sourceforge.net/, viitattu
14.4.2009.
Deursen, Arie van; Klint, Paul & Visser, Joost (2000). Domain-Specific Languages: An
Annotated Bibliography. http://homepages.cwi.nl/~arie/papers/dslbib/, viitattu
14.4.2009.
Denecker, Marc & Ternovska, Eugenia (2007). Inductive situation calculus.
Artificial Intelligence, 171 (5-6), s. 332–360.
Dijkstra, Edsger Wybe (1972). The Humble Programmer. Communications of the ACM 15
(10), s. 859–866.
DSL Tools (2007). Domain-Specific Language Tools. http://msdn.microsoft.com/en-
us/library/bb126235.aspx, viitattu 27.7.2009.
DSM Forum (2009). DSM Forum. http://www.dsmforum.org/, viitattu 14.4.2009.
ECMA-334 (2006). ECMA-324. http://www.ecma-
international.org/publications/files/ECMA-ST/Ecma-334.pdf, viitattu 27.7.2009.
Lähteet 68
Eeva, Veikko (2006). Kevyt ja joustava ohjelmistokehitys.
http://www.iki.fi/~veikko.eeva/joustava.pdf, viitattu 14.4.2009.
Eeva, Veikko (2008). Reactive, concurrent machines and a DSL to write them.
http://forums.aigamedev.com/showthread.php?t=1724, viitattu 14.4.2009.
Ellinger, Benjamin (2008). Artificial Personality: A Personal Approach to AI. Teoksessa
Rabin, Steve (toim.): AI Game Programming Wisdom 4, s. 17–26. Boston: Course
Technology.
Endriss, Ulrich; Paolo Mancarella; Fariba, Sadri; Terreni, Giacomo & Toni, Francesca
(2004). Abductive Logic Programming with CIFF: System Description. Teoksessa Alferes,
José Júlio & Leite, João (toim.): Proceedings of the 9th European Conference on Logics in
Artificial Intelligence, s. 680–684. Springer.
Eskelinen, Markku (2001). Towards Computer Game Studies, Part 1: Narratology and
Ludology. http://www.siggraph.org/artdesign/gallery/S01/essays/0416.pdf, viitattu
14.4.2009.
Falkenberg, Eckhard D.; Hesse, Wolfgang; Lindgreen, Paul; Nilsson, Björn E.; Oei, J. L.
Han; Rolland, Colette; Stamper, Ronald K.; Assche, Frans J. M. van; Verrijin-Stuart,
Alexander A. & Voss, Klaus (1998). A Framework of Information System Concepts. Leiden:
International Federation for Information Processing.
Feldman, Michael (2009). Intel Gets Ready to Push Ct Out of the Lab.
http://www.hpcwire.com/features/Intel-Gets-Ready-to-Push-Ct-Out-of-the-Lab-
42634332.html, viitattu 14.4.2009.
Finnson, Hilmar (2007). CADIA-Player: A General Game Playing Agent. Reykjavik:
Háskólinn í Reykjavík.
Friedman, Mark B. (2008). Mainstream NUMA and the TCP/IP stack: Part I.
http://blogs.msdn.com/ddperf/archive/2008/06/10/mainstream-numa-and-the-tcp-ip-
stack-part-i.aspx, viitattu 14.4.2009.
Friedman, Mark B. (2009a). Parallel Scalability Isn't Child's Play.
http://blogs.msdn.com/ddperf/archive/2009/03/16/parallel-scalability-isn-t-child-s-
play.aspx, viitattu 29.4.2009.
Friedman, Mark B. (2009b). Parallel Scalability Isn't Child's Play, Part 2: Amdahl's Law vs.
Gunther's Law. http://blogs.msdn.com/ddperf/archive/2009/04/29/parallel-scalability-
isn-t-child-s-play-part-2-amdahl-s-law-vs-gunther-s-law.aspx, viitattu 29.4.2009.
Furtado, André W. P. & Santos, André L. M. (2006). Using Domain-Specific Modeling
towards Computer Games Development Industrialization. Teoksessa Tolvanen, Juha-
Lähteet 69
Pekka; Sprinkle, Jonathan & Gray, Jonathan (toim.): 6th OOPSLA Workshop On Domain-
Specific Modeling, s. 1–14. Jyväskylä: Jyväskylän yliopistopaino.
Gamics (2009). Gamics laboratory.
http://gamics.cs.helsinki.fi/Agenda.html, viitattu 14.4.2009.
García, Inmaculada & Mollá, Ramón (2006). Using a discrete event simulator as real time
graphic applications kernel. Simulation Modelling Practice and Theory, 14 (7), s. 1043–
1056.
García, Inmaculada; Mollá, Ramón & Barella, Toni (2004). GDESK: Game Discrete Event
Simulation Kernel. Journal of WSCG 12 (1–3), s. 121–128.
GEMS - Generic Eclipse Modeling System (2009). GEMS Home page.
http://www.eclipse.org/gmt/gems/, viitattu 14.4.2009.
Genesereth, Michael; Love, Nathaniel & Pell, Barney (2005). General Game Playing:
Overview of the AAAI Competition. AI Magazine, 26 (2), s. 62–72.
Glass, Robert J. (2003). Facts and Fallacies of Software Engineering, 2. painos. Boston:
Addison-Wesley Professional.
Greenfield, Jack & Short, Keith (2004). Software Factories: Assembling Applications with
Patterns, Models, Frameworks, and Tools. Indianapolis: Wiley Publishing.
Gregor, Douglas (2004). Boost.Signals.
http://www.boost.org/doc/libs/1_38_0/doc/html/signals.html, viitattu 14.4.2009.
Gunther, Neil J. (2009). Taking the Pith Out of Performance: Poor Scalability on Multicore
Supercomputers. http://perfdynamics.blogspot.com/2009/02/poor-scalability-on-
multicore.html, viitattu 14.4.2009.
Hardwidge, Ben (2009). Nvidia and AMD to accelerate gaming AI on GPUs.
http://www.custompc.co.uk/news/605389/nvidia-and-amd-to-accelerate-gaming-ai-on-
gpus/page1.html, viitattu 14.4.2009.
Haugen, Øystein & Mohagheghi, Parastoo (2007). A Multi-dimensional Framework for
Characterizing Domain Specific Languages. Teoksessa Tolvanen, Juha-Pekka; Sprinkle,
Jonathan & Gray, Jonathan (toim.): 7th OOPSLA Workshop On Domain-Specific
Modeling, s. 10–19. Jyväskylä: Jyväskylän yliopistopaino.
Hecker, Chris (2009). Structure vs Style. http://chrishecker.com/Structure_vs_Style,
viitattu 14.4.2009.
Lähteet 70
Hiltunen, KooPee & Haila, Teemu (2009). Finnish Games Industry 2008.
http://www.hermia.fi/neogames/tutkimukset_ja_julkaisut/?x11656=297520, viitattu
14.4.2009.
Hutchinson, Alex; Johnson, Soren; Mosqueira, Joshua; Russell, Adam & Teich, Tara
(2009). AI and Designers: Mind the Gap.
http://aigamedev.com/coverage/gdc09-slides-highlights#session5, viitattu 14.4.2009.
IEEE Computational Intelligence Society (2008). CIG'08, IEEE Symposium on
Computational Intelligence and Games. http://www.csse.uwa.edu.au/cig08/, viitattu
14.4.2009.
IGDA AI SIG (2009). Special Interest Group on Artificial Intelligence.
http://www.igda.org/ai/, viitattu 14.4.2009.
INotifyPropertyChanged (2009). INotifyPropertyChanged Interface.
http://msdn.microsoft.com/en-
us/library/system.componentmodel.inotifypropertychanged.aspx, viitattu 29.9.2009.
Ivan, Tom (2008). L.A. Noire the Most Expensive Game in Development?
http://www.edge-online.com/news/la-noire-most-expensive-game-development, viitattu
14.4.2009.
Järvinen, Aki (2008). Games without Frontiers: Theories and Methods for Game Studies
and Design. Tampere: Tampereen yliopisto, humanistinen tiedekunta.
Kakas, Antonis; Mancarella, Paolo; Sadri, Fariba; Stathis, Kostas & Toni, Francesca
(2008). Computational Logic Foundations of KGP Agents. Journal of Artificial Intelligence
Research, 33, s. 285–348.
Kelly, Steven & Tolvanen, Juha-Pekka (2008). Domain-Specific Modeling: Enabling Full
Code Generation. Hoboken: John Wiley.
Kemppi, Paula (2008). Tekoäly Hex-pelissä.
http://www.cs.helsinki.fi/u/tapasane/Seminaarit/KorttiJaLautapelit/syksy2008/PaulaKe
mppi_Hex.pdf, viitattu 14.4.2009.
Kent, Stuart (2008). DSL Tools and Oslo.
http://blogs.msdn.com/stuart_kent/archive/2008/11/07/dsl-tools-and-oslo.aspx, viitattu
23.6.2009.
Kieburtz, Richard; McKinney, Laura; Bell, Jeffrey; Hook, James; Kotov, Alex; Lewis,
Jeffrey; Oliva, Dino; Sheard, Tim; Smith, Ira & Walton, Lisa (1996). A software
engineering experiment in software component generation. Teoksessa International
Lähteet 71
Conference on Software Engineering: Proceedings of the 18th international conference on
Software engineering, s. 542–552. Washington: IEEE Computer Society.
Kleppe, Anneke (2009). Software Language Engineering: Creating Domain-Specific
Languages Using Metamodels. Boston: Pearson Education.
Kline, Dan (2008a). In-Depth: Stanford Conference Explores The State Of AI.
http://www.gamasutra.com/php-bin/news_index.php?story=20917, viitattu 7.4.2009.
Kline, Dan (2008b). AI Architecture: Anim AI layer.
http://dankline.wordpress.com/2008/12/09/ai-architecture-anim-ai-layer/, viitattu
14.4.2009.
Kosar, Tomaž; López, Pablo E. Marínez; Barrientos, Pablo A. & Mernik, Marjan (2008). A
preliminary study on various implementation approaches of domain-specific language.
Information and Software Technology, 50 (5), s. 390–405.
Krajewski, John (2009). Creating All Humans: A Data-Driven AI Framework for Open
Game Worlds.
http://www.gamasutra.com/view/feature/1862/creating_all_humans_a_datadriven_.php,
viitattu 14.4.2009.
Kücklich, Julian (2003). Perspectives of Computer Game Philology. Game Studies, 3 (1).
http://www.gamestudies.org/0301/kucklich/, viitattu 14.4.2009.
Left 4 Dead (2008). Left 4 Dead. http://www.l4d.com/, viitattu 27.7.2009.
Leppänen, Mauri (2005). An Ontological Framework and a Methodical Skeleton for
Method Engineering - A Context Approach. Jyväskylä: Jyväskylän yliopistopaino.
Linden, Frank J. van der; Rommes, Eelco & Schmid, Klaus (2007). Software Product Lines
in Action: The Best Industrial Practice in Product Line Engineering. Berlin: Springer-
Verlag.
Mattson, Timothy G.; Sanders, Beverly G. & Massingill, Berna L. (2005). Patterns for
Parallel Programming. Boston: Pearson Education.
McCarthy, John (2007). What is artificial intelligence.
http://www-formal.stanford.edu/jmc/whatisai/node1.html, viitattu 14.4.2009.
McCorduck, Pamela (2004). Machines Who Think: A Personal Inquiry into the History on
Prospects of Artificial Intelligence. 2. painos. Natick: A K Peters.
Mernik, Marjan; Heering, Jan & Sloane, Anthony M. (2007). When and How to Develop
Domain-Specific Languages. ACM Computing Surveys (CSUR), 37 (4), s. 316–344.
Lähteet 72
MetaCase (2009). MetaCase - Domain-Specific Modeling with MetaEdit+.
http://www.metacase.com/, viitattu 14.4.2009.
Meyer, Bertrand (1997). Object-Oriented Software Construction, 2. painos. Upper Saddle
River: Prentice Hall.
Microsoft (2009a). Microsoft DreamSpark. https://www.dreamspark.com/default.aspx,
viitattu 14.4.2009.
Microsoft (2009b). Overview of Domain-Specific Language Tools.
http://msdn.microsoft.com/en-us/library/bb126327(VS.80).aspx, viitattu 14.4.2009.
Microsoft (2009c). WeakEvent Patterns. http://msdn.microsoft.com/en-
us/library/aa970850.aspx, viitattu 14.4.2009.
Microsoft (2009d). New NUMA Support with Windows Server 2008 R2 and Windows 7.
http://code.msdn.microsoft.com/64plusLP, viitattu 14.4.2009.
Microsoft (2009e). "Oslo" Developer Center. http://msdn.microsoft.com/en-
us/oslo/default.aspx, viitattu 14.4.2009.
Millington, Ian (2006). Artificial Intelligence for Games. San Francisco: Morgan
Kaufmann.
Minsky, Marvin (1997). Future of AI Technology.
http://web.media.mit.edu/~minsky/papers/CausalDiversity.html, viitattu 14.4.2009.
Moreno-Ger, Pablo; Fuentes-Fernández, Rubén; Sierra-Rodríguez, José-Luis &
Fernández-Manjón, Baltasar (2009). Model-checking for adventure videogames.
Information and Software Technology, 51 (3), s. 564–580.
Murray, Janet (1998). Hamlet on the Holodeck: The Future of Narrative in Cyberspace.
Cambridge: MIT Press.
Nareyek, Alexander (2004a). AI in Computer Games. Queue, 1 (10), s. 58–65.
Nareyek, Alexander (2004b). Computer Games - Boon or Bane for AI Research? Künstliche
Intelligenz 1/2004, s. 43–44.
Newell, Gabe (2008). Gabe Newell Writes for Edge. http://www.edge-
online.com/blogs/gabe-newell-writes-edge, viitattu 14.4.2009.
Nowaczyk, Sławomir (2006). Partial Planning for Situated Agents based on Active Logic.
Teoksessa Ågotnes, Thomas & Alechina, Natasha (toim.): Proceedings of the Workshop
on Logics for Resource-Bounded Agents (LRBA 2006), The 18th European Summer School
in Logic, Language and Information (ESSLLI 2006), s. 99–112.
Lähteet 73
Orkin, Jeff (2004). Symbolic Representation of Game World State: Toward
Real-Time Planning in Games. Teoksessa Fu, Dan; Henke, Stottler & Orkin Jeff (toim.):
Proceedings of the AAAI Workshop on Challenges in Game AI, s. 26–30. Menlo Park: AAAI
Press.
Paige, Richard; Ostroff, Jonathan & Brooke, Phillip (2000). Principles for modeling
language design. Information and Software Technology, 42 (10), s. 665–675.
PDDL (2009). PddlExtension.
http://ipc.informatik.uni-freiburg.de/PddlExtension, viitattu 14.4.2009.
Performance Counter (2009). Performance Counters.
http://msdn.microsoft.com/en-us/library/aa373083%28VS.85%29.aspx, viitattu
27.7.2009.
Pfeifer, Borut (2008). Creating Designer Tunable AI. Teoksessa Rabin, Steve (toim.): AI
Game Programming Wisdom 4, s. 27–38. Boston: Course Technology.
Plunkett, Luke (2009). First Physics, Now AI Is Being Moved To Your Graphics Card.
http://kotaku.com/5136715/first-physics-now-ai-is-being-moved-to-your-graphics-card,
viitattu 14.4.2009.
Poppendieck, Mary & Poppendieck, Tom (2003). Lean Software Development: An Agile
Toolkit. Upper Saddle River: Addison-Wesley.
Prolog (1999). Prolog: The ISO Standard Documents.
http://pauillac.inria.fr/~deransar/prolog/docs.html, viitattu 27.7.2009.
Rao, Anand S. (1996). AgentSpeak(L): BDI Agents Speak Out in a Logical Computable
Language. Teoksessa Velde, Walter van de & Perram, John W. (toim.): Agents Breaking
Away, 7th European Workshop on Modelling Autonomous Agents in a Multi-Agent World
(MAAMAW'96), 1038, s. 42–55. New York: Springer.
ReaderWriterLockSlim (2009). ReaderWriterLockSlim Class.
http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx,
viitattu 27.7.2009.
Reddy, Raj (1988). Foundations and Grand Challenges of Artificial Intelligence. AI
Magazine, 9, s. 9–21.
Remo, Chris (2009). Molyneux Demonstrates Internal Lionhead Experiments.
http://www.gamasutra.com/php-bin/news_index.php?story=22955, viitattu 14.4.2009.
Reynolds, Brian (2004). AI and Design: How AI Enables Designers.
http://archive.gdconf.com/gdc_2004/reynolds_brian.ppt, viitattu 14.4.2009.
Lähteet 74
Riley, Patrick (2003). SPADES a system for parallel-agent, discrete-event simulation. AI
Magazine, 24 (2), s. 41–42.
Ruby (2009). About Ruby.
http://www.ruby-lang.org/en/about/, viitattu 27.7.2009.
Russell, Adam (2008a). Situationist Game AI. Teoksessa Rabin, Steve (toim.): AI Game
Programming Wisdom 4, s. 3–15. Boston: Course Technology.
Russell, Adam (2008b). Ecological Balance in AI Design. Teoksessa Rabin, Steve (toim.):
AI Game Programming Wisdom 4, s. 49–57. Boston: Course Technology.
Ryazanov, Sergey (2005). The Impossibly Fast C++ Delegates.
http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx, viitattu
14.4.2009.
Sánchez-Ruíz, Arturo J.; Saeki, Motoshi; Langlois, Benoît & Paiano, Roberto (2007).
Domain-Specific Software Development Terminology: Do We All Speak the Same
Language? http://www.dsmforum.org/events/DSM07/papers/sanchez-ruiz.pdf, viitattu
14.4.2009.
Sandia National Laboratories (2009). More chip cores can mean slower supercomputing,
Sandia simulation shows.
http://www.sandia.gov/news/resources/releases/2009/multicore.html, viitattu 14.4.2009.
Sayeed, Mohamed; Bae, Hansang; Zheng, Yili; Armstrong, Brian; Eigenmann, Rudolf &
Saied, Faisal (2008). Measuring High-Performance Computing with Real Applications.
Computing in Science and Engineering, 10 (4), s. 60–70.
Schaeffer, Jonathan & van den Herik, Jaab (2002). Games, computers, and artificial
intelligence. Artificial Intelligence, 134, s. 1-7. Elsevier Science B. V.
Schechter, Greg (2004). Simulating "Weak Delegates" in the CLR.
http://blogs.msdn.com/greg_schechter/archive/2004/05/27/143605.aspx, viitattu
14.4.2009.
Schwab, Brian (2004). AI Game Engine Programming. Boston: Charles River Media.
Scogland, Thomas; Balaji, Pavan; Feng, Wu-chun & Narayanaswamy, Ganesh (2008).
Asymmetric Interactions in Symmetric Multi-core Systems: Analysis, Enhancements and
Evaluation. Teoksessa Proceedings of the ACM/IEEE Conference on High Performance
Computing, SC 2008, s. 1–12. Piscataway: IEEE Press.
Selic, Bran (2006). Model-Driven Development - Its Essence and Opportunities.
http://www.cs.tut.fi/tapahtumat/olio2006/selic.pdf, viitattu 14.4.2009.
Lähteet 75
Serious (2009). Nordic Serious Games.
http://nsg.jyu.fi/index.php/Main_Page, viitattu 14.4.2009.
Short, Keith (2008). Oslo and the DSL Toolkit.
http://blogs.msdn.com/keith_short/archive/2008/11/06/oslo-and-the-dsl-toolkit.aspx.
viitattu 23.6.2009.
Sicart, Miguel (2008). Defining Game Mechanics: Game Studies.
http://gamestudies.org/0802/articles/sicart, viitattu 14.4.2009.
Sleep (2009). Sleep Method (Int32). http://msdn.microsoft.com/en-
us/library/d00bd51t.aspx, viitattu 27.7.2009.
SpirOps (2009). SpirOps A.I. http://www.spirops.com/products.php?m=2, viitattu
14.4.2009.
Stahl, Thomas & Völter, Markus (2006). Model-Driven Software Development:
Technology, Engineering, Management. Chichester: John Wiley.
Stern, Andrew (2002). Creating Emotional Relationships with Virtual Characters.
Teoksessa Trappl, Robert; Petta, Paolo & Payr, Sabine (toim.): Emotions in Humans and
Artifacts, s. 333–360. Cambridge: MIT Press.
Sternberg, Robert (1985). Beyond IQ: A Triarchic Theory of Human Intelligence. New
York: Cambridge University Press.
StopWatch (2009). Stopwatch Class. http://msdn.microsoft.com/en-
us/library/system.diagnostics.stopwatch.aspx, viitattu 27.7.2009.
Sweeney, Tim (2006). The Next Mainstream Programming Language: A Game Developer's
Perspective. http://www.cs.princeton.edu/~dpw/popl/06/, viitattu 14.4.2009.
T4 (2007). Generating Artifacts By Using Text Templates. http://msdn.microsoft.com/en-
us/library/bb126445.aspx, viitattu 29.9.2009.
Takatsuki, Yo (2007). Cost headache for game developers.
http://news.bbc.co.uk/2/hi/business/7151961.stm, viitattu 14.4.2009.
ThreadPool (2009). ThreadPool Class. http://msdn.microsoft.com/en-
us/library/system.threading.threadpool.aspx, viitattu 27.7.2009.
Tilastokeskus (2009). 2.11 Hajontaluvut - variaatiokerroin.
http://www.stat.fi/tup/verkkokoulu/data/tt/02/11/index.html, viitattu 14.4.2009.
Tiller, Craig (2009). Who Put Physics In Charge?
http://forums.aigamedev.com/showthread.php?t=1640&page=3, viitattu 14.4.2009.
Lähteet 76
Togelius, Julian (2007). On industrial-academic collaboration in game AI.
http://togelius.blogspot.com/2007/12/on-industrial-acadmic-collaboration-in.html,
viitattu 14.4.2009.
TTLRY (2009). TTLRY. http://www.ttlry.fi/atk-sanakirja/su020.htm#3930, viitattu
27.7.2009.
Uudenmaan TE-keskus/SILE-projekti (2008). Suomen pelialan koulutustarpeet.
http://www.hermia.fi/neogames/tutkimukset_ja_julkaisut/?x11656=70430, viitattu
14.4.2009.
VolatileRead (2009). VolatileRead Method. http://msdn.microsoft.com/en-
us/library/system.threading.thread.volatileread.aspx, viitattu 27.7.2009.
VolatileWrite (2009). VolatileWrite Method. http://msdn.microsoft.com/en-
us/library/system.threading.thread.volatilewrite.aspx, viitattu 27.7.2009.
VS2008 (2009). Visual Studio 2008 SDK 1.1.
http://www.microsoft.com/downloads/details.aspx?familyid=59EC6EC3-4273-48A3-
BA25-DC925A45584D&displaylang=en, viitattu 27.7.2009.
Wardrip-Fruin, Noah (2007). On Academic and Game Industry AI.
http://grandtextauto.org/2007/12/17/on-academic-and-game-industry-ai/, viitattu
14.4.2009.
Weizenbaum, Joseph (1966). ELIZA—a computer program for the study of natural
language communication between man and machine. Communications of the ACM 9 (1),
s. 36–45.
West, Mick (2009). Intelligent Mistakes: How to Incorporate Stupidity Into Your AI Code.
http://www.gamasutra.com/view/feature/3947/intelligent_mistakes_how_to_.php,
viitattu 14.4.2009.
White, Walker; Demers, Alan; Koch, Christoph; Gehrke, Johannes & Rajagopalan,
Rajmohan (2007). Scaling games to epic proportions. Teoksessa Chan, Chee Yong; Ooi,
Beng Chin & Zhou, Aoying (toim.): Proceedings of the ACM SIGMOD International
Conference on Management of Data, s. 31–42. New York: ACM.
Wikipedia (2009a). Game artificial intelligence. http://en.wikipedia.org/wiki/Game_AI,
viitattu 14.4.2009.
Wikipedia (2009b). First video game. http://en.wikipedia.org/wiki/First_video_game,
viitattu 14.4.2009.
Wikipedia (2009c). Pac-Man. http://fi.wikipedia.org/wiki/Pac-Man, viitattu 14.4.2009.
Lähteet 77
Wikipedia (2009d). Antero Vipunen. http://fi.wikipedia.org/wiki/Antero_Vipunen,
viitattu 14.4.2009.
Wikipedia (2009e). Luotteet. http://fi.wikipedia.org/wiki/Luotteet, viitattu 14.4.2009.
Wile, David S. (2001). Supporting the DSL Spectrum. Journal of Computing and
Information Technology, 9 (4), s. 263–287.
Xaitment (2009). Products Overview. http://xaitment.com/english/products-
overview.html, viitattu 14.4.2009.
XNA 3.0 (2009). Microsoft XNA Game Studio 3.0.
http://www.microsoft.com/downloads/details.aspx?FamilyId=7D70D6ED-1EDD-4852-
9883-9A33C0AD8FEE&displaylang=en, viitattu 27.7.2009.
78
Liite A: Testauslaitteistojen kokoonpanotiedot
Testikone A: yksiydinkone (lähteenä msinfo32 ja CPU-Z 1.50)
Käyttöjärjestelmä Microsoft Windows XP Home Edition
BIOS Phoenix Technologies, LTD 3.11
Emolevy Asustek Kelut 2.02
Suoritin x86 Family 6 Model 10 Stepping 0 AuthenticAMD 1999 MHz
(AMD Sempron™ 3000+)
Välimuisti L1: 64 KiB (2-joukkoassosiatiivinen, lohkot 64 B)
L2: 64 KiB (2-joukkoassosiatiivinen, lohkot 64 B)
L3: 512 KiB (16-joukkoassosiatiivinen, lohkot 64 B)
Fyysinen muisti 1536,00 MiB (DDR 166 MHz 3-5-3-7)
Näennäismuisti 2,00 GiB
Roskienkeruu Desktop (kaikki vaihtoehdot: Compact, Desktop ja Server)
Testikone B: kaksiydinkone (lähteenä msinfo32 ja CPU-Z 1.50)
Käyttöjärjestelmä Microsoft Windows XP Professional
BIOS Dell Inc. A08
Emolevy Dell Inc. 0KX350
Suoritin x86 Family 6 Model 15 Stepping 6 GenuineIntel 2161 MHz (Intel®
Core™ 2 Duo)
Välimuisti L1: 32 KiB 2 (8-joukkoassosiatiivinen, lohkot 64 B)
L2: 32 KiB 2 (8-joukkoassosiatiivinen, lohkot 64 B)
L3: 4096 KiB (16-joukkoassosiatiivinen, lohkot 64 B)
Fyysinen muisti 2048,00 MiB (DDR 2 322,5 MHz 5-5-5-15(-21))
Näennäismuisti 2,00 GiB
Roskienkeruu Desktop (kaikki vaihtoehdot: Compact, Desktop ja Server)
79
Liite B: Testiohjelman runko
for(int i = 0; i <= rounds1; ++i)
{
for(int j = 0; j < rounds2; ++j)
{
Thread.Sleep(i * frequencyMultiplier);
var stopWatch = new Stopwatch();
stopWatch.Start();
StateMachine.QueueCommand(new NullCommand
{
Watch = stopWatch,
Array = roundsArray,
Index = j,
Delay = i * 10
});
}
semaphore.WaitOne();
StateMachine.QueueCommand(new CallBackCommand
{
//CallBackCommand releases this semaphore when it’s executed.
Sema = semaphore
});
semaphore.WaitOne();
var b = new StringBuilder();
b.AppendLine();
for(int n = 0; n < roundsArray.Length; ++n)
{
b.AppendLine(string.Format("{0};{1};{2}", n, roundsArray[n], i * 10));
}
File.AppendAllText(@"excel_data.csv", b.ToString());
semaphore.Release();
}
80
Liite C: Esimerkkikoodi
namespace Luote
{
public partial class StateMachineCreator
{
public static StateMachine Vipunen
{
get
{
//The statemachine with all of the states.
StateMachine stateMachine = new StateMachine
{
States = new[]
{
new State("State1", StateSettings.None |
StateSettings.StartState),
new State("State2", StateSettings.None |
StateSettings.AlwaysActive),
new State("State3", StateSettings.None)
}
};
stateMachine["State1"].BindingManager.
AddStateTransitionBinding(new
TransitionCommand("StateTransition1",
stateMachine["State1"], stateMachine["State2"]));
stateMachine["State1"].BindingManager.
AddStateTransitionBinding(new
TransitionCommand("StateTransition2",
stateMachine["State1"], stateMachine["State3"]));
stateMachine["State3"].BindingManager.
AddStateTransitionBinding(new
TransitionCommand("StateTransition1",
stateMachine["State3"], stateMachine["State2"]));
return stateMachine;
}
}
}
}