

Information for the BZFlag Developer
====================================

BZFlag source code lives in the following directories:

applications
------------
src/bzadmin	- the BZFlag admin tool and chat client
src/bzflag	- the BZFlag client
src/bzfs	- the BZFlag server
tools/		- various helper tools

game dependent libraries
------------------------
plugins/	- optional server plugins
src/game	- core game logic

game independent, platform independent libraries
------------------------------------------------
src/3D		- 3D geometry  (actually; not much 3D here, fonts and textures)
src/common	- general utility
src/geometry	- geometric mathematics
src/mediafile	- sound and image file support
src/obstacle	- collision detection
src/ogl		- wrapper classes for OpenGL
src/scene	- scene graph

game independent, platform dependent libraries
----------------------------------------------
src/date	- build dates and versioning
src/net		- networking
src/platform	- general platform dependent code

"other stuff"
-------------
Xcode/		- project definitions for Apple XCode
MSVC/		- project definitions for Microsoft Visual C
data/		- images, sounds, fonts, translations
include/	- public headers
m4/		- configuration macros
man/		- documentation in manual page format
misc/		- kitchen sink of anything
package/	- packaging aids for specific operating systems

Note that only a few directories contain code directly related to the
game BZFlag.  In particular: bzflag, bzadmin, bzfs, plugins, and game.
(And obstacle, but that will hopefully be made more general some day.)
The rest of the code could potentially be used in a different game.
If your code is BZFlag specific then it should go into one of the
above directories (game if it can potentially be used by more than one
app, otherwise into the appropriate app directory).  If not then put
it in one of the other directories or add a new directory.


Coding conventions
==================

If you plan on contributing any source code to BZFlag, we would like
you to follow certain conventions.  Contributions that don't conform are
likely to be ridiculed and rejected until they do.

Code Organization
-----------------
Follow the above organization when introducing new files.  Any code
that would potentially be useful in another game goes outside of the
app directories and outside the game directory.  Platform dependent
code normally goes into platform, net.  Code that is specific to
BZFlag should go into the game directory.  There are README files in
most all of the source directories that describe what belongs in those
directories

Header files that are private to a library go into that library's
directory.  Header files exported from a library go into the include
directory off the top-level.  Header files for classes introduced in
an application directory should never go into a #include outside of
that application directory.

C files use the .c extension.  C++ files use the .cxx extension for
everything except plugins which use the .cpp extension.  Header files
for both C and C++ use the .h extension.

