# 部署到 SLS ｜ Deploying to SLS (Student Learning Space)

从档案到一个会自动记分的 SLS 课业，一步一步来。
Step by step, from the file to a live, auto-graded activity in your Module.

> **用哪一个档案：** 请用 repo 最上层的 **`unit34sls.zip`**（里面就是 `sls/index.html`）—— 这一版内嵌 xAPI，学生做完，分数会自动出现在**教师后台的 Gradebook** 里。
> 根目录的 `game.html` 是给 GitHub Pages／一般网站用的**无 xAPI 版**，上传到 SLS 也能玩，但**不会记分**。两版的游戏内容与题目完全相同。
>
> **Which file:** use **`unit34sls.zip`** from the top level of the repo (it contains `sls/index.html`) — this build has xAPI embedded, so each student's score lands in the **teacher gradebook** automatically.
> The `game.html` at the root is the **no-xAPI build** for GitHub Pages or any website; it will run inside SLS but will **not report any marks**. The game content is identical in both.

---

## 1. 下载压缩档 ｜ Download the archive

**不必自己压缩。** repo 最上层的 `unit34sls.zip` 已经压好了，里面就一个 `index.html`，
躺在压缩档的最外层，没有多包资料夹 —— 那正是 SLS 唯一认得的结构。下载下来直接上传就行。

**You do not need to zip anything.** `unit34sls.zip` at the top level of the repo is
already packaged: a single `index.html` sitting at the root of the archive with no
folder around it, which is the only structure SLS recognises. Download and upload as is.

> 为什么不叫你自己压：Mac 的 Finder「压缩」会顺手塞进一个 `__MACOSX` 资料夹，
> SLS 读不到；而 `index.html` 一旦被多包一层，上传后也是一片空白。
> Why not do it by hand: Finder's own Compress quietly adds a `__MACOSX` folder that
> SLS cannot read, and one extra folder level around `index.html` uploads as a blank screen.

## 2. 改过题目的话，重打一次 ｜ Rebuilt the game? Repackage

只有在你改过 `sls/index.html` 之后才需要这一步。压缩档是脚本产生的，不是手压的 ——
手压的那一份迟早会跟 `index.html` 对不上：改了题目忘了重压，上传的就是旧版，
而且画面上看不出任何异样。

Only needed if you have edited `sls/index.html`. The archive is generated rather than
zipped by hand, because a hand-made one eventually falls behind `index.html` — edit the
questions, forget to re-zip, and the old version uploads with nothing on screen to show it.

```bash
python3 tools/pack-sls.py     # 重打 unit34sls.zip ｜ rebuilds unit34sls.zip
```

没有 Python 也行，用命令行压也一样 —— 重点是 `-j`，它把资料夹层级丢掉：
No Python? The command line does the same job — the point is `-j`, which drops the folder paths:

```bash
zip -j unit34sls.zip sls/index.html
unzip -l unit34sls.zip     # 确认里面只有最外层的 index.html ｜ check: index.html at the root, nothing else
```

## 3. 用对元件类型 ｜ Upload as the correct component type

> ⚠️ **这一步选错，整个班的分数就没了，而且当下完全看不出来。**
> 选成 **Text/Media**：游戏照样打得开，学生照样从头做到尾，画面上没有任何异样 ——
> 但**分数一个都不会记录**，教师后台永远是空的，你要等到去看成绩时才会发现。
> 这是作者自己踩过的坑，所以这一段写在最前面。
>
> ⚠️ **Get this step wrong and the whole class's marks are gone, with nothing on screen to warn you.**
> With **Text/Media** the game opens fine, students play it through to the end, and everything
> looks normal — but **not a single mark is recorded**. The gradebook stays empty and you only
> find out when you go looking for the marks. The author made exactly this mistake, which is
> why it sits at the top of this section.

**这一步是第一次做最容易错的地方。**
**This is the step most people get wrong on their first try.**

