Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions .claude/skills/course/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: course
description: Interactive Claude Code learning course with progress tracking
argument-hint: "[lesson-number | next | progress | reset | exit | update | complete]"
argument-hint: "[lesson-number | next | progress | reset | exit | update | complete | lang en|zh-TW]"
---

# Dungeons & Agents - Interactive Course
Expand Down Expand Up @@ -95,6 +95,47 @@ Be specific in instructions: "Update the Take Button in the Actions Section" not
- `exit` → Save position and exit the course
- `update` → Check for and apply updates from GitHub
- `complete` → Mark course as complete and show graduation message
- `lang [en|zh-TW]` → Set course language

---

## Language / Locale

The course supports English (`en`) and Traditional Chinese (`zh-TW`).

### Detecting locale

Read the `locale` field from `dungeon/course-progress.json`. If the field is missing, default to `en`.

### Setting locale

When $ARGUMENTS starts with `lang`:

1. Parse the language code (e.g., `lang zh-TW` or `lang en`)
2. Update `dungeon/course-progress.json` to include `"locale": "zh-TW"` (or `"en"`)
3. Display confirmation:

```
╭──────────────────────────────────────────────╮
│ Language set to: 繁體中文 (zh-TW) │
│ │
│ Run /course to continue learning │
╰──────────────────────────────────────────────╯
```

### Using locale

When locale is `zh-TW`:

- Read lesson files from `learn-claude/zh-TW/XX-*.md` instead of `learn-claude/XX-*.md` (use the `file_zh` field from lessons.json)
- Use `title_zh` and `name_zh` from lessons.json for dashboard display
- The tutor should converse in Traditional Chinese
- Keep code blocks, CLI commands, file paths, and slash commands in English

When locale is `en` (default):

- Use `file` and `title` fields from lessons.json as before
- The tutor converses in English

---

