The function / variable / class names should hint at their role.
func computeTime(d: int):
func computeTime(daysElapsed: int):
Look at how others named things in the code, and follow that.
Be mindful of naming conventions, i.e.:
- player refers to the person playing the game, while character is used for the player's ingame representation,
- team refers to the collection of players who can win the game together, role refers to the special abilities one gets for the game.
obj.fetch()
thing.Get()
obj.get()
thing.get()
The first word in a function name should be a verb, in a class / variable it should be a noun.
timerIncrement()
calculatedTime
incrementTimer()
timeCalculated
Use camelCase inside files and use snake_case in filenames. Enumerations are in CamelCase with first letter capitalized.
directoryCrawler.gd
crawl_directory(path_name: String)
directory_crawler.gd
crawlDirectory(pathName: String)
Whenever applicable, do not mix back end calculations with front end display functions. Use autoloads for complex back end work.
The nodes on the scene tree are not that easy to syncronize. The important game state should be stored in an autoload singleton, which should also take care of the networking. Always send data to the server, and let the server distribute the data to the other clients.
Adding types to all variables make development much more simple and less error- prone.
func doesSomething(a, b):
var counter = 0
var result = a
while counter < 5:
result = result ^ b
return result
func doesSomething(a: float, b: int) -> float:
var counter: int = 0
var result: float = a
while counter < 5:
result = result ^ b
return result
Assertions help us find places with predictable bugs and functions that are not yet implemented.
funct doSomething():
# TODO: implement this function
pass
funct doSomething():
assert(false, "Not implemented yet")
funct getData():
assert(len(data) > 0, "The data should be saved first before trying to access it")
return data
funct movement():
match a:
1:
goLeft()
2:
goRight()
3:
jump()
_:
assert(false, "Unreachable")
Apply the principle of "least knowledge".
- Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
- Each unit should only talk to its friends; don't talk to strangers.
- Only talk to your immediate friends.
https://en.wikipedia.org/wiki/Law_of_Demeter
players[i].player.inventory += item
players[current].addInventoryItem(item)
Use match instead whenever possible.
if (a ==1):
doSomething()
elif (a == 2):
doSomethingElse()
elif (a ==3):
doYetAnotherThing()
else:
doDefaultThing()
match a:
1:
doSomething()
2:
doSomethingElse()
3:
doYetAnotherThing()
_:
doDefaultThing()
if objectExists():
if objectIsGreen():
if objectIsMoving():
return true
else:
return false
else:
return false
else:
return false
if not objectExists():
return false
if not objectIsGreen():
return false
if not objectIsMoving():
return false
return true
var colors = {1: "green", 2: "red", 3: "orange", 4: "purple"}
var colors = {}
colors[1] = "green"
colors[2] = "red"
colors[3] = "orange"
colors[4] = "purple"
func doSomethingComplex() -> void:
# Setup
[ 30 lines of code ]
# Process
[ 60 lines of code ]
# Cleanup
[ 20 lines of code ]
func doSomethingComplex() -> void:
var values = setup()
process(values)
cleanup()
(don't repeat yourself)
process(obj1)
process(obj2)
process(obj3)
for obj in [obj1, obj2, obj3]:
process(obj)
It should be easy to navigate the code at a glance. Separate private and public functions whenever applicable. Separate the server-side and client-side functions.
Separators are comment lines start with # -- and can contain any number of dashes. Separated server and client functions are used by the control flow charting script.
func receiveClientData() -> void:
[ ... ]
func notifyServer() -> void:
[ ... ]
func recieveClientNotification() -> void:
[...]
# -- Client functions --
func notifyServer() -> void:
[ ... ]
# -- Server functions --
func receiveClientData() -> void:
[ ... ]
func recieveClientNotification() -> void:
[...]
The control flow charting scripts looks for comments in the code make the function boxes. Use comments with two "hash" symbols to describe the code conscisely for the graphing script. The script understands comment lines above the code and on the same line to the right of the code. Multi-line description is possible by using multiple lines above the code.
func addCharacter(networkId: int) -> void:
## Create character resource
var newCharacterResource: CharacterResource = Characters.createCharacter(networkId)
## Create character node
var newCharacter: KinematicBody2D = newCharacterResource.getCharacterNode()
## Randomize position
var characterPosition: Vector2
characterPosition.x = rng.randi_range(100, 500)
characterPosition.y = rng.randi_range(100, 500)
add_child_below_node(characterNode, newCharacter) ## Add node to scene
newCharacterResource.setPosition(characterPosition) ## Apply position
# TODO
setTime()
# TODO: add timezones
setTime()