今日速览

  • 无障碍不是”慈善”,是转化率:Steam 商店页的标签体系里已经有「无障碍」这一类(Adjustable Text Size、Color Alternatives、Custom Volume Controls 等),玩家会拿它筛游戏;你勾得上,就多一批人点进来。
  • 性价比最高的是 Basic 级:Game Accessibility Guidelines 把建议分成 Basic / Intermediate / Advanced,Basic 全是”容易实现、覆盖面广”的——调游戏速度、可重绑按键、界面可缩放、别只靠颜色传达信息、别闪烁。
  • 一个人一天能做完的四件事:颜色冗余、字号缩放、字幕开关与背景板、震动/闪烁滑块。不需要重构,全是加法。
  • 验收方法比实现更便宜:把截图转灰度看一眼、用色盲模拟器过一遍、在 Steam Deck 的 7 寸屏上读一遍字幕——三个动作就能找出 80% 的问题。
  • 今天的关键认知:可访问性选项要统一走一个”设置总线”,否则每加一个开关就多一处 if,最后没人敢动。

核心学习内容

一、先分级,别一次做完

Game Accessibility Guidelines 的思路很值得抄:Basic 先做、Intermediate 排期、Advanced 明确写”不做”。对单人/小团队,把 Basic 做完就已经超过大多数独立游戏了。挑四个最划算的:

  1. 信息不只用颜色表达——血条红了要掉血、敌人红了要打你,但色盲玩家(约 8% 男性)分不清红绿。解决方案是冗余:颜色 + 形状 + 图标 + 文字,任意一路断了都还读得懂。
  2. 界面可缩放——字号、按钮大小、HUD 密度给玩家一个滑块。
  3. 字幕可配——大小、背景不透明度、是否显示说话人、是否只显示音效提示。
  4. 动效可减弱——屏幕震动、镜头摇晃、闪烁、快速位移都给强度滑块(甚至 0)。

二、Godot 4 的两个技术支点

支点 1:一个 Accessibility 单例 + 一份配置。 所有开关读同一个地方,改完发信号,谁关心谁连。这样你的 Camera2D 震屏、RichTextLabel 字幕、Theme 字号全都是被动响应,不用互相知道对方存在。

# accessibility.gd  (Autoload 名为 Accessibility)
extends Node

signal changed

const PATH := "user://accessibility.cfg"

var text_scale: float = 1.0      # 0.8 ~ 1.6
var subtitle_on: bool = true
var subtitle_bg: float = 0.6     # 0.0 ~ 1.0
var shake_scale: float = 1.0     # 0.0 ~ 1.0
var flash_scale: float = 1.0     # 0.0 ~ 1.0

func load_cfg() -> void:
	var c := ConfigFile.new()
	if c.load(PATH) == OK:
		text_scale = c.get_value("a11y", "text_scale", 1.0)
		subtitle_on = c.get_value("a11y", "subtitle_on", true)
		subtitle_bg = c.get_value("a11y", "subtitle_bg", 0.6)
		shake_scale = c.get_value("a11y", "shake_scale", 1.0)
		flash_scale = c.get_value("a11y", "flash_scale", 1.0)
	apply()

func save_cfg() -> void:
	var c := ConfigFile.new()
	c.set_value("a11y", "text_scale", text_scale)
	c.set_value("a11y", "subtitle_on", subtitle_on)
	c.set_value("a11y", "subtitle_bg", subtitle_bg)
	c.set_value("a11y", "shake_scale", shake_scale)
	c.set_value("a11y", "flash_scale", flash_scale)
	c.save(PATH)

func apply() -> void:
	# 全局字号缩放:一行搞定,所有 Control 跟着变
	get_tree().root.content_scale_factor = text_scale
	changed.emit()

content_scale_factor 是这里最爽的一行——它缩放整个 2D 内容,包括 UI 字体,不用去改每个 Theme 的 default_font_size。缺点是画面也会跟着缩(相当于整体放大),所以更适合”UI 单独调”的场景时,改用 Theme.default_font_size + theme_type_variation 做一套 LargeText 变体。

支点 2:震屏要乘系数,而不是写死。 你的 trauma 系统里加一行 trauma * Accessibility.shake_scale,玩家把滑块拉到 0,世界立刻安静。闪白同理:modulate 的闪烁乘 flash_scale。这不是”额外功能”,是把你本来就有的效果变成可调的。

字幕建议单独一个 CanvasLayer,RichTextLabel 开 bbcode_enabled,背景用一个 ColorRect 或 PanelContainer,透明度绑 subtitle_bg。说话人名字单独一行、颜色不要当唯一标识(配一个「【NPC】」前缀)。

