# Reporting an Issue
- Report all issues
- Trivial documentation issues welcome ([example](https://github.com/bwapi/bwapi/issues/616))
- Non-trivial feature requests welcome ([example](https://github.com/bwapi/bwapi/issues/393))
# Creating a Pull Request
- Do development on the [`develop`](https://github.com/bwapi/bwapi/tree/develop) branch.
# Versioning
BWAPI versioning is categorized as follows: `major.minor.patch [Beta]`
Version Component | Description
------------------|----------------
major | Increased when massive structural changes are made.
minor | Increased when breaking changes are made. Modules will need to be recompiled.
patch | Increased when non-breaking changes are made.
Beta | Appended to a major version increase until stability has been verified.
# Coding Standards
## Spacing
- Use double-spaces instead of tabs. You should be able to convert tabs to spaces automatically in your editor's settings.
- Always indent for each scope level.
- Always put a space between all arithmetic, binary, and conditional operators.
- Don't put a space between function names and the open parenthesis.
- Put a space after a comma.
Examples of spacing
~~~{.cpp}
// bad, can't tell if assignment is a typo, and
// there is a space between the member function and its parameters
if(Broodwar->canMake (UnitTypes::Terran_Marine, builder))
reservedMinerals=-UnitTypes::Terran_Marine.mineralPrice();
// good, the arithmetic is clear
if(Broodwar->canMake(UnitTypes::Terran_Marine, builder))
reservedMinerals = -UnitTypes::Terran_Marine.mineralPrice();
// bad, the scope is not indented, no space following the comma
if ( Broodwar->canMake(UnitTypes::Terran_Marine,builder) )
reservedMinerals = -UnitTypes::Terran_Marine.mineralPrice();
// good, alternative spacing style for if statements
if ( Broodwar->canMake(UnitTypes::Terran_Marine, builder) )
reservedMinerals = -UnitTypes::Terran_Marine.mineralPrice();
~~~
## Formatting
- Use [ANSI style](http://en.wikipedia.org/wiki/Indent_style#Allman_style) braces.
- Break up large single-line if statements to be multi-line if statements.
- Format constructor initializer lists as follows (so that the colon is in the same column as the commas):
~~~{.cpp}
BulletImpl::BulletImpl(BW::CBullet* originalBullet, u16 _index)
: bwOriginalBullet(originalBullet)
, index(_index)
{
}
~~~
## Naming
- Use meaningful names. If a variable's purpose cannot be identified by another project member without analysing the code, then the variable needs to be renamed.
- In local looping scopes, single-letter variable names are generally used as follows:
- `b` for Bullet
- `f` for Force
- `p` for Player
- `r` for Region
- `u` for Unit
- `i` for iterator/index
- Member variables and member function names should be in [lower camel case](http://en.wikipedia.org/wiki/CamelCase). Examples: `getUnitsInRectangle`, `wasSeenByBWAPIPlayer`.
- Constants and macros should be in ALL CAPS and words separated by underscores. Example: `PLAYER_COUNT`
- Use [upper Camel Case](http://en.wikipedia.org/wiki/CamelCase) for classes, structures, enums, and namespaces.
## Hacking
- Offsets must be in hexadecimal. Example: `0x00408CF0`.
- Offsets must be placed in `BW/offsets.h`.
- Avoid using inline assembly unless it is impossible to do so.
- Always perform version checking before making code patches, to maintain partial cross-version compatibility.
## Documentation
- Use the triple slash (`///`) format.
- Try to include as much details on the function as possible. Redundancy can express clarity.
- Include example code if possible.
- Wrap lines before the 100th column.
### Doxygen Generation
- Use `@` for doxygen commands.
- Use `@see` to refer to other functions/classes.
- When introducing a new function, include a `@since` tag with the version number.
- Include `@returns`, and `@retval` where necessary.
- When specifying `@param`, also specify if the argument is optional. Present an indented description on the next line, and also specify its default value if applicable.
### Intellisense Compatibility
- Use the [summary tag](https://msdn.microsoft.com/en-us/library/ms177242.aspx) to wrap the function/class/enum description.
- Use the [param tag](https://msdn.microsoft.com/en-us/library/ms177235.aspx) to identify all of the parameters.
- Identify if an argument is optional with `(optional)` on the same line as the tag.
- Put parameter descriptions indented on the next line, between the tags.
Examples of documentation:
~~~{.cpp}
/// Sets the size of the text for all calls to drawText following this one.
///
/// (optional)
/// The size of the text. This value is one of Text::Size::Enum. If this value is omitted,
/// then a default value of Text::Size::Default is used.
///
///
/// Example usage
/// @code
/// void ExampleAIModule::onFrame()
/// {
/// // Centers the name of the player in the upper middle of the screen
/// BWAPI::Broodwar->setTextSize(BWAPI::Text::Size::Large);
/// BWAPI::Broodwar->drawTextScreen(BWAPI::Positions::Origin, "%c%c%s",
/// BWAPI::Text::Align_Center,
/// BWAPI::Text::Green,
/// BWAPI::Broodwar->self()->getName().c_str() );
/// BWAPI::Broodwar->setTextSize(); // Set text size back to default
/// }
/// @endcode
/// @see Text::Size::Enum
virtual void setTextSize(Text::Size::Enum size = Text::Size::Default) = 0;
~~~
~~~{.cpp}
/// Retrieves the region at a given position.
///
///
/// The x coordinate, in pixels.
///
///
/// The y coordinate, in pixels.
///
///
/// @returns Pointer to the Region interface at the given position.
/// @retval nullptr if the provided position is not valid (i.e. not within the map bounds).
///
/// @note If the provided position is invalid, the error Errors::Invalid_Parameter is set.
/// @see getAllRegions, getRegion
virtual BWAPI::Region getRegionAt(int x, int y) const = 0;
/// @overload
BWAPI::Region getRegionAt(BWAPI::Position position) const;
~~~
## Language Features
- Use the `nullptr` keyword instead of `NULL`.
- Create move constructors if appropriate.
- Use the `const` keyword where appropriate.
- Use std::array instead of C-style arrays.
- Use explicit enum types (preferably enum class) instead of ints.
- Use in-class member initialization.
- Use the keywords default, delete, override, final, etc.
# Changing the API
## Adding a Virtual Function
1. Add it after all other virtual functions.
2. Label it with Doxygen `@since` tag, indicating the version it was introduced.
Note: Virtual functions are implementation defined, but Visual Studio appears to maintain some consistency regarding the use of virtual functions. Adding a new function to the end will maintain some backwards compatibility.
## Renaming a Function
1. Rename the function.
2. Create a non-virtual function with the old name that calls the new function.
3. Label it with Doxygen `@deprecated` tag and refer to the new function.
4. Optionally add a compiler deprecation warning (until we move to VS 2015).
5. Remove it after the next 2 minor versions or next major version, whichever comes first.
## Deprecating a Function
1. Label it with Doxygen `@deprecated` tag.
2. Provide reason for the deprecation and alternatives if applicable.
3. Optionally add a compiler deprecation warning (until we move to VS 2015).
4. Remove it after the next 2 minor versions or next major version, whichever comes first.