# Implicit Control Flow

Implicit control flow is an optional modification to the way ChoiceScript behaves. It changes ChoiceScript's requirements by removing the need for `*finish`, `*goto`, `*goto_scene`, or `*ending` at the end of `*choice`, `*elseif`, and `*else`.\
隐式控制流是对 ChoiceScript 行为方式的一种可选修改。它改变了 ChoiceScript 的要求，移除了在 `*choice`、`*elseif` 和 `*else` 末尾需要使用 `*finish`、`*goto`、`*goto_scene` 或 `*ending` 的必要性。

Devblog update: <https://forum.choiceofgames.com/t/new-choicescript-features-implicit-control-flow-gosub-parameters/30042>\
开发博客更新：<https://forum.choiceofgames.com/t/new-choicescript-features-implicit-control-flow-gosub-parameters/30042>

## Usage

用法

To use implicit control flow, simply add the following to your `*create` variable section in startup.txt:\
要使用隐式控制流，只需在startup.txt文件的`*create`变量部分添加以下内容：

```choicescript
*create implicit_control_flow true
```

(You can also `*set implicit_control_flow true` or `false` in other places in your scene files.)\
（您也可以在场景文件的其他位置`*set implicit_control_flow`为`true`或`false`。）

## Features

特性

Usually, in ChoiceScript, the code below would produce an error:\
通常，在ChoiceScript中，以下代码会产生错误：

```choicescript
*temp player_gender "Male"

Coming inside, your friend greets you.

*if (player_gender = "Female")
    "Hey girl!"
*elseif (player_gender = "Nonbinary")
    "Hey pal!"
*else
    "Hey man!"

Still smilling, your friend continues, "How're you today?"
```

The error produced here would be:\
此处产生的错误为：

> "It is illegal to fall in to an `*else` statement; you must `*goto` or `*finish` before the end of the indented block."

As seen in the previous `*choice`, `*elseif`, and `*else` pages, ChoiceScript requires that all of these commands have either a `*finish`, `*goto`, `*goto_scene`, or `*ending` at the end of the code block; otherwise, the code will throw up an error.\
如先前 `*choice`、`*elseif` 和 `*else` 页面所述，ChoiceScript要求所有这些命令在代码块末尾必须包含 `*finish`、`*goto`、`*goto_scene` 或 `*ending`；否则，代码将抛出错误。

So to correct that, the following changes would be needed:\
因此，要修正这一点，需要进行以下更改：

```choicescript
*temp player_gender "Male"

Coming inside, your friend greets you.

*if (player_gender = "Female")
    "Hey girl!"
    *goto smilling_friend
*elseif (player_gender = "Nonbinary")
    "Hey pal!"
    *goto smilling_friend
*else
    "Hey man!"
    *goto smilling_friend

*label smilling_friend
Still smilling, your friend continues, "How're you today?"
```

As seen here, if you want to simply proceed down the file, the use of several `*gotos` is quite redundant. Games that feature heavy use of `*if`, `*elseif`, and `*else` might end up with dozens or more of these extra `*gotos` and `*labels` just to proceed through simple `*if/*elseif/*else` sequences.\
正如这里所见，如果你只想简单地按顺序执行文件中的代码，使用多个 `*goto` 语句就显得相当冗余。那些大量使用 `*if`、`*elseif` 和 `*else` 语句的游戏，可能最终会为了处理简单的 `*if/*elseif/*else` 序列而添加数十个甚至更多的额外 `*goto` 和 `*label` 语句。

By using implicit control flow, however, the requirement for `*gotos` and `*labels` is removed. Our very first code example would not flag any errors and would proceed down the code without requiring the extra `*gotos` and `*labels`.\
然而，通过使用隐式控制流，就无需 `*goto` 和 `*label` 语句了。我们最初的代码示例将不会标记任何错误，并且可以在不需要额外 `*goto` 和 `*label` 语句的情况下顺序执行代码。

When implicit control flow is enabled, `*choice` works basically the same as `*fake_choice`, except you can also freely nest a `*choice` inside another `*choice` with implicit control flow.\
启用隐式控制流时，`*choice` 的功能基本与 `*fake_choice` 相同，区别在于你还可以在隐式控制流中，自由地将一个 `*choice` 嵌套在另一个 `*choice` 内部。

## Notes

注意事项

Implicit control flow is convenient, but ChoiceScript's original behavior can help find unintended bugs.\
隐式控制流虽然方便，但 ChoiceScript 的原始行为有助于发现意外的程序错误。

