Giter Club home page Giter Club logo

roblox-style-guide's Introduction

RBX.Lua Style Guide

This is a style guide for ROBLOX's variant of Lua. These guidelines are to keep code consistent across projects, and allow contributors to learn exactly how to write code for those projects.

This style guide is based off of Olivine Lab's Lua Style Guide.

Table of Contents

  1. Strings
  2. Functions
  3. Properties
  4. Variables
  5. Classes
  6. Naming Conventions
  7. Conditional Expressions & Equality
  8. Blocks
  9. Whitespace

Strings

  • Use double quotes for strings.

    -- bad
    local name = 'John'
    
    -- good
    local name = "John"
  • Strings longer than 80 characters should be concatenated. Do not use double-brackets ([[]]) or backslashes (\), line breaks and whitespace will effect them.

    -- bad
    local str = "This is an incredibly long string that exceeds 80 characters and just keeps going. This string has no regard for your well being and will stop at nothing to make your life a living hell."
    
    -- bad
    local str = [[This is an incredibly long string that exceeds 80 characters
    and just keeps going. This string has no regard for your well being and will
    stop at nothing to make your life a living hell.]]
    
    -- bad
    local str = "This is an incredibly long string that exceeds 80 characters \
    and just keeps going. This string has no regard for your well being and will \
    stop at nothing to make your life a living hell."
    
    -- good
    local str = "This is an incredibly long string that exceeds 80 characters "..
      "and just keeps going. This string has no regard for your well being and "..
      "will stop at nothing to make your life a living hell."

[⬆]

Functions

  • Prefer lots of small functions to large, complex functions. Consider reading Small Functions are Good for the Universe.

  • Prefer function syntax over variable syntax.

    -- bad
    local nope = function()
      -- code
    end
    
    -- good
    local function yup()
      -- code
    end
  • Perform validation early and return as soon as possible.

    -- bad
    local function isGoodName(name)
      local isGood = #name > 3
      isGood = isGood and #name < 30
    
      -- code
    
      return isBad
    end
    
    -- good
    local function isGoodName(name)
      if #name < 3 or #name > 30 then return false end
    
      -- code
    
      return true
    end
  • Prefer defining functions after variables.

    -- bad
    local function foo()
      -- code
    end
    
    local bar = true
    local baz = "something"
    
    -- good
    local bar = true
    local baz = "something"
    
    local function foo()
      -- code
    end

[⬆]

Properties

  • Use dot notation when accessing known properties.

    local luke = {
      IsJedi = true,
      Age = 28
    }
    
    -- bad
    local isJedi = luke["IsJedi"]
    
    -- good
    local isJedi = like.IsJedi
  • Use subscript notation ([]) when accessing properties with a variable.

    local luke = {
      IsJedi = true,
      Age = 28
    }
    
    local function getProp(prop)
      return luke[prop]
    end
    
    local isJedi = getProp("IsJedi")

[⬆]

Variables

  • Always use local to declare variables.

    -- bad
    superPower = SuperPower.new()
    
    -- good
    local superPower = SuperPower.new()
  • Group top-level variables by services, dependencies, constants, and globals. Separate each group by a line space.

    -- bad
    local CONSTANT = true
    local global = "This can be changed"
    local run = game:GetService("RunService")
    local replicatedStorage = game:GetService("ReplicatedStorage")
    local module = require(replicatedStorage.ModuleScript)
    
    -- good
    local run = game:GetService("RunService")
    local replicatedStorage = game:GetService("ReplicatedStorage")
    
    local module = require(replicatedStorage.ModuleScript)
    
    local CONSTANT = true
    
    local global = "This can be changed"
  • Assign variables at the top of their scope when possible. Scattering them around makes functions hard to parse.

    -- bad
    local function bad()
      test()
      print("doing stuff")
    
      -- code
    
      local name = getName()
    
      if name == "test" then
        return false
      end
    
      return name
    end
    
    -- good
    local function good()
      local name = getName()
    
      test()
      print("doing stuff")
    
      -- code
    
      if name == "test" then
        return false
      end
    
      return name
    end

[⬆]

Classes

  • All classes must define a .new() function for instantiation. This follows ROBLOX's convention for class constructors.

    -- bad
    local gal = Person("Savanna")
    
    -- good
    local gal = Person.new("Savanna")

