Last Updated: 24. November, 2022
UOX3 Version: v0.99.6-RC1
This section contains the latest notable updates made to the style guide.
This style provides a common, shared set of (lightweight) guidelines for anyone who wishes to contribute source code and/or scripts to the UOX3 project, in order to help ensure that those contributions follow a standardized approach not only for code style, but also for conventions and practices used in the project. This also improves the maintainability of the project in the future.
The UOX3 code base has historically been a hodgepodge of different styles and approaches, written by people with varying programming skills over a period of more than 20 years, and that history highlights the need for a standard that can be followed when working on the project.
These guidelines are not meant to be understood as hard requirements, yet the closer to the guidelines that new contributions adhere to, the easier it will be to review any changes in context of the current code base and - if accepted - merge those contributions in.
Above all else, please take to heart the general guidelines listed below and follow them as best you can:
If you have identified a need for a change that conflicts with the above points, or with anything else in this Style Guide, create a new topic on the Communtiy Forums and state your case, or bring it up in the Discord chat. None of these "rules" are etched in stone, they can (and should) be challenged, updated and added to when appropriate.
Currently, any new code written for UOX3 should target C++11 to C++17, and aim to be cross-platform conforming across Windows, Linux and macOS platforms, when compiled using VS2017-2022, GCC/G++ v8-9 and/or CMake v?. Avoid using features specific to C++20 or newer, to not introduce additional compiler dependencies and requirements.
UOX3 aims to be cross-platform conformant across (at least) 64-bit Windows, Linux and macOS platforms, with feature parity between each platform. Implementations specific to any one particular platform should be avoided if possible, though there might be exceptions for special cases where platform-specific handling is unavoidable - such as when dealing with console and/or networking.
Any code being contributed that does not compile, run and function the same on all the above-mentioned platforms will probably not be approved for inclusion in UOX3 until/unless necessary changes have been made to comply with the above.
Always prefer self-descriptive names (skillUsageDelay instead of skUseDel, itemCount instead of ic)
If creation of new source files is necessary, use camelCase when naming the files to make the name more readable in a list of other, perhaps similarly named files. Try to stick close to existing naming practice.
Use PascalCase for class/function/method names.
Use camelCase for variables, non-method class/struct members and function/method parameters.
This Style Guide makes no differentiation between functions and methods for the purpose of comment blocks.
//o-----------------------------------------------------------------------------------------------o
//| Function - CSocket::AddTrigWord()
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Adds trigger word to list of trigger words detected in player's speech
//o-----------------------------------------------------------------------------------------------o
//o-----------------------------------------------------------------------------------------------o
//| Function - CSocket::TargetOK()
//o-----------------------------------------------------------------------------------------------o
//| Purpose - Gets/Sets socket property to indicate whether waiting for client target
//o-----------------------------------------------------------------------------------------------o
auto CSocket::TargetOK( void ) const -> bool
{
return targetok;
}
auto CSocket::TargetOK( bool newValue ) -> void
{
targetok = newValue;
}
auto CItem::GetType( void ) const -> ItemTypes
{
return type;
}
auto CItem::SetType( ItemTypes newValue ) -> void
{
type = newValue;
}
Example:
// Not ideal
std::string myString;
myString = "Hello";
// Better
std::string myString = "Hello";
// Preferred
auto myString = "Hello"s; // note the 's' at the end
// Using auto with a variable
auto myChar = "Hello"; // type is const char* pointer to const char[5] array
auto myString = "Hello, World!"s; // type is std::string (note the 's' at the end)
auto myVar = GetMyVarValue(); // type depends on what GetMyVarValue() returns
// Using auto with functions
auto CItem::SetRegion( UI16 newValue ) -> void
{
regionNum = newValue;
UpdateRegion();
}
auto CItem::GetRegionNum( void ) const -> UI16
{
return regionNum;
}
using R32 = float;
using R64 = double;
using UI08 = std::uint8_t; // 0 to 255
using SI08 = std::int8_t; // -128 to 127
using UI16 = std::uint16_t; // 0 to 65535
using SI16 = std::int16_t; // -32768 to 32767
using UI32 = std::uint32_t; // 0 to 4294967295
using SI32 = std::int32_t; // -2147483648 to 2147483647
using UI64 = std::uint64_t; // 0 to 18446744073709551615
using SI64 = std::int64_t; // -9223372036854775808 to 9223372036854775807
// Good - C++-style cast
static_cast<R32>( double_value )
// Avoid - C-style cast
( R32 )double_value
For consistency with the rest of the code base, indent your code using tabs (size: 4), not spaces.
case CCP_FAME: *vp = INT_TO_JSVAL( gPriv->GetFame() ); break;
case CCP_KARMA: *vp = INT_TO_JSVAL( gPriv->GetKarma() ); break;
case CCP_ATTACK: *vp = INT_TO_JSVAL( Combat->calcAtt( gPriv, true )); break;
case CCP_CANATTACK: *vp = BOOLEAN_TO_JSVAL( gPriv->GetCanAttack() ); break;
case CCP_BRKPEACE: *vp = INT_TO_JSVAL( gPriv->GetBrkPeaceChance() ); break;
case CCP_HUNGER: *vp = INT_TO_JSVAL( gPriv->GetHunger() ); break;
pStream.ReserveSize( 44 );
pStream.WriteByte( 0, 0x1C );
pStream.WriteShort( 1, 44 );
pStream.WriteLong( 3, 0xFFFFFFFF );
pStream.WriteShort( 7, 0xFFFF );
pStream.WriteString( 14, "System", 6 );
pStream.WriteByte( 20, 0 );
( x, y, z )
void MyFunction( std::string myString, int myInt )
var foo = x - 1;
var bar = x <= 10;
bool myClass::MyMethod()
if( x == 1 )
for( int i = 0; i < 10; ++i )
if( foo || ( !bar ))
if(( x == y ) && ( z != x ))
[x, y, z]
static_cast<SI16>
if( something )
{
...
}
void myFunction( std::string myString )
{
}
if( something )
{
// one liner
}
bool cScript::OnCreate( CBaseObject *thingCreated, bool dfnCreated )
{
if( !ValidateObject( thingCreated ))
return false;
std::string functionName = "onCreateDFN";
...
}
for( auto &MapArea : MapRegion->PopulateList( this ))
{
if( MapArea == nullptr )
continue;
// First remove nearby characters from sight
...
}
UOX3 Style Guide for Code by Xuri @ Copyright 2022-2024
Built upon FAQ Template framwork provided by CodyHouse.