Expand All @@ -107,7 +148,8 @@ When $ARGUMENTS is empty, show the course dashboard:
{
"completed": [],
"current": null,
"graduated": false
"graduated": false,
"locale": "en"
}
```
2. Read lesson list from `skills/course/lessons.json`
Expand Down
79 changes: 68 additions & 11 deletions .claude/skills/course/lessons.json
Original file line number Diff line number Diff line change
@@ -1,48 +1,105 @@
{
"title": "Learn Claude Code",
"title_zh": "學習 Claude Code",
"parts": [
{
"name": "Introduction",
"lessons": [{ "id": "00", "title": "Welcome", "file": "00-intro.md" }]
"name_zh": "簡介",
"lessons": [
{
"id": "00",
"title": "Welcome",
"title_zh": "歡迎",
"file": "00-intro.md",
"file_zh": "zh-TW/00-intro.md"
}
]
},
{
"name": "Getting Started",
"name_zh": "入門",
"lessons": [
{
"id": "01",
"title": "Your First Session",
"file": "01-first-session.md"
"title_zh": "你的第一次 Session",
"file": "01-first-session.md",
"file_zh": "zh-TW/01-first-session.md"
},
{
"id": "02",
"title": "CLI Navigation",
"file": "02-cli-navigation.md"
"title_zh": "CLI 導航",
"file": "02-cli-navigation.md",
"file_zh": "zh-TW/02-cli-navigation.md"
},
{ "id": "03", "title": "Managing Context", "file": "03-context.md" },
{ "id": "04", "title": "Modes", "file": "04-modes.md" }
{
"id": "03",
"title": "Managing Context",
"title_zh": "管理上下文",
"file": "03-context.md",
"file_zh": "zh-TW/03-context.md"
},
{
"id": "04",
"title": "Modes",
"title_zh": "模式",
"file": "04-modes.md",
"file_zh": "zh-TW/04-modes.md"
}
]
},
{
"name": "Project Context",
"name_zh": "專案上下文",
"lessons": [
{ "id": "05", "title": "CLAUDE.md", "file": "05-claude-md.md" },
{ "id": "06", "title": "Writing Rules", "file": "06-writing-rules.md" },
{ "id": "07", "title": "Prompting", "file": "07-prompting.md" },
{
"id": "05",
"title": "CLAUDE.md",
"title_zh": "CLAUDE.md",
"file": "05-claude-md.md",
"file_zh": "zh-TW/05-claude-md.md"
},
{
"id": "06",
"title": "Writing Rules",
"title_zh": "撰寫規則",
"file": "06-writing-rules.md",
"file_zh": "zh-TW/06-writing-rules.md"
},
{
"id": "07",
"title": "Prompting",
"title_zh": "提示技巧",
"file": "07-prompting.md",
"file_zh": "zh-TW/07-prompting.md"
},
{
"id": "08",
"title": "Creating Skills",
"file": "08-creating-skills.md"
"title_zh": "建立技能",
"file": "08-creating-skills.md",
"file_zh": "zh-TW/08-creating-skills.md"
}
]
},
{
"name": "Agents",
"name_zh": "代理",
"lessons": [
{ "id": "09", "title": "Subagents", "file": "09-claude-agents.md" },
{
"id": "09",
"title": "Subagents",
"title_zh": "子代理",
"file": "09-claude-agents.md",
"file_zh": "zh-TW/09-claude-agents.md"
},
{
"id": "10",
"title": "Application Agents",
"file": "10-application-agents.md"
"title_zh": "應用程式代理",
"file": "10-application-agents.md",
"file_zh": "zh-TW/10-application-agents.md"
}
]
}
Expand Down
46 changes: 44 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,54 @@ When adding or modifying enemies:
- When implementing features, check reference/complete/game.js, reference/complete/ui/ui.js, and reference/complete/data/ for reference
- Use these as guardrails to ensure your implementations match the intended patterns and structure

## Internationalization (i18n)

The game supports English (`en`) and Traditional Chinese (`zh-TW`). Locale is detected via URL query parameter `?lang=zh-TW`.

### Architecture

- **`strings.js`**: Core i18n infrastructure — `detectLocale()`, `t()` helper, `S` string map, `T` template functions, `localizeHTML()`
- **Data JSON files**: Use inline `_zh` suffix fields (e.g., `name_zh`, `description_zh`) — not separate overlay files
- **Items**: Use `icon` field for icon lookup instead of English name matching

### Translation helper `t()`

Dual-signature function:
- `t(localeMap)` — for system strings: `t(S.welcome)` returns the localized string from `{ en: "...", "zh-TW": "..." }`
- `t(obj, field)` — for data objects: `t(room, "name")` returns `room.name_zh` (zh-TW) or `room.name` (en)

### Template functions `T.*`

Locale-aware string formatters for sentences with parameters:
- `T.youGo(dir)`, `T.youPickUp(item)`, `T.youAttackFor(name, dmg)`, `T.enemyDefeated(name)`, etc.

### When adding translatable content

1. Add `_zh` fields to data JSON files alongside English fields
2. Add new system strings to the `S` object in `strings.js` with both `en` and `zh-TW`
3. Use `t()` or `T.*` in game.js/ui.js — never hardcode English strings
4. Add items with an `icon` field for icon lookup

### Course locale

- Course language is stored in `dungeon/course-progress.json` as `"locale": "en"` or `"locale": "zh-TW"`
- Lesson translations are in `learn-claude/zh-TW/`
- Set via `/course lang zh-TW`

### Testing

Run `npm test` to verify i18n infrastructure:
- `t()` function behavior for both locales
- `T.*` template functions output
- Data file integrity (all `_zh` fields present)
- `S` string completeness

## General Principle

When you add any game artifact (character, room, item, enemy), update:

1. The data file (JSON)
2. The UI elements that display/interact with it
1. The data file (JSON) — include `_zh` fields for zh-TW translations
2. The UI elements that display/interact with it — use `t()` for all user-facing strings
3. Any visual assets (pixel art) if applicable

---
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
English | [繁體中文](README.zh-TW.md)

# Learn Claude Code

An interactive course for learning Claude Code in Claude Code.
Expand Down Expand Up @@ -49,10 +51,17 @@ Each lesson teaches a Claude Code concept, then has you apply it to the game. By
Start the game server:

```bash
node dungeon/server.js
pnpm start
```

Then open http://localhost:3000 in your browser.
- English: http://localhost:3000
- Traditional Chinese: http://localhost:3000?lang=zh-TW

When building step-by-step during the course, use the student workspace:

```bash
pnpm run dev
```

---

Expand Down Expand Up @@ -114,6 +123,8 @@ learn-claude-code/
| `/course exit` | Pause and save position |
| `/course reset` | Start over |
| `/course update` | Update to latest version |
| `/course lang zh-TW` | Switch to Traditional Chinese |
| `/course lang en` | Switch to English |

---

Expand Down
Loading