Prompt Engineering Best Practices

Writing clear, specific prompts helps the AI understand your needs and provide better assistance. This guide teaches you how to communicate effectively with Roflow's AI.

Core Principles

1. Be Specific

Vague:

"Make the game better"

Specific:

"Add a respawn cooldown of 5 seconds to prevent spawn camping"

2. Provide Context

No Context:

"Fix the bug"

With Context:

"The player's health doesn't reset when they respawn. It should reset to 100 but stays at whatever it was when they died. The respawn code is in src/handlers/SpawnHandler.lua"

3. State Your Goal

Unclear Goal:

"Change the inventory system"

Clear Goal:

"Refactor the inventory system to use attributes instead of IntValues so it's easier to replicate to the client"

4. Mention Constraints

No Constraints:

"Add a shop system"

With Constraints:

"Add a shop system using Knit framework. It should use RemoteEvents for purchases and store data with DataStore2. Keep it under 200 lines"

Prompt Patterns

Pattern 1: Feature Request

Template:

Add [feature] to [location].
It should [behavior].
Use [framework/pattern] if applicable.

Example:

Add a double jump ability to src/controllers/PlayerController.lua.
It should allow jumping once more while in the air, with a 0.5 second cooldown between jumps.
Use the existing input handling system.

Pattern 2: Bug Fix

Template:

[Problem description]
Expected: [what should happen]
Actual: [what actually happens]
Location: [file/function]

Example:

Players are falling through the map when they spawn.
Expected: Players should spawn on the SpawnLocation part at position Y=50
Actual: They spawn below the baseplate and fall infinitely
Location: src/services/SpawnService.lua, function spawnPlayer()

Pattern 3: Refactoring

Template:

Refactor [code] from [current approach] to [desired approach].
Reason: [why this is better]
Maintain: [what should stay the same]

Example:

Refactor src/systems/CombatSystem.lua from using BindableEvents to using Promises.
Reason: Promises provide better error handling and flow control
Maintain: The same public API so other modules don't need changes

Pattern 4: Explanation Request

Template:

Explain [code/concept] in [file/context].
Focus on: [specific aspect]

Example:

Explain how the replication system works in src/core/ReplicationManager.lua.
Focus on: How it determines which data to send to which clients

Pattern 5: Code Review

Template:

Review [file] for [concerns].
Check for: [specific issues]
Suggest: [type of improvements]

Example:

Review src/modules/DataManager.lua for performance issues.
Check for: Memory leaks, inefficient loops, unnecessary connections
Suggest: Optimizations that don't break existing functionality

Contextual Information

What to Include

The AI benefits from knowing:

  1. File Paths: Exact location of relevant code
  2. Framework: Knit, Flamework, Aero, etc.
  3. Dependencies: Packages or libraries in use
  4. Code Style: Patterns you want to maintain
  5. Error Messages: Exact errors if debugging

Example with Rich Context

I'm using Knit framework with TypeScript.

The Weapon service in src/server/services/WeaponService.ts
isn't properly detecting hits.

Current behavior:
- FireServer is called from client
- Server checks for parts in workspace
- Humanoids are damaged

Problem:
- Sometimes hits don't register despite the ray hitting
- No error messages appear

Could you review the hit detection logic and suggest improvements?
Keep it compatible with the existing weapon configuration system.

Common Mistakes

Mistake 1: Too Vague

❌ "Make it work"

  • AI doesn't know what "it" is or what "work" means

✅ "Fix the RemoteEvent handler in ShopService.lua so purchases actually deduct the correct currency amount"

Mistake 2: Assuming Context

❌ "Add this to the player"

  • AI doesn't know what "this" refers to

✅ "Add a speed boost attribute to the player's character that multiplies their WalkSpeed by 1.5"

Mistake 3: Multiple Unrelated Requests

❌ "Fix the spawn bug, add a shop, optimize the lighting, and update the README"

  • Too many unrelated tasks in one prompt

✅ Break into separate conversations:

  1. "Fix the spawn bug in SpawnHandler.lua"
  2. Then: "Add a shop system"
  3. Later: "Optimize lighting settings"

Mistake 4: No Acceptance Criteria

❌ "Make the game faster"

  • No way to measure success

✅ "Reduce server script execution time by identifying and optimizing loops that run every frame. Target: under 2ms total per frame"

Effective Techniques

Technique 1: Step-by-Step Requests

Instead of one big request, break it down:

Step 1: "Show me how the current damage system works in CombatService.lua"
Step 2: "Now add critical hit chance (10%) that deals 2x damage"
Step 3: "Add a particle effect when a critical hit happens"

