本帖最后由 SQwatermark 于 2021-1-27 16:41 编辑

请看 https://www.mcbbs.net/thread-1079039-1-1.html
简介
Introduction
要了解如何修改 Minecraft 字体,有必要先了解一下相关的文件,打开原版资源包的 assets\minecraft\textures\font 文件夹,里面有 224 张 png 图片。分别为 "ascii.png","asscii_sga.png" 和 "unicode_page_xx.png"(xx从00到ff,但并不完全),在1.13以上的版本中,还要多两张图片,"accented.png" 和 "nonlatin_european.png"。

  • ascii.png 用于存储 ASCII 编码字符
  • ascii_sga.png 用于存储标准银河字母(Standard Galactic Alphabet,SGA),也就是附魔台周围浮现出的文字(修改这些字体不会在附魔台以外的任何地方造成不良后果)
  • unicode_page_xx.png 用于存储 Unicode 编码字符,其中也包括了 ASCII 编码的所有字符,但是字体并不相同,ascii.png 中的字体是 Minecraft 开发团队制作的,看起来更像素一些。而 unicode_page_xx.png 中的字体为 GNU Unifont,由 Roman Czyborra 制作,涵盖了基本多文种平面中的所有字符。ASCII 字符默认优先于 Unicode 字符显示,但是当在语言设置界面选择 强制使用Unicode字体 时,只会使用 unicode_page_xx.png 中的字符。
  • accented.png 用于存储注音文字
  • nonlatin_europea.png 用于存储非拉丁语欧洲文字


此外,在assets\minecraft\font 文件夹下还有名为 "glyph_sizes.bin" 的十六进制文件,用于存储字符的宽度
Minecraft 渲染 Unicode 文字的思路是把0x00000000到0xFFFFFFFF的每个文字都做成材质贴图,按照高 16 位进行分割,形成assets/minectaft/textures/font/unicode_page_ff.png这样的图片,每个文字都是方格的;

为了解决文字宽度不同的问题,设置了一个文件(assets/minecraft/font/glyph_sizes.bin)来保存对应图像的水平坐标区间,采用一个字节来保存(高 4 位保存 xMin ,低 4 位保存 xMax ,当然精度方面也就只有 4 位了,但是考虑到 mc 的马赛克性质,确实足够用了),这些字节直接按照 Unicode 值作为文件中位置。

基本多文种平面(Basic Multilingual Plane)
这张表格与 unicode_page_xx.png 形成对应关系,但是 Minecraft 并未使用其全部内容(不包含08、D8-F8)
教程
Guide
我写字超丑的,所以这里只介绍如何将现成的字体加入资源包,而不会教怎么自己制作字体(教程百度就有)。

注意:
  • 从 1.6 开始,Minecraft 支持高清字体,所以可以放心把分辨率调高(游戏时可能会卡)
  • 字体可以是彩色的,但是会让样式代码生成的彩色文本变得奇怪

1.13 之前
使用MINECRAFT字体生成器,贴内有使用教程,用起来还蛮方便的,就是容易卡死。

1.13 之后
1.13 版本对字体进行了改进:
1.13-pre6:Improved fonts(改进了字体)
1.13-pre7:Fixed outstanding issues with the new improved fonts(修复了新优化的字体造成的较突出的问题)