Headers
-------
Don't put interface headers into the common.h header.  Class interface
headers should include just what is necessary to make the interface
work.  The source implementation file should include it's interface
and whatever else it might need specific to the implementation.  For C
code, the header file should include everything the C code needs
(otherwise there's no point to the header) including prototypes for
all non-static functions.

The include order for headers within a header is common.h, system
headers, common interface headers, and then local interface headers.

The include order for headers within a source file is its own
interface header if there is one, or common.h otherwise, system
headers, common implementation headers, and then local implementation
headers.

Adhering to this order will avoid nasty ordering dependencies and
makes it easy to change things down the road.

Ideally, there should be one class per file.  There are, of course,
exceptions to this such as simple utility classes that are local to
that same file's implementation.  If it's a public class, though, it's
usually best to separate it out into another file by itself.

Avoid "extern" in C files.  This prevents the compiler from type
checking in most cases.  If you need access to something, put it in a
header.  That's what headers are for.

C++ features
------------
Earlier versions of BZFlag avoided certain features of C++ that have
matured enough to be widely and well supported.  These features are
now permitted and encouraged including:

  bool			-- the boolean type and True and False are gone
  standard C++ library	-- use where appropriate (AList is gone)
  templates		-- use sparingly where appropriate

These should still be avoided:

  exceptions		-- still poorly supported on old lame compilers
  run-time typing	-- if you find yourself needing RTTI, its often a
			   sign of bad design.  Try to find another way to
			   implement your idea.

Multiple inheritance is strongly discouraged unless in the Java style
of single implementation inheritance and multiple interface
inheritance.  Multiple inheritance otherwise can quickly lead to very
hard to understand code.

To prevent ambiguity, do not use the C++ "using" keyword just to avoid
typing explicit references to the "std" namespace.  Other namespaces,
especially those defined in BZFlag code, may be introduced with
"using" when it improves code readability.

Only use standard C++ language features, at no time should any
compiler-specific extensions be used (GNU or VisualC++ extensions).
If an extension can not be avoided then it must be able to be disabled
or replaced using a #define in config.h.  BZFlag is a cross-platform
application so it is important to remember that not all builds will
use your specific compiler. This also includes not using features
in C99 and C1x as the windows compiler only supports C++11 and
there are some features in the later C versions that were not adopted
by the C++ standard, namely the 'not' and 'or' keywords instead of ! and ||.
Also MSVC seems to be a bit picky about what bits of older standards it
supports. When the windows compiler supports this, we should stick with
a consistent method and not mix AND with &&. Use the same type of operators
that are in the existing code.

Formatting
----------
Everybody has their own style and has things they don't like about any
other style.  Well, we can't have a zillion styles in the code, so
follow the BZFlag style if you want your contribution included. 
BZFlag is formatted using the Allman Style, and this is enforced
with the artistic styler, astyle, using these command line options:

astyle --style=allman -nxjQ --convert-tabs --max-code-length=120 \
  --recursive './*.cxx' './*.cpp' './*.h'

The source code serves for examples of the following rules.

  1)  Indents are 4 characters.  Tabs are 4 characters.  There are vi
      and emacs settings in each file to adopt, enforce, remind, and
      encourage this convention.  Suggestions are welcome here for
      setting up other environments.  Here are the lines that should
      be included at the end of source files:

	// Local Variables: ***
	// mode: C++ ***
	// tab-width: 4 ***
	// c-basic-offset: 4 ***
	// indent-tabs-mode: nil ***
	// End: ***
	// ex: shiftwidth=4 tabstop=4

      In emacs the the indent-region command (bound to C-M-\ by
      default) does a good job of making the needed changes to conform
      to this convention.  Installing exTabSettings in MSVC will make
      it conform.

  2)  The opening brace of all blocks goes on the next line following the
      statement introducing it.  The closing brace is indented
      like the statement except for functions where it aligns with the
      open brace.  For example:

	void foo()
	{
	  for (;;) 
	  {
	    if (expr) 
		{
	    }
	  }
	}

  3)  An else clause goes on next line just like the opening brace:

	if (expr)
	{
	} 
	else 
	{
	}

  4)  If *either* the if block or else block requires brackets then
      they both get brackets.  if neither requires brackets then use
      brackets on both or neither at your discretion.  In case both
      styles are allowed, don't change the existing code just because
      it is not coded like you prefer.

  5)  When using `delete' or `delete[]' don't bother to test the
      pointer if it's NULL first.  use new and delete rather than
      malloc and free.

  6)  Data members should be usually private unless making plain old
      data.  separate methods from data in class definitions with
      (possibly redundant) access specifiers.  public c'tors/d'tors
      should be first, followed by public member functions, protected
      member functions, private member functions, and data members.

  7)  Macro names are all capitals, class names have the first letter
      of each word capitalized, all other names have the first letter
      of each word except the first capitalized.  Only macros may use
      underscores, except for in the names of method parameters where
      a leading underscore is allowed to make it different from a
      member variable.

	#define FOO bar
	class MyClass 
	{
	public:
	    void addStuff(int addMe, int _y) { y = addMe + _y; }

	private:
	    int y;
	};

  8)  Put spaces after statements followed by expressions and spaces
      around operators.  For example:
	if (a == b)
      not
	if(a==b)

  9)  Do not leave old commented code hanging around and do not submit
      patches with "// Added by foo on xx" comments.  This is what
      version control software is for.

 10)  Do not code very long lines.  Try to stay within 120 columns if
      possible, but don't go over 200 if you should raise that limit
      for some reason.

