Validation Techniques — GDScript
Skill codes on this page
| Code | Level | Skill |
|---|---|---|
| C713 | 1–2 | identifies input data for validation |
| C723 | 3–4 | existence checking |
| C724 | 3–4 | type checking |
| C725 | 3–4 | range checking |
| C735 | 5–6 | two of the three checks |
| C745 | 7–8 | all three checks |
| C753 ✍️ | 9–10 | ALL input data, plus reasonableness and completeness |
Definition. Validation checks the reasonableness of data inputs, while the program runs. It is not testing (testing happens to the finished program; validation happens to every input, every run). The three named checks: existence (was anything entered?), type (is it the right kind of value?), range (is it within acceptable limits?).
This ladder is not a checklist. The individual checks are separate codes only at level 3–4. Above that, single codes stand for the combination: C735 = two checks working, C745 = all three, C753 = all inputs plus reasonableness and completeness. Consistency qualifiers decide the band: some inconsistencies (5–6) → minor (7–8) → none (9–10).
In the validation Part B you add existence/type/range checks to the picked feature's real inputs, label them as you go, and run a test to show a check actually fires — a validation that never catches a bad value is scenery.
C713 — Identify the inputs
Level 1–2 is a written list of what needs validating:
# C713 — inputs to validate in this feature: # team name — NameField (LineEdit), free text # zone — ZoneSpinBox (SpinBox), whole number # top-up — TopUpField (LineEdit), dollars and cents
Earns the tick: every user-facing input of the picked feature named. (Choosing constrained controls — a SpinBox can't receive letters — is good design, but the codes below want checks in code.)
C723 — Existence check
Definition. A test to see if a value has been entered as input or not.
# club-ladder — app.gd func add_team(raw_name: String) -> void: var team_name := raw_name.strip_edges() if team_name == "": # C723 — existence: nothing entered message_label.text = "Type a team name first." return
Note the real-world details worth copying: strip_edges() first (spaces are not a name), and an error message that says what to do, not just "invalid".
C724 — Type check
Definition. A test to see if a value is of the specified data type or structure.
GDScript's idioms — check before converting, or the conversion itself is the crash:
# C724 — type: is the text actually a number? if not $TopUpField.text.is_valid_float(): $MessageLabel.text = "Enter an amount in dollars, like 10.50" return var amount := float($TopUpField.text)
String.is_valid_int() and is_valid_float() are the workhorses. The is keyword type-checks objects — real use in tile-matching-game: if child is Card: (board.gd).
C725 — Range check
Definition. Tests to see if a value is within a given range of acceptable values.
# C725 — range: zones only run 1..3, amounts have a ceiling if zone < 1 or zone > MAX_ZONE: $MessageLabel.text = "Zone must be 1 to %d" % MAX_ZONE return if amount <= 0.0 or amount > MAX_TOP_UP: $MessageLabel.text = "Top-up must be between $0.01 and $%.2f" % MAX_TOP_UP return
The limits are named constants (MAX_ZONE, MAX_TOP_UP) — that's C7-1 working for C7-3. Clamping (maxi(1, column_count) in club-ladder's board.gd) is the accept-and-correct cousin of reject-and-message; for user input, prefer the message — silent correction hides the user's mistake from them.
C735 and C745 — The checks working together
One validated input, all three checks, in the order that cannot crash — existence, then type, then range:
# C745 — full validation of the top-up amount (existence → type → range) func validate_top_up(raw: String) -> String: var text := raw.strip_edges() if text == "": # C723 — existence return "Enter an amount first." if not text.is_valid_float(): # C724 — type return "Enter a number, like 10.50" var amount := float(text) if amount <= 0.0 or amount > MAX_TOP_UP: # C725 — range return "Amount must be between $0.01 and $%.2f" % MAX_TOP_UP return "" # empty string = valid
C735 (5–6) is two of these working on real inputs; C745 (7–8) is all three, with at most minor inconsistencies. Error messages are part of the standard — "Must be between 8 and 72 in length" beats "Invalid input" because it tells the user how to fix it (that Discord message was the class's best-in-show in the Validation Detective activity).
C753 — All inputs, plus reasonableness and completeness ✍️
Level 9–10 widens the lens from single fields to the whole data set:
All relevant inputs validated — not just the easy one.
Completeness — is anything missing? Real example:
deck.gdskips half-empty CSV rows withif row.size() < 2: continue(tile-matching-game).Reasonableness — can these values be true together? The model is club-ladder's cross-check:
# club-ladder — app.gd ## In a competition where teams play each other, one team's win is always # C753 ✍️ ## another's loss — so total wins must equal total losses. Worth saying on ## screen rather than quietly showing figures that cannot be true. func totals_warning() -> String: if total_wins == total_losses: return "" return "Check your data: %d wins recorded, but %d losses." % [total_wins, total_losses]
Earns the tick: every input covered, a completeness check on incoming records, at least one reasonableness rule that crosses fields — and (✍️) the rule written down: work out what rules your data has to obey, and say so in a comment.
Then prove it fires. End the validation task by entering a bad value and showing the message appear — the package script asks for exactly this test run.
Check Your Understanding
- Name the three validation checks and their level 3–4 codes.
Answer
Existence C723, type C724, range C725.
- Why are C735 and C745 single codes rather than lists of checks?
Answer
Above level 3–4 the descriptor rewards the combination — two checks working (C735), then all three (C745) — with consistency qualifiers deciding the band.
- What makes "Must be between 8 and 72 in length" a better error message than "Invalid input"?
Answer
It tells the user exactly how to fix the problem — specific beats generic.
- Give an example of a reasonableness check (C753).
Answer
A cross-field rule — e.g. club-ladder's "total wins must equal total losses"; values that are individually fine but cannot be true together.
