程序化生成 Blockbench .bbmodel、烘焙骨骼动画、headless 渲染核验的离线工具库。
纯离线,不进游戏运行时。产出的是作者资产和校对图——给人看、给人改,然后由调用方 自己决定怎么装进游戏。
src/bbmodel_maker/
├── workspace.py 项目根 / 产出目录 / 资源命名空间的唯一解析处(跨层)
├── model/ 几何与格式:护甲骨架、box-UV、bbmodel 4.10 ↔ 5.0
├── rig/ 骨骼与动画:正逆解、关键帧轨道、体素生物 Rig、PlayerAnimator 采样
├── render/ z-buffer 软渲 bbmodel、诚实视角命名与固定取景、玩家姿态、手持物
├── gates/ 后验判据:七道几何门 + 动画门,每道自带缺陷注入器
└── workbench/ 生图工作台 CLI:接触表、护甲上身预览、变体派生、姿态回程
pip install git+https://github.com/Kizunad/bbmodel-maker@v0.1.0
pip install "bbmodel-maker[geckolib] @ git+https://github.com/Kizunad/bbmodel-maker@v0.1.0" # 要 GeckoLib 转换时只依赖 numpy 和 pillow。bbmodel_to_geckolib 驱动的是 web Blockbench 的官方 codec,
只有那一条路径要 playwright。
库不猜调用方的目录布局。在项目根放一个 bbmodel.toml:
[workspace]
lib = "modelScript" # 生成脚本与产出所在目录
namespace = "yourmod" # MC 资源命名空间
client_resources = "client/src/main/resources" # 可选,读动画 JSON / 写导出资产时才需要解析顺序:显式传参 → $BBMODEL_PROJECT_ROOT → bbmodel.toml → .git → cwd。
.git 是文件时(git worktree)同样认。
from bbmodel_maker import Workspace
ws = Workspace.discover()
ws.models / "Thing.bbmodel" # 产出路径
ws.rel(path) # 打印用的短路径
ws.resolve_texture(src, near=) # bbmodel 贴图路径:项目根 → bbmodel 同目录 → 原样# 看 bbmodel 真长相(别只信平涂示意图)
bbmodel-render path/to/Thing.bbmodel
# 人工闸门:六视角接触表 + 特征点名 + 差分自证,出完停下等人看
bbmodel-contact-sheet Thing.bbmodel --gates gen_thing --prev out/Thing_round1.bbmodel
# 把护甲戴到真 MC 玩家模型上,查有没有漏盖
bbmodel-armor-preview gen_hide_armor --slot chest --coverage
# Blockbench 里改完的姿态读回成 POSE 表
bbmodel-to-pose Anim.bbmodel --anim club_smash --tick 5- 1 texel ≈ 1 单位:护甲 cube 的贴图分辨率就这么低。任何「逐 texel 的描边 / 虚线 / 交替缝线」放大后都是棋盘格。细节要么做成几何,要么别做。
- 共面 z-fighting:两块 cube 同向外表面落在同一平面且投影相交 → 渲染器逐像素乱挑 → 一片高频噪点,极容易被误读成「贴图脏了」。
- 正交三视图结构上看不见水平面:臂顶、脚底这类精确平面上的穿模,只能靠逐面采样查。
yaw=180渲的是 −z 面:背面剔除只画法线转到 +z 的面。视角名一律走framing派生, 别手写角度表。- 自动取景不能跨图比较:
render()不传focus时每张图各算各的包围盒。要比就传framing.focus_for()出来的公共取景。 - 渲出来的 PNG 读不回来:验证只能靠 PIL/numpy 逐像素采样,把结果打成人类可读的数字表。
数材质像素用色相单位向量(归一化后比距离,
< 0.035~0.05判命中)——绝对亮度阈值在 不同光照/朝向下会失效,色相不会。 - bbmodel 5.0 在 4.x 里打开是一个 cube 都看不见,不报错,只是空场景。用
to_fmt410降级。 - Blockbench 存的动画和生成器直出的动画,符号不一样:读 animation 通道时取反 X/Y、
存盘时不取反。
bb_anim_axes的WRITE_LAYERS/READ_LAYERS是分开的,别当成互逆。 - uuid 是身份句柄不是内容:多数生成器用
uuid.uuid4()现取,每跑一次都不同。做字节回归 要先把 uuid 按首次出现顺序归一化,否则每次都「变了」。 - 落盘前一律
mkdir(parents=True, exist_ok=True):产出目录通常 gitignored, 干净 checkout 上不存在。
PYTHONPATH=src python3 -m unittest discover -s tests -p "test_*.py"248 例。
gates 的迁移用例、manifest 点名器、contact_sheet 的端到端用例目前只在调用方仓库里
有覆盖——它们拿真实资产当 fixture(某个具体的草包 / 背篓 bbmodel)。库这边缺的是等价的
合成 fixture。在补上之前,改这三块要连调用方的测试一起跑。
同理,preview_player_anim / held_item_pose 两个工作台入口还没进库:它们依赖一份
biped 骨架数学与关节解剖判据,那部分还在调用方仓库里,要一起搬。
从 Kizunad/Bong 的 modelScript/ 抽出,
git filter-repo 保留了完整提交历史(可以 git log --follow 追到 2026 年初)。