Do you use setters and getters?

Hi!
What code would you use in your work?

var new_position = Vector2(100, 100)
position += step

or

var new_position = Vector2(100, 100)
set_position(get_position() + step)

Of course, this example is a bit strange, but I wanted to know if you use setters and getters to work with variables? And do you create your own in your functions?

I think some of the answer depends on your environment. If you work alone then you can do whatever you like and if you are part of a team then you should follow the agreed code standards.

Personally I rarely use setters and getters but I think I should use them more often. I start with just changing the variable value directly and only implement a set/get if I need to trigger some extra actions that are not handled elsewhere.

In your example of e.g. changing a player position then I wouldn’t use a setter because extra considerations like running into a wall or an enemy would be handled by the physics or collision code. There’s nothing more for you to do here so let that other code handle it.

If I were changing the player.health variable then I probably would implement a setter because if my player’s health reaches a certain value then I might want to change to the image to wounded (that’s probably in the same code scope) or emit a signal to some other code scope like updating the game dashboard.

I tend to create named functions for some of these things e.g. player.UpdateHealth(newvalue) but I think my own code discipline would be better if these were wisely named variables with setter/getter structures then I could refer to the property/variable directly and let the player code file worry about any extra stuff.

2 Likes

I use them when I have to.

For example, a health variable should not be less than zero so I’ll use:

var health: int: 
	set(value): health = maxi(0, value)
1 Like

Use them for classes that share the exact same data.

class_name Database

static var Character_List = { "Adam" : CharData, "Eve" : CharData }
class_name Character extends Node

@export var Character_ID : String

var Character : CharData :
	get : return Database.Character_List[Character_ID ]
	set(value) : Database.Character_List[Character_ID ] = value

func Increase_Strength():
	Character.Strength += 10
	pass

1 Like

I often work in teams, so I try to avoid public properties and use private variables as much as possible, which means I work a lot with setters / getters to have better control over the variables.

There are also property getters / setters as mentioned by GameDevGeezer:

Although they seem handy, I usually avoid them because they introduce unexpected behavior to others who may expect simple assignments, especially for public properties.

My rule of thumb is:

  • use getters and setters for property access from outside the class (public)
  • use setters for property access from within the class (private) only if I want side effects or validation (e.g. clamp the result), otherwise simple assignments

Sometimes I also use a function for handling relative changes as wrapper for the setter , e.g.:

signal health_changed
var _health: float = 5.0
var _max_health: float = 10.0

func set_health(new_health: float) -> void:
   _health = clamp(new_health, 0.0, _max_health)
   health_changed.emit()

func change_health(change_amount: float) -> void:
   set_health(_health + change_amount)

In the end, the question of when to use setters/getters often boils down to personal preference, I’ve seen a lot of people just use assignments (or property setters/getters) for this stuff, and not care about access. This probably also depends on how complex your project is

1 Like

Personally, I use it if there is a reason to. For example: input validation, error checking, or logging. But if the team (or the project you are working) convention is to have getter and setter, then it trumps everything else.

In this case I view it as bad practice. There is almost never a reason to use Godot’s built-in setter and getter functions. Only use them if you need to (e.g. call from animation)

Generally abstractions should decrease the number of characters you have to type, not increase them.

It’s important to understand these are a separate concept from Godot’s set/get functionality, which have nothing to do with the functions in your example. But, when I need custom behavior when a variable is set I usually opt for Godot’s variable set/get instead of a set_{var_name}-style function.

Of course, as mentioned by others, the use should be consistent within the codebase.

Whether variable setting should have any side effects is a matter of opinion, some think you shouldn’t be able to use ±/* with anything other than simple scalar numbers :slightly_smiling_face: It’s a matter of design. I prefer to use them, though you do have to be careful when deciding on what’s expected and what isn’t.

1 Like

Hi there!

When deciding between these two methods for setting positions, both approaches have their own merits, but they are often used based on personal or project-specific preferences.