Note: This is the latest, and hopefully last, revision.

Note: Due to the fact that the PHPBB extension for creating "Pages" such as this one strips off leading white space on a line some sections will appear in the format usually used for program code for readability and general appearance because that preserves leading white space.

eScript Style and Distro submission Guide
This is a suggested guide for those writing eScript programs and a required guide for on the Distro team or for those wishing to submit eScript programs or packages to the Distro. I want to thank Austin for creating the original style guide. I'm pretty sure it was his handy work. If not then my thanks to whomever created it. I changes a few things but most of this guide was taken from the original.

Naming Conventions:
-------------------

FileNames:
All single word or single word and partial word file names should be lower case.

CODE: Select all

initialize.src
getreg.src
With filenames containing multiple words, the letter of the first word is lowercase, while the first letter of each additional word is capitalized. This naming convention is known as camelCase. All file extensions are lowercase.

CODE: Select all

    Examples:
        npcBackpack.inc
        myIncludeFile.inc
        showAll.src

    Exceptions:
        Commands are all lowercase.
        Core files, such as itemdesc.cfg, serverspecopt.cfg,npcdesc.cfg, etc.,  are all lowercase.
The case of the file name is important on non-Windows systems such as Linux. On Linux systems npcBackpack.inc and NPCBackpack.inc are interpreted as different files.

Note: I will concede that abbreviations in a file name can be uppercase eg. NPCBackpack.inc. Just make certain that your references to those files match the same case as the file name.

Variables:
Please, for the love of God, give your variables names that are relevant to the values they might hold. For example, if your variable might contain the amount of gold found in a character's backpack name it something like char_gold or mobile_gold. Longer variable names are allowed. Do not be afraid to use long names if you need them to be descriptive. Variables used for iterations in for loops can be single characters eg. i, j, k unless they are used later in your code and need to be descriptive.

CODE: Select all

    Examples:
        var stuff;
        var my_integer;
        var my_string;
        var layer_array;
	var counter i;
Exceptions:
Constant variables should be in all caps (all capitalized) and words are separated using the underscore character '_'.

CODE: Select all

        CONST MY_CONSTANT := 10.0;
        CONST NUMBER_OF_GUARDS := 100;
Note: This may not be true for Core constants such as MOVEOBJECT_FORCELOCATION.

Functions:
All functions should use the PascalCase convention, which as you can see has the first
letter of each word capitalized.

CODE: Select all

    Examples:
        function ListOnlineDrow(who)
        function GetLastName(who, num_of_letters)
    Methods:
        object.MethodFunction(arguments)
Exceptions:
If the function/s is part of a special package it can include a small prefix to define its origin i.e. AI_GetNerves(mobile).


Programs:
All programs are named after the file in which they are contained. Unlike their filenames though, they should either follow the 'camelCase' or 'PascalCase' naming conventions.

