跳转到内容

Trainz/refs/ACS 文本格式

来自维基教科书,开放世界中的开放书籍
logo
Trainz 训练入门
TOC | 入门趣味 | AM&C | 创作 | 书内参考 ORP 参考:  • 索引 • 容器 • 种类 • 标签 | 附录  • 版本
 词汇表
 HKeys-CM
 HKeys-DVR
 HKeys-SUR
 HKeys-WIN
 鼠标使用
 符号

ACS 文本格式 是一种由 Auran 定义的国际语言支持的文本格式,用于存储 config.txt 文件 和其他通用键值数据。最简单的说,ACS 文本文件是一个用 UTF-8 编码的标准文本文件。

在历史上,ACS 文本文件必须以 Unicode BOM 序列(字节顺序标记)开头,这通常由导出或导入模块在创建资产的过程中初始化。然而,虽然这通常仍然推荐,但自从 2005 年 TRS2006 发布以及放弃将 GMAX 与 Trainz 捆绑在一起的做法以来,这不再是严格要求的。
  • 但许多 BOM 代码行将在许多下载的旧资产的 config.txt 文件中很明显,作为不可见的代码,当资产及其 config.txt 文件打开以编辑时,它占据着文件的首行。

基本文件结构

[编辑 | 编辑源代码]
用程序员的行话
  1. 一个 '键' (或 '关键字')是一个 '特定' 的人类和机器可读的 '标识符' 专门指属于一组此类合法可指定的 标识符唯一或 枚举 性质。这些键是将含义从人类翻译成机器 CPU 时使用的词法标识符。如果该术语不合法,则机器的软件无法解释并赋予拼写(或拼写错误)的术语意义。[注 1] 一个简单的现实是,如果一个术语拼写错误,计算机就无法匹配该值,并且不知道如何处理该结构(行)。这是一个故障或错误,通常会造成处理停止,或者至少生成一个记录术语不匹配的列表。
  2. 一个 '值' — 这些通常是严格定义的类型,从基本的机器依赖数据元素到这些元素组合成更复杂的数据类型。例如,在某些编码方案中,一个字符是一个简单的 8 位字节值,但在 Unicode 中是一个两个字节的序列。字符串是数组中的一系列字符。显然,后者的尺寸是单个字节字符字符串的两倍。
  3. '无序' 列表是数据行,可以重新排列而不会对含义产生负面影响。 — 您将在 Trainz 配置文件中很快看到,标签或容器可以出现在其适当容器中的任何位置,配置文件是其中一个这样的容器,它包含其他容器。数据出现顺序与它被列出和读取的时间无关。
  4. '处理范围' — 意味着在特定情况的瞬时子程序、子例程或处理程序内(即一些预测和处理的上下文',因此是特定的 '过程'
  5. "ACS 文本文件包含一个无序的 键值 对列表。在任何给定的处理范围中,每个键都必须是唯一的。"
  • 通过这种方式,N3V 程序员指的是一些标签名称并非对特定的 种类容器 是唯一的,而是根据上下文在这些上下文中重复使用,并且上下文处理软件 — 处理这种容器及其值的子例程,知道它在做什么,并且它不是该合法上下文中的另一个 L 值 — R 值合法对。新用户应将 标签和容器索引表 和其中的父子关系添加到书签并经常参考。
  • 为了一个具体且常见的例子:今天,标签 'region' 是一个配置文件容器(配置文件)合法值,仅在 种类地图 资产中合法(从约 V2.5 - V2.7,TR06 时代开始),因此它被分组在 KIND 地图中,与其他特定于地图或定义地图所需的标签一起。此外,您将体验到其他配置文件容器,它们也具有 region 作为合法标签名称,但它们的 TBV 将更低。也就是说,如果配置文件/资产更新到更高的 TBV,'region' 将会生成一个错误,而不是警告。
  • 那,旧内容使用一个现在非法的字符串值作为 R 值,例如 'United Kingdom'、'United States' 或 'Australia',几乎在当时的 EVERY KIND OF ASSET — 但在 TR06 之后更高版本的 TBV 中会创建一个错误消息,因为该关键字现在仅在需要指向 种类地区 的地图配置文件容器中合法,该容器定义了诸如基准(中心)纬度、经度、半球、水色、基准高度、默认连接杆以及特定地区和时期的道路车辆列表等内容,所以(哎呀!)2021 年的意大利或俄罗斯汽车不会出现在 1925 年的北美道路上(哎呀!)或冬季、秋季和春季都会因为 “密歇根州地图文件夹” 错误地位于赤道以南的某个地方而无法显示(哎呀!)并且日出和日落反映了该地区,而不是美国北部。哦,我的天哪!

 

技术极客语言...
这里的狡猾短语是直接引用 N3V Wiki 源页面(链接在页面底部),我们希望解释和定义短语能够使极客语言变得易于理解和理解,以便外行人能够内化含义并使含义 '掌握' 并 '可控制'。

关于 '程序员'' 称为上下文无关文法,面向外行读者

  • EBNF 字符串 '::=' 是将右侧的 ('R 值')赋值给左侧的术语(变量键或关键字)的通用赋值运算符 ('L 值')。 (这主要是因为主要语言之间对赋值和等号运算符存在不同的解释。[注 2]

在下面的抽象中, '|' (管道字符) 用于表示 布尔 'OR' 运算符,因此下面定义通用键的分隔符(分隔符)的第一行可以翻译为

'单个空格' 分隔符由 空格制表符 字符在 ASCII 代码中定义。这些可以被聚合(添加到合理长度)作为 EBNF 键 '<whitespace>'. (在 Trainz 中,打开以编辑的资产通常显示为 L 值和 R 值参数之间存在许多多个空格 ('空白填充'),使得 R 值的第一个字符在解压缩的 config.txt 文件中与第 41 列对齐)。

键值对可以用 扩展巴克斯-诺尔范式 (EBNF) (元语法 形成上下文无关文法) 如下定义

  • 观察以下从上到下的链式定义术语或这些行的语法... 整个链式定义是独立的。
<singlespace> ::= ' ' | <TAB> ;
<whitespace> ::= <singlespace> | { <singlespace> } ;
<line-start> ::= { <whitespace> | <EOL> } ;
<key-value-pair> ::= <line-start> <key> <whitespace> <value> <EOL> ;
<acs-text-file> ::= [ <unicode-bom> ] { <key-value-pair> } <line-start> ;
  • (我从 1976 年就开始编程了,即使是我的眼睛也因为阅读和试图理解这些内容而变得模糊不清... 所以我们在这里在维基教科书中为你编写!)
  1. 需要注意的是,<value> 在某些情况下可能会跨越多行。在 Trainz 中,值总是用双引号 (" 字符或成对的花括号字符:'{' 和 '}' 分隔。Trainz 值也可以是未定义的或 NIL。演示这些的资产通常是可选的,一些是较新的标签,较新的软件会为较旧的内容默认使用这些标签,而这些内容在它生成的版本时代没有选项。
  2. 将 '[' ... ']' 翻译成可选。
  3. N3V 的标准声明为 <acs-text-file> ::= [ <unicode-bom> ] { <key-value-pair> } <line-start> ;
    1. 以空行开头,或者(可选地...)以包含 Unicode 字节顺序标记的开头[注 3]
用外行人的术语

Auran/N3V 建立了一个数据结构系统,其中包含键值对,一些值是复杂类型,可以包含其他简单和复杂类型。

这些被称为数据结构,例如结构体联合体数组,在许多语言中,尤其是C语言衍生的计算机语言,在Trainz中通常被统称为“容器”。当您看到一个容器包含另一个容器时,您正在处理一个结构,该结构的一部分是另一个结构类型,例如数组(例如乘客列表产品类型)或转向架(卡车,指定车轮、X、y、z 安装点因素、安装类型等,但所有与其他因素相关的数据,因此“**分组在一起**”,因为它是一起使用的,这也是我们人类对其理解的最佳方式)。

允许的键名字符

[编辑 | 编辑源代码]
本节介绍在 Trainz 中创建键名或标签的过程。普通用户不需要处理这些内容,但内容创建者,特别是脚本编写者可能会使用,并且很有可能会用到它。
  • 尽管如此,这些限制也适用于文件名,因此使用违反此标准的用户名可能会在验证时失败。不过,如果您喜欢错误消息,请随意使用。

一个**键**(**键名**)是一个最多包含 511 字节的 Unicode 字符序列。控制字符 (ASCII 0..31) 和空格字符 (ASCII 32) 不允许。大写 ASCII 字符 (ASCII 64..89) 不允许。左大括号字符 (ASCII 123) 不允许作为键的第一个字符。右大括号字符 (ASCII 125) 不允许。

为了保证未来的兼容性,强烈建议在构建符合此“ACS 文本文件标准”的 config.txt 时,实现限制键使用以下字符集。在解析 ACS 文本文件时,实现必须接受所有有效字符。

  • 'a' .. 'z'
  • '0' .. '9'
  • '-'
  • '/'
  • '_'

注意这些关键省略'\', ':', ';', '`', '~',, '@', '*', '#', '$', '%', '^', '&', '{', '[', ')', ']'

每个值可以包含零个或多个 UTF-8 字符。有几种类型的值可以使用唯一的编码。值类型是根据标签和/或值内容自动识别的,不会将任何类型信息写入文件。

<value> ::= <null-value> | <numeric-value> | <numeric-array-value> | <string-value> | <kuid-value> | <container-value> ;
警告:  除了多行未处理文本块标签(例如描述许可证)之外,任何包含字符串值的标签不得包含尾随空白字符。
这种情况将产生警告和错误消息,例如:

错误:mocrossing 中的 'category-region' 标签没有选择。

警告:'US ' 不是 'category-region' 标签的有效值(这是写入的: "US ",错误消息中添加了单引号)。此标签现在为空,必须选择新值。




空值实际上是一个零长度的值。

<null-value> ::= [ <whitespace> ] ;

数值是整数或小数表示形式。

<number> ::= [ "-" ] <digit> { <digit> } [ "." <digit> { <digit> } ] ;
<numeric-value> ::= <number> [ <whitespace> ] ;

数值数组值

[编辑 | 编辑源代码]

数值数组值是一个由多个数字组成的序列,用逗号隔开。

<array-separator> ::= [ <whitespace> ] "," [ <whitespace> ] ;
<numeric-array-value> ::= <number> <array-separator> { <number> <array-separator> } <number> [ <whitespace> ] ;


字符串值

[编辑 | 编辑源代码]

字符串值是由双引号 (ASCII 34) 包围的零个或多个 UTF-8 字符序列。双引号字符 (ASCII 34) ('"')、冒号 (':')、正斜杠 (ASCII 47) ('/') 和反斜杠字符 (ASCII 92) ('\') 的出现次数有严格的规定。除了作为 Windows OS 路径规范 的一部分,所有字符在字符串值中都是禁止使用的,从技术上讲,此类参数是字符串而不是字符串值,相比之下,字符串值只是简单的术语。

示例: 一些道路交叉口可以通过选择枚举的字符串值数值来自动更换皮肤,该数值索引了相应的纹理库资产。术语{'字符串值数值' 仅仅意味着它是一个作为字符串传递给软件的数字字段,因为确定数据元素类型和大小的软件比直接在引号之间输入数字数据要复杂得多。

简而言之,它简化了值的输入和通信。
 • 另一些则可以使用名称,例如在标志和一般建筑物中,以及大多数较旧的火车站模型中。
 • 相反,一些资产使用字符串值传递值来控制更复杂的事物,例如用于设置已故 Andi06 的无形火车站的数字和文本值的混合,其中数字定义了站台乘客限制、起始编号和车站名称,就像自 TR2004 以来所有交互式车站一样,但同时:站台高度、站台曲线、站台长度(由于是无形的,它必须被与之匹配的样条线或块状物体覆盖)、轨道数量及其指定(在某些情况下),没有人喜欢模拟乘客漂浮在弯曲轨道的铁轨上,或者那些站在铺砌的路上,或者在站台甲板上方盘旋 6-10 英寸。


以下真实世界的片段有几个很好的示例。首先,请注意,实际字符串值用于在 TRAINZ 数据模型中定义变量,这些变量也可以被归类为程序员和程序代码关注的值。它们的作用实际上是将信息传递给该代码,以影响操作,无论是数字模型的外观,还是数字模型的行为(如果资产在某种程度上是可编程的)。

load4

 {
   size                                2
   initial-count                       0
   
   attachment-points
   {
     0                                 "a.gen_goods2"
     1                                 "a.gen_goods9"
   }
   
   allowed-products
   {
     0                                 <kuid:57344:10003>
   }
   
   conflicts-with-queues
   {
     0                                 "load0"
     1                                 "load1"
     2                                 "load2 "
     3                                 "load3"
   }
 }
}


上面的 Load 容器和子容器都是字符串值,并且都不应该遵循字符串处理规则。实际上,上面有一个(以及此资产中相关子容器中的另一个)是错误的,并且无法在 Trainz 中加载,因为它违反了字符串值处理例程的解析规则......您能找到它吗?答案在下面的这个注释[注释 4]中给出。

字符串

[编辑 | 编辑源代码]

字符串不同于字符串值,两者都是不同性质的枚举值,......它们的上下文和预期长度,通过应用于它们的编码(或规则、算法无论什么)在多行上扩展,这些都是字符串。关键是长度、允许和上述字符串值禁止包含/包含换行符和任何类型的终止空白字符。字符串可以跨多行继续,并且可以包含空白(包括换行符或 CR-LF ASCII EOL 序列)和终止空白字符(空格或制表符)在闭合引号之前。分隔符是包含的引号。

<string-value> ::= <double-quote> { <string-character> } <double-quote> [ <whitespace> ] ;

字符串值改进

[编辑 | 编辑源代码]

Trainz 不直接禁止冒号、正斜杠和反斜杠字符,但 Windows 禁止,因此任何包含这三个字符中的任何一个的路径规范都必须引用目录层次结构。[注释 5] 同时,Trainz 不会在文件规范中允许某些字符,而 Windows 则完全可以接受在文件夹或文件名中使用这些字符。(.e.g. '/', '\', '(' and ')' (圆括号) 可以是 用户名 的一部分,当这种情况为真时,它们的文件夹在打开以编辑时永远不会在 OS 文件名中包含这些字符,而是用下划线 '_' 替换。在读取文件时,Trainz 的 CM 也会在文件名包含分号:';' 时出现问题,但容忍它作为输入(源)文件夹名称的一部分,例如:"File kuid2 56063 101000 1;v2-1;Boxcar traincar;40ftBoxcar_LehighValley1000_LARS-aRus"(刚刚从此系统的存档文件夹名称中摘录。[注释 6]

KUID 值是在 kuid 有效格式 中的单个 KUID。

<kuid-value> ::= <KUID> [ <whitespace> ] ;

容器值

[编辑 | 编辑源代码]

容器值在多行上嵌套其他键值对。

<container-value> ::= [ <EOL> ] "{" <EOL> { <key-value-pair> } <line-start> "}" ;

键排序

[编辑 | 编辑源代码]

“ACS 文本格式”在技术上是一种无序的键值对集合,但是所有现有的实现都保留了对简单(读写)操作的顺序。建议未来的实现保持这一约定。

格式违规

[编辑 | 编辑源代码]

在解析期间检测到格式违规的影响是未定义的。遵循此规范的实现不得生成违反此规范任何方面的文件。


华夏公益教科书