Jump to content

Basics of Jedi Knight coding (Updated 12/16/16: Please Contribute!)

Recommended Posts

Update 12/16/16: 

I want to expand and improve this article. As it is it's kind of a vague outline based only on my own limited knowledge. The purpose of this guide is teach how the source code of Jedi Academy and Jedi Outcast is structured, especially concepts that are not immediately obvious by just copying and editing the code. Please help me improve and correct this article by posting below with anything you think might be useful.


Helpful Resources:


IOQuake3 Wiki: http://wiki.ioquake3.org/Game_Development

Contains a lot of useful information directly relevant to Jedi Knight coding. It explains a lot of conventions like entities, vectors, and the internal libraries (the Q functions) used by Jedi Outcast, Jedi Academy, and originally Quake 3. I highly recommend at least skimming this section and the main page linked above for anyone who wants to get into coding for OpenJK. Technically this is the wiki for a Q3 modification called ioquake3, like OpenJK except for the original Quake 3 game.


OpenJK SP Coding guide: https://github.com/JACoders/OpenJK/wiki/Singleplayer-Overview

Explains some concepts of how the Single Player game code is structured in OpenJK. Describes how to switch between JK2 SP and JA SP using the shared jasp executable, how networking support works in SP, a little bit about how to add new values for save games.


Coding Tutorials Section on JKHub: https://jkhub.org/tutorials/category/1-coding/

Many helpful guides here if you are just getting your workspace set up or trying to do something specific. A few of these are referenced below.




This guide to help people jump into making code modifications for Jedi Academy and Jedi Outcast without getting lost or confused. We strongly recommend using OpenJK to make SP and engine mods, and JA++ to make JA+ or general MP modifications, and this guide assumes you are using them. If you need to setup OpenJK for compiling, check here for a step-by-step walkthrough. This guide also assumes some basic knowledge of programming, but if you want to get your foot in the door with learning C/C++, check out this guide written by Eezstreet.


If you are brand new to modding these games, keep this in mind: Jedi Knight II: Jedi Outcast (JO) and Jedi Knight: Jedi Academy (JA) both have two parts, Single Player (SP) and Multiplayer (MP). The two parts of the game are similar but they have their own code files and executables, and are written in very similar but different languages, that is, SP is written in C++ and MP is written in C. All you probably need to know is that C++ almost entirely contains and can be used to write C but has many new features, syntax, and external libraries added, some to replace old C functions.


At this point, you may be wondering even with this guide, how will you ever find your way through this giant crazy mess of source code that is Jedi Academy and Outcast? Look at file names, and use the search function of Visual Studio. It is your friend. Raven writes a lot of comments in their code, and the functions and files are all named according to their purpose. If you've ever modded these games before outside the code, just try searching keywords like Class_Imperial or WP_BLASTER or FP_PUSH (the list goes on and on) and you'll get tons of hits.


General Code structure ---

The code of both Single and Multi Player is organized into client and server side; client-side files a cl_ (this is the .exe in SP) or cg_ (the cgame/client-game code), and server-side code has the g_ prefix . Files with code that is shared between the cgame and server game code start with the b_ or bg_ prefix. What effects does this have?


Multiplayer: when you edit a bg_ file you must compile all projects/DLLs for the game to run properly (that means cgamex86, jampgamex86, and uigamex86 DLLs). You can also separate the code for clients and servers; clients don't necessarily need to have server code, and vice versa. Some mods like JA+ can be played without a client-side plugin. ClientThink (which calls many other gameplay functions) is called whenever a packet arrives which could be multiple times per frame, unless g_synchronous clients is set to 1. The G_RunFrame call tree is only called once per server frame (server fps is determined by sv_fps).


SP: the game is actually run as if it were a multiplayer game in some ways, with the Player and NPCs actually treated as clients in the code and the gameworld and gameplay mechanics treated as the "server".  The jagamex86 DLL contains the cgame and server game code, and the executable is called the client and it contains the UI/menu code. When the game loads up initially only the executable (and renderer DLL?) is loaded. The jagamex86 DLL is only loaded when you start a gameplay session by loading/saving/starting a new game. Other things to keep in mind are that the player is ALWAYS client number 0, and this is often used to separate code that the player uses from that of NPCs. ClientThink (the exact name in SP is ClientThinkReal or something similar) that is called every frame for every client as long as that client has a BSTATE that can be executed.


Also worth keeping in mind is that with OpenJK, Jedi Academy SP and Jedi Outcast SP share the same executable file. More detail to be added later.


Internal Libraries ---

If you look through the source code, you might notice two things... some functions that start with Q_, and that nowhere in their code does Raven include or make calls to external libraries you might be used to using (like vectors or the C++ string class). The Q_ functions are Raven's versions of the functions normally included in the standard library for C (for example Q_strcat is their version of the strcat function in C), therefore most of these functions will have the same or a similar name and usage to a C function.


Why did Raven write their own internal library? This way, they don't need to to import any libraries into their game logic code, nor do they have to worry about changes to an external library affecting their game logic code. In OpenJK, there is some support for external libraries from the STL, like std::vector. Can anyone add clarification for which libraries are supported?


Look up C functions here: http://www.cplusplus.com/ (Don't let the name fool you, they have all the documentation for C as well, and C++ contains 98% of C anyway)


Entities ---

These are the meat of the game. These are the same as entities used in maps; that is anything from a button to a door, to an NPC or the Player(s). As previously stated, Players and NPCs are a special kind of entity that is also a client; this is true for both Single and Multiplayer in JA/JK2.


In Single Player all entities are stored in an array called g_entities. (Can anyone confirm for multiplayer?) The index of the array where a client is stored in g_entities is equivalent to s.number. Example: I have an entity called ent that is a stormtrooper, and ent->s.number is 104. Therefore that stormtrooper will be in g_entities[104]). The player will always be stored in g_entities[0].


More info here.


Vectors --

If you've taken a high school physics class, you should know a bit about what these are, but I'll try to explain anyway.


Vectors are lines that have a length (or magnitude), a position (in x y z coordinates) and also a direction (in x y z values) in a 2D or 3D space. They can be used to make boxes or shapes (like for example, a rectangular box for collision detection around a lightsaber blade). These are used by the code to test for: collision, for a clear path to or line of sight, how close/far away something is, and probably more. The main type used in Q3 is vec3_t. Raven has their own functions to do vector operations like adding, subtracting, and dot/cross products which make vectors useful.


More info here.

Edited by Dusty
added moderator note
Smoo, Asgarath83 and Futuza like this
Link to comment
  • 4 months later...
  • 4 years later...

Can i ask some help. I trouble with Cmake. Every time error and error come. 


CMake Error: Error SetGlobalGenerator called with null

CMake Error: Error: generator : NMake Makefiles
Does not match the generator used previously: Visual Studio 16 2019
Either remove the CMakeCache.txt file or choose a different binary directory.



Link to comment
  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...