```choicescript
*choice
    #Be very naughty.
        Santa refuses to give you a present.
    #Be mostly nice.
        Santa gives you a present reluctantly.
    #Be as nice as can be.
        Santa gives you a present enthusiastically.

Inside the gift box is a video game!
```

In the following example, the `*choice` will behave as a `*fake_choice`; all options will proceed down the code. If choice `#1` is selected, it will mention that Santa refused to give you a present—but because the code continues down, you will still receive the video game.\
在以下示例中，`*choice` 将表现得像 `*fake_choice`；所有选项都会继续执行后续代码。如果选择了选项 `#1`，它会提到圣诞老人拒绝给你礼物——但由于代码继续向下执行，你仍然会收到视频游戏。

Therefore, if the author forgets to include a different branch for choice `#1`, the previous error message could remind them to check their branching.\
因此，如果作者忘记为选项 `#1` 设计不同的分支，之前的错误提示可以提醒他们检查分支逻辑。

Another advantage of implicit control flow is that branches are immediately apparent because of using `*goto`; any `#options` that do not branch will not have a `*goto` following.\
隐式控制流的另一个优势在于，由于使用了 `*goto` 指令，分支结构一目了然；任何未设置分支的 `#options` 都不会跟随 `*goto` 指令。

To use the Santa example, with original CS, you would need:\
以圣诞老人为例，在原始ChoiceScript中，你需要编写：

```choicescript
*choice
    #Be very naughty.
        Santa refuses to give you a present.
        *goto coal
    #Be mostly nice.
        Santa gives you a present reluctantly.
        *goto present
    #Be as nice as can be.
        Santa gives you a present enthusiastically.
        *goto present

*label present
Inside the gift box is a video game!
*finish

*label coal
You get a lump of coal instead.
*finish
```

With implicit control flow, the same passage could read:\
通过隐式控制流，同一段文字可以这样表达：

```choicescript
*choice
    #Be very naughty.
        Santa refuses to give you a present.
        *goto coal
    #Be mostly nice.
        Santa gives you a present reluctantly.
    #Be as nice as can be.
        Santa gives you a present enthusiastically.

Inside the gift box is a video game!
*finish

*label coal
You get a lump of coal instead.
*finish
```

It's immediately visible that `#option A` branches, but `#B` and `#C` fall directly through.\
可以立即看出，`#选项A` 会分支，但 `#B` 和 `#C` 会直接顺序执行。

## Known Bug

已知错误

While implicit control flow seems like a powerful tool, there's a specific scenario where it doesn't function well.\
虽然隐式控制流看起来是一个强大的工具，但在某些特定场景下它并不能很好地发挥作用。

```choicescript
*label haha
*choice
    #varA
        *set varB true
        text
    *if varB
        #varB
            text
            *finish
*goto haha
```

The expected interpretation of that code would be the player is given an only choice `#varA` upon the first visit of "haha". Picking `#varA` would loop the player back to the beginning of "haha," but now they can pick either `#varA` again or the now-revealed `#varB`.\
这段代码的预期解释是，玩家在首次访问"haha"时仅获得选项 `#varA`。选择 `#varA` 会使玩家循环回到"haha"的开头，但此时他们可以再次选择 `#varA`，或选择现已显示的 `#varB`。

However, CS throws an error when the player picks `#varA`: "It is illegal to fall out of a `*choice` statement; you must `*goto` or `*finish` before the end of the indented block." Removing the command `*set varB true`, however, fixes the error, although the player will now be trapped in an infinite limbo of `#varA`. A simple fix would be moving the `*goto hehe` inside the body of `#varA`, though this begs up the question, "why bother using implicit control flow at all?"\
然而，当玩家选择 `#varA` 时，CS 会抛出一个错误："从 `*choice` 语句中跳出是非法的；在缩进块结束前必须使用 `*goto` 或 `*finish`。"不过，移除命令 `*set varB true` 可以修复此错误，尽管玩家现在将陷入 `#varA` 的无限循环困境。一个简单的解决方法是将 `*goto hehe` 移到 `#varA` 的代码块内部，但这引出了一个问题："何必费心使用隐式控制流呢？"

## Comparison

比较

Here is a simple visual comparison with ICF on and off:\
以下是开启与关闭隐式控制流的简单视觉对比：


---

# 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/implicit-control-flow.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.
