<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=Lua_code_style_guidelines</id>
	<title>Lua code style guidelines - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://olddev.minetest.org/index.php?action=history&amp;feed=atom&amp;title=Lua_code_style_guidelines"/>
	<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=Lua_code_style_guidelines&amp;action=history"/>
	<updated>2026-04-15T05:10:09Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.38.7</generator>
	<entry>
		<id>https://olddev.minetest.org/index.php?title=Lua_code_style_guidelines&amp;diff=100&amp;oldid=prev</id>
		<title>&gt;Wuzzy: namespace tables might be phased out, but probably not *soon* :-)</title>
		<link rel="alternate" type="text/html" href="https://olddev.minetest.org/index.php?title=Lua_code_style_guidelines&amp;diff=100&amp;oldid=prev"/>
		<updated>2021-03-21T01:52:41Z</updated>

		<summary type="html">&lt;p&gt;namespace tables might be phased out, but probably not *soon* :-)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
This is largely based on [https://www.python.org/dev/peps/pep-0008 the Python style guide] except for some indentation and language syntax differences.  When in doubt, consult that guide.&lt;br /&gt;
&lt;br /&gt;
Note that these are only ''guidelines'' for more readable code.  In some (rare) cases they may result in ''less'' readable code.  Use your best judgement.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
* Incorrect or outdated comments are worse than no comments.&lt;br /&gt;
&lt;br /&gt;
* Avoid inline comments, unless they're very short.&lt;br /&gt;
&lt;br /&gt;
* Write comments to clarify anything that may be confusing. Don't write comments that describe things that are obvious from the code.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt; &amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;width = width - 2  -- Adjust for 1px border on each side&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt; &amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;width = width - 2  -- Decrement width by two&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Comments should follow English grammar rules, this means '''starting with a capital letter''', using commas and apostrophes where appropriate, and '''ending with a period'''. The period may be omitted in single-sentence comments. If the first word of a comment is an identifier, its casing should not be changed. '''Check the spelling.'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
-- This is a properly formatted comment.&lt;br /&gt;
-- This isnt.              (missing apostrophe)&lt;br /&gt;
-- neither is this.        (lowercase first letter)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Comments should have a space between the comment characters and the first word.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
--This is wrong.&lt;br /&gt;
-- This is right.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Inline comments should be separated from the code by two spaces.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
foo()  -- A proper comment.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you write comments for a documentation generation tool, write the comments in LuaDoc format.&lt;br /&gt;
&lt;br /&gt;
* Short multi-line comments should use the regular single-line comment style.&lt;br /&gt;
&lt;br /&gt;
* Long multi-line comments should use Lua's multi-line comment format with no leading characters except a &amp;lt;code&amp;gt;--&amp;lt;/code&amp;gt; before the closer.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
Very long&lt;br /&gt;
multi-line comment.&lt;br /&gt;
--]]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Lines, spaces, and indentation ==&lt;br /&gt;
&lt;br /&gt;
* Indentation is done with one tab per indentation level.&lt;br /&gt;
&lt;br /&gt;
* '''Lines are wrapped at 80 characters''' where possible, with a hard limit of 90.  If you need more you're probably doing something wrong.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Continuation lines ===&lt;br /&gt;
&lt;br /&gt;
* Conditional expressions have continuation lines indented by two tabs.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
if long_function_call(with, many, arguments) and&lt;br /&gt;
		another_function_call() then&lt;br /&gt;
	do_something()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
