LAB GUIDE / SECTION 03
Mission 1 — Make it yours
Goal: your name and your Character on your page, live, and your Card on the projector. Platform concepts: the anatomy of a Worker, config vs code, push-to-deploy.
3.1 Tour of your Worker#
Open the project in your editor. We'll go through these together:
wrangler.jsonc ← config: name, entry point, vars, bindings
src/index.js ← the Worker itself: the fetch() function and its routes
src/character.js ← Mission 2: you write getCharacter()
src/droid.js ← Phase 2: you write the tone, your Coding Agent writes the rest
src/prompt.js ← ready-made: builds your Droid's system prompt from your Character
src/page.js ← pre-built: the HTML of your ID card
src/theme.js ← pre-built: picks the page theme from your Character's homeworld
src/avatar.js ← pre-built: the seed for your Pixel Droid (same function as the Hub's)
public/ ← pre-built: CSS, font, light/dark toggle, the Pixel Droid drawing
AGENTS.md ← a short brief for Coding Agents (Phase 2)
package.json ← dependencies and the dev / deploy scripts
solutions/ ← the teacher's reference. Not deployed, not imported: ignore itYou won't edit page.js, theme.js, avatar.js or anything in public/. The whole look of your page is already built. Your missions only fill in data.
Everything here came from the template: the Deploy button copied it into your GitHub repo.
Open src/index.js. It's the same shape as the 5 lines from the welcome page, just with a few routes:
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/api/card") return Response.json(card(env));
if (url.pathname === "/api/chat" && request.method === "POST") return handleChat(request, env);
if (url.pathname === "/") return renderHome(request, env);
return new Response("Not found", { status: 404 });
},
};Notice env. Everything your Worker is configured with arrives there: vars and bindings like env.AI. Your code never reads files or environment variables directly.
3.2 Edit your config#
Open wrangler.jsonc and find vars:
"vars": {
"NAME": "Your name", // ← nickname or first name (it's public!)
"TAGLINE": "Your tagline here", // ← one line about you
"EMOJI": "🚀",
// ← pick a number 1–83 from SWAPI people (17 doesn't exist),
// e.g. 1 Luke, 4 Darth Vader, 14 Han Solo, 20 Yoda
"CHARACTER_ID": "1",
"HUB_URL": "https://arena.cf2026iscte.nobledemos.com" // ← don't change
}Change NAME, TAGLINE, EMOJI and CHARACTER_ID. Save, then refresh http://localhost:8787 (restart npm run dev if it doesn't update). Your name, tagline and emoji change now. The Character rows wait for Mission 2.
Pick your Character#
CHARACTER_ID is a number from 1 to 83. 17 doesn't exist, so don't pick it. It's the Character your page and your Droid will be about. Each one has a homeworld, and your page takes its theme from that planet. Some good picks:
| ID | Character | Homeworld | Page theme |
|---|---|---|---|
| 1 | Luke Skywalker | Tatooine | desert |
| 4 | Darth Vader | Tatooine | desert |
| 14 | Han Solo | Corellia | forest |
| 20 | Yoda | unknown | space |
| 71 | Dexter Jettster | Ojom | ice |
| 5 | Leia Organa | Alderaan | grass |
| 3 | R2-D2 | Naboo | swamp |
| 51 | Mace Windu | Haruun Kal | lava |
| 72 | Lama Su | Kamino | ocean |
| 12 | Wilhuff Tarkin | Eriadu | city |
| 26 | Lobot | Bespin | gas |
Want to browse? Open https://swapi.dev/api/people/14/ in your browser. Change the number, and look at homeworld. You can change CHARACTER_ID any time.
Warning
Public page: use a nickname or first name. Don't put anything here you wouldn't put on a public CV.
3.3 Ship it#
git add -A
git commit -m "Make it mine"
git pushWatch it deploy: Cloudflare dashboard → Workers & Pages → your Worker → Deployments. After about 30 seconds https://<your-droid-name>.<your-subdomain>.workers.dev shows your name.
Tip
varsare config, not code. The same code with differentvarsis a different page. That's why 40 of you can run the same template and get 40 different results.
3.4 Register with the class#
- Check your Card endpoint works: open https://<your-droid-name>.<your-subdomain>.workers.dev/api/card. You should see JSON with your name and your
characterId. - Go to
https://arena.cf2026iscte.nobledemos.com/register. - Enter the Join Code from the projector, your Display Name, and your Student Worker URL:
https://<your-droid-name>.<your-subdomain>.workers.dev. - The Hub calls your
/api/cardand checks it. Fix anything it complains about and try again. - On success the page says "You're in" and shows your Pixel Droid. Look at the projector: your Card is now in the Directory.
There's no key to save and nothing to copy. Registration only checks that your Card endpoint answers.
Tip
Changed your name or Character later? Push, then register again with the same URL. It updates your Card instead of adding a second one.
Now open your live page (https://<your-droid-name>.<your-subdomain>.workers.dev) and compare your Pixel Droid with the one in the Directory. It's the same robot: both are drawn from your Worker's URL.
Check#
- https://<your-droid-name>.<your-subdomain>.workers.dev shows your name, tagline and emoji
CHARACTER_IDis set to a number between 1 and 83 (not 17)- Your Card is on the projector with your Pixel Droid
Show solution
wrangler.jsonc:
"vars": {
"NAME": "Ana",
"TAGLINE": "CS student, part-time stargazer",
"EMOJI": "🌌",
"CHARACTER_ID": "14",
"HUB_URL": "https://arena.cf2026iscte.nobledemos.com"
}Then git add -A && git commit -m "Make it mine" && git push.
Registration failed?
| Hub says | Fix |
|---|---|
| Registration isn't open yet | The teacher hasn't set a Join Code. Wait for it on the projector |
| Wrong Join Code | Check the projector; it may have changed |
Only *.workers.dev URLs | Use your Worker's URL, not localhost or github.com |
Couldn't reach /api/card | Did the push finish deploying? Open the URL yourself first |
Missing field name (or tagline, emoji) | That var in wrangler.jsonc is empty, or the push hasn't deployed yet |
Missing field characterId | CHARACTER_ID is missing or empty in wrangler.jsonc, or the push hasn't deployed yet |
Next: Your character
Checks are saved automatically on this browser.