SLG - C.N开发文档

1. 项目概述

1.1 项目简介

本项目旨在开发一款以时间回溯为主题的视觉小说游戏,基于Godot 4.4引擎实现。游戏将包含对话系统、背景切换、音频管理、选项分支、好感系统、章节选择和记录查看等核心功能,为玩家提供沉浸式的视觉小说体验。

1.2 核心功能

  • 对话系统:支持角色对话、旁白、内心独白等多种文本展示方式
  • 背景管理:支持背景图片切换,包含淡入淡出等过渡效果
  • 音频系统:支持BGM和SFX的播放与管理
  • 选项系统:支持多层级选项分支,影响剧情走向
  • 好感系统:记录玩家与游戏角色的互动关系
  • 章节回溯:允许玩家选择已解锁的章节回溯剧情
  • 记录查看:允许玩家查看已解锁的CG、音乐和剧情记录

2. 主要架构

2.1 对话系统 (DialogueSystem)

对话系统是游戏的核心组件,负责解析对话文件、构建对话层级结构和管理对话流程。

主要功能

  • 解析文本文件中的对话、选项、配置和跳转指令
  • 构建对话层级结构,处理选项的父子关系
  • 管理当前对话行和对话推进

2.2 主控制器 (Main)

主控制器负责协调各个系统组件,处理用户输入,管理UI显示和场景转换。

主要功能

  • 处理用户输入(鼠标点击、键盘按键)
  • 推进对话流程
  • 处理选项分支
  • 管理背景切换和过渡效果
  • 控制音频播放

2.3 玩家系统 (Player)

玩家系统负责管理玩家属性、技能和游戏进度。

主要功能

  • 存储玩家基本属性(等级、生命、技能等)
  • 管理玩家技能和天赋
  • 记录游戏进度和解锁状态

关键属性

  • 基础属性:生命
  • 技能系统:参照《极乐迪斯科》设计,分为体格、身手、意志、灵感、魅力和信用六大类,每类四个技能

2.4 菜单系统 (Menu)

菜单系统负责管理游戏的主菜单界面,提供设置、回忆录、制作人员和退出等功能入口。

主要功能

  • 提供游戏主菜单界面
  • 管理章节选择和记录查看功能
  • 处理游戏设置和退出

关键方法

  • _on_memoirs_pressed(): 进入回忆录(章节选择)界面
  • _on_quit_pressed(): 退出游戏

3. 功能实现

3.1 对话系统实现

3.1.1 对话文件格式

对话文件采用纯文本的自然语言格式,支持以下语法:

  • 对话角色名: "对话内容"
  • 选项- 选项文本(缩进表示层级关系)
  • 配置[key=value](如背景、音频等)
  • 跳转->target(跳转到指定行或场景)

示例:

主角: "这是一段对话。"
[bg = scene1.png]
- 选择选项1
  主角: "你选择了选项1。"
- 选择选项2
  主角: "你选择了选项2。"
  - 子选项1
    主角: "你选择了子选项1。"
  - 子选项2
    主角: "你选择了子选项2。"
->scene:next_scene.txt

3.1.2 对话解析流程

  1. 加载对话文件并按行解析
  2. 使用正则表达式识别不同类型的行(对话、选项、配置、跳转)
  3. 构建对话层级结构,处理选项的父子关系
  4. 按顺序处理对话行,执行相应的操作

3.2 选项系统实现

3.2.1 选项显示与选择

  1. 遇到选项行时,收集同级选项并显示
  2. 玩家选择选项后,跳转到选项对应的分支
  3. 处理分支内容,直到分支结束
  4. 跳转到分支结束后的下一行继续执行

3.2.2 多层级选项处理

  1. 使用缩进表示选项的层级关系
  2. 构建选项的父子关系,形成树状结构
  3. 使用选项栈管理多层级选项的处理
  4. 处理完子选项后,返回父选项的处理流程

3.3 背景系统实现