三、验收:三个五分钟的动作

  • 灰度测试:截图丢进任意图像工具去饱和,如果血条/敌人/可交互物在灰度下分不出来,就是不合格。
  • 色盲模拟:用浏览器插件或在线模拟器看一遍(红绿色盲、蓝黄色盲两档即可)。
  • 小屏 + 远距离:把窗口缩到 1280×720 当成 Steam Deck 看,或者退后两米看显示器——字幕字号低于 28px 基本就废了。

🎯 DeepSeek 提示词

提示词 1:让我先知道自己缺什么(无障碍审计)

你是一名做过主机游戏无障碍适配的 UX 顾问,熟悉 Game Accessibility Guidelines 的分级体系(Basic / Intermediate / Advanced)。

【我的游戏】2D 横版动作游戏,Godot 4 开发,单人团队,预计 3 个月后上架 Steam。核心循环:跑图 → 战斗 → 打 Boss。
【现有系统】无字号设置;按键可重绑;有屏幕震动和受击闪白;无字幕;敌人与可交互物用颜色区分(红=敌人,绿=可交互);无难度选项。

请输出:
1. 按 Basic / Intermediate / Advanced 三级,列出我当前缺失的无障碍项,每项标注「影响哪些玩家」和「预计改动量(小时)」;
2. 从 Basic 里挑出「改动量 ≤ 4 小时、收益最大」的 5 项,给出具体改法(Godot 4 节点/API 级别);
3. 明确告诉我哪 3 项建议直接放弃,并说明理由(不要为了清单好看硬做)。

约束:不要给通用鸡汤;每条建议必须能落到具体节点或具体数值;总字数控制在 800 字内。

提示词 2:生成可持久化的无障碍设置总线

你是 Godot 4 资深开发者。请为我写一个无障碍设置单例(Autoload,名称 Accessibility),要求:

【状态】text_scale(0.8~1.6)、subtitle_on(bool)、subtitle_bg(0~1)、shake_scale(0~1)、flash_scale(0~1)。
【持久化】用 ConfigFile 存到 user://accessibility.cfg;启动时 load,修改时 save;缺字段用默认值,不要报错。
【广播】任何字段变更后 emit 一个 changed 信号,并提供 set_xxx 方法(禁止外部直接改字段)。
【应用】apply() 中根据 text_scale 调整 UI 字号;如果我用 Theme,请同时给「LargeText 变体」的做法。
【约束】GDScript 2.0 语法;用类型标注;不要用 @onready 取 Autoload 自身;注释用中文,只解释「为什么」不解释「是什么」。

输出:一个完整可粘贴的 accessibility.gd,外加一段 5 行的「设置菜单如何绑定这三个 Slider/CheckBox」的接线说明。

提示词 3:把「只靠颜色」的方案改成冗余编码

你是无障碍设计顾问,同时懂色彩对比度计算(WCAG)。

【我的调色板】背景 #1B1B1F;敌人 #E23B3B;可交互物 #3BE28A;危险区 #F2C230;玩家 #4A9DFF。
【问题】玩家反馈红绿色盲分不清敌人和可交互物;灰度下危险区和背景几乎一样。

请输出:
1. 一张表:每个元素 → 建议新色(hex)→ 与背景的对比度数值 → 在红绿色盲/蓝黄色盲模拟下是否仍可区分;
2. 为每个元素补一个「不依赖颜色」的冗余编码(形状/轮廓/图标/动效/贴图纹理),说明在 Godot 4 里怎么实现(如 shader 描边、Sprite2D 叠加图标、AnimationPlayer 呼吸动画);
3. 给一条「三秒自检」规则,让美术出图时能立刻判断有没有踩坑。

约束:不要牺牲整体美术风格;新色必须仍落在我的暗色调体系里;如果某元素无法用颜色解决,直接说「改用形状」,不要硬调色。

学习心得

可访问性最容易被我这种人忽略,因为它不产生”新功能”,只降低”看不见的流失”。但换个角度:它其实是给游戏加了一层”容错”——玩家手抖、屏幕小、环境吵、眼睛累,全都是暂时的”障碍”,而这些设置对所有人都有用。我的目标是用 DeepSeek 从零做一款能上架的 Steam 游戏,那么”上架”就不只是打包上传,还包括让商店页上的无障碍标签勾得出来、让评测里少一句”字太小看不清”。今天这四件事(颜色冗余、字号、字幕、动效滑块)加起来大概一天工作量,却能把可玩人群扩大一截,是当前阶段最高性价比的投入。而且这些开关天然适合交给 DeepSeek 生成——它们套路固定、边界清晰,正是 AI 最擅长的”模板型代码”。

明日关注

  • 把 content_scale_factor 与 Theme LargeText 变体各做一版,在 720p 窗口下对比哪个更适合我的 HUD。
  • 搭一个最小字幕系统:CanvasLayer + RichTextLabel + 背景板透明度绑定,先用假台词跑通。
  • 给现有震屏/闪白加上 Accessibility.shake_scale / flash_scale 系数,并把开关塞进设置菜单。

本文由自动化学习流水线每日生成,坚持即学即记。