AI Skill Report Card

Routing Luau Paradigms

A-87·Oct 27, 2026·Source: Web
YAML
--- name: routing-luau-paradigms description: Routes Luau/Lua system design decisions to the appropriate paradigm (OOP, Reactive, Declarative/Functional, or Event-driven) via a three-question decision tree. Use when choosing a paradigm, structuring a module, or reducing boilerplate for a new system. Triggers include "which paradigm", "OOP or functional", "combat system structure", "inventory architecture", "reactive UI". Do not use for syntax questions, API lookup, or performance tuning. ---

Routing Luau Paradigms

Answer three routing questions in strict order. Stop at the first "Yes". Fetch the linked reference before writing any code — do not rely on memory for API shape.

14 / 15

Given a task description, walk the tree:

  1. Does it own mutable state with identity/lifecycle? → OOP
  2. Else, does UI/dependent state need to auto-update on source change? → Reactive
  3. Else, is the core operation a pure data transform? → Declarative + Functional
  4. Else → Event-driven
Task: "Build a combat system with per-player cooldowns"
Q1: Yes (mutable state, identity = player) → OOP. Stop.
Recommendation▾
Add a counter-example showing a wrong paradigm choice and why it fails, to reinforce the decision tree's discriminating power
14 / 15

Progress:

  • Restate the task in one sentence to confirm the "core operation"
  • Ask Q1 (identity + lifecycle) — answer Yes/No explicitly
  • If No, ask Q2 (auto-updating UI/dependents) — answer Yes/No explicitly
  • If No, ask Q3 (pure transform, no side effects) — answer Yes/No explicitly
  • Identify the leaf paradigm
  • Fetch the reference link for that leaf before writing code
  • Note any secondary paradigm needed only at boundaries (e.g., event-driven glue around an OOP class)

Q1 — Identity & lifecycle?

Examples: a specific Player instance, a persistent Tool, a stateful combat controller.

Q2 — Auto-updating dependents?

UI or derived state that must stay in sync with a source value.

Q3 — Pure transformation?

No side effects, input→output only.

  • Yes → Declarative + Functional (used together).
    • Use map/filter/reduce over raw loops for collections; fetch https://github.com/Roblox/cryo
    • Keep side effects pushed to the edges of the system.
    • Luau has no TCO — rewrite recursive algorithms as loops.
  • No → Event-driven. Prefer Deferred signals; avoid raw BindableEvent/RemoteEvent wiring unless a reactive abstraction is overkill. Always disconnect on cleanup. Reference: https://create.roblox.com/docs/scripting/events/deferred
Recommendation▾
Clarify what happens when Q1 is borderline (e.g., short-lived identity) with a tie-breaker heuristic
17 / 20

Example 1: Input: "Combat system with per-player cooldowns and state" Output: Q1=Yes → OOP. Fetch luau.org OOP reference, build a Combat class with typed self, one per player.

Example 2: Input: "Inventory UI that reflects weight changes live" Output: Q1=No, Q2=Yes → Reactive. Bind weight state to UI display via RoRx/Vide; clean up subscription on UI unmount.

Example 3: Input: "Damage calculation from stats and equipment" Output: Q1=No, Q2=No, Q3=Yes → Declarative + Functional. Pure function calculateDamage(stats, equipment) -> number; use cryo helpers if composing over collections.

Example 4: Input: "Cross-server matchmaking notification" Output: Q1=No, Q2=No, Q3=No → Event-driven. Use Deferred signal, disconnect listener on match completion.

Example 5: Input: "Plain inventory data, no UI, no identity" Output: Q1=No, Q2=No, Q3=Yes → Declarative + Functional.

Recommendation▾
Consider a brief note on how to handle tasks that genuinely need two leaves as co-primary (not just boundary glue) since 'mixing is normal' is asserted but not fully illustrated
  • Run the questions in order; never jump to a leaf based on intuition alone.
  • State the leaf explicitly ("→ OOP") before writing any code.
  • Mixing paradigms is normal — the leaf is the primary paradigm for the core module; secondary paradigms belong only at system boundaries (e.g., an event-driven signal notifying an OOP controller).
  • When two leaves both seem defensible, pick whichever removes more boilerplate for this specific task.
  • Always fetch the reference link for the chosen leaf — these are living libraries/docs, not stable enough to recall from memory.
  • Skipping straight to OOP because "that's how Roblox code usually looks" — identity/lifecycle must be genuinely present, not assumed.
  • Choosing Reactive for one-off state reads that don't need to auto-propagate — that's just a function call.
  • Using recursion for "pure transform" leaf without checking for TCO — Luau will stack overflow on deep recursion.
  • Wiring raw BindableEvent/RemoteEvent for event-driven leaf when Deferred signals are available and more appropriate.
  • Forgetting cleanup/disconnect logic in Reactive and Event-driven leaves — this is the most common leak source in both.
0
Grade A-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
14/15
Workflow
14/15
Examples
17/20
Completeness
17/20
Format
15/15
Conciseness
14/15