CODE: Select all

    Examples:
        (FileName is "bardInstruments.src"), thus the program is named:
        program bardInstruments(item)

        (FileName is "enumerateTowns.src), thus the program is named:
        program EnumerateTowns(who, uX, uY, lX, lY, realm)
Exceptions:
There are certain exceptions with special kinds of programs, such as commands
i.e. command_MyCommand(who, params) or textcmd_MyCommand or a spell program eg. spell_GreaterHeal(who)

Note: When it comes to your code, eCompile and the eScript language is case neutral, unlike C++. The case of a program name, variable or constant does not effect compilation or execution of your programs (scripts). These guidelines are intended to promote readability of source code. File names are a different matter as they are sent to the operating system and on some systems case is important. Also remember that an in-game command is a file name.

=== Other Formatting ===

Return:
This guideline is more of a suggestion.

CODE: Select all

// Not preferred.
        return;
// Preferred
        return 0; // If calling function does not require a value returned.
             or
        return <some_value>;
Math:

CODE: Select all

        var math := 4 + 3 * 10; // 70 or 34? Use parethesis to control better.
        var pemdas := ( ( 4 * 4 ) + ( 8 / ( 3 + 2 ) ) ) - ( 100 + some_var );
Please note that I do not prefer spaces between parenthesis and values, or parenthesis and another parenthesis. However a case could be made for readability when having the spaces present. So we won't have a hard and fast rule regarding this. However spacing between values and operators is strongly encouraged.
Either of the following will be acceptable:

CODE: Select all

        var pemdas := ((4 * 4) + (8 / (3 + 2))) - (100 + some_var);
        var pemdas := ( ( 4 * 4 ) + ( 8 / ( 3 + 2 ) ) ) - ( 100 + some_var );
Strings:
// Strings have spaces around the + operator.

CODE: Select all

        var string := "Hello there " + "Stephen." + " I am " + math + " years old.";
Function Usage:

CODE: Select all

        var value := SomeFunction(argument_1, argument_2);
        var other_value := object.SomeMethodFunction(argument_1);
Properties:

CODE: Select all

        object.somepropery := some_value;
Comments:

CODE: Select all

// Do unto others as you would have them do unto you.
// Matthew 7:12

/*
 * This is another option
 * When creating multi line comments.
 *
 */

A word about comments in your code, you can never have too many comments documenting what your code is doing but you can certainly have too few.

Whenever possible you should provide a comment block preceding a function like the example below, especially if this function is one that might be used by others.

Taken from Austin's damage.inc file:

CODE: Select all

/*
 * ApplySpellDamageEX(mobile, amount, type, source, circle)
 *
 * Purpose: Does spell damage to mobile taking into account mobile's AR
 *
 * Parameters
 * mobile: Victim
 * amount: Raw damage
 * type:   Fire, cold, energy, poison or physical
 * source: Source of the damage
 * circle: Circle or level of spell. Basic spells are 1 through 8.
 *
 * Return value: damage amount done
 *
 */
If, While, etc. Stuff:
Please take note of the indentation inside the conditional satements (if and case) and the loops (while, do, repeat, and for etc.). This is important for readability so others can look at your code and understand it. You should always indent 4 spaces inside each if or loop.

CODE: Select all

   
        if ( something )
                Code here;
        endif
        
        The 'or' operator:
        if ( this || that ) // Don't use 'or' spelled out.
        
        The 'and' operator:
        if ( this && that ) // Don't use 'and' spelled out.
        
        if ( this || ( one && two ) ) // Parenthesis are important for order of operations.


        if(something)
                do this stuff....
        endif

        if(something)
                this gets done...
                if(this happens)
                        this other stuff gets done
                else
                        do this stuff
                endif
        endif



        case ( something )
                value:    code;
                break;
                default:  code;
                break;
        endcase

        while ( something )
                code here;
                sleepms(2);
        endwhile

        do
                codehere;
                sleepms(2);
        dowhile ( case );
    
        foreach iteration in ( iterated )
                codehere;
                sleepms(2);
        endforeach

        for ( i; i <= 4; i:=i+1 )
                codehere;
                sleepms(2);
        endfor

        for i:=1 to value
                codehere;
                sleepms(2);
        endfor
Declarations:

CODE: Select all

// Preferred.
	var a := {};
        var a := array{1, 2, 3};
// Either below is acceptable but not preferred.
        var b := array{};.
        var b := array;
  
// Struct setup
        var my_var := struct; // This is preferred for readability. Assign members and values separately.
        my_var.+member := something;
        my_var.+member2;
// Or...
        var my_var := struct{"member":=something, "member2"};
    
// Dictionary Setup
	var my_var := dict; // This is preferred for readability. Assign members and values separately.
        var my_var := dictionary{"key"->value, "key2"->value};
Note on variable declarations: In most cases, because eScript is a loosely typed language, you do not need to assign a value to a variable when you declare it. The code is legal in the following example:

CODE: Select all

    var something;
    something := 1234;
    something := "A string literal";
Changing the type of value stored in a variable is not good coding practice but in eScript it is allowed. It also can be convenient and that's why you might see it done in some scripts. Do not do it in any code submitted to the Distro! It can create issues and it is harder to debug.

There are two, possibly three, variable types that must have their type declared in the var declaration, structs, dicts, and possibly arrays.

Other Notes:
* If at all possible do not use spaces for indents, use tabs. I would prefer tab spacing set to 4. If you must use spaces indent 4 spaces.

All Distro scripts that use gumps, can use the gumps package to build them.


Additional Distro submission guidelines:

Follow as closely as possible the eScript guidelines for coding.

General use include files (*.inc) can be placed in /scripts/include. Examples are client.inc, itemtypes.inc etc.
All specialised include files specific to a package shall be included in the package that requires them.

Packages:
Going forward, packages should be as self-contained as possible. This means that if at all humanly possible a package should be able to be dropped in without modifying any other packages or scripts outside the package. This is especially important if you are submitting an optional package that shard devs can, should they choose, add to their server. If you need to add or modify some function in an existing Distro include file,copy that include file to your package and modify it there. Please add comments in your copy of the file indicating where the changes were made. This will help keep the Distro as simple as possible.

Packages will follow the "Austin" format:
/pkg/packagename
<main scripts go here> start.src, logon.src, reconnect.src etc.

/pkg/packagename/commands
<any command specific to this package>
Commands need to be placed in sub directories in the /commands directory that pertain to the level of the intended user. In the Distro the folders must be named player, councilor (or coun), seer, gm, admin, developer (or dev), test. You only need to create the sub-directories that will actually contain commands.

/pkg/packagename/config
<cfg files> itemdesc.cfg, icp.cfg, npcdesc.cfg (for any custom NPCs your package may need) or any cfg files specific to the package.

/pkg/packagename/include
<include.inc files specific to this package>

/pkg/packagename/itemname
<method and use scripts required for an item defined in the package> Create additional itemname directories for additional items as required. The use script for an item should be named use.src and the method script should be namedmethods.src


Also familiarize yourself with the control package in \pkg\utils\control and create an icp.cfg file for your package. Try to be as thorough as possible when adding the info to the icp file. Thanks to the work of Edwards we no longer need to define commands that may be specific to a package.

We don't yet have a system set-up to submit candidate packages for the Distro or optional add-on packages.
Hopefully, we can get that done and make it available. You can submit patches to the Distro through Git.



*** Insert small tutorial here for submitting patches through GitHub ***
*** Someone other than me will write this tutorial or be assigned it ***