Help:Modules

From IdleOn MMO Wiki

Introduction

This article serves as a style guide for developing modules on the wiki.

Module Basics

Modules are Lua files that can be invoked by articles, templates, or other modules.

Module Structure

Modules should adhere to the following structure in order:

  • Strict Module Import
  • Dependency Module Imports
  • Module Declaration

Strict Module Import

The strict module is a special built-in module that should be included at the top of every module. Unlike other modules, it does not exist in the Module namespace.

require('strict')

Dependency Module Imports

Next, dependency modules should be imported in alphabetical order. The module should be stored as a variable with the same name without the namespace.

local Assert = require('Module:Assert')
local NumberParser = require('Module:NumberParser')

Module Declaration

After defining imports, the top-level module should be declared, followed its function declarations.

Formatting

Semicolons

Do not use semicolons to end statements unless it is absolutely necessary as they add visual clutter.

Parentheses

Do not use parentheses to wrap entire expressions. They should only be used to override default precedence or to make precedence more obvious. This same logic applies to constructs such as if-statements and loops.

local x = 5
local y = 8

-- BAD: Expressions should not be wrapped in parentheses
if (x < y) then ... end

-- GOOD: Expressions should not be wrapped in parentheses
if x < y then ... end

-- GOOD: Parentheses can be used to override default operator precedence
local z = (x + y) * 2

-- OKAY: Parentheses can be used to emphasize default operator precedence
local z = (x * 2) > y

Strings

Prefer the use of single quotes when defining strings instead of double quotes. Double quotes should be used for strings which would otherwise require escape characters.

-- GOOD: Single quotes are used
local myString1 = 'Hello, world!'

-- BAD: Use single quotes instead
local myString2 = "Hello, world!"

-- GOOD: Double quotes are preferable over escape characters.
local myString3 = "What's a module?"

Block Indentation

Each time a new block is opened, the indent increases by 4 spaces. When the block ends, the indent level returns to the previous indent level.

One statement per line

Limit each line to a single statement.

Line length

Lines should not exceed 120 characters in length whenever possible.

Whitespace

A single blank line always appears:

  • After the "strict" module import
  • After the last dependency module import
  • Between top-level declarations
require('strict')

local Assert = require('Module:Assert')
local NumberParser = require('Module:NumberParser')

local p = {}

function p.main(frame)
    local args = frame:getParent().args
    return p._main(args)
end

function p._main(args)
    return NumberFormat.parse(args[1])
end

return p

Variable Declarations

  • Variables should be declared as late as possible to minimize their scope.
  • Don't declare multiple variables at the same time. An exception is made for functions that return multiple variables at once.
-- BAD: Only declare one variable per line
local a, b = 2, 3

-- GOOD: One variable declared per line
local a = 2
local b = 3

-- GOOD: Match function returns multiple values
local a, b = str:match('(%w+)(%d+)')

Naming

Module Names

Module names should reflect the core functionality of the module. They are typically nouns or noun phrases. Modules must be created in the Module namespace, and their names should be written in PascalCase.

Example Explanation
Module:NumberParser This module parses numbers and converting them between different formats used throughout the wiki.
Module:Assert This module provides utility functions for common assertion use-cases.

Class Names

For modules that are designed to be invoked from templates, the class containing the entry point should be named "p". For modules that are designed to be included in other modules, the primary class should match the name of the module. With the exception of the "p" class, all classes should be written in PascalCase, and are typically named after nouns or noun phrases.

Method and Function Names

The names of all functions should be written in lowerCamelCase. They are typically named after verbs.

Parameter Names

Parameter names are written in lowerCamelCase. They should be descriptive enough to know what they do at a glance.

Local Variable Names

Local variable names are written in lowerCamelCase.

Constant Names

Values that should be considered constant be written in UPPER_SNAKE_CASE.

Documentation

Documentation should be compatible with the Lua Language Server specification.