Obtaining the Code
I intend to release the compiled mod to public JK2 sites for users. I
expect that I will also release the source code to these sites eventually.
In the interval, I would like to retain a little more "contact"
with interested developers. Note that if you want to make changes and
build the code, you will need Microsoft Visual Studio. If you just want to
read the code to figure out how things really work, or just for the heck
of it, that is fine too.
If interested, please send me an
e-mail and let me know you would like to get the code. I will send you
a URL where you can obtain a code package.
The Code
I confess to being very new to the Microsoft Development environment
and to the arcane mysteries of game code. As such, some of the things I
have to say here may be mistaken early impressions. However, I am not new
to coding, so I wanted to make a section of documentation to provide as
much guidance as possible to those who may build on this work.
By way of apology I must admit that I have not followed good coding
style and carefully built my changes to the code in blocks that can be
included or excluded by pre-processor #ifdef statements. My only excuse is
that all of the work done by Tchouky and Dest on Jedimod and other authors
of the jetpack mod, etc. fails to meet this standard also! I am however,
careful to keep the code under source control so that I can track, and
roll back if necessary, any changes that I have made.
Ideally, I would like to be able to distribute and receive code changes
by "patch" modules. In the UNIX world this is pretty standard,
but I don't see a mechanism for doing this in the Microsoft development
environment. Failing this, or until someone shows me a better way, it
would be very helpful if folks who build on this work and want the changes
incorporated into the "official" mod submit changes that are
carefully marked. The use of #ifdef statements would be just marvellous.
Of course, I can use windiff if I must to find the changes ;-).
The rest of this section is given over to describing how the code
modifications were performed. Hopefully, this will show a number of
mechanisms and techniques available for implementing future changes. I
certainly found that a lot of trial and error was required to fully
understand how the game worked, particularly when you want to implement
code that requires co-ordination between the clients and server
components. There are also a number of real limitations on some of the
changes you can make. This is due to the fact that the entire code for the
game is not available. Only the code sections that control game features
and entities is available. The base level quake engine code is not
available. That means that you cannot change any of the base level data
structures, particularly for client-server communication.
NOTE: the following sections are substantially incomplete. I will
work on them when time allows -- the fate of all code documentation...
sigh.
ClientCompile
The Grapple
As implemented in Jedimod the grapple overloads the +use button. That
is, the key you assign to the "use" function is effectively
re-assigned to operate the grapple. This is a huge problem for most
multiplayer maps, but there are a few maps developed by the JK2 community
that require explicit "use" of door, panel, and landing pad
actuators. By assigning a "new" button for grapple, we can keep
the original +use button for its intended purpose.
There are at least two types of "buttons" defined in JK2 code
(or quake). The first type of button is a toggle. A toggle button just
changes the state of some entity from state A to state B. The second press
of that button changes the state back from B to A. Examples of such
buttons are: toggling the state of a force power such as force speed,
absorb, rage, etc.
A second type of button is an action button. Action buttons are not
toggles and only are considered "on" while the button is being
pressed. Once the button is released, the action is turned
"off". Examples of such buttons are: force grip, force
lightning, force jump, or attack.
Note that the user can bind any key to a button, so this has
nothing to do with what key you choose to use to "press" the
button.
The first type of button, the toggle, is usually implemented as a
"command". That is, you could also make the button toggle by
typing the appropriate command on the console. Pressing a key that is
bound to this type of button is equivalent to sending the command on the
console. This command is interpreted by the server and changes any
necessary state variables that might be associated with the player. For
example, pressing the force protect button causes a variable in the client
state representing the fact that they have engaged force protect to
"true". Any action on that player that might be effected by
force protect will check that state variable to determine the correct
action to take. So, if you are hit by a saber while the force protect
state variable is true, the server will take damage from your force pool
rather than shield and health.
The second type of button is implemented differently. While these
buttons can also be effected by console commands -- for example, the
console command +moveup will cause the force jump button to be pressed,
their state is communicated to the server directly with player state
information. Another way to think about this is that the client changes
the player state information sent to the server for this type of button,
rather than sending a command to the server which might then be used to
set some player state information. These types of buttons are limited in
number because they are all sent as a single bit in a 32 bit integer value
that is part of each player entity state information.
Each bit in this integer represents a button being pressed (1) or not
(0). When the server receives this state information is can mask each bit
as needed to determine if a particular button is pressed. For example, the
server can see if the attack button is being pressed by the client by
checking the BUTTON_ATTACK bit.
The original grapple used the BUTTON_USE bit, which is also used by the
server to see if the client is pressing the "use" button. A
careful scrutiny of the bit fields currently used by JK2 reveals that only
the first eleven bits of the "button" state variable are used.
Generically, the console command, or key binding used to actuate these
buttons is +buttonN where N is the index of the bit field. The buttons
+button1 through +button11 are already redefined and used by +attack, +moveup,
+force_drain, etc. However, +button12 (and others higher) are free.
Thus the improvement for the grapple was implemented by setting the
user interface code to bind the grapple key to +button12 and setting the
server code to look for the bit field represented by a mask of 8192 (2^12,
or BUTTON_GRAPPLE) to indicate the use of the grapple.
Note that the grapple is one of those devices that requires the
constant press of a button to control -- hence the choice of the action
button type rather than the toggle.
Since both the client and the server has the same information from the
player state, each can manage the appropriate action while the grapple
button is being pressed.
The Jetpack
Duel Types