Instantly share code, notes, and snippets.

Embed
What would you like to do?
Interrogation Style Guide

Lua style guide

Linting

This project makes use of Luacheck for catching common mistakes. Install it and configure it for your text editor.

Editor configuration

We recommend Atom for editing Lua code along with the following packages:

Rules

  • Don't use semicolons

    -- DO:
    print("hello")
    -- DON'T:
    print("hello");
  • Use 2 spaces for indentation. No tabs.

    -- DO:
    if a > 0 then
      print("hello")
    end
    
    -- DON'T:
    if a > 0 then
        print("hello")
    end
  • Use double quotes for string literals

    -- DO:
    print("Hello world!")
    -- DON'T:
    print('Hello world!')
  • Use spaces between binary operators and operands

    -- DO:
    return a + b
    -- DON'T:
    return a+b
  • Don't add spaces between -, # unary operators and operands

    -- DO:
    local question_count = #questions
    local minus_x = -x
    -- DON'T:
    local question_count = # questions
    local minus_x = - x
  • Don't pad parentheses with spaces

    -- DO:
    my_function(a, b, c)
    return (a + b) * c
    -- DON'T:
    my_function( a, b, c )
    return ( a + b ) * c
  • Don't add spaces before ( in function calls or definitions

    -- DO:
    function my_function(a, b)
      my_other_function(a, b)
    end
    -- DON'T:
    function my_function (a, b)
      my_other_function (a, b)
    end
  • Start comments with a space

    -- DO
    --DON'T
  • Use meaningful names for variables, functions, arguments, fields and other things.

    Try to avoid abbreviations. Single letter variables are only allowed for indices (i, j, etc.) and coordinates (x, y, z, t, etc.).

    -- DO:
    local position = get_player_position()
    local distance_from_origin = math.sqrt(position.x * position.x + position.y * position.y)
    -- DON'T:
    local a = f()
    local b = math.sqrt(a.x * a.x + a.y * a.y)
  • Use snake_case for variable, args, function and field names.

    -- DO:
    local my_variable
    local my_other_variable
    function my_function()
    end
    
    -- DON'T:
    local myVariable
    local MyOtherVariable
    function mY_fUncTion()
    end
  • Use UpperCamelCase for class names.

    -- DO:
    local Button = { __index = {} }
    function Button.__index:some_method()
    end
  • Use MACRO_CASE for enumeration constants.

    -- DO:
    local STATE_IDLE = 1
    local STATE_PRESSED_DOWN = 2
    local STATE_HOVERED = 3
  • Use .0 for float number literals

    Lua's number type makes no difference between 2 and 2.0, but it helps to visually annotate numbers as floats or integers depending on their usage.

    -- DO:
    local new_x = x * 2.0 -- coordinates are float
    local next_index = index + 1 -- indices are integer
    
    -- DON'T:
    local new_x = x * 2
    local next_index = index + 1.0
  • No unused variables except unused function arguments

    Luacheck will yell at you for this.

    -- DON'T:
    function my_function()
      local something = some_function()
      -- the value in something never gets used
    end
    
    -- Acceptable:
    function transform_coordinates(x, y)
      return x * 2.0, 0.0
    end
  • Separate logical blocks with single blank lines

    What counts as a logical block is up to you, but try to avoid 30-line-long blocks of code with no visual structure. Don't use more than one blank line!

    -- DO:
    local last_animation = self.blink_last_animation or 1
    local repeat_count = self.blink_repeat_count or 0
    local fear_treshold = subject.idle_animation_fear_treshold
    
    local next_animation
    if repeat_count >= (last_animation == 1 and 1 or 5) then
      next_animation = 3 - last_animation
    else
      next_animation = math.random(2)
    end
  • Pre-calculate constant hashes and game object IDs

    Hashing and accessing game objects by their string URL is an O(n) operation. Pre-calculate hashes to avoid creating them in performance-sensitive code.

    -- DO:
    local h_scene_init = hash("scene_init")
    
    function on_message(self, message_id, message)
      if message_id == h_scene_init then
        -- Do stuff
      end
    end
    
    -- DON'T:
    function on_message(self, message_id, message)
      if message_id == hash("scene_init") then
        -- Do stuff
      end
    end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment