打开主菜单

Ballance Wiki β

脚本

Ghomist讨论 | 贡献2020年7月13日 (一) 13:18的版本 Building Block
关于Virtools脚本语言,请见VSL
一张使用 Virtools Script Deobfuscation 进行还原脚本后的Ballance游戏核心文件的截图

脚本Ballance 方面是指游戏文件(可使用 Virtools 查看和修改)中的相关脚本,控制着游戏的加载和运行。

脚本可以被加密使得在 Virtools 中查看时仅显示 [Script Hidden]。查看具体脚本信息需要相应的解密工具,具体参见Virtools Script Deobfuscation。游戏内部nmo文件全部被加密,通过工具手段可以破解游戏内部的信息、运行机制与逻辑等,也可以将其中的BB保存提取,放入自制图中使用,不过若需激活需特殊手段,详见下文。

目前常常利用脚本添加存档点的火苗、柱子的渐变、灯塔上灯的影子等。但因脚本控制着游戏的加载和运行,可实现的功能远不止于此。

目录

运用脚本的实例

第一张使用脚本的自制地图完美思维3之场景版

第一张大量应用脚本的自制地图是镜花水月

运行原理

一般在自制地图文件中的脚本被Ballance加载时不会激活,因此需要特殊手段激活脚本使其运作生效。

目前在不改动游戏文件的情况下唯一可行的方法是机关替换。被替换入关卡内的机关会被游戏激活,同时其脚本也会被激活。在此机关上使用名为Active ScriptActive ObjectBB可以使关卡内任意物件的脚本被激活。

一般替换入脚本内的机关为PH\PS_FourFlames.nmo(出生点盘点火),因为所有关卡都需要一个出生盘点火以保证关卡的正常加载。因此,将其解密后可作为脚本插入地图的通用模板使用。