这两段话几乎没说啥,但实际上这次改动极大地方便了玩家自定义字体。
我这里使用 1.15.2 版本进行演示如何添加一个 tff 字体:

  • 打开原版的 assets\minecraft\font 文件夹,里面比1.12 版本多了两个文件:default.json 和 alt.json ,前者用于控制普通文字的字体,后者用于控制附魔台文字的字体。(本帖第三部分详解了这两个文件
  • 将 tff 字体放到资源包的 assets\minecraft\font 路径下,注意文件名不能含有 [a-z0-9/._-] 以外的字符,也就是说不能含有大写字母(这一点对于资源包的所有文件都适用,大概?),我从网上下载了一款丁永康硬笔楷书用于演示,并命名为 name_of_the_font.ttf
  • 在资源包的 assets\minecraft\font 路径下新建 default.json,填写以下内容:
  1. {
  2.     "providers": [
  3.         {
  4.             "type": "ttf",
  5.             "file": "minecraft:name_of_the_font.ttf",
  6.             "shift": [0, 0],
  7.             "size": 11.0,
  8.             "oversample": 2.0
  9.         }
  10.     ]
  11. }
复制代码
此处的 "shift","size" 和 "oversample" 都使用了默认值

  4. 进入游戏查看,发现字体位置偏上,且过于模糊:

  5. 调整 default.json 中设定的值:
  1. {
  2.     "providers": [
  3.         {
  4.             "type": "ttf",
  5.             "file": "minecraft:name_of_the_font.ttf",
  6.             "shift": [0, 1],    //向下移动1像素
  7.             "size": 11.0,
  8.             "oversample": 4.0   //提高了采样
  9.         }
  10.     ]
  11. }
复制代码
  6. 重新进入游戏观察,OK(但是这个字体本身不适合 mc,这里只是示例就不讲究这么多了)

如何对单个字进行调整
如果你觉得某个字写的不好看,想要自己修改,但苦于在浩如烟海的文字中寻找,可以使用这里介绍的方法快速锁定字符的位置:

  • 随便在网上搜一个 Unicode 编码转换工具,将想要修改的文字转换为 Unicode 编码,例如汉字 "囧" 的 Unicode 码是 \u56e7
  • 忽略 "\u",根据 "56" 找到 unicode_page_56.png,根据 "e7" 找到第15行第8个字符(e和7分别为十六进制第15和第8个数字),就是汉字 "囧" 了

在 1.13 以上的版本,可以直接用 default.json 文件指定字符对应的图片,详见这篇文章
p.s. 可以用这种方法将一些文字替换成形象的图画(但是不希望用这种方法说抽象话)

OptiFine 相关
OptiFine 目前并未在字体方面给出较大改进,不支持 Unicode 字体和 tff 字体,这部分文档也没什么需要解释的:OptiFine帮助文档:高清字体
default.json
翻译自 reddit 上的一篇文章 的节选,并作了一些补充:
  1. {
  2. "providers": [
  3. {
  4.   "type": "bitmap",
  5.   "file": "minecraft:font/nonlatin_european.png",
  6.   "ascent": 7
  7.   "chars": [
  8.     ...
  9.   ]
  10. },
  11. {
  12.   "type": "bitmap",
  13.   "file": "minecraft:font/accented.png",
  14.   "height": 12,
  15.   "ascent": 10,
  16.   "chars": [
  17.     ...
  18.   ]
  19. },
  20. {
  21.   "type": "bitmap",
  22.   "file": "minecraft:font/ascii.png",
  23.   "ascent": 7,
  24.   "chars": [
  25.     ...
  26.   ]
  27. },
  28. {
  29.   "type": "legacy_unicode",
  30.   "sizes": "minecraft:font/glyph_sizes.bin",
  31.   "template": "minecraft:font/unicode_page_%s.png"
  32. }
  33. ]
  34. }
复制代码
这个文件包含一系列字体提供器(providers)。当游戏想要渲染一个字符,它会在每个提供器中(从上到下地)寻找这个字符。有三种类型的提供器。

第一种类型:
  • "type": "bitmap" 这表示包含很多字符的位图
  • file 表示相对于 assets/<命名空间>/textures/ 的路径而且应该指向一张 png 图片
  • ascent 是字符向上偏移的像素值
  • height 是字符的像素高度
  • chars 是位图包含的一系列字符(用 Unicode 编码表示),和图片进行对照不难理解其含义

第二种类型:
  • "type": "legacy_unicode" 仅用于 Unicode 字体
  • sizes 是相对于 assets/<命名空间>/ 的资源路径,指向包含字形尺寸的二进制文件。默认为 glyph_sizes.bin
  • template 是相对于 assets/<命名空间>/textures/ 的资源路径,其中 %s 将被替换为包含 Unicode 字形的图片的页码

第三种类型:
  • "type": "ttf" 表示 TTF 字体文件
  • file 是相对于 assets/<命名空间>/font/ 的资源路径,且应该是一个 ttf 字体文件
  • shift 是有两个值的数组。分别为水平方向偏移和竖直方向偏移。默认值为 [0, 0]
  • size 是字符的像素尺寸。默认值为 11.0
  • oversample 是字体的分辨率。当你提升这个值,字体将会渲染得更清晰,分辨率会更高。默认为 2.0
  • skip 是提供器不应该提供的字符。例如,如果写 "skip": "a",那么字符 "a" 就会以默认的 Minecraft 字体渲染,但是其他文字将会使用你提供的字体。

补充:
  • 上述资源路径都要加命名空间,原版的命名空间表示方法为在路径前加 minecraft:
  • 所有文件都不能使用 [a-z0-9/._-] 以外的字符,包括大写字母!
  • 当游戏想要渲染一个字符,它会在每个提供器中(从上到下地)寻找这个字符,这意味着只要在一个提供器中找到某个字符,就不会使用后面的提供器的这个字符。资源包中的提供器会优先加载。