-- KOTH -- King of the Hill! Technical notes, tips for source browsing: Most functions are prefixed by two or three lowercase letters. These letters indicate the file that the function definition is in (e.g. gfxDrawTerrain). Similarly, global variables referenced outside their respective file are prefixed with two or three letters and an underscore to indicate which file they are declared in (e.g. ter_sizex). Structures are named by identifier and then the they are defined in file, which is a header file instead of a C file (e.g. NewPlayer_pkt in packets.h or Char_fnt in font.h). Prefix mappings are like this: clv -> ai-clever.c ai -> ai-moron.c aih -> aihandlers.c bal -> ballistics.[ch] cfg -> cfgfile.[ch] ch -> clihandlers.[ch] demo -> demo.[ch] gfx -> gfx.[ch] cl -> kclient.[ch] sv -> kserver.[ch] log -> log.[ch] pkt -> packets.[ch] pl -> player.[ch] rl -> relay.[ch] rnd -> rnd.[ch] sky -> sky.[ch] sh -> svrhandlers.[ch] tcp -> tcpcore.[ch] ter -> terrain.[ch] txt -> text.[ch] con -> conversions.[ch] wep -> weapon.[ch] and others in weapons/ wgx -> weapongfx.[ch] and others in weapons/ In addition there are a few gm_ global game variables floating about, these are exported in game.h and stored in kclient.c and kserver.c. The C style conventions used in KOTH are based on the Stroustrup C style of XEmacs 20.4 c-mode, with four-space tab stops. Most indentation using tabs should work independent of tab width, but some alignment (such as multiline function definitions/function calls) may be off. For optimal source reading set the tab width to four in your editor of choice. UPDATE: Currently the code is indented with the command indent -i4 -sc -bli0 -bl0 -cbi0 -ss -cli4 -cdw -l80 -nsaf -npcs -nsai -nprs -nsaw -npsl The code entry points for the client and server are in kserver.c and kclient.c respectively. Program flow is fairly straightforward: initialize, enter main game loop, and alternate between three states of play: pregame where players will be able to chat and buy weapons, the actual game where players use those weapons on each other, and postgame where scores are tallied and displayed. The game is based around the networking code in in tcpcore.c and relay.c. The relay code abstracts the packet interface by identifying packets by a special two-byte identifier and then doing a callback to the apropriate registered handler. The bulk of the game (reacting to network events) occurs in and dispatched from these handlers, so they probably merit the closest study. For those looking to add new weapons, the artillery code (ballistics.c, weapon.c, weapongfx.c) is the place to go. There are also several queues used for various purposes. The death queue, gm_death_queue, is used to avoid polluting shared code by indicating which tanks have died this turn so that the binary specific code can react to the death event (server awards bounty, the players see a "so-and-so has died" message, etc). The activate shot queue, gm_AS_queue, is used in the event that an activate shot event is recived before the current turn has finished playing out on the client (which operates asynchronously, unlike the server and AIs). The AS queue stores shot "generations", that is, each shot generated to marked with a generation which indicates to which turn it belongs. The AS queue is then processed, activating appropriate shots as it goes along. The wind speed queue, gm_WS_queue serves a similar purpose. In order to avoid having the wind speed change in the middle of the turn because the server has sent out a new wind speed but based it's calculations on the old, the WS queue stores wind speed changes and applies the new one as each new turn occurs. The logo is based on a screenshot taken of some very early prototype code written to test the terrain-drawing algorithm. The letters "KOTH" are in the tekton font and the letters "King of the Hill" are in cuneifontlight. The bitmapped font in font5.xpm was rendered in the GIMP from the font windsordemi. All of these are Type1 postscript fonts in the freefonts package available at ftp.gimp.org. Here's a quick listing of the various packet types, to dissect them see packets.h, to see what they actually mean, see clihandlers.c and svrhandlers.c. Client -> Server commands: (the rlRegisterHandler section of svInitialize() of kserver.c will have the authoritative listing) NP: New Player SN: Set Name MS: Message GT: Get Terrain CR: Change player's ready FS: Fire Shot BW: Buy Weapon Server -> Client commands: (the rlRegisterHandler section of clInitialize() of kclient.c will have the authoritative listing) UT: Update Terrain NT: Please retrive New Terrain MS: Message MC: Message with Color GM: Game Mode GT: Game Type UR: You Are id # ST: Set Tank position AP: Add Player RP: Remove Player SN: Set Name of some player TF: Tank #n Fires shot CR: Change Readiness (mostly from dead to live or live to dead) AS: Activate Shots. Causes the shot list to be executed. BW: Your Weapon Buy request has been accepted/denied SM: Set Money amount PV: Protocol Version WS: Wind Speed WT: Wall Type US: Update Score NR: New Round TR: Total Rounds TC: Set someone tank's color UF: Update fire info (who's shot it is in turn mode, denotes the end of each shot round in simultaneous mode) Some notes on terrain coordinates vs. screen coordinates: So to easily support clients at multiple resolutions, all calculations take place in "terrain coordinates", as are the values in the player, ballistics, terrain, etc data structures. Many drawing functions use the distinction "tx" and "sx" (or ty and sy) to indicate terrain coordinates and physical screen coordinates respectively. This is only an issue for functions in gfx.c and weapongfx.c; anywhere else things are going to be in terrain coordinates. The API for gfx.c is currently a bit inconsistant, however: some functions want their parameters in screen coordinates, others in terrain coordinates. The header file should give you some indication as to which is which so it isn't too bad, but also here is a good rule of thumb: terrain coordinates can be converted into screen coordinates, but the reverse should be avoided, particularly the conversion should only be done once if possible. The functions in the form gfxTerrainToScreenXCoord() and similar are for converting between the two, their purpose should be fairly obvious. Coord functions calculate absolute coordinates, whereas Dimen functions simple calculate dimensions. Functions that just draw to the screen (such as gfxDrawCircle) take screen coordinates, whereas functions that have to do comparison of the environment to decide what to draw (such as gfxDrawArea or gfxDrawTerrain) take terrain coordinates. In fact, gfx.c is intended to be as abstract an interface as possible, so many of the screen-coordinate-using functions (such as gfxBlitTankSprite) are in fact not exported in the header file because they are low-level and not useful to other modules, which should instead use the higher-level interface (in this case, gfxDrawTank). Tanks color values: (16-bit hexidecimal RGB components, which is what KOTH uses) R G B Red FFFF 0000 0000 Green 0000 FFFF 0000 Blue 8888 8888 FFFF Cyan 0000 FFFF FFFF Magenta FFFF 0000 FFFF Yellow FFFF FFFF 0000 White FFFF FFFF FFFF Indigo 8888 0000 BFFF Orange BFFF 8888 0000 Aqua 0000 BFFF 8888