游戏原本文件中包含了大量vt2.1才可使用的BB,所以此类BB在现有vt版本下无法正常运行。不过Ballance内部保留了vt2.1的加载器,可以运行这类BB。此类BB在高版本vt中表现为橙黄色,导入及复制时会有报错信息: Building Block <XXX> is invalid (no prototype guid) (DLL not here / behavior's guid has changed from the last DLL),其中XXX为BB的名称。

新版的素材包内附有脚本插入模板的vt工程文件,梨栠的制图模板中自带有一个已经解密的出生盘点火。

脚本构造单元

Building Block

指“构造单元”,交流时一般简称“BB”。(下文大量使用此术语遂均采用简写表达)

BB是脚本中最小的执行单位之一,每个BB都有特定的行为,且一般有如下几项逻辑出入口:

  • 行为入口(Behavior In,简BI),每个BB至少有一个行为入口;
  • 行为出口(Behavior Out,简BO);
  • 变量入口(Parameters In,简PI);
  • 变量出口(Parameters Out,简PO);

从BI可激活BB内部的功能,BB使用的外部变量从PI处获取,产生的新变量从PO引出,并存于PO指向的目标地址,BB执行完毕后按条件激活对应的BO,可使之后的BB激活。

每个BB至少有一个BI,有时可以不需要任何BO,PI,PO。

没有目标地址的PO会将变量丢失。变量不一定需要一个目标地址,若产生的变量不必要,可以直接丢弃。

导入BB时若与vt版本不兼容,则会出现如下两种情况:

  1. BB所兼容版本低于vt版本,导入后Debug报错且BB外观显橙黄色。此类BB无法在vt中正常运行,但依旧可以正常用来构造脚本。从Ballance游戏目录下提取出的BB部分只兼容vt2.1,所以写出的脚本无法在vt中运行,却可以在Ballance中运行。
  2. BB所适用版本高于vt版本,无法正常导入,vt报错。例如:在vt3.5中导入vt2obj的脚本。

BB可以由SDK编译得到,这意味着用户可以自定义新BB的行为。不过SDK对应着vt的版本,由于缺少2.1版本的SDK,目前编译的第三方BB无法被Ballance读取使用。

常用Building Blocks

下面列出了常用的Building Blocks,制作脚本或解读脚本可能需要了解其相关信息,包括使用方式、参数需求等。

逻辑类

  • Binary Memory
  • Is In Group
  • Switch On Parameters
  • Group Iterator,以及其他类似Iterator

操作变量类

  • OP

获取对象类

  • Get Current Camera

操作对象类

  • Set Position
  • Translate
  • Set World Matrix
  • Hide
  • Show
  • Active Script(Active Object)
  • Object Copy
  • Object Delete

条件激活类

  • Key Event
  • Send Message(Send Message To Group)
  • Wait Message
  • Box Box Intersection
  • Test

操作Array类

  • Get Cell
  • Set Cell
  • Get Key Row
  • Add Row

物理相关(绝大部分只能通过解密的游戏文件提取)

  • Physicalize,目前已知三类:
    • 路面、钢轨等物理化,调用网格及碰撞表面信息;
    • 纸球物理化,直接调用网格进行物理化;
    • 木球、石球物理化,物理化为球类,可设定半径;
  • SetPhysicsForce
  • Set Physics Globals

除上面列出的BB以外,还需学会使用Parameter Operation(详见下文),以对大部分变量进行的快速操作。其功能类似于OP,不过无需逻辑调用,在变量输出被调用的时候自动执行。目前认为Parameter Operation的执行速度略优于OP(待考证)。

Parameters Operations

指“变量操作”,其功能是对各类变量进行操作,并得到新的变量。

Parameters Operations有两个输入口,一个输出口。右键选择Setting可以调整输入输出的变量类型及操作类型。

输入口可以只使用一个。由于其通过输出口调用的性质,输出口需要连接目标地址。若输出口没有目标地址,则此Parameters Operations无法执行。

由于Parameters Operations不需要行为输入来激活(不同于BB:OP),在其输出口的变量需要被调用时自动执行,因此使得Parameters Operations具有即时性,且可以缩短脚本执行时间(待考证)。

Behavior Graph

指“行为段”,简称BG。

其外部表现类似于BB,必有至少一个BI,可自行添加PI、PO、BI、BO。其内部由一个或一组BB及其他构造单元组成,相当于将一些构造单元打包封装进行执行。BG本身也属于构造单元,这意味着BG可以嵌套。

BG可以有效减少重复的构造单元段落,使脚本更加简洁明了。其名称可以随意改变,使用好的命名可以使得脚本可读性有较大提升。

Comment

即“注解”。

Comment不参与脚本的执行,不过它可以很好地标注脚本,增强可读性。当Comment与其他构造单元叠加时会被置于底层。

右键选择“Add Comment”可添加空白的Comment。

脚本实现框架

此处仅对于脚本常使用的一些框架、模板进行简要介绍。

玩家球操控

非物理状态下操控

球在盘点处生成和换球结束时,游戏会将玩家球物理化,使得其坐标、旋转角等参数无法直接调整,目前的解决方案是在操作玩家球之前先将其反物理化,即可进行设置坐标等操作。

值得注意的是,非物理物件的玩家球不受物理系统的控制,也就是说玩家球的速度会丢失,静止在反物理化时的位置,无法发生任何碰撞,且玩家无法直接控制玩家球运动。所以在进行操作之后,务必将玩家球重新物理化。重新物理化时需判断玩家球的种类,再根据种类读取Balls.nmo内的相应参数,并使用对应球的物理化BB进行物理化。

通过此方法操作玩家球会不可避免地使其丢失当前速度,重新物理化后的玩家球速度为0。

部分可实现实例:

  • 传送门(配合BB:Box Box Intersection可实现);
  • 瞬移、闪现等类似功能。

物理状态下操控

当玩家球依然属于物理物件时,也可对玩家球进行部分操作。例如,可对其施加额外的力。

使用的BB:SetPhysicsForce可从已解密的Gameplay.nmo中提取得到。

若不加控制地持续施加力,会使玩家球脱离玩家掌控,游戏难以正常进行。一般的控制手段分两种:

  • 使用BB:Key Event,以按键控制;
  • 使用BB:Box Box Intersection,以碰撞检测控制;

部分可实现实例:

  • 区域内玩家球反重力、零重力(或以按键控制);
  • 球向上飞行或加速下落;

自定义物理属性

一般对于路面进行此操作。

一般方案是使用BB:Physicalize手动对路面进行物理化而不归入路面组,由此可自行设定其参数。其物理化所需参数信息如下表:

参数变量名 类型 释义
Fixed? bool 是否为固定(不可移动)物理物件,
默认为TRUE(仅对于路面、钢轨及Stopper)
Friction float 摩擦力
Elasticity float 弹力
Mass float 质量(在Fixed?参数为TRUE时无意义)
Collision Group String 碰撞组
Start Frozen bool 是否初始时冻结
Enable Collision bool 是否允许碰撞,默认为TRUE
Automatic Calculate
Mass Center
bool 是否自动计算质量中心
Linear Speed Dampening float 线性阻尼
Rot Speed Dampening float 旋转阻尼
Collision Surface String 碰撞表面,一般为当前网格的名字
concave 1 Mesh 物理化时所使用的网格

此方法配合BB:Group Iterator(组迭代器)可实现按组物理化为路面,归入指定组的物件将会被物理化成相同参数的路面。这样可以节约BB、脚本数量,也可满足制图者归组的习惯。

值得注意的是,手动物理化出的路面虽然无需归入原版路面组,但仍需要归入声音组,选择性归入影子组。

可行的另一方案是使用BB:Set Cell等BB对Array操作,直接更改游戏路面参数。不过这样做具有全局性,将会使所有路面均改变物理参数,一般来说不推荐这么做。

展望

脚本可实现的功能、玩法绝不仅限于Ballance本体,未来有希望在Ballance内实现各种同人作品,开展全新玩法,实现更强更全面的功能,制作更佳的游戏关卡场景等。