# ChoiceScript 中的成就系统

> <https://www.choiceofgames.com/make-your-own-games/achievements-in-choicescript/>

成就是玩家过往行为的记录存档。在游戏中添加成就系统不是必要的，但许多玩家确实乐在其中。

## 初学者请不要直接从这里开始学习！

请务必先阅读我们基础的 [ChoiceScript 介绍](/zh-hans_choicescript-guide/guan-fang-zhi-nan/choicescript-jian-jie.md)页面。

## 存储成就：首先将你的游戏导出为 HTML

当你使用`*ifid` 并[将游戏导出为 HTML](/zh-hans_choicescript-guide/guan-fang-zhi-nan/dao-chu-bing-fa-bu-nin-de-you-xi.md) 时，HTML 文件会将你的**进度、检查点和成就存储在用户的浏览器**中。成就一旦激活，将保持永久激活状态，即使玩家通过菜单重新开始游戏也是如此。

如果你是在本地运行 ChoiceScript 服务器并刷新页面时，游戏会忘记所有发生过的事情，包括遗忘所有成就。

如果您最终决定[通过我们发布游戏](https://www.choiceofgames.com/looking-for-writers/)，我们将在苹果、谷歌和 Steam 平台发布您的成就，并将其永久存储在玩家账户中。

## 成就对应积分值

每个成就都对应特定数量的"积分"；每款游戏共有 1000 点积分可分配给所有成就。每款游戏最多可设置 100 个成就；单个成就的积分奖励不得超过 100 点。

高价值成就越稀有，在玩家好友列表中就越显眼，因此我们建议至少设置一项价值 100 点的成就。

由于苹果、谷歌和 Steam 平台审核通过后**不允许修改成就**，这使情况变得更为棘手。应用商店建议我们不要在游戏初始版本中耗尽全部"点数预算"，而应保留部分预算用于支持后续更新与新内容。

## 定义您的成就

成就定义位于`startup.txt` 文件顶部，与 `*title` 和 `*create` 命令并列，格式如下：

```
    *achievement lover visible 50 I'm a Lover, Not a Fighter
        Romance the dragon without killing it.

    *achievement dragonslayer visible 100 Dragon Slayer
        Who is the greatest dragon in the kingdom?
        Kill the dragon Axilmeus.

    *achievement secret hidden 50 Discovered the Secret
        hidden
        Discover the secret hidden within the dragon's lair.
```

第一条 `*achievement` 行包含成就的短名称、可见性、积分和标题。下一行缩进的内容是获得前的描述（如果成就被隐藏，则要填写“hidden”一词）。再下一行缩进的内容是获得后的描述（如果有的话）。

### 短名称

单个单词，全部使用小写字母、数字或下划线。不能包含点号或空格。此名称不会向玩家显示。例如：“dragonslayer”

短名称必须是唯一的。不能有两个成就都使用“dragonslayer”这个短名称。

### 可见性

“hidden”或“visible”。在玩家获得该成就之前，隐藏或显示其标题和描述。

请注意，苹果不允许我们隐藏成就的存在；成就仍会出现在列表中，只是标题显示为“隐藏”，且没有描述。

（王洛木：Steam 也是这样啊。）

#### 避免设置完全隐藏的成就

* 成就的目的是鼓励玩家去发现它们；没有任何标题或描述，就很难起到激励作用。
* 考虑使用隐晦的标题和描述来代替。

### **点数**

见上方（注意预算！）例如：100

### 显示标题

（王洛木：以下关于标题和描述的部分是关于美观的建议。这样写会容易好看。实际使用的时候不要愉悦长度限制即可。）

* 例如：“Dragon Slayer”（屠龙者）
* 保持简短。绝对上限为 50 个字符（包括空格），但请尽量远低于此限制。（某些平台仅允许 30 个字符。）
* 使用“（Title Case）实词首字母大写”进行书写。
* 不要使用结尾标点，例如“屠龙者。”是不正确的。

### 预获得描述

玩家获得成就前的描述，例如“杀死巨龙。”

* 限制在 200 个字符以内，包括空格。
* 这可以是对玩家的指令，也可以只是关于如何获得成就的隐晦提示，不一定要是祈使句。例如：“谁是王国里最强大的反派？”
* 句子必须以标点符号结尾；例如，“杀死巨龙”不是一个完整的句子，缺少句号。
* The pre-earned description must be the word “hidden” if the achievement is hidden.\
  如果成就是隐藏的，则预先获得的描述必须是 `hidden` 一词。（王洛木：由于这里本来就是文本的位置，所以不需要使用双引号）

### 获得后描述（可选，不建议使用）

玩家获得成就后的描述。如果预先获得的描述只是一个线索，或者成就是隐藏的，此描述可以直接向玩家解释目标是什么。例如：“杀死巨龙阿西尔梅乌斯。”

* 限制在 200 个字符以内，包括空格。
* 若此处留空，我们将使用解锁前描述作为解锁后描述。您的大部分成就都应如此处理。
* 若成就为隐藏状态，则该选项（获得后描述）为必填项。
* 在 Steam 平台上，每个成就仅有一段描述文字，不区分解锁前与解锁后描述。对于可见成就，我们采用解锁前描述；对于隐藏成就，则采用解锁后描述。
* 请勿使用过去时态撰写解锁后描述。尽可能采用祈使语气，例如"揭开秘密"而非"你已发现秘密"。否则当玩家在Steam解锁全部成就后，部分描述将呈现过去时态，而另一些则保持祈使句式。
* 句子必须以标点符号结尾；例如，“杀死巨龙”不是一个完整的句子，缺少句号。

## **成就的排列顺序很重要**

你编写 `*achievement` 命令的顺序，就是它们在成就列表中显示的顺序。

## 激活成就

你可以使用成就的短名称来授予玩家成就，例如：

```
    *achieve dragonslayer
```

玩家将会看到一个横幅，就像这样：

**成就：屠龙者**\
击杀巨龙。

（在 iOS 系统上，则会触发 Game Center 的成就横幅，该横幅仅显示成就标题。）

**每当玩家 `*achieve` 成就时，成就横幅都会显示，即使玩家已经获得过该成就。**&#x8FD9;是有意设计的；如果玩家重玩游戏，显示他们已经达成的成就横幅并无不妥。若您不希望出现此行为，可先按以下方式检查该成就是否已达成。

## 检查成就

`*check_achievements` 命令会创建名为"`choice_achieved_dragonslayer`"的临时变量，您可通过这些变量检测玩家是否已激活某项成就。

您可以使用 `*check_achievements` 为已经达成特定成就的玩家解锁内容。

```
*check_achievements
*if choice_achieved_dragonslayer
    You killed the dragon! (Perhaps in a previous playthrough.)
    Here's a nifty secret...
```

你也可以使用 `*check_achievements` 来激活元成就，即在你已激活其他成就后触发的成就。（王洛木：比如：拿到了其他的奖杯就给你个白金杯。）

```
*check_achievements
*if choice_achieved_dragonslayer and choice_achieved_lover
    *achieve dragonmaster
```

你也可以使用 `*check_achievements` 来防止显示玩家已经达成的成就横幅，但这通常不值得麻烦。如果玩家重新开始游戏并再次游玩，通常再次显示横幅是合适的。

```
*label loop
*check_achievements
*if not(choice_achieved_dragonslayer)
    *achieve dragonslayer

*choice
    #Loop.
        *goto loop
    #Continue.
        *finish
```

### 有问题吗？

若对本文件有疑问，请在 [ChoiceScript 论坛](http://www.choiceofgames.com/forum/categories/choicescript-help)发帖咨询。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://raster.gitbook.io/zh-hans_choicescript-guide/guan-fang-zhi-nan/choicescript-zhong-de-cheng-jiu-xi-tong.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