Violations of these rules in the existing code are not excuses to
follow suit.  Non-conforming code may be fixed.  Patches to
non-conforming code should follow the non-conforming code's style if
following the rules would cause an ugly mess.


Performance
-----------

If the code you are editing is in a performance-critical section of
BZFlag (that is, if it is called multiple times per frame on the
client, or per server loop on the server), you should profile the
proposed changes.  The new code does not necessarily need to be
faster, but a quantitative analysis is required.


Committing Changes
==================

Make atomic changes in a way that a system will be working, or at least
will compile successfully, before and after committing a set of changes.

Try to separate out bigger commits into smaller ones.  In particular,
if a change involves multiple functionality changes, the commit should
be broken up into smaller coherent chunks.  This way if a bug or other
issue with a particular commit is later encountered, the change can be
more easily isolated and undone or fixed.

Submitting changes
--------------

If you do not have source code commit access and would like to propose
a change for inclusion, you should create a pull request. Requests
should be submitted on GitHub at:

https://github.com/BZFlag-Dev/bzflag/pulls

In general, these should be relatively small succinct changes that
can be readily reviewed, tested, and applied.  Changes that are
difficult to review, test, or apply will likely not be accepted.  That
said, creating useful changes that have been discussed with the
existing developers is one of the more immediate means to become a
developer for BZFlag yourself.

Licensing and Developer Agreement
---------

By committing to a source code repository or submitting a patch/pull request, you
the developer are assigning copyright of the submission to the project maintainer (Tim Riker),
and his successors, as defined in the BZFlag Developer Agreement located at
https://github.com/BZFlag-Dev/bzflag/wiki/Developer-Agreement

Grant of Copyright Assignment
Each Contributor hereby assigns to the project maintainer all right, title,
and interest worldwide in all Copyright covering the Contribution.

All submissions are subject to these terms.

Notes.
You may not place any restrictions on how the project maintainer (Tim Riker)
maintains or handles your submitted works.  Works that are derivations of
existing works in the project are subject to the current project licenses
(LGPL and MPL) and any other licenses the project may be released under.
Authors that submit works must have the legal right to agree to these terms,
either as original author or authorized licensee of derived works.

Testing
=======

If you have rendering problems, you might want to try setting:

LIBGL_ALWAYS_INDIRECT=1

On many systems this will force software rendering.  It will greatly
reduce the performance, but may assist in solving rendering issues.

A debug build may be specified via:

./configure --enable-debug

A profile build is specified via:

./configure --enable-profile


Sounds
======
Sounds are stored as uncompressed 22.050KHz WAV files.  We will likely
move to OGG someday.


Images
======
Images are stored as portable network graphics (.png).  Compression is
okay, but no additional options such as interlacing.


BZDB
====
BZDB is the generic name:value pair database within bzflag and
bzfs.  It is useful for data that can be serialized to a string that
needs to be accessible to many areas of the code.  It also provides
facilities for saving persistent pairs to the config file and
downloading variables from the server.

BZDB is not an object broker, and isn't meant to be.  If you have data
within an object that needs to be accessible from a number of places,
but don't want to pass the object around, you could store that data
within BZDB (if accessed often, such as game variables like gravity,
you will need a cached version anyway to avoid the overhead of
lookup).  Using BZDB adds unnecessary overhead if objects generally
keep their data hidden without needing persistent state.

Basically, if your data can be serialized to a string, and it makes
sense to do so (eg: config file option, game variable downloaded from
server), use BZDB.  If you wanted an object broker, use a freakin'
global.


Version numbers
===============
The BZFlag versioning info is defined in:   include/version.h

There are a number of #defines in that file that define the Major,
Minor, and Revision versions, as well as the build type, build date,
build user, and network protocol version.

The BZFlag version number is in the format of:

  MajorVersion.MinorVersion.Revision

All "development" versions use an odd number for the minor version
number.  All "release" versions use an even number for the minor
version, e.g.. 1.9.x is a development version for a future 1.10
release.  Release versions also use even revision version
numbers.  Maintenance work is done on odd numbered revisions and
releases are even numbered.  For development versions the revision
version represents significant feature changes or stages in a
development version, such as a change to the network protocol or a
move to a definite testing stage.  For "release" versions, the
revision represents patches or bug fixes to the base release, but not
new feature development.  This allows the developers to "leave some
room" for patches and emergency fixes to a release line.