1. 在 **Module Editor** 里，把游标移到元件列的 **Question** 上
   In your **Module Editor**, hover over **Question** in the component bar
2. 选 **Free-Response → Interactive Response**（**不要**选 Text/Media —— 那个元件根本不会回报分数）
   Select **Free-Response → Interactive Response** — **not** Text/Media, which cannot report scores at all
3. 上传 `unit34sls.zip`
   Upload `unit34sls.zip`
4. **Maximum Marks** 设成游戏的满分 —— 本游戏是 **20**（SLS 上限是 99）
   Set **Maximum Marks** to the game's full score — **20** for this game (SLS caps it at 99)

> 官方说明 ｜ Official reference: [SLS Teacher User Guide — Creating HTML5 Content for Interactive Response](https://www.learning.moe.edu.sg/teacher-user-guide/author/html5-content-development/)

## 4. 确认分数真的进了后台 ｜ Verify the scores arrive

自己（或一位学生）完整做一次之后：
After you — or a student — has completed one full run:

1. 打开 SLS 里的这个 Module ｜ Open your Module in SLS
2. 点 **Learning Progress**（成绩簿图示）｜ Click **Learning Progress** (the gradebook icon)
3. 分数应该出现在这个 Interactive Response 元件底下 ｜ The score should appear under the Interactive Response component

分数是空的？依序检查：
If the score is blank:

- 元件类型是不是 Interactive Response，而不是 Text/Media
  Check the component really is Interactive Response, not Text/Media
- Maximum Marks 是不是还停在预设的 0
  Check Maximum Marks isn't still at the default 0
- 请学生重新整理再做一次 —— 第一次载入偶尔需要
  Ask the student to refresh and retry — occasionally needed on the first load

## 5. 上架社群资源库（可选）｜ Submit to the Community Gallery (optional)

想把课业分享给其他老师：
To share your activity with other teachers:

1. 打开 Module Editor（铅笔图示）｜ Open your Module Editor (pencil icon)
2. 在 **Module Details** 卡片上点 **Settings** 图示（那个小齿轮 —— *不是*三点选单，也*不是*编辑器其他地方的 Module Settings 齿轮）
   On the **Module Details** card, click the **Settings** icon — a small gear, *not* the three-dot menu and *not* the main Module Settings gear elsewhere in the editor
3. 在那里加上标签，别人才搜得到
   Add tags there so others can find it

注意：资源库连结即使审核通过、公开了，仍然需要登录 SLS 才看得到。
Note: gallery links require an SLS login to view, even once approved and public.

## 已知限制 ｜ Known constraints

| 限制 ｜ Constraint | 说明 ｜ Detail |
|---|---|
| SLS sandbox | 阻挡所有外部网址：xAPI 程式库、图片、字型全都得内嵌或 base64 写进 HTML 里<br>Blocks all external URLs — every asset (xAPI library, images, fonts) must be inlined or base64-encoded inside the HTML |
| 分数上限 ｜ Marks cap | Interactive Response 元件最高 99 分<br>99 marks maximum for Interactive Response components |
| 压缩档结构 ｜ ZIP structure | `index.html` 必须在最外层，不可多包资料夹<br>`index.html` must sit at the root — no nested folder |
| 元件类型 ｜ Component type | 必须是 **Question → Free Response → Interactive Response**，xAPI 记分才会运作。选 Text/Media 一分都记不到，而且画面上看不出来<br>Must be **Question → Free Response → Interactive Response** for xAPI score reporting to work at all. Text/Media records nothing, with no visible sign that anything is wrong |
| 档案大小 ｜ File size | SLS 上限 500MB，但请尽量控制在 200KB 以内，学生 iPad 才载得快<br>The SLS limit is 500MB, but aim to stay under ~200KB so it loads fast on student iPads |
| 手机控制 ｜ Mobile controls | 除了键盘，一定要有画面上的触控按钮 —— SLS 课业多半在 iPad 上做<br>Provide on-screen touch buttons alongside keyboard controls — SLS activities are mostly used on iPads |
