Creating Custom Functions
Functions are how you stop repeating yourself. Instead of writing the same ten lines in five places, you write them once as a function and call it by name. They are the single biggest step from "copying snippets" to "writing scripts".
Get a free executor
You need an executor to run any Roblox script. Grab one free.
Defining a function
A function packages steps under a name: local function heal(player) ... end. You call it with heal(somePlayer). Define it once, use it anywhere — and when the logic needs to change, you change it in one place.
Use local functions by default, the same reason you use local variables: speed and no accidental clashes.
Parameters and return values
Parameters let a function work on different inputs each call — heal(playerA) versus heal(playerB). A return value lets a function hand a result back: local d = distance(a, b). Thinking in "inputs and outputs" is the core skill of writing clean functions.
Keep each function focused on one job. A function that does one thing is easy to name, test and reuse.
Scope matters
Variables declared inside a function only exist inside it. That is a feature — it keeps your logic self-contained and prevents one function from stepping on another. If two functions need to share something, pass it as a parameter rather than reaching for a global.
Clean scope is what keeps a growing script from turning into spaghetti; script structure and best practices covers how to organise it.
Where to go next
Functions become powerful once they react to the game — connect them to working with Roblox events — and once you pull them from Roblox's own libraries via utilizing APIs and libraries.