Next: Compilation tips, Previous: Graphics backends, Up: Hacker's guide [Contents][Index]
Since Liquid War 3 the algorithm to power Liquid War is pretty much unchanged, at least, there has been no revolution, the basic principles remain the same. This has been explained in Liquid War 5 doc, but is repeated here, along with the specific Liquid War 6 stuff.
The very important things to remember are:
rand
/ random
functions, it also does not use
any float value either, since different type of processors/contexts might give slightly different
results because of rounding problems.
N
of the cursor, then in the worst case, all adjacent places are at distance N+1
.
As of Liquid War 6, the corresponding code is in src/lib/ker/ker-spread.c
. The second
step is to move the fighters, make them act. In Liquid War 6, the corresponding code is in
src/lib/ker/ker-move.c
. One can have a look at the code source for the
function lw6ker_game_state_do_round
in src/lib/ker/ker-gamestate.c
to see
how these are called.
Most of the algorithm code has something to do with the following types (which are structs):
lw6map_level_t
defined in which is used to store the level data.
lw6ker_game_struct_t
defined in src/lib/map/map.h
which is used to store the memory data required by the
algorithm, but which are immutable. There’s a difference between those data and the ones stored in the level
struct. For instance, those data are “private” since lw6ker_game_struct_t
is opaque, while
everything is lw6map_level_t
is “public”. Also, data in lw6ker_game_struct_t
might be
highly redundant for performance issues and is optimized for speed while data in lw6map_level_t
is
just plain data and won’t change if the algorithm is updated.
lw6ker_game_state_t
defined in src/lib/ker/ker.h
which is used to store the level data required by the
algorithm, and which changes during the game. This is typically where an information such as “there’s a red
fighter in slot (3,23,1)” will be stored.
lw6pil_pilot_t
defined in src/lib/pil/pil.h
which is used to handle all the threading issues. It keeps
a track of 3 game states. A “reference” state which is the state of the game considering all input has been received
from the network, and is validated. A “draft” state which might be anticipated and updated “as if the
players we did not get input from did not move there cursors”. This can give the illusion that the game
is running smoothly while in reality input from other players on the network is choppy. In a local game,
“draft” and “reference” are equivalent, since there’s no doubt about what’s on the network. And finally,
a “backup” state which can be pulled in case of a serious flaw and is a good way to solve the “hey, someone
untrusted is throwing garbage on the net”. One can always pull a backup.
Most of the time, hacking on the algorithm, changing the gameplay, does not require
to touch anything but the code in src/lib/ker
.
See See libmap. See See libker. See See libpil.
One of the key functions is lw6ker_game_state_get_fighter_id
, which will return
the id of a fighter at a given position.
Then its companion function lw6ker_game_state_get_fighter_by_id
can be called,
it will return a lw6ker_fighter_t
, which contains the real data.
The type lw6ker_fighter_t
is not opaque and can be freely accessed by the caller,
which, typically, is a graphics backend trying to display informations. Try and grep
for the string “lw6ker_game_state_get_fighter_id” withing the src/lib/gfx
source tree
for examples.
One thing that is very important when hacking on libker
: you should always
leave the lw6ker_game_state_t
struct in a state that is compatible with a
correct usage of public “getters” in src/lib/ker/ker.h
. The reason is that
this code can be executed by separate threads, more precisely, in “dirty read” mode,
the rendering thread will try and display a “game state” while this very “game state” is
being updated by another thread.
Next: Compilation tips, Previous: Graphics backends, Up: Hacker's guide [Contents][Index]