设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 590|回复: 2
打印 上一主题 下一主题

[原创发布] 黑暗圣剑传说RGSS脚本研究

[复制链接]

Lv1.梦旅人

梦石
0
星屑
199
在线时间
15 小时
注册时间
2022-9-1
帖子
7
跳转到指定楼层
1
发表于 2026-3-1 20:27:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
写在前面:本文撰写的版本是黑暗圣剑传说ver1.0 ,根据水友提供的资料早在2005年5月29日,1.0正式版已对外发布。在启动exe后,游戏开始页面显示黑暗圣剑传说Final版
后续可能还有更新,貌似在2006年5月8日发布过新版本,请自行甄别各自的游戏版本,如果看下文发现跟自己的工程对不上,那就说明版本对不上。




本文将按照脚本编辑器左侧列表的顺序依次解释每个脚本,包括概述、核心代码的含义、柳柳自定义的脚本这三大部分,旨在帮助曾经像我一样,不懂代码,自己更没有写过一行代码的编程小白理解这个经典项目。
我在大学2012年左右第一次接触柳柳的这个上古作品,对于里面的脚本与其说一知半解,说是一头雾水更合适。一晃眼,12年的游戏策划生涯过去了,还是没有手搓代码的能力,但是vibe coding经验积累了不少,于是打算花时间认真回看一下这款ruby语言 RGSS脚本的RMXP研发出来的入坑作。
致敬始终坚持走在这条路上初心未改的朋友。



正片开始





