File: engine_code_overview.md

package info (click to toggle)
triplea 1.9.0.0.7062-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,960 kB
  • sloc: java: 143,218; xml: 70,206; sh: 133; makefile: 9
file content (291 lines) | stat: -rw-r--r-- 7,400 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

## Design Goals


The goal of the game engine is to provide a framework to
build turn based strategy games.The
engine provides networking and data model support.



## The big picture

The developer of a game using the TripleA engine must do
three things. Create a game.xml file
describing the game, write Delegates to handle game logic (or reuse existing
delegates), write GamePlayer classes that handle the user interaction (either
human or automated).


The engine provides a parser to parse the game xml data,
network transparent game data updates, and handles network communication
between Delegates and GamePlayers.

## Game Data

Game data is read from an xml file that follows the game.dtd
schema.
data\games\strategy\engine\xml directory).

## The game xml file specifies

* Game name and version<
* Class used to load the game
Territory names
* Connection between territories
* Resource types
* Players and alliances
* Unit types
* Production rules
* Initial unit placement,
* Initial territory ownership
* Initial resource allocation
* Attachments (more later)
* Game play sequence


All the data above is parsed by the game, and can be
accessed through the GameData object.


The xml file format must be general enough to describe the
data for any turn based strategy game, yet specific enough to be able to
describe a game completely.


The problem is that each game differs in the type of data
that must be specified.For example,
some games may need to specify how many hits a unit can take before it dies,
while other games don�t.In order for
the xml file to be flexible enough to handle all games the concept of an
attachment is used.


An attachment is a set of name:value pairs.<span
style="mso-spacerun: yes">  This set of name value pairs can be attached
to unit types, players, territories, or resources.


This tells the xml parser to create an instance of
UnitAttachment, attach it to the infantry unit type, and initialize the
attachment with an attack value of 1, and a defense value of 2.



The game parser uses the java bean syntax for setting the
attachment values.If an attachment
has an option name of code, then it will call setCode(value) to set the
attachments value.The setCode method
will always use a string as its argument.



After an attachment is created, the engine validates it by
calling validate().This allows the
attachment to throw a GameParseException if it is initialized with an invalid
state.Throwing a game parse exception
will stop the parser, and terminate the program.




getAttachment,
where key is the name of the attachment. 
In the above example key would be unitAttachment.  Objects implementing the Attatchable
interface are PlayerID, Resource, Territory, and UnitType.


--------


Turn based strategy games generally go through a series of
well defined steps.In axis and allies,
these steps are tech roll, purchase, combat move, battle, non combat move,
place, collect resources.



The logic for each step is encapsulated in a delegate.


A delegate is the game logic for one step of the game.<span
style="mso-spacerun: yes">  In axis and allies there would be a delegate
for movement, a delegate for purchase, a delegate for placing etc.<span
style="mso-spacerun: yes">   A delegate is responsible for validating
player actions, and updating the game state to reflect player actions.



Ideally delegates would be independent of each other, and
could be mixed and matched.For example
if a risk game and an axis and allies game were both implemented in using the
TripleA framework, then you should be able to create a new game that combines
the axis and allies battle logic with the movement logic of risk, simply by reusing
the respective delegates.Currently
this flexibility is not available because there is a degree of interdependence
between the delegates.In tripleA, the
battle delegate uses services supplied by the movement delegate, and vice
versa.Other dependencies exist as
well.



Delegates are restricted in what they are allowed to do. A
delegate must talk to game players and get random data through its
DelegateBridge.Also a delegate cannot
change the game data directly, but must use the ChangeFactory to create
changes, and then add them through the Delegates DelegateBridge.



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;




In the game xml file you can specify the sequence of steps
the game goes through in the gamePlay tag.









&lt;delegate name=&quot;battle&quot;
javaClass=&quot;BattleDelegate&quot;/&gt;

&lt;delegate name=&quot;move&quot;
javaClass=&quot;MoveDelegate&quot;/&gt;

&lt;step
name=&quot;usMove&quot; delegate=&quot;move&quot; player=&quot;bush&quot;/&gt;

&lt;step
name=&quot;usFight&quot; delegate=&quot;battle&quot;
player=&quot;bush&quot;/&gt;

&lt;step
name=&quot;canMove&quot; delegate=&quot;move&quot;
player=&quot;chretian&quot;/&gt;

&lt;step
name=&quot;canFight&quot; delegate=&quot;battle&quot;
player=&quot;chretian&quot;/&gt;



This tells the engine that there are two delegates, battle
and move, and that there are four steps, usMove, usFight, canMove, canFight,
and that the game cycles through these 4 steps until the game ends.





 The
     delegates start method is called.

 If a
     GamePlayer is specified in the game xml file for the step, then the
     players start method is called.
     The argument to start is the name of the step specified in the game
     xml file.
 The
     delegates end method is called.Signifying
     that the step is over.




###




To preserve network transparency game data is not changed
directly by the delegates.All changes
to game data are made by through the DelegateBridge.addChange(Change
aChange).This allows the game engine
to synchronize changes in game data between machines.



The Change class encapsulates a change of game data.<span
style="mso-spacerun: yes">  Changes are created using the ChangeFactory
class.



For example, a Delegate wanting to change the owner of a
territory would use the following code,



Change
aChange = ChangeFactory.changeOwner(aTerritory, aPlayer);





##




A GamePlayer is responsible for making moves in a game.<span
style="mso-spacerun: yes">  A game player can be anything from a GUI to
an AI to a PBEM interface.



A GamePlayer sends messages to the current game delegate
saying what moves the player would like to make.<span style="mso-spacerun:
yes">  The Delegate will then validate the move, and if the move is
valid, alter the GameData.



##




Communication between delegates and game players is done
through a simple remote method invocation scheme.




A Delegate can send a message to any GamePlayer while it is
executing (ie after its start method is called, and before its end method
returns) and a GamePlayer can send a message to the Delegate that is currently
running while the GamePlayer is after its start method is called and before its
start method returns.

###




Because delegates and game players may not be on the same
machine, communication is done through Bridges.<span style="mso-spacerun:
yes">  



A delegate can send a message to a player through its
delegateBridge using the sendMessage(..) functions.<span style="mso-spacerun:
yes">  



A GamePlayer can only send a message to the games current
delegate. The message is sent using the
GamePlayers PlayerBridge.

The game engine takes care of routing these messages across
the network if necessary.