-
-
Notifications
You must be signed in to change notification settings - Fork 118
Architecture
If you are unfamiliar with the codebase, this document will help you find your way. The C-Dogs SDL codebase has grown quite a lot, so can be confusing to jump into initially. The architecture will be described in very broad terms and details will be subject to change (or this document goes out of date). Always defer to the code itself rather than taking this as gospel.
The main()
function resides in cdogs.c
at the bottom; this is where major components are initialised and destroyed after the game ends. The game itself starts in the main menu, which leads to a series of game screens, which is probably not of interest at this point. The game loop is inside game.c
, and is a typical update/render loop (except being very messy). If you are familiar with game programming patterns and are handy with a debugger, feel free to break into this and plug away.
Menus/Game Screens: The game begins in a series of menus or game screens. Most of the menus are split between menu.c/h
and mainmenu.c/h
, where the former is mostly generic, and the latter creates the main menu system.
Config: Inside the options menus, the user can change the game's config, which is stored in a global structure in config.c/h
. Many of the game's components refer to this global structure, as a way of realising config changes.
Campaign: When a game mode/campaign is selected, the game loads a campaign file from the /missions
game directory into a campaign object, which is simply a collection of Missions with some metadata such as the title of the campaign. Most of this is found in campaign.c/h
. Campaign also stores the big collection of characters used in its missions.
Mission: There are currently two types of missions: classic and static. Classic maps come from C-Dogs, and are the procedurally-generated maps with randomly placed rooms. Static maps are statically laid out via the editor. Missions also store other attributes regardless of their type such as objectives, available weapons and characters used. Please see the editor to make sense of how missions work.
Map: Maps are loaded from missions. Maps are little more than a collection of tiles, ordered left-to-right and top-to-bottom, in a rectangle.
Tile: tiles are 16x12 chunks in the map. C-Dogs is a tile-based game; all game entities reside on a tile, and this is tracked in the tile's things collection. As well as having a position attribute, when entities are moved, across different tiles, they are removed from the last tile they were on and added to the new tile.
Actor: these are the characters (PC and NPC) in the game. They can have weapons and are manipulated using commands, which correspond to player controls. This resides in actor.c/actor.h
. Refer to the various ai source files to see how the AI systems control actors - ultimately they return a set of commands.
Object/TObject: these are the static, tile-based objects in the game, such as crates and barrels. Most are destructible, although some are just decorations (wreckages, marks on the ground/walls). Be aware that pickups (including keys) are not objects, even though they don't move. See objs.c/h
.
MobileObject/TMobileObject: these are all the moving objects, as well as pickups including keys. This includes things such as bullets, grenades, gas clouds, explosion clouds. The code locations are currently spread between objs.c/h
and bullet_class.c/h
.
DrawBuffer: for rendering, the process starts in draw_buffer.c/h
. This works somewhat like a camera; a draw buffer is created at a certain offset (camera position), and the buffer is filled with a rectangular section from the map. The draw buffer also handles line-of-sight and drawing order.
Blitting, GraphicsDevice: C-Dogs currently handles drawing by blitting pixels itself to a buffer in GraphicsDevice, and pushing it all at once to a single SDL_Surface. The various routines in blit.c/h
work with _Pic_s and _PicOld_s, which are just pixel/palette arrays, and convert/push them to the graphics buffer. Some manipulation such as masking/tinting is available here. There are plans to convert this to more efficient use of SDL_Textures.
Coordinate systems: C-Dogs has three integer-based coordinate systems. All three are in screen coordinates, not world coordinates (i.e. down is positive Y). This is perhaps because it was written when floating-point was very slow, but it also helps keep the game deterministic, so no changes are planned. From big to small they are tile coordinates, real coordinates and full coordinates. Tile coordinates determines which tile they are on. Real coordinates refer to pixel coordinates; anything rendered, and static entities use this system. Full coordinates subdivide real coordinates by 256 (or << 8
if you spot this in the code). Moving entities use this system so that smooth movement is possible. There are conversion routines found in vector.c/h
to convert between coordinate systems.
Here are some things you can try to see if you understand the code:
- Change the knockback of bullets (hint: start forwards from actor updates, or backwards from the collision handling code)
- Enable all actors to slash each other as if they had the knife equipped (hint: check the collision code)
- Change the line-of-sight code so that players can't see past objects (hint: the LOS code is depending on a utility function that returns whether one can see past a tile)