Prompt Engineering Showcase

Behind the Prompt

Participants answered six questions and walked away with their own playable 3D games. Below shows the instructions and guardrails that made this experience possible.

For this activity, participants did not start with a blank screen. They answered a few questions, and Copilot built a first playable version of the game. From there, they could test it, react to it, and make it their own.
⚡ Workflow

How It Works — From Interview to Playable Game

1 Interview
6 questions
2 Generate
the game
3 Update
manifest
4 Test &
iterate
To keep the process fast, Copilot only needs the game template and the manifest. There is no setup step for students. Each game opens directly in the browser as a single HTML file.
📄 SKILL.MD — System Prompt

The Instructions We Gave Copilot

We wrote a Copilot Custom Skill for this event. It is just a Markdown file, but it gives Copilot a clear job: what to ask, what to build, and what rules to follow. Ours lives at:

# File location .github/copilot/skills/build-my-game/SKILL.md # YAML frontmatter triggers the skill --- name: build-my-game description: "Create a custom Three.js video game for NCWIT Indiana AIC Awards Event. Trigger phrases: create my game, make a game, build my game..." ---

When a participant says "build my game", Copilot loads these instructions and uses them to guide the whole workflow from the interview to the finished game.

Why it mattered: A simple phrase starts the workflow, but the instructions behind it are detailed enough to keep the results consistent.
🎤 Step 1 — The Interview

Prompt Strategy: Constrain the Input Space

The first prompt-engineering move was to reduce ambiguity before any code was written. Instead of open-ended chat, the skill collects the important design choices in one single dialog.

## Step 1: Interview the Participant Use the vscode_askQuestions tool to ask ALL questions in a single call: 1. Your Name 2. Game Genre 3. Game Setting 4. Color Theme 5. Special Feature 6. Game Title # Ask for the title last, after gameplay and theme choices
Prompt idea: ask for a small number of high-leverage choices up front. That gives the model enough structure to generate something specific without inviting drift.
Why this works: most choices are bounded, but the title stays open-ended. The prompt narrows the design space without making every game feel the same.
🏗️ Step 2 — Code Generation Rules

Prompt Strategy: Make the Output Legible and Bounded

Once the inputs are structured, the next job is keeping the generated code short and predictable. These constraints also shape what Copilot actually writes.

## Step 2: Generate the Game - Create games/<name>/index.html - Single-file HTML with inline Three.js - Compound 3D models (no generic shapes!) - Keyboard + touch controls - Title screen, score, game-over, play-again ## Important Rules - NEVER require npm, node, or any build tools - NEVER create external JS/CSS files - ALWAYS use Three.js r128 from CDN
# Keep the output portable - Must work when opened directly in a browser - No external JS or CSS files - No npm, no Node.js, no build tools # Require a complete playable loop - Title screen with name, instructions, and "Press SPACE or Tap" - Score display via HTML overlay - Game-over screen with final score + Play Again - Responsive design on desktop and mobile # Prevent common breakages - Web Audio API only; no external sound files - Resume AudioContext on first user gesture - Keyboard controls AND mobile touch controls
Prompt idea: good constraints do double duty. They simplify the student experience, and they also stop the model from wandering into package setup, a multi-file sprawl, or broken browser behavior.
🎨 Visual Theming Instructions

No Generic Cubes Allowed

We did not want every game to look like a quick demo. So the instructions explicitly push Copilot to build compound 3D models from multiple primitives instead of relying on default cubes and spheres.

// Example from the prompt: build a spaceship function createSpaceship() { const group = new THREE.Group(); // Body const body = new THREE.Mesh( new THREE.CylinderGeometry(0.3, 0.4, 1.2, 8), material ); group.add(body); // Nose cone const nose = new THREE.Mesh( new THREE.ConeGeometry(0.3, 0.5, 8), material ); nose.position.y = 0.85; group.add(nose); // Wings const wing = new THREE.Mesh( new THREE.BoxGeometry(1.8, 0.05, 0.4), material ); group.add(wing); return group; }
# Setting-specific visual recipes from the prompt - Underwater: Fish = sphere body + cone tail + triangle fins - Medieval Fantasy: Knight = box body + sphere head + cone helmet + thin box sword - Candy Land: Gummy bear = sphere body + small sphere ears + cylinder limbs - Cyberpunk City: Hover-bike = flat box + cylinder engines + emissive glow - Haunted: Ghost = sphere + taper + semi-transparent material # Rule of thumb Use at least 3-4 primitives per character so the visuals feel designed, not autogenerated.
🧠 Repository Memory

What We Learned Along the Way

Copilot has persistent memory for this repository. As we tested the activity, we saved lessons so the same mistakes never happened twice. Memory lives in two places:

# Repo memory — fast-path rules - Start with the interview immediately; only read _template/index.html + manifest.js. - Ask ALL 6 questions in ONE call, exact wording, title last. - Manifest is .js (NOT .json) — loaded via <script>, no fetch. # known-issues.md — read before generating, updated when bugs are found - Mobile: title screen must respond to tap, not just SPACE; touch controls required. - Camera: decorative buildings must not overlap the play area. - Gameplay: no hazards at spawn; every platform must be reachable. - Audio: resume AudioContext on first gesture or browsers block sound. # Self-healing loop (SKILL.md Step 5) When a participant reports a bug → append the lesson to known-issues.md → then fix the game.
How memory helped: Every new game benefits from bugs we already caught. When a participant finds a problem, we save it as a rule so it doesn't happen again.
🔬 Techniques

Design Choices That Helped

1. Structured Choices → Consistent Output

We used predefined genre, setting, and color choices instead of relying entirely on free text. That made it easier to map each student choice to clear visual and gameplay instructions.

2. Negative Instructions

Some of the most useful instructions were about what to avoid: generic shapes, unnecessary setup, and repetitive runner-style mechanics.

3. Concrete Examples

Instead of saying "make it interesting," we included small concrete examples. That gave Copilot something specific to adapt.

4. Fast-Path Optimization

Early versions spent too much time looking around the repo before doing useful work. Once we told Copilot to start the interview immediately and only read two files, the process sped up.

5. Memory as Iteration

Repository memory let us improve the workflow without rewriting the whole skill. When something went wrong, we saved the lesson and used it next time.

6. Single-File Constraint

Requiring a single HTML file was not just a convenience choice. It also kept the output from getting overly complex. Students could open the game and keep working.