The network protocol version is a string.  When changes to the protocol
are made that render it incompatible with prior releases, the version
number of the protocol must be changed.  This is necessary to prevent
incompatible clients from attempting connections.  When a change is
made, the network protocol version needs to be set to the application
version that is current at that time.  This is also when the revision
of the application should be incremented.

The displayed application version includes additional information in
the format:

  Major.Minor.Revision-BuildDate-BuildType-BuildOS

BuildDate represents the date of the build in the format YYYYMMDD.
This string is generated during runtime by the compiler's preprocessor
__DATE__ macro.

BuildType is a string that represents the intended use of the build.
For development releases, the build type is normally "DEVEL".  For
testing releases, the build type can be "ALPHA", "BETA", "RC1" etc.
For final release versions the build type should be "STABLE" or
"MAINT".  The build type provides a human readable keyword for the
version and intended or expected stability of the build.

BuildOS is the operating system that the building system is running;
on systems that use the automake build system this is automatically
generated.

If a build includes SDL or SDL2, the build string ends in "-SDL" or
"-SDL2", respectively.

Making a Release
================
In order to make a release, there are handful of steps that need to be
taken.  If any step fails to be completed successfully, the release
cannot proceed.  A checklist of items to be completed follows:

- All code is committed to the repository.

- ChangeLog includes a comment for all items added since the previous
  release, preferably denoting who made what changes.

- Man files and bzfs.conf files are updated with latest changes.

- Version numbers are updated to the next expected release number.
  This minimally includes updating README, ChangeLog, configure.ac,
  buildDate.cxx, Version.rc, Xcode/BZFlag.xcodeproj/project.pbxproj,
  Xcode/BZFlag-Info.plist, and the title.png image.  Version numbers in all
  other platform-specific README.* files should also be verified.

- Edit updateConfigFile in clientConfig.cxx to update any necessary
  configuration settings, and remove the 'break;' from the latest switch
  case so that it will update the config version.

- When BZ_PROTO_VERSION has already changed since the last release,
  increment it one more time in buildDate.cxx, bzfquery.*, and
  bzls.lua to distinguish the new release from development versions.

- BZ_BUILD_TYPE is changed to MAINT in buildDate.cxx.

- Update package/win32/nsis/*.nsi (for windows) with appropriate
  version numbers.

- Perform a "make distcheck" on multiple (preferably all) platforms.
  This will verify that a proper source distribution can be made.
  Also verify that all non-autotools builds build properly.

- Tag the release.  Tag format should be consistent with the other
  tags using the format of vMAJOR.MINOR.RELEASE.
	e.g. git tag -a v2.6.0 -m 'Version 2.6.0 release'
	     git push origin v2.6.0

- Perform a "make dist" generate a source release tarball.

- Verify that the source tarball can be expanded, builds, and runs.

- Build platform-specific binaries from the source tarball.

- Post the source tarball, zip and platform-specific binaries to
  SourceForge.  Update the per-operating system default download
  settings.

- Add a new page to the BZFlag wiki for the new version and update
  other pages (including Download, Releases, Versions) appropriately.

- Increment and commit the version number in configure.ac and other
  files (see above) to the source repository so that later builds are
  immediately distinguished.  Also, change BZ_BUILD_TYPE back to DEVEL
  in buildDate.cxx.

- Update the following:
https://github.com/BZFlag-Dev/bzflag.org
https://github.com/BZFlag-Dev/download.bzflag.org

- Post release at:
https://forums.bzflag.org
https://github.com/BZFlag-Dev/bzflag

Testing the server
==================

An example line to use for bzfs testing is:

src/bzfs/bzfs -c -d -d -d +f good +f bad -fb -j -ms 3 -password \
 password -s 10 -sa -sb -sw 1 -st 15 -world misc/maps/hix.bzw