Naming Conventions

  • Avoid single letter names. Be descriptive with your naming. You can get away with single-letter names when they are variables in loops.

    -- bad
    local function q()
      -- code
    end
    
    -- good
    local function query()
      -- code
    end
    
    -- good
    for i=1, #list do
      -- code
    end
  • Use underscores for ignored variables.

    -- good
    local _, message = pcall(function() return error("Oops!") end)
    
    --good
    for _, name in pairs(names) do
      -- code
    end
  • Use lowerCamelCase when naming objects, functions and instances.

    -- bad
    local not_like_this = {}
    local OrLikeThis = true
    
    --- good
    local variableWithManyWords = {}
    
    local function doThatThing()
      -- code
    end
  • Use PascalCase for classes and properties.

    -- bad
    local person = require(replicatedStorage.Person)
    local guy = person.new("John")
    local name = guy.name
    
    -- good
    local Person = require(replicatedStorage.Person)
    local guy = Person.new("John")
    local name = gui.Name
  • Use CAPITALS_AND_UNDERSCORES for constants.

    -- bad
    local thisWillNeverChange = false
    
    -- good
    local THIS_WILL_NEVER_CHANGE = true
  • When defining services, remove "Service" from the name when possible.

    -- bad
    local contextActionService = game:GetService("ContextActionService")
    local userInputService = game:GetService("UserInputService")
    local httpService = game:GetService("HttpService")
    
    -- good
    local contextAction = game:GetService("ContextActionService")
    local userInput = game:GetService("UserInputService")
    local http = game:GetService("HttpService")
  • Use is or has for boolean-returning functions that are part of a class.

    -- bad
    local function evil(alignment)
      return alignment < 100
    end
    
    -- good
    local function isEvil(alignment)
      return alignment < 100
    end

[⬆]

Conditional Expressions & Equality

  • false and nil are falsy in conditional expressions. All else is true.

    local str = ""
    
    if str then
      -- true
    end
  • Use shortcuts when you can, unless you need to know the difference between false and nil.

    -- bad
    if name ~= nil then
      -- code
    end
    
    -- good
    if name then
      -- code
    end
  • Prefer true statements over false statements where it makes sense. Prioritize truthy conditions when writing multiple conditions.

    -- bad
    if not thing then
      -- code
    else
      -- code
    end
    
    -- good
    if thing then
      -- code
    else
      -- code
    end
  • Short ternaries are okay.

    local function defaultName(name)
      -- return the default "Waldo" if name is nil
      return name or "Waldo"
    end
    
    local function brewCoffee(machine)
      return machine and machine.isLoaded and "coffee brewing" or "fill your water"
    end

[⬆]

Blocks

  • Single line blocks are okay for small statements. Try to keep lines to 80 characters. Indent lines if they overflow past the limit.

    -- good
    if test then return false end
    
    -- good
    if test then
      return false
    end
    
    -- bad
    if test < 1 and doComplicatedFunction(test) == false or seven == 8 and nine == 10 then doOtherComplicatedFunction() end
    
    -- good
    if test < 1 and doComplicatedFunction(test) == false or
        seven == 8 and nine == 10 then
    
      doOtherComplicatedFunction()
      return false
    end

[⬆]

Whitespace

Install EditorConfig for your text editor to have your tabs and other settings configured automatically on a per-project basis.

  • Use soft tabs set to 2 spaces.

    -- bad
    function()
    ∙∙∙∙local name
    end
    
    -- bad
    function()
    ∙local name
    end
    
    -- good
    function()
    ∙∙local name
    end
  • Place 1 space before opening and closing braces. Place no spaces around parenthesis.

    -- bad
    local test = {one=1}
    
    -- good
    local test = { one = 1 }
    
    -- bad
    dog.set('attr',{
      Age = "1 year",
      Breed = "Bernese Mountain Dog"
    })
    
    -- good
    dog.set('attr', {
      Age = "1 year",
      Breed = "Bernese Mountain Dog"
    })
  • Place an empty newline at the end of the file.

    -- bad
    (function(global)
      -- ...stuff...
    end)(self)
    -- good
    (function(global)
      -- ...stuff...
    end)(self)
    
  • Surround operators with spaces.

    -- bad
    local thing=1
    thing = thing-1
    thing = thing*1
    thing = 'string'..'s'
    
    -- good
    local thing = 1
    thing = thing - 1
    thing = thing * 1
    thing = 'string' .. 's'
  • Use one space after commas.

    --bad
    local thing = {1,2,3}
    thing = {1 , 2 , 3}
    thing = {1 ,2 ,3}
    
    --good
    local thing = {1, 2, 3}

[⬆]

roblox-style-guide's People

Contributors

ajacksified avatar yonaba avatar catwell avatar ntd avatar dmarcoux avatar triyangle avatar homenucleonics avatar llj098 avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.