Technique 2: Provide Examples

Add type annotations to PlayerStats.lua.
Example style:
```lua
function calculateDamage(attacker: Player, target: Player, baseDamage: number): number
    -- implementation
end

### Technique 3: Reference Existing Code

"Add a new weapon type following the same pattern as the Sword implementation in src/weapons/Sword.lua"


### Technique 4: Ask for Explanation First

Before making changes, can you explain:

  1. How the current system works
  2. What changes would be needed
  3. Any potential issues with the approach

## Iterative Refinement

### Start Broad, Then Refine

**Iteration 1:**
> "Add a leveling system"

**AI Responds with plan**

**Iteration 2:**
> "Good plan, but instead of using IntValues, use attributes for better performance"

**Iteration 3:**
> "Also add a level-up sound effect and particle burst"

<Callout type="tip" title="Conversational Approach">
  Treat it like a conversation. Start with the main idea, then refine based on the AI's responses.
</Callout>

## Framework-Specific Tips

### Knit Framework

"Create a new Knit service called InventoryService. Include these methods:

  • AddItem(player, itemId)
  • RemoveItem(player, itemId)
  • GetInventory(player)

Use Knit.CreateService pattern and proper type annotations."


### Flamework

"Create a Flamework component for a collectible coin. It should:

  • Attach to BasePart instances
  • Detect player touch
  • Fire a signal when collected
  • Despawn after collection

Use @Component decorator and dependency injection."


### TestEZ

"Write TestEZ specs for DataService.lua. Test cases:

  • saveData successfully stores player data
  • loadData retrieves correct data
  • handlePlayerRemoving saves before cleanup

Use GIVEN/WHEN/THEN structure."


## Dos and Don'ts

### ✅ Do

- Be specific about file locations
- Explain the "why" behind requests
- Provide relevant error messages
- Ask clarifying questions
- Iterate on responses
- Use technical terminology correctly

### ❌ Don't

- Assume the AI remembers previous sessions (it doesn't)
- Request proprietary or copyrighted code
- Ask for complete games ("make Phantom Forces")
- Expect the AI to read your mind
- Skip reviewing AI-generated code
- Ignore warnings or suggestions

## Measuring Prompt Quality

Good prompts typically:

1. **Get useful results on first try** (or second)
2. **Require minimal back-and-forth** to clarify
3. **Produce code that works** without major changes
4. **Address the root problem** not just symptoms

Poor prompts lead to:

1. AI asking for clarification
2. Generated code that doesn't fit your needs
3. Multiple revision cycles
4. Frustration and wasted time

## Practice Examples

### Exercise 1: Improve This Prompt

❌ **Original:**
> "The thing isn't working"

✅ **Improved:**
> "The shop purchase handler in src/server/services/ShopService.lua isn't deducting coins when items are purchased. The purchase goes through but player.Coins.Value stays the same. Can you review the deduction logic?"

### Exercise 2: Add Context

❌ **Original:**
> "Add validation"

✅ **Improved:**
> "Add input validation to the trade system in TradeService.lua. Validate that:
> 1. Both players are online
> 2. Items exist in inventories
> 3. Trade isn't already in progress
> 4. Items aren't equipped
> Return descriptive error messages for each case."

### Exercise 3: Be Specific

❌ **Original:**
> "Optimize this"

✅ **Improved:**
> "Optimize the UpdateLeaderboard function in src/modules/Leaderboard.lua. It's currently looping through all players every second to update stats. Refactor to only update when stats actually change using player.Changed events."

## Advanced Prompting

### Using Code Blocks

Include code in your prompts for precision:

I have this function:

function damagePlayer(player, amount)
    player.Character.Humanoid.Health -= amount
end

Modify it to:

  1. Check if character and humanoid exist
  2. Emit a damaged event
  3. Play a hurt sound
  4. Return actual damage dealt (accounting for damage reduction)

### Referencing Multiple Files

```
"I need to refactor the communication between:
- src/client/controllers/UIController.lua
- src/server/services/UIService.lua

Currently they use RemoteFunctions which blocks the client.
Convert to RemoteEvents with callbacks for better performance.
Update both files to maintain the same external API."
```

## Next Steps

- [Prompt Patterns](/docs/prompt-guide/patterns) - More prompt templates
- [Context Management](/docs/prompt-guide/context-management) - Providing better context
- [Common Pitfalls](/docs/prompt-guide/common-pitfalls) - Avoid these mistakes
- [AI Features](/docs/ai-features/chat-panel) - Learn about the chat interface