[size=16.0000pt]Game_Temp游戏运行时的临时记事本1. 这个类是干嘛的?它的注释写得很清楚:“在没有存档的情况下,处理临时数据的类”。
策划视角的理解:
想象您在玩《黑暗圣剑传说》。
· 您打开菜单,又关掉 —— 这个“菜单打开过”的状态,需要一个地方记一下。
· 您和 NPC 说话,显示了一半文本,按了确定 —— “接下来要显示哪行字”需要一个地方记一下。
· 您踩了一个地雷,进入战斗 —— “敌人的队伍ID是多少”、“能不能逃跑”这些信息,需要一个地方记一下。
这些信息不需要存档(下次读档不需要记住菜单刚才是不是开着),但当下必须记下来,否则游戏逻辑就乱套了。
$game_temp 这个全局变量,就是这本**“临时记事本”**。
2. 关键代码解析[size=14.0000pt]定义和初始化默认值
· 常见默认值
o 开关类:通常是 false(关)。比如 @in_battle = false(默认不在战斗中)。
o 数字类:通常是 0。比如 @battle_troop_id = 0
o 文本类:通常是 nil(空)或 ""(空字符串)。
o 特殊类@choice_start = 99。这个 99 是 RMXP 的一个惯例,表示“选择项还没开始”或者“无效值”。
3. 《黑暗圣剑传说》的特色修改这就是您要逐行阅读的意义所在了。请注意看这两行,这是柳柳(作者)加进去的“私货”
[size=14.0000pt]attr_accessor :mgbuy_calling            调用购买魔法
[size=14.0000pt]attr_accessor :$book1
[size=14.0000pt]attr_accessor :$book2
[size=14.0000pt]attr_accessor :$book3
[size=14.0000pt]解析:
[size=14.0000pt]:mgbuy_calling:
[size=14.0000pt]原版 RMXP 默认只有 shop_calling(调用普通商店)和 name_calling(调用取名画面)。
[size=14.0000pt]这里多了一个“购买魔法”的标志。说明这个游戏里有一个独立的系统,玩家可以在特定地点购买魔法,而不是买道具。
[size=14.0000pt]当脚本检测到 $game_temp.mgbuy_calling = true 时,画面就会跳转到那个特殊的“魔法商店”界面。
[size=14.0000pt]:$book1 等:
[size=14.0000pt]这里的 $ 符号命名有点奇怪(通常属性变量用 @ 开头,如 @book1),但 Ruby 允许这样写,这实际上是在类内部直接定义了全局变量 $book1 的访问器。
[size=14.0000pt]这显然是用来记录游戏里的特定收集进度。比如“大地之书”、“火焰之书”是否已获得。
[size=14.0000pt]把它放在 Game_Temp 里,意味着这些数据可能不需要存档,或者作者是为了方便在全局随时调用。
[size=14.0000pt]4. 总结
[size=14.0000pt]这段代码作为脚本阅读的第一课非常典型。
[size=14.0000pt]
[size=14.0000pt]结构:定义类 -> 定义属性 -> 初始化默认值。
[size=14.0000pt]作用:它是游戏状态流转的中转站。
[size=14.0000pt]
[size=14.0000pt]Game_System[size=14.0000pt] Game_System 就是游戏的“系统管家”**。
它负责掌管那些需要存档保存的全局设置(比如禁止存档、计时器、窗口皮肤),以及所有的音频播放
· Game_Temp:用完即弃的草稿纸(如“当前对话框的内容”)。
· Game_System:随身携带的档案袋(如“主角的名字”、“总共存档了几次”、“当前BGM是什么”)
《黑暗圣剑传说》的特色修改A. 双计时器系统原版 RMXP 默认只有 1 个计时器(显示在屏幕上的倒计时)。
这意味着游戏里可能存在两套倒计时机制。比如:
· 计时器1:显示给玩家看的“限时任务倒计时”。
· 计时器2:隐藏的系统计时器(比如“种下的种子多久成熟”、“Buff还剩多久”)。
B. 复杂的 BGM (背景音乐) 控制系统这是整段代码里最长、也是最“硬核”的部分。作者重写了 bgm_play 方法。
原版逻辑很简单:让你放啥就放啥
但作者加了一个全局开关 $playing_self_BGM
[size=12.0000pt]1.
如果 $playing_self_BGM == true(正在播放自定义音乐)
[size=12.0000pt]2.
· 此时地图想切换BGM? -> 拒绝切换!只把新BGM的名字记在 $map_bgm 里,但音响继续放当前的自定义音乐。
· 目的:防止场景切换(比如走进新地图)打断正在播放的剧情音乐或小游戏音乐。
[size=12.0000pt]3.
如果 $playing_self_BGM == false(正常模式)
[size=12.0000pt]4.
· 正常播放BGM。
策划含义
这说明游戏里有强制覆盖背景音乐的特殊场景。
· 比如:进入一个“回忆杀”剧情,或者玩一个“音乐小游戏”。此时地图BGM必须被屏蔽,不能因为玩家乱跑就变调了。
C. 音量调整 (细节)注意看 se_play 方法:
Audio.se_play("Audio/SE/" + se.name, se.volume * 0.72, se.pitch)
作者把音量乘以了 0.72
策划含义
这通常是为了混音平衡。可能原版的音效太吵,容易盖过BGM,作者统一把所有音效音量压低了 28%,让听感更舒适。这就是脚本修改带来的精细化控制。
D.被注释掉的双手武器#attr_accessor :two_handed_weapons      被注释掉的双手武器效果
调试用放在 Game_System 是“可以工作”的合理方案,但并非“设计最优”的方案。 它是特定开发阶段(追求快速实现)和特定框架限制(RMXP脚本结构)下的产物
    合理的架构思维:每个类应有一个清晰的职责。Game_System 应该专注于运行时状态管理(如音乐、计时器、系统开关),而静态的游戏规则数据应尽可能与具体的数据对象(如武器、角色)关联。
    那么柳柳为什么为何把它放在 Game_System?
    1. 它是“系统级规则”的全局开关
    Game_System 类的核心职责是处理系统附属数据和全局设置

    双手武器的判定规则,在某种程度上确实属于“游戏规则”层面的系统设置,类似“禁止存档”、“禁止遇敌”等标志。

    合理性:它希望定义一个全局生效的规则,任何场景、任何角色装备武器时,都可以查询 $game_system.two_handed_weapons 来判断。
    问题:这种设计将“游戏规则数据”与“系统状态数据”混在了一起。Game_System 变成了既管理BGM、计时器,又管理游戏机制规则的“大杂烩”类,违反了面向对象设计中的单一职责原则。
    2. 历史与开发成本的考量
    RMXP的脚本架构是预设的,对于初学者或独立制作人来说,修改引擎核心数据类(如 RPG::Weapon)的门槛和风险都较高。

    快速实现:在 Game_System 中添加一个数组,可以最快速地实现功能。开发初期,制作人可能更关注“让游戏跑起来”。
    后续调整:随着项目复杂,发现这种设计难以维护(例如,要修改双手武器判定逻辑,需要到处查找调用),于是将其注释掉,这本身就是一次重构的尝试。

Lv1.梦旅人

梦石
0
星屑
199
在线时间
15 小时
注册时间
2022-9-1
帖子
7
2
 楼主| 发表于 2026-3-3 13:44:01 | 只看该作者
