跳转到内容

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

 

技术极客语言...
这里的棘手短语是 N3V 维基源页面(链接在页面底部的下方)的直接引述;我们希望解释和定义短语能使极客语言变得易于理解和理解,以便外行人能够内化含义并使含义变得“熟练”和“可控”。

关于所谓的上下文无关语法,针对外行读者

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

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

'单个空格' 定界符由 空格制表符 字符在 ASCII 代码中定义。这些可以聚合(添加到合理的长度)作为 EBNF 键 '<whitespace>'。(在 Trainz 中,打开以进行编辑的资产通常会显示 L-value 和 R-value 参数之间有许多多个空格('空白填充'),因此 R-value 的第一个字符在解压缩的 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 字节顺序标记的行开头[note 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> ;
警告:  除了多行未处理文本块标签,例如descriptionlicense,任何带值的字符串值不得包含尾随空格字符。
这将产生警告和错误信息,例如

错误:在“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> ] ;


字符串值

[编辑 | 编辑源代码]

字符串值是零个或多个 UTF-8 字符的序列,用引号(ASCII 34)括起来。双引号(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"
   }
 }
}


上面的加载容器和子容器都是字符串值,而且都不应该遵循字符串处理规则。事实上,上面有一个(以及该资产中相关子容器中的另一个)是错误的,而且不会在 Trainz 中加载,因为它破坏了字符串值处理例程的解析规则……你能发现它吗?答案在下面的注意中给出[注意 4]

字符串

[编辑 | 编辑源代码]

字符串不同于字符串值——两者都是本质不同的枚举值……它们的上下文和预期长度——通过应用于它们的编码(或规则、算法等等),这些编码可以扩展到多行,这些都是字符串。关键在于长度、允许和禁止上面提到的字符串值包含/包含换行符和任何类型的终止空格字符。字符串可以跨越多行,并且可以包含空格(包括换行符或 CR-LF ASCII EOL 序列)和终止空格字符(空格或制表符)在结束引号之前。分隔符是包含的引号。

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

字符串值细化

[编辑 | 编辑源代码]

Trainz 不会直接禁止冒号、正斜杠和反斜杠字符,但 Windows 会禁止,因此任何包含这三个字符的路径规范都必须引用一个目录层次结构。[注意 5] 同时,Trainz 不允许在文件规范中使用某些字符,而 Windows 则可以很乐意地在文件夹或文件名中使用这些字符。(例如, '/', '\', '(' 和 ')'(括号) 可以是用户名的一部分,当这种情况发生时,它们的文件夹在打开编辑时永远不会在 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 文本格式”从技术上讲是无序的键值对,但是所有现有的实现都为简单的(读写)操作保留了顺序。建议未来的实现保持这种约定。

格式违规

[编辑 | 编辑源代码]

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


华夏公益教科书