Wiki documentation guide
This page describes the structure and formatting standards that should be used when adding or editing wiki pages.
Contents
Code Formatting
This section will cover how code used in example should be formatted. It may not be fully extensive and sometimes personal judgment is needed, but it will attempt to cover as many topics as possible. These guidelines should be strictly adhered to as much as possible to create the best sense of consistency. Since ZScript's formatting is strongly rooted in C/C++, it will borrow many of its conventions from the languages, but not all of them. C# is a close equivalent to ZScript since it similarly is a memory managed language based around the C/C++ syntax.
Syntax
Formatting
- Use 4 spaces to denote an indent.
- Use Allman syntax for braces:
if (expr)
{
// Code.
}
- Always include braces:
// Wrong:
if (expr) DoThing();
// Wrong:
if (expr)
DoThing();
// Correct:
if (expr)
{
DoThing();
}
- Keywords such as
if
,while
,is
, etc. should always be lowercase. - Use proper grammar in comments, including punctuation.
- Comments should always have a space after the start and, if a block, before the end:
// Proper line comment.
/* Proper block comment. */
- Don't include a comment unless it clarifies a particularly confusing aspect of the example (and in this case, choosing a better example may be the best choice). Comments are meant to explain why something is the way it is, not what should be self-evident in the code itself when using proper naming conventions and formatting.
- Loop formatting:
for (int i = 0; i < cap; i++)
{
}
while (expr)
{
}
do
{
} while (expr);
- Branch formatting:
if (expr)
{
}
else if (otherExpr)
{
}
else
{
}
- Switches should always have a
break
at the end of each case unless a fall-through is expected:
switch (val)
{
case 0:
DoThing();
break;
default:
DoDefaultThing();
break;
}
Fields And Variables
- Variable and field names should be brief, descriptive, and accurately describe what they're representing.
- Local variables and non-Actor properties should always use camel casing (e.g.
myVar
). - Actor properties should always use Pascal casing (e.g.
MyProperty
). - Constants and enum values should always use snake casing in all uppercase letters (e.g.
MY_CONSTANT
). - Enum values should be denoted with a prefix to mark what enum they belong to (e.g.
PREF_ENUM_VALUE
). - If a variable or field refers to a specific enum, the name of the enum should be used if possible instead of a specific datatype:
enum EMyFlags
{
// ...
}
int flags; // Don't do this.
EMyFlags flags; // Do this instead.
- When setting a variable or field to a value, use correct data types:
uint w = 5u;
int x = 5;
double y = 5.0;
bool z = true;
string s = "This is a string.";
Name n = 'This is a name.';
Constants and Enums
- Constants should always be given the correct data type when declaring them to prevent confusion with math:
const HEALTH_THRESHOLD = 50; // This is an int because health is tracked as such.
const DAMAGE_RANGE = 256.0; // This is a float since ranges are tracked with double precision floats.
- For enums, whether a semi-colon is used or if the last value has a comma is left up to the code writer:
enum EMyEnum
{
ME_VALUE1,
ME_VALUE2,
ME_VALUE3, // Optional comma.
}; // Optional semi-colon.
- If a specific data type is being used with the enum, make sure it's properly spaced:
enum EMyEnum : uint
- Only specify a value for enum values if it won't automatically be captured by default enumeration behavior.
- For flag enums, always include a default 0 value and use bitshifting over raw powers of 2. For these, it's ok to explicitly define every value:
enum EMyFlags
{
MF_NONE = 0,
MF_FLAG1 = 1,
MF_FLAG2 = 1<<1,
MF_FLAG3 = 1<<2
}
Functions
- Function names should be brief, descriptive, and accurately describe what they're doing. Always use Pascal casing.
- Action functions should always have an
A_
prefix and should be play scoped:
action void A_MyFunction() {}
- Functions that check certain criteria should appropriately ask a question:
bool IsOpen() { /* ... */ }
bool CanUse() { /* ... */ }
- Functions that perform tasks should contain a verb describing the action:
void OpenDoor() { }
void UseItem() { }
- Anonymous functions should be declared like so:
SPRT A 5
{
// Code.
}
- The exception to this is single line anonymous functions:
SPRT A 5 { /* Single statement. */ }
Field And Function Modifiers
- Accessors (
protected
,private
) should always come first when declaring fields and defining functions:
protected int myField;
private void MyFunction() {}
- Scopes should always come second after accessors:
protected ui int myUIField;
private clearscope void MyDataFunction() {}
- For functions, whether or not it's static should always come third:
protected ui static void MyUIFunction() {}
- For fields, other modifiers e.g.
readonly
andtransient
should come third and can be specified in any order:
private ui transient int myUIField;
Classes and Data Types
- Primitive data types should always use all lowercase e.g.
int
,double
, etc. Non-primitive types likeName
andSound
should use Pascal casing. - Classes, structs, and enums should always use Pascal casing and should not have numbers in their names e.g.
MyClassName
,FMyStruct
,EMyEnum
. Structs can optionally start with anF
prefix and enums should always start with anE
prefix. - Use proper spacing when declaring classes:
class MyClass : MyBaseClass replaces DoomImp
{
}
Highlighting
Use syntaxhighlight with "csharp" in lieu of wiki-specific formatting. While not perfect, it offers the closest highlighting to how ZScript actually works and looks better than using code blocks denoted with a single space at the start.
<syntaxhighlight lang="csharp"> Code here. </syntaxhighlight>
Example:
// This is some test code.
void DoThing()
{
int x = 5;
double y = 2.0;
}
Note that this syntax formatting does not support [[]]-style wiki links.
Functions
At the top of the page
Return values and access modifiers, such as private, protected, native, don't need formatting.
The name of the function must be in bold. Names of the arguments should be in italics.
Default values for arguments must always be provided!
Using monospaced {{c| }}
formatting is preferable, but it seems to fail on functions that have =
in them.
Example:
virtual void '''SomeMissileFunction'''(Actor ''missile'', double ''angle'' = 0)
Result:
virtual void SomeMissileFunction(Actor missile, double angle = 0)
If the function is defined in a specific class, the name of the class must be provided on top of the function in bold, with a link to the parent class. For example:
Actor virtual int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags = 0, double angle = 0)
In the text
Using the code instruction is recommended to highlight functions, operators, access modifiers and keywords in the text: <code>MyFunction()</code>, <code>if</code>, <code>private</code>
Result: MyFunction()
, if
, private
However, if you want to add a link to the function, using bold might be preferable, because code formatting makes the link practically invisible. Compare these two clickable options:
DrawString()
(clickable but not obvious)- DrawString() (obviously clickable)
But it may not be desirable to use because code formatting makes
Fields can be highlighted in bold: '''health'''
Result: health.
Function arguments
When describing function arguments, the recommended formatting rules are:
- Use a bulletted list, with a new element for each function (bulleted lists begin with
*
) - Both the argument type and the argument name should be provided. The name should be in bold.
- The whole argument (both the type and the name) should be enclosed in monospace formatting {{c| }}
- The description of the argument, most of the time, should be on a separate line beginning with
:
Example:
*{{c|Actor '''missile'''}} :The actor type to be used as the projectile. *{{c|double '''angle'''}} :The offset relative to the shooter's angle to fire the projectile at.
Result:
- Actor missile
- The actor type to be used as the projectile.
- double angle
- The offset relative to the shooter's angle to fire the projectile at.
Bulleted lists
Bulletted lists can be created with *
. Descriptions should be placed on a separate line, starting with :
.
*Bullet point :Bullet point description.
Result:
- Bullet point
- Bullet point description.
When using bulleted lists to describe arguments of a function, it's preferable that the whole string uses {{c| }}
for monospaced font, and the field name is highlighted in bold, like so:
*{{c|datatype '''fieldname'''}} :Description of a field.
For example:
- Vector2 position
- Determines the position of the element.