Game_Switches

Game_Switches 这个类,专门用来管理 RPG Maker 里的开关(Switches)。 是最底层的基础设施,通常比较稳定,没必要就不动。
这段代码是原版 RMXP 的标准代码,柳柳在这里没有进行明显的修改。
但是,有一个细节值得策划们注意,这体现了 RMXP 引擎本身的限制:
硬编码的上限 5000:
代码里两次出现了 if switch_id <= 5000。
这意味着这个游戏的开关数量上限被锁死在 5000 个。


Game_Variables
Game_Variables 类与之前的 Game_Switches 结构高度相似,本质上是对底层 数组 的一层封装。
从架构设计的角度来看,它实现了以下机制:

数据容器封装:
它将 Ruby 原生的数组 @data 封装为一个具备游戏逻辑含义的“变量池”。通过重写 [](读取)和 []=(写入)方法,接管了所有对游戏变量的存取操作。这是典型的门面模式,为底层数据结构提供了统一的访问接口。
惰性初始化与默认值策略:
这是策划需要特别关注的设计点。
在 def [](variable_id) 方法中:
    if variable_id <= 5000 and @data[variable_id] != nil
      return @data[variable_id]
    else
      return 0  # 关键逻辑
    end
   
引擎预设了一个规则:任何未被赋值的变量,其初始值默认为 0。
这意味着脚本无需在游戏启动时为几千个变量一一赋初值(这会消耗大量内存),而是采用“用到时再判断”的策略。当策划在事件中引用一个从未设置过的变量时,系统不会报错,而是安全地返回 0。这大大降低了逻辑配置的容错成本。

硬边界约束:
if variable_id <= 5000 设定了数据边界。引擎将变量的寻址空间限制在 0-5000 之间,防止越界访问导致的内存溢出或程序崩溃。这是一个基于性能权衡的配额管理机制。

本段代码完全沿用 RMXP 引擎默认脚本,柳柳无任何自定义修改。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
199
在线时间
15 小时
注册时间
2022-9-1
帖子
7
3
 楼主| 发表于 2026-3-3 16:52:13 | 只看该作者
Game_SelfSwitches

Game_SelfSwitches 类负责管理游戏中的独立开关,是 RMXP 事件编辑器的基础功能,用于控制如“宝箱已开”、“NPC对话过一次”等局部状态。
由于其功能单一、逻辑封闭,且与地图事件系统(Game_Map、Game_Event)耦合紧密,通常不需要在底层进行扩展。柳柳在此处未做修改,说明游戏内的局部事件触发逻辑均使用了标准功能,没有引入特殊的独立开关判定机制。

Game_Screen
Game_Screen 类是游戏视觉表现的状态机。它本身不负责“画”出图像,而是负责计算和管理所有画面特效的当前状态。
本段代码完全沿用 RMXP 默认脚本,无任何功能性修改。涉及到底层渲染逻辑,属于引擎的“地基”。除非要重写整个战斗系统或引入全新的渲染管线,否则修改此处风险极高且收益不大。
柳柳未对此处进行修改,说明游戏中的天气、色调、震动等表现手段均使用了引擎原生功能,未引入特殊的视觉需求。
我们可以更深入的从系统架构来看,这段代码的的职责。
特效状态管理:
它并不直接调用显卡绘图,而是维护了一组描述画面状态的“参数值”。例如,色调、闪烁颜色、震动偏移量。它将这些数值实时计算好,供底层的 Sprite 类读取并渲染。
时间插值机制:
请关注 update 方法中的这段代码:
    @tone.red = (@tone.red * (d - 1) + @tone_target.red) / d
这是经典的线性插值算法。
当策划在事件指令里设置“渐变色调 2 秒”时,系统不会瞬间变色,而是利用这个公式,在每一帧计算当前应有的颜色值,从而实现平滑的过渡效果。无论是天气变化、色调渐变还是画面闪烁,都依赖于此。

图片资源池的双轨制管理:
这是最值得注意的设计细节。       if $game_temp.in_battle
      for i in 51..100
        @pictures.update
      end
    else
      for i in 1..50
        @pictures.update
      end
    end
    系统硬编码将 100 个图片槽位划分为两个区域:
* 1-50 号图片:专用于地图场景。进入战斗后会自动停止更新,处于“冻结”状态。
* 51-100 号图片:专用于战斗场景。平时不更新,战斗开始后激活。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2026-6-4 09:27

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表