* Function arguments are indented by two tabs if multiple arguments are in a line, same for definition continuations.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
foo(bar, biz, &amp;quot;This is a long string...&amp;quot;&lt;br /&gt;
		baz, qux, &amp;quot;Lua&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
function foo(a, b, c, d,&lt;br /&gt;
		e, f, g, h)&lt;br /&gt;
	[…]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
* If the function arguments contain a table, it's indented by one tab and if the arguments get own lines, it's indented like a table.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
register_node(&amp;quot;name&amp;quot;, {&lt;br /&gt;
	&amp;quot;This is a long string...&amp;quot;,&lt;br /&gt;
	0.3,&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
list = filterlist.create(&lt;br /&gt;
	preparemodlist,&lt;br /&gt;
	comparemod,&lt;br /&gt;
	function()&lt;br /&gt;
		return &amp;quot;no comma at the end&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
* When strings don't fit into the line, you should add the string (changes) to the next line(s) indented by one tab.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
longvarname = longvarname ..&lt;br /&gt;
	&amp;quot;Thanks for reading this example!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local retval =&lt;br /&gt;
	&amp;quot;size[11.5,7.5,true]&amp;quot; ..&lt;br /&gt;
	&amp;quot;label[0.5,0;&amp;quot; .. fgettext(&amp;quot;World:&amp;quot;) .. &amp;quot;]&amp;quot; ..&lt;br /&gt;
	&amp;quot;label[1.75,0;&amp;quot; .. data.worldspec.name .. &amp;quot;]&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
* When breaking around a binary operator you should break after the operator.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
if a or b or c or d or&lt;br /&gt;
		e or f then&lt;br /&gt;
	foo()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Empty lines ===&lt;br /&gt;
&lt;br /&gt;
* Use a single empty line to separate sections of long functions.&lt;br /&gt;
&lt;br /&gt;
* Use two empty lines to separate top-level functions and large tables.&lt;br /&gt;
&lt;br /&gt;
* Do not use a empty line after conditional, looping, or function opening statements.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
function foo()&lt;br /&gt;
	if x then&lt;br /&gt;
		bar()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
function foo()&lt;br /&gt;
&lt;br /&gt;
	if x then&lt;br /&gt;
&lt;br /&gt;
		bar()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Don't leave white-space at the end of lines.&lt;br /&gt;
&lt;br /&gt;
=== Spaces ===&lt;br /&gt;
&lt;br /&gt;
* Spaces are not used around parenthesis, brackets, or curly braces.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
foo({baz=true})&lt;br /&gt;
bar[1] = &amp;quot;Hello world&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
foo ( { baz=true } )&lt;br /&gt;
bar [ 1 ]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Spaces are used after, but not before, commas and semicolons.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt; &amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;foo(a, b, {c, d})&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt; &amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;foo(a,b,{c , d})&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Spaces are used around binary operators with following exceptions:&lt;br /&gt;
** There mustn't be spaces around the member access operator (&amp;quot;.&amp;quot;)&lt;br /&gt;
** Spaces around the concatenation operator (&amp;quot;..&amp;quot;) are optional.&lt;br /&gt;
** In short one-line table definitions the spaces around the equals sign can be omitted.&lt;br /&gt;
** When in-/decrementing a variable by 1, the spaces around the + and - operator can be omitted if you want to &amp;quot;get the neighbour&amp;quot; of something, e.g. when increasing some counter variable.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local num = 2 * (3 / 4)&lt;br /&gt;
foo({bar=true})&lt;br /&gt;
foo({bar = true})&lt;br /&gt;
local def = {&lt;br /&gt;
	foo = true,&lt;br /&gt;
	bar = false,&lt;br /&gt;
}&lt;br /&gt;
i = i+1&lt;br /&gt;
sometable[#sometable+1] = v&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local num=2*(3/4)&lt;br /&gt;
local def={&lt;br /&gt;
	foo=true,&lt;br /&gt;
	bar=false,&lt;br /&gt;
}&lt;br /&gt;
playerpos.y = playerpos.y+1  -- playerpos.y is not an integer&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use spaces to align related things, but don't go overboard:&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local node_up   = minetest.get_node(pos_up)&lt;br /&gt;
local node_down = minetest.get_node(pos_down)&lt;br /&gt;
-- Too long relative to the other lines, don't align with it&lt;br /&gt;
local node_up_1_east_2_north_3 = minetest.get_node(pos_up_1_east_2_north_3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local x                       = true&lt;br /&gt;
local very_long_variable_name = false&lt;br /&gt;
&lt;br /&gt;
local foobar    = true&lt;br /&gt;
local unrelated = {}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tables ===&lt;br /&gt;
&lt;br /&gt;
* '''Small tables may be placed on one line.'''  Large tables have one entry per line, with the opening and closing braces on lines without items; and with a comma after the last item.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local foo = {bar=true}&lt;br /&gt;
foo = {&lt;br /&gt;
	bar = 0,&lt;br /&gt;
	biz = 1,&lt;br /&gt;
	baz = 2,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
foo = {bar = 0,&lt;br /&gt;
	biz = 1,&lt;br /&gt;
	baz = 2}&lt;br /&gt;
foo = {&lt;br /&gt;
	bar = 0, biz = 1,&lt;br /&gt;
	baz = 2&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* In list-style tables where each element is short multiple elements may be placed on each line.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local first_eight_letters = {&lt;br /&gt;
	&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;,&lt;br /&gt;
	&amp;quot;e&amp;quot;, &amp;quot;f&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;h&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Naming ==&lt;br /&gt;
&lt;br /&gt;
* '''Functions and variables should be named in &amp;lt;code&amp;gt;lowercase_underscore_style&amp;lt;/code&amp;gt;''', with the exception of constructor-like functions such as &amp;lt;code&amp;gt;PseudoRandom()&amp;lt;/code&amp;gt;, which should use UpperCamelCase.&lt;br /&gt;
&lt;br /&gt;
* Don't invent compound words.  Common words like &amp;lt;code&amp;gt;filename&amp;lt;/code&amp;gt; are okay, but mashes like &amp;lt;code&amp;gt;getbox&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;collisiondetection&amp;lt;/code&amp;gt; aren't.&lt;br /&gt;
&lt;br /&gt;
* Avoid leading and/or trailing underscores.  They're ugly and can be hard to see.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
&lt;br /&gt;
* Don't put multiple statements on the same line.&lt;br /&gt;
&lt;br /&gt;
* You can put conditionals / loops with small conditions and bodies on one line.  This is discouraged for all but the smallest ones though.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local f, err = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
if not f then return err end&lt;br /&gt;
&lt;br /&gt;
if     foo then return foo&lt;br /&gt;
elseif bar then return bar&lt;br /&gt;
elseif qux then return qux&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
if not f and use_error then error(err) elseif not f then return err end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Don't compare values explicitly to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;nil&amp;lt;/code&amp;gt;, unless it's really needed.&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #282;&amp;quot;&amp;gt;Good:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
local f, err = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
if not f then return err end&lt;br /&gt;
&lt;br /&gt;
local t = {&amp;quot;a&amp;quot;, true, false}&lt;br /&gt;
for i = 1, 5 do&lt;br /&gt;
	-- Needs an explicit nil check to avoid triggering&lt;br /&gt;
	-- on false, which is a valid value.&lt;br /&gt;
	if t[i] == nil then&lt;br /&gt;
		t[i] = &amp;quot;Default&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: #b44;&amp;quot;&amp;gt;Bad:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
if f == nil then return err end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Don't use unnecessary parenthesis unless they improve readability a lot.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Lua&amp;quot;&amp;gt;&lt;br /&gt;
if y then bar() end -- Good&lt;br /&gt;
if (not x) then foo() end -- Bad&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Write function definitions of the form &amp;lt;code&amp;gt;function foo()&amp;lt;/code&amp;gt; instead of the lambda form &amp;lt;code&amp;gt;foo = function()&amp;lt;/code&amp;gt;, except when inserting functions in tables inline, where only the second form will work.&lt;br /&gt;
&lt;br /&gt;
* '''Avoid globals like the plague.'''  The only globals that you should create are namespace tables&amp;amp;mdash;and even those might eventually be phased out.&lt;br /&gt;
&lt;br /&gt;
* Don't let functions get too large.  Maximum length depends on complexity; simple functions can be longer than complex functions.&lt;br /&gt;
&lt;br /&gt;
[[Category:Rules and Guidelines]]&lt;/div&gt;</summary>
		<author><name>&gt;Wuzzy</name></author>
	</entry>
</feed>