NEI Recipe Panels

[!INFO] Git Commit: 592ea85 | Updated: 2026-09-27

Minecraft 1.7.10 / Forge 10.13.4.1614 的 Not Enough Items 插件。在 NEI 配方界面的每条配方上多一个面板按钮,点它扣掉一个可合成的配方蓝图,给玩家一块刻好这条配方的配方面板;面板像挂画一样贴在墙上,用 NEI 自己的绘制代码把配方渲染成一块平面贴图。右键已放置的面板(或在物品栏里按 NEI 的配方键)可以把这条配方重新在 NEI 中打开。

  • 源码目录:/Users/evlos/a/mirror/nei-recipe-panels/
  • modid:neirecipepanels(≠ 分类名 nei-recipe-panels)
  • @Mod 名称:NEI Recipe Panels,version = Tags.VERSION,acceptedMinecraftVersions = "[1.7.10]"
  • 依赖:required-after:NotEnoughItems;mcmod.info 进一步写明 NotEnoughItems@[2.8.150,)

内容概览

维度 数量 说明
方块 1 配方面板方块
物品 2 配方蓝图、配方面板
游戏设定 5 配置文件、NEI 集成、刻印流程、面板显示设置、面板渲染管线

方块列表

  • 配方面板方块 - 贴墙的 1/16 薄片方块,6 个朝向,不碰撞、不可见,画面全靠离屏 FBO + TESR 绘制

物品列表

  • 配方蓝图 - 刻印消耗品,无使用逻辑,纸 + 纸 + 红石合成,也能把面板合成回空白蓝图
  • 配方面板物品 - 承载刻印配面的物品,右键贴墙;已刻印时显示名变成 Encoded Recipe Blueprint

游戏设定列表

  • 配置文件 - config/neirecipepanels.cfg,recipe 与 server 两个分类共 5 个选项,含 panelMode 四值穷举
  • NEI 集成 - 实现的 2 个 NEI 接口、调用的 14 个 NEI API、配方界面的面板按钮与按键打开
  • 刻印流程 - 快照存了什么、服务端 7 步校验、gzip 字节数与槽数上限
  • 面板显示设置 - 每块面板的标题(上限 48 字符)与背景透明开关,潜行右键配置
  • 面板渲染管线 - 离屏 framebuffer 超采样渲染、TESR blit、物品栏图标替换、Waila 悬停、GT 兼容

实现的核心机制

只存引用,不存配方内容。 面板的 NBT 里只有 NEI 的 RecipeId(JSON 文本)、一个快照版本号 ver = 3,以及每格当时显示第几个循环变体的下标数组(resultPerm / inPerms / otherPerms)。物品、坐标、概率、NC 标记每次都由 ResolvedRecipe.of 从当下还活着的 handler 重新算出来,所以面板永远显示配方的当前状态。代价是需要三级降级来打开配方:recipeId 直开 → 产物全开再跳转 → 静默放弃。

服务端重建而非信任。 客户端提交的快照经 RecipeSnapshot.sanitize 过三关(gzip 字节数 ≤ maxSnapshotBytes、两个下标数组长度 ≤ maxIngredients、NBT 解析不抛异常),通过后返回规范化副本(recipeId 截断到 12000 字符)而不是原样发放。改面板设置的消息还额外限制 8 格距离。

离屏渲染。 NEI 的配方绘制是 GUI 代码,直接放进世界会 z-fight。所以每块面板用 glOrtho 在配方像素单位下把配方画进正方形 framebuffer(边长 clamp 到 176–360,纹理再 ×3 超采样、生成 mipmap),而刻意不用 glScalef——GregTech 的自定义物品渲染器在非单位 modelview 缩放下会出错。真正的四边形只由 TileEntity 特殊渲染器 blit 出去。

本 mod 没有的部分

以下内容在源码中确实不存在,不是省略:

维度 grep 证据
热键绑定 grep -rn "new KeyBinding" src/ 无输出。本 mod 不注册任何自己的 KeyBinding,全部按键走 NEI 的绑定 id(KeyManager.getKeyCode("recipe.recipe") / "recipe.usage",回落 R / U)
命令 grep -rn "CommandBase|registerCommand|addChatCommand|ICommand" src/ 无输出。CommonProxy.serverStarting 是空方法,未做任何 CommandBase 注册
实体 grep -rn "registerEntity" src/ 无输出,无 Entity*.java 文件
多方块结构 源码中没有 TileEntity 容器/控制器类;唯一的 TileEntity 是单方块的 RecipePanelTile
世界/维度 grep -rn "registerDimension|registerWorldProvider" src/ 无输出
附魔 源码无 Enchantment 相关类或注册
Buff/Debuff 源码无 Potion / PotionEffect 相关类
群系 源码无 BiomeGen / 群系注册
结构 源码无世界结构生成代码
成就 源码无 Achievement 相关类
物品效果 源码无 onUpdate / onWornTick 等持续效果覆写

没有 Access Transformer、没有 Mixin、没有 Core Mod。 gradle.properties 里 accessTransformersFile =(空)、usesMixins = false、coreModClass =(空),src/ 下也没有 META-INF 目录或任何 AT 配置文件。

没有实现任何"提供配方"的 NEI 接口。 本 mod 只消费 NEI 配方,不生产配方:grep -rn "implements" src/ 全量结果中来自 NEI 的只有 IConfigureNEI(NEIRecipePanelsConfig)与 IContainerInputHandler(PanelInputHandler)两个;IRecipeHandler、ICraftingRecipeProvider、IItemListOverlay、IWorldAwareIItemListProvider 均无实现(IRecipeHandler 只作为方法参数类型被调用)。

没有 NEI 配方/覆盖层的注册代码。 src/main/resources 下只有 assets/neirecipepanels/{lang,textures},没有 plugins 目录;grep -rn "registerRecipeHandler\|registerOverlayHandler\|registerCraftingHandler\|plugins" src/ 无输出。

配方面板物品没有合成配方。 ModItems.registerRecipes() 只注册两条产出蓝图的无序配方。

方块没有对应的 ItemBlock。 GameRegistry.registerBlock(recipePanel, null, "recipe_panel") 第二参数传 null,方块完全由物品的 onItemUse 放置。

其他事实

  • README 提到的 server.maxAlternatives 在代码中不存在——Config 只有 maxIngredients 与 maxSnapshotBytes 两个上限
  • dependencies.gradle 里 GregTech、Waila、Avaritia、spark 全部是 devOnlyNonPublishable / runtimeOnlyNonPublishable,即不作为本 mod 的发布依赖;GregTech 与 Waila 在缺席时会优雅退化(回退到写死的颜色 / IMC 消息空操作)
  • 源码里出现的 SRG 名只有两处:func_148857_g(S35PacketUpdateTileEntity.getChatComponent(),见 RecipePanelTile.onDataPacket)与 func_152596_g(MinecraftServer.getConfigurationManager().isOp(GameProfile),见 MakeRecipePanelMessage.Handler.isOp)