# Gosub

## Gosub

ChoiceScript 支持一种简单的子程序形式。子程序是一段可以通过 `*gosub` 命令在同一\[\[场景]]文件内的多个不同位置按需访问的代码块。这基本上消除了为了在不同地方使用而反复复制粘贴相同代码块的需要，同时也使得后续的任何修改实现起来更加快捷。

请注意，`*gosub` 命令仅在同一场景文件内有效。该命令的一个扩展，\[\[Gosub scene|\*gosub\_scene]]，允许从任何场景文件调用子程序，从而进一步减少了游戏文件中相同代码的重复。

### Usage

例如，假设在你的游戏中，你有四项主要属性（比如力量、敏捷、智力和智慧），在你的状态页面上以百分比条的形式显示，这意味着你可能不希望这些属性的值超过100。为了确保这一点，你可以使用一个非常简单的子程序，你可能会把它放在场景文件的底部。它可能看起来像这样：

```
*label cap_stats
*if strength > 100
    *set strength 100
*if dexterity > 100
    *set dexterity 100
*if intelligence > 100
    *set intelligence 100
*if wisdom > 100
    *set wisdom 100
*return
```

现在，你已经有效地创建了一个\[\[Label|标签]]为 `cap_stats` 的子程序，方法很简单，就是在末尾添加那个至关重要的 \[\[Return|\*return]] 命令。`*return` 命令仅用于标识一个子程序。

现在，你可以在同一个文件内的任何地方（例如，在你应用任何新属性增益的地方）使用这个子程序的现成脚本，而无需在场景的其他地方重复或复制粘贴这些行，只需在需要的地方使用 `*gosub` 命令即可。例如：

```
*choice
   #Train body.
       *set strength +10
       *set dexterity +10
       *gosub cap_stats
       You train your body.
       *finish
   #Train mind.
       *set intelligence +10
       *set wisdom +10
       *gosub cap_stats
       You sharpen your mind.
       *finish
```

当游戏遇到 `*gosub cap_stats` 行时，它会立即跳转到 `*label cap_stats` 行（如前一示例所示）并执行该处的所有脚本，直到遇到 `*return` 命令。此时，它会立即跳回发起调用的 `*gosub` 行，并从该点继续执行。本质上，在你使用 `*gosub cap_stats` 的地方，ChoiceScript 实际上会执行以下操作：

```
*choice  
    #Train body.  
        *set strength +10  
        *set dexterity +10  
        *if strength > 100  
            *set strength 100  
        *if dexterity > 100  
            *set dexterity 100  
        *if intelligence > 100  
            *set intelligence 100  
        *if wisdom > 100  
            *set wisdom 100  
        You train your body.  
        *finish  
    #Train mind.  
        *set intelligence +10  
        *set wisdom +10  
        *if strength > 100  
            *set strength 100  
        *if dexterity > 100  
            *set dexterity 100  
        *if intelligence > 100  
            *set intelligence 100  
        *if wisdom > 100  
            *set wisdom 100  
        You sharpen your mind.  
        *finish
```

这只是一个简单的示例，用以说明 `*gosub`（运行子程序脚本）与 `*return` 组合是如何工作的。然而，单个子程序的长度或复杂度并无实际限制，这使其成为 ChoiceScript 中最有用的功能之一。

{% hint style="info" %}
如果你发现自己在代码中多次重复某个特定部分，不妨考虑将其转换为子程序，并在实际的故事脚本中仅使用 `*gosub` 来调用——尤其是当你日后可能需要修改该代码的任何部分时。将所有重复内容整合到文件底部的一个子程序中，远比在文件中多处重复编辑要轻松快捷得多。
{% endhint %}

## 高级 `*gosub`｜Advanced `*gosub`

请注意，子程序可以嵌套，这意味着在一个子程序中，你可以 `*gosub` 到另一个子程序，然后再到另一个，依此类推，直到遇到实际的 `*return` 命令。通过这种方式，可以创建相当复杂和精细的程序。然而，一个典型的 ChoiceScript 游戏可能永远不需要这样做。对于大多数游戏来说，使用多个简单的子程序来处理完全不同且毫无关联的目的就足够了。

## 注意｜Note

{% hint style="info" %}
尽管上面的例子已被用来阐释在何种情况下以及如何考虑使用 `*gosub` 子程序，但避免未封顶百分比值问题的最简单方法是使用ChoiceScript 的 "Fairmath" 系统——这在关于\[\[算术运算符]]的文章中有更详细的介绍。
{% endhint %}


---

# 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/gosub.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.