3.3.1 背景切换

  1. 解析背景指令,支持多种格式(如[bg = image.png][bg = image.png with fade(0.5,0,0.5)]
  2. 构建背景队列,按顺序处理背景切换
  3. 支持淡入淡出等过渡效果

3.3.2 过渡效果

  1. 支持自定义淡出时长、黑屏停留时长、淡入时长和过渡颜色
  2. 使用Tween实现平滑的过渡动画
  3. 在过渡过程中临时隐藏对话UI,完成后恢复显示

3.4 音频系统实现

  1. 支持BGM和SFX两种音频类型
  2. 使用AudioStreamPlayer播放音频
  3. 通过配置指令控制音频播放(如[bgm=music.ogg][sfx=sound.wav]

3.5 好感度系统实现(待开发)

3.5.1 设计方案

  1. 在Player类中添加好感度相关属性

    var affinity = {
      "角色1": 0,
      "角色2": 0,
      // 更多角色
    }
  2. 在选项处理中添加好感度变更逻辑

    func on_option_selected(option):
      # 现有处理逻辑...
      
      # 好感度变更处理
      if "affinity_change" in option:
        var changes = option.affinity_change
        for character in changes:
          Player.affinity[character] += changes[character]
  3. 在对话文件中添加好感度变更标记

    - 友好回应 [affinity=角色1:+5]
      角色1: "谢谢你的理解。"
    - 冷漠回应 [affinity=角色1:-3]
      角色1: "随你怎么想吧。"

3.6 章节选择实现(待开发)

3.6.1 设计方案

  1. 创建章节数据结构

    var chapters = [
      {
        "id": "chapter1",
        "title": "第一章:开始",
        "scene_path": "res://Assets/atory/c1s1.txt",
        "unlocked": true,
        "completed": false
      },
      // 更多章节
    ]
  2. 实现章节选择界面

    func load_chapter_selection():
      for chapter in chapters:
        if chapter.unlocked:
          var btn = ChapterButton.instantiate()
          btn.text = chapter.title
          btn.disabled = !chapter.unlocked
          btn.pressed.connect(func(): load_chapter(chapter.id))
          chapter_container.add_child(btn)
  3. 章节完成后更新状态

    func complete_chapter(chapter_id):
      for chapter in chapters:
        if chapter.id == chapter_id:
          chapter.completed = true
          # 解锁下一章节
          var next_index = chapters.find(chapter) + 1
          if next_index < chapters.size():
            chapters[next_index].unlocked = true

3.7 记录查看实现(待开发)

3.7.1 设计方案

  1. 创建记录数据结构

    var records = {
      "cg": [],    # CG图片记录
      "music": [], # 音乐记录
      "story": []  # 剧情记录
    }
  2. 实现记录解锁逻辑

    func unlock_record(type, id):
      if id not in records[type]:
        records[type].append(id)
  3. 实现记录查看界面

    func load_record_view(type):
      for record_id in records[type]:
        var item = RecordItem.instantiate()
        item.setup(type, record_id)
        record_container.add_child(item)

4. 存档系统(待开发)

4.1 设计方案

  1. 创建存档数据结构

    var save_data = {
      "player": {  # 玩家数据
        "name": "",
        "attributes": {},
        "skills": []
      },
      "progress": {  # 游戏进度
        "current_scene": "",
        "current_line": 0,
        "chapters": [],
        "records": {}
      },
      "relationships": {  # 角色关系
        "affinity": {}
      },
      "settings": {  # 游戏设置
        "text_speed": 1.0,
        "auto_mode": false,
        "bgm_volume": 1.0,
        "sfx_volume": 1.0
      },
      "timestamp": 0  # 存档时间戳
    }
  2. 实现存档保存功能

    func save_game(slot_id):
      # 收集当前游戏状态
      save_data.player.name = Player.player_name
      save_data.player.attributes = {
        "lv": Player.player_lv,
        "hp": Player.player_hp,
        # 更多属性
      }
      save_data.progress.current_scene = dialogue_system.scene_id
      save_data.progress.current_line = dialogue_system.current_line
      save_data.relationships.affinity = Player.affinity
      save_data.timestamp = Time.get_unix_time_from_system()
      
      # 保存到文件
      var save_path = "user://saves/save_%d.json" % slot_id
      var dir = DirAccess.open("user://saves")
      if not dir:
        DirAccess.make_dir_recursive_absolute("user://saves")
      
      var file = FileAccess.open(save_path, FileAccess.WRITE)
      file.store_string(JSON.stringify(save_data))
      file.close()
  3. 实现存档加载功能

    func load_game(slot_id):
      var save_path = "user://saves/save_%d.json" % slot_id
      if not FileAccess.file_exists(save_path):
        return false
      
      var file = FileAccess.open(save_path, FileAccess.READ)
      var json_string = file.get_as_text()
      file.close()
      
      var json = JSON.parse_string(json_string)
      if not json:
        return false
      
      # 恢复游戏状态
      Player.player_name = json.player.name
      Player.player_lv = json.player.attributes.lv
      Player.player_hp = json.player.attributes.hp
      # 更多属性恢复
      
      Player.affinity = json.relationships.affinity
      
      # 加载场景并跳转到保存的行
      load_scene(json.progress.current_scene)
      dialogue_system.current_line = json.progress.current_line
      
      return true

5. 用户界面

5.1 主界面

  • 背景显示区域
  • 对话框(显示角色名和对话内容)
  • 选项按钮区域
  • 菜单按钮(设置、存档、加载、自动、跳过等)

5.2 菜单界面

  • 设置按钮(打开设置界面)
  • 回忆录按钮(打开章节选择和记录查看界面)
  • 制作人员按钮(显示制作人员信息)
  • 退出按钮(退出游戏)

5.3 章节选择界面

  • 已解锁章节列表
  • 章节缩略图和描述
  • 返回按钮

5.4 记录查看界面

  • 分类标签(CG、音乐、剧情)
  • 记录项列表
  • 详情查看区域
  • 返回按钮

6. 资源管理

6.1 文件结构

/Assets
  /fonts        # 字体文件
  /images       # 背景和CG图片
    /c1s1       # 第一章第一节的图片
    /c1s2       # 第一章第二节的图片
  /sounds
    /bgm        # 背景音乐
    /sfx        # 音效
  /atory        # 对话文件
    c1s1.txt    # 第一章第一节的对话
    c1s2.txt    # 第一章第二节的对话
/Scenes
  /main         # 主游戏场景
  /menu         # 菜单场景
  /AnimatedButton # 动画按钮组件
/Scripts
  /utiles       # 工具脚本
    DialogueSystem.gd  # 对话系统
    Player.gd          # 玩家系统

6.2 资源命名规范

  • 背景图片:场景ID_序号.扩展名(如c1s1_01.png
  • 音频文件:类型_名称.扩展名(如bgm_main.oggsfx_click.wav
  • 对话文件:章节ID.txt(如c1s1.txt

7. 开发计划

7.1 第一阶段:核心系统

  • 对话系统实现
  • 背景管理系统实现
  • 音频系统实现
  • 选项系统实现

7.2 第二阶段:扩展功能

  • 好感度系统实现
  • 存档系统实现
  • 章节选择功能实现
  • 记录查看功能实现

7.3 第三阶段:优化和完善

  • UI美化和动画效果
  • 性能优化
  • 多语言支持
  • 辅助功能(自动模式、跳过已读、文本速度调整等)

8. 注意事项和建议

8.1 性能优化

  • 使用资源预加载减少加载时间
  • 优化图片大小和格式,减少内存占用
  • 使用对象池管理频繁创建和销毁的对象(如选项按钮)

8.2 扩展性考虑

  • 使用配置文件管理游戏参数,便于调整和扩展
  • 设计模块化的系统架构,便于添加新功能
  • 使用信号机制实现系统间的松耦合通信

8.3 用户体验

  • 提供丰富的设置选项(文本速度、音量、自动模式等)
  • 实现存档/读档功能,便于玩家随时保存和恢复游戏进度
  • 添加辅助功能(如文本历史记录、跳过已读文本等)

9. 结语

本文档提供了视觉小说游戏开发的整体框架和实现方案,涵盖了核心系统、功能实现、用户界面和资源管理等方面。开发团队可以根据实际需求和资源情况,调整和扩展本方案,实现一款功能完善、体验良好的视觉小说游戏。

随着项目的推进,本文档将不断更新和完善,以反映最新的开发进展和设计变更。

本文作者:晝行燈

版权声明:本文采用 CC BY-NC 4.0 协议授权

转载需注明作者及原文链接: https://mansifield.pages.dev/p49bxu/