Wiki documentation guide

From ZDoom Wiki
Jump to navigation Jump to search

This page describes the structure and formatting standards that should be used when adding or editing wiki pages.

Page naming

Page names must follow specific established conventions:

  • Class pages: Classes:Classname. For example, Classes:Actor. This is important not only to keep order, but also for the Template:Class template (such as {{class|Actor}}) to function properly.
If you spot a class page that does not have "Classes:" in its name for some reason, feel free to move it and add the name (leave a redirect behind! this option is checked by default).
  • Struct pages: Structs:Structname For example, Structs:PlayerInfo. Note, these pages are also tied to a template: Template:Struct (such as {{struct|PlayerInfo}}).
  • Function pages: just the name of the function directly. For example, DamageMobj.
If the same function exists in ACS and ZScript, for example, append (ZScript) or (ACS) to the name of the page. Make sure to add a note to the top of each of the pages. Template:SameNameNote is often a good choice.
Appending (ZScript) or (ACS) to both pages is not always necessary. Oftentimes one page already exists, so only the newer page will need this clarification.

Page structure

In-page links

Please use links as much as you can. All key words and key terms must ideally have inter-wiki links in them.

Remember to use helpful templates. For example:

Always add the class prefix — these are not optional in ZScript! Class prefix should ideally be written in PascalCase. The template works without issues for this.
  • Please don't dismiss adding a See also section at the end of the page and linking all pages that seem relevant or thematically related to the current one.

Class and struct pages

Class and struct pages names should begin with the words "Classes:" and "Structs:" respectively, such as Classes:Actor or Structs:StringTable.

The general page structure for any of the two should look something like this:

General description of the class/struct and its purpose.

== Fields ==
A list of fields in this class in the form of a bulleted-list, with descriptions

== Methods ==
=== Virtual ===
A bulleted list of virtual functions defined in this class/struct
=== Static ===
A bulleted list of static functions defined in this class/struct
=== Non-static ===
A bulleted list of non-static (dynamic) functions defined in this class/struct

== [[ZScript]] definition ==
{{ZScriptDefinitionNote|<path to Github code>}}
This template inserts a warning that this code is for reference only and adds a link to where this code is contained on Github. Note, you don't need a full link; instead your link must begin with whatever comes after zscript/ in the link, and everything before it (specifically, https://github.com/ZDoom/gzdoom/blob/master/wadsrc/static/zscript must be dropped).

<syntaxhighlight lang="csharp">
Copy-paste the definition of the class from GZDoom Github, unless it's way too long. This is especially relevant for various in-game actors that come with their own peculiar behaviors. Always use the <syntaxhighlight lang="csharp"> block for this.
</syntaxhighlight>

== [[DECORATE]] definition ==
{{DecorateDefinitionNote}}
DECORATE definition goes here ONLY if it was already added to the page previously. Since DECORATE is no longer used, new definitions in DECORATE should not be added.

== Examples ==
An example bit of code demonstrating how this class/struct can be used. If you can't add an example right now, put {{noexamples}} here.

== See also ==
A bulleted list of links to other pages that are relevant/connected to this one, if any.

A list of relevant categories at the end:
[[Category:ZScript]]

Example pages:

Useful templates:

Function pages

The general structure of a function page looks like this:

'''{{class|ParentClassName}}'''

keyword type '''FunctionName'''(argtype ''argname'' = defvalue)

== Usage ==
General description of how this function is used.
=== Parameters ===
A bulleted list of the arguments used by the function, if any. Example:
*{{c|argtype '''argname'''}}
:Argument description.
=== Return values ===
Description of the return values of the function. If more than one, used a bulleted list.

== [[ZScript]] definition ==
{{ZScriptDefinitionNote|<path to Github code>}}
This template inserts a warning that this code is for reference only and adds a link to where this code is contained on Github. Note, you don't need a full link; instead your link must begin with whatever comes after zscript/ in the link, and everything before it (specifically, https://github.com/ZDoom/gzdoom/blob/master/wadsrc/static/zscript must be dropped).

<syntaxhighlight lang="csharp">
Copy-paste the definition of the class from GZDoom Github, unless it's way too long. This is especially relevant for various in-game actors that come with their own peculiar behaviors. Always use the <syntaxhighlight lang="csharp"> block for this.
</syntaxhighlight>

== Examples ==
An example bit of code demonstrating how this class/struct can be used. If you can't add an example right now, put {{noexamples}} here.

== See also ==
A bulleted list of links to other pages that are relevant/connected to this one, if any.

A list of relevant categories at the end:
[[Category:ZScript]]


Example pages:

Useful templates:

Formatting of 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!

Example:

virtual void '''SomeMissileFunction'''(Actor ''missile'', double ''angle'' = 0)

Result:

virtual void SomeMissileFunction(Actor missile, double angle = 0)

Note: Using monospaced {{c| }} formatting for the whole function is preferable, but it seems to fail on functions that have = in them, and the only way around it is to use }}={c| at every instance of the = symbol.

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:

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.

Code Formatting

This section will cover how code used in examples 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.

Highlighting

Use the <syntaxhighlight lang="csharp"> to begin a code block, and </syntaxhighlight> to close it. Please avoid using the old-style code formatting with spaces at the start of the string. While the old-style formatting allows combining code with links and color highlights, it's generally much less convenient. If the code utilizes references to other classes and functions that the user may not understand, it's preferable to add a note with a bulletted list of relevant links.

<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.

If for any reason you need to use old-style code (for example, you're editing an old page that has a lot of it, or you want to create code that does have inter-wiki links), please mind the existence of the following templates:

  • Template:Comment — makes the string dark-green, italicized and adds // before it.
Example: {{comment|This is a comment}} will turn into // This is a comment.
  • Template:LanguageCodeNote — this should be used in practically any place where a player-facing string is written out in the code explicitly.
It's considered bad practice to write player-facing strings, such as those for Inventory.PickupMessage, directly in the code; instead authors should mostly rely on storing strings in the LANGUAGE lump. However, it's considered fine to write out strings explicitly as an example. So, this note should be added to such examples.
Usage: {{LanguageCodeNote}} turns into // This is an example. It's recommended to use LANGUAGE for player-facing strings..

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.
  • It is highly preferable that action functions have an A_ prefix.:
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 and transient 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 like Name, String, Sound, etc. 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 an F prefix and enums should always start with an E prefix.
  • Use proper spacing when declaring classes:
class MyClass : MyBaseClass replaces DoomImp
{

}