Skip to content

选择和分支

玩家选择 (?)

让玩家做出选择,影响故事走向。

基本语法

? 问题描述
- [选项文本] -> 目标场景
- [选项文本] -> .标签

除了单行选项外,NovaMark 现在也支持块级选项,用于“先更新状态,再跳转”的场景。

? 1. 感到不安、担心或烦躁
- [从未]
  @set score = score + 0
  -> .q2
- [有时]
  @set score = score + 1
  @flag answered_q1
  -> .q2

示例

? 你要做什么?
- [检查周围] -> .look_around
- [大声呼救] -> .call_for_help
- [原地等待] -> .wait_here

.look_around
> 你环顾四周...
-> next_scene

.call_for_help
> 没有人回应...
-> next_scene

.wait_here
> 你决定等待...
-> next_scene

带条件的选择

某些选项可以根据条件显示或禁用:

? 你要如何行动?
- [继续前进] -> .continue
- [使用钥匙] -> .use_key
- [使用魔法石] -> .use_stone if has_item("magic_stone")

条件语法-> 目标 if 条件表达式

块级选项也支持条件头:

? 你要如何行动?
- [使用钥匙] if has_item("key")
  @flag used_key
  -> .open_door
- [离开]
  -> .leave

块级选项

当你希望“玩家选中某个选项后,先执行少量白名单动作,再跳转”时,可以使用块级选项。

? 压力测试
- [从未]
  @set score = score + 0
  -> .q2
- [持续]
  @set score = score + 3
  @flag high_stress
  -> .q2

执行顺序是固定的:

  1. 玩家选中选项
  2. 按顺序执行块中的动作
  3. 执行最后的 -> 目标

块级选项限制

第一版块级选项有以下约束:

  • 选项块的最后一条(结尾语句)必须是以下两者之一:
    • -> target(跳转到标签或场景)
    • @call scene(调用子场景)
  • 结尾语句之前,只允许以下四组前置命令(Prelude 白名单):
    • @set
    • @flag
    • @give
    • @take
  • @return 在块级选项体内不被允许
  • @call 之后不允许再写其他语句
  • 不能在块级选项中使用 @bg@check、嵌套选择等其他语句
  • 单行选项和块级选项不能混写

合法示例

-> target 结尾:

- [使用药水]
  @give potion 1
  -> .next

@call scene 结尾:

- [逛逛商店]
  @set visited_shop = true
  @call shop_scene

非法示例

- [有时]
  @set score = score + 1

上面非法,因为缺少结尾语句。

- [有时] -> .q2
  @set score = score + 1

上面也非法,因为单行选项后不能再接缩进块。

- [先调用再继续]
  @call shop_scene
  @set shop_visited = true

@call 之后不能再跟其他语句。

选择选项详解

部分说明
-选项开始标记
[文本]显示给玩家的选项文本
-> 目标选择后跳转的目标
if 条件可选的条件判断,写在目标之后
缩进块可选的块级动作体,允许先执行 @set/@flag/@give/@take 再跳转

条件检定 (@check)

基于条件执行不同分支。

基本语法

@check 条件表达式
@success
  // 条件为真时执行
@fail
  // 条件为假时执行
@endcheck

示例

@check hp >= 50
@success
  林晓: 我还能坚持!
@fail
  林晓: 我需要休息...
  @set hp = 50
@endcheck

骰子检定

@check roll("2d6") >= 8
@success
  > 你成功通过了检定!
  @set courage = courage + 5
@fail
  > 检定失败...
  @set hp = hp - 10
@endcheck

物品检查

@check has_item("key")
@success
  > 你用钥匙打开了门。
  @take key 1
  -> .inside
@fail
  > 门锁着,你没有钥匙。
@endcheck

标记检查

@check has_flag("met_spirit")
@success
  神秘精灵: 我们又见面了,年轻的旅人。
@fail
  > 这片森林似乎隐藏着什么秘密...
@endcheck

分支语句 (if/endif)

基于条件执行代码块。

基本语法

if 条件表达式
  // 条件为真时执行
endif

if 条件表达式
  // 条件为真时执行
else
  // 条件为假时执行
endif

示例

if has_item("treasure_map")
  > 你拿出地图查看位置。
else
  > 你没有地图,只能凭感觉走。
endif

if gold >= 100
  @set gold = gold - 100
  @give legendary_sword 1
  > 你买下了传奇之剑!
endif

条件表达式

比较运算符

运算符说明示例
==等于hp == 100
!=不等于hp != 0
>大于gold > 50
>=大于等于hp >= 50
<小于hp < 20
<=小于等于gold <= 10

逻辑运算符

运算符说明示例
andhas_item("key") and hp > 0
orhas_flag("saved") or gold >= 100
notnot has_flag("boss_defeated")

算术运算

可以在条件中使用算术表达式:

@check str + roll("1d20") >= 15
@success
  > 你成功说服了守卫!
@fail
  > 守卫不为所动...
@endcheck

支持的运算:+, -, *, /, %

完整示例

#scene_combat "战斗"

@check hp > 0
@success
  ? 敌人逼近,你要:
  - [攻击] -> .attack
  - [防御] -> .defend
  - [使用药水] if has_item("healing_potion") -> .use_potion
  - [逃跑] -> .flee
  
  .attack
  @check roll("1d20") >= 10
  @success
    > 你的攻击命中了!
    @set enemy_hp = enemy_hp - 15
  @fail
    > 你miss了!
    @set hp = hp - 10
  @endcheck
  -> .check_result
  
  .defend
  > 你举起盾牌防御。
  @set defense_bonus = 5
  -> .enemy_turn
  
  .use_potion
  @take healing_potion 1
  @set hp = hp + 50
  > 你恢复了 50 点生命值!
  -> .enemy_turn
  
  .flee
  @check roll("1d20") >= 12
  @success
    > 你成功逃跑了!
    -> scene_escape
  @fail
    > 逃跑失败!
    @set hp = hp - 20
  @endcheck
  -> .check_result
  
  .check_result
  @check enemy_hp <= 0
  @success
    @flag defeated_enemy
    > 你击败了敌人!
    -> scene_victory
  @fail
    @check hp > 0
    @success
      -> .enemy_turn
    @fail
      > 你被打败了...
      @ending game_over
    @endcheck
  @endcheck
  
@fail
  > 你已经倒下了...
  @ending game_over
@endcheck
Last updated on