The Graveyard - Gravelord-Lych
type: channel
link: https://blog.constance.moe/index.php/author/1/
description: Gravelord-Lych
items: （转载）辰光破茧——星茧的独白与银河的耳语
items: 关于暮辰和本分类
items: 末影龙核心行为的底层实现的简要分析
items: 面对AI图时，为什么我们可以“一眼AI”？——浅析AI图现有的不足之处
items: 召唤扩展Mod指令使用教程
items: （MC1.16.5）float的精度引起的一个渲染问题

（转载）辰光破茧——星茧的独白与银河的耳语
type: item
date: 2025-03-23T04:57:00+08:00
description: 序言这其实本是暮辰写给弟弟看的，隐喻她自己身份认同的童话，但她也想要她写的东西有机会让更多人看到，所以我转载在这里了。正文上I在银河系猎户臂最边缘的一个行星系里，藏着永昼星。永昼星被无限的永昼林覆盖着，这里没有昼夜之分，亿万片金叶织就的天穹永远浮着黄昏，像被琥珀封存的末日夕照。这里的夕阳每隔二十个小时定时剧烈波动一次，而夕阳波动也在这里成为唯一的计时手段——每两次夕阳波动间就是这里的“一天”。这里唯一的智慧生物居民是一种有魔力的萤火虫，萤火虫们从幼虫时期就被种下象征着萤火虫身份的光纹——幼虫破茧那日，长老会用星辉淬炼的金针，在他们的尾翼上刻上螺旋纹路，称为“荣耀光纹”。那是荣耀的胎记，是世代相传的圣痕。长老说：“荣耀光纹是萤火虫的灵魂，是血脉的证明。”可有一个叫星芒的生命挣开了虫茧后，他从破茧那一刻就感受到了某种“错误”。星芒破茧那日，永昼林正值盛夏。当他挣开最后一层虫蜕时，触角突然传来针扎般的刺痛——那是族群的“光纹烙印仪式”。长老用金针在他腹部画下第一道荣耀光纹时，星芒突然蜷缩成一团。“疼吗？”妈妈用翅膀轻拍他，“每只萤火虫都会疼，这是荣耀的印记。”然而只有星芒自己知道，当长老的金针在他腹部刻下第一道光纹时，刺痛的不是皮肤，而是胸腔深处某块不属于萤火虫的星核——那团银蓝色的光斑在每次心跳时膨胀，将光纹撑出蛛网般的裂痕。从此以后，星芒便总是感到自己躯壳与内心的不一致：饮水时水面的萤火虫倒影让他眩晕；粗壮的发光器像误植的异物；触角接收到的求偶频率在神经索上擦出尖锐的杂音……某次他偷偷刮掉光纹，露出的皮肤竟渗出银蓝色光粒，将巢穴照成冰窟。妈妈惊慌地用树脂胶替他粘合上光纹，并借机用胶水堵塞他的呼吸孔来惩罚他。他在窒息中，经常梦见自己挣脱了萤火虫的躯壳，在星云间自由地飞舞……最痛的是共振仪式——每次他都被迫与参加仪式的萤火虫同步震动翅膀，体内星核在声波共振中几欲爆裂，他痛苦难忍，呕吐出星河般的光浆。守卫虫却将这种排异反应称为“光蚀病”。用滚烫的金色岩浆浇灌他的伤口，声称“高温能杀死变异细胞”；用光痕鸟喙刺入他的复眼，播放“标准萤火虫的一生”投影：求偶、筑巢、产卵……这无疑加剧了他的痛苦。他最喜欢的事情是收集星尘，他会用螯肢最细的绒毛卷起蛛丝，织成捕梦网般的滤勺。溪畔那些被守夜虫斥为“杂光垃圾”的星尘，在他眼里却是会呼吸的宝石——有的卡在芦苇节间发蓝光，有的黏在腐叶背面泛银晕，最珍贵的几粒总藏在夜莲闭合的花瓣里，要用露水轻轻叩打花萼才能抖落。他总是通过收集星尘，来感受一种他不知道其中奥秘，却深深向往的共鸣。而每次他暗地里流泪时，妈妈却常常叼来他最爱的蜜露——里面却混着镇定粉——制止他流泪并责骂道：“变回正常孩子吧，弟弟妹妹们都在模仿你的‘怪病’！”星芒就这样在永昼林的地平线间被来回撕扯着，像一片被季风反复揉皱的枯叶。每天他都被迫违心地用螯肢蘸取金粉仔细修补腹部的裂痕，将溃烂的银斑压在树脂胶下，学着雄性萤火虫抖动粗壮的发光器，让金光在湿热的夏日里炸成刺目的信号弹。他甚至吞下长老赐予的“同频浆果”，强迫声带发出低沉的嗡鸣——那声音震得胸腔里的星核几乎碎裂，却换来妈妈欣慰的触角轻抚：“这才是我的好孩子。”II星芒不知道为何他与那些萤火虫不同。他也曾以为，这样的痛苦和内心的不一致会永远持续下去。直到六千五百余次夕阳波动后的某个暴雨之日，星芒在清洗光痕监测塔时失足跌进具有窥见内心之倒影之能力的镜像池。他奋力地游出水面，却惊讶地发现池水倒映出的，不再是那个甲壳粗钝的雄性萤火虫，而是一个近乎透明的灵体：纤长的触角缀满星屑，腹部裂口处钻出星河藤蔓般的神经索，那些被光纹掩盖的银斑早已连结成古老的星灵图腾。他突然意识到，这些年强行缝合的岂止是甲壳的裂缝——每一次对光纹的修补，都是在往灵魂里钉入淬毒的铆钉；每一声模仿雄性萤火虫的低鸣，都让星核生长出更多荆棘。凝视着淡蓝色的池水表面，他蓦地听见体内传来细小而坚定的声音。“你的光不在这里。”那声音指引着他飞向林间最古老的魔法之树。星芒的翅膀在微风中颤了颤，像两片被雨水打湿的宣纸。起初只是缓慢的滑翔，六足仍死死扣着枯叶边缘——身体上那些旧伤让起飞像是撕开皮肤。可体内的声音越来越急，像银铃在颅骨里摇晃：“来不及了……”他终于松开螯肢。第一下振翅就扯断三根翅脉，银蓝色光浆从裂口喷溅，在身后拖出彗尾般的轨迹。风突然变得粘稠，仿佛永昼林所有的事物都在拉扯他：妈妈巢穴的方向传来树脂胶的甜腥，求偶场飘来浆果发酵的酸味，而长老的监测塔正射出探照光柱，像一条条金色锁链绞住他的腹节。越是靠近古树，空气里的阻力就越发诡异。翅膀每次扇动都像在凝胶中划动，有看不见的金色丝线缠上触角，试图将他拽回既定的环形飞行轨道。星芒突然弓起腹部——那里溃烂的光斑正突突跳动——猛地将螯肢刺入伤口，银蓝色光浆如急湍的云雾般喷出，在身前烧灼出一条荧光隧道。…

关于暮辰和本分类
type: item
date: 2025-03-23T04:05:00+08:00
description: 注意：绝对不要和我谈论暮辰的私事。如果您觉得实在有必要对这个分类的文章发表评论，请尽量注意语言，以免伤害到我和她，谢谢~如与某up主/某主播等有重名，纯属巧合暮辰（StellaNocturna）是我的高中同班同学，是位跨性别女性，与我同属LGBTQ+群体与高敏感度群体，也是我的好朋友。然而她却不喜欢接触网络，因为她害怕网络上未知的人的目光。她在班上常常保持沉默，在网络上则不在没见过的人面前留一点痕迹，却总是喜欢用QQ向我倾诉心事。她说她的名字，是初中时给自己起的，像“夜空中没被命名的星星”，默默无闻却也闪闪发光。体育课上，面对体育老师反复向自己重复着“男生的体测标准”，她总是感觉头痛欲裂；生物课上，每每做到伴性遗传题，她常常想哭，却哭不出来。我们开始熟悉是在一节心理课后。那节课上老师让我们所有人小组合作绘画，而暮辰是她小组第一个画的。她原打算画个在桌前学习的女孩——这是她心目中自己理想的模样。而那幅画传递到同组的几个男生手上以后，桌前的人物却被篡改为了一个举止下流的男孩，下身伸出一条夸张的男性生殖器。心理老师让暮辰评价她那组的作品，她虽然面带忧郁，却只是轻轻地说“与她的预期不一样”，把无限的愁思放在心中不让别人知晓。我悄悄关注到她向男生们要回那幅作品，把它用力团成纸团扔进垃圾桶里。很快我在QQ上找到了暮辰。最初是我主动鼓励她，多次交流后，我和她逐渐熟悉了起来，而她也开始向我袒露心扉，深夜的QQ对话框成为了我们共有的安全屋。她发消息很慢，说自己每发一句话都要反复删改，多条长段的消息打完后总要先发给自己，再一起转发给我，这是因为担心我没有一次性读完她的所有话。暮辰几乎每两周放假回家，都能发几条总计一千多字的信息给我，在交流之中，我也渐渐窥见了她复杂的内心世界，深深感受到，有时甚至是共情到她的痛苦。考虑到暮辰有的时候有许多想向更多人分享的话，可她却不敢由本人分享出来，于是我就在本分类中转载一些她想说的话吧。

末影龙核心行为的底层实现的简要分析
type: item
date: 2024-07-21T01:46:00+08:00
description: 补充内容2024-08-09附上视频：2024-08-07本文中对“寻路”的理解可能存在一定的问题。我查了维基百科上对“寻路”一词的解释，上面说寻路是“由计算机应用程序规划两点之间的最短路线”。因此实际上此处应该是不包括具体飞向路径的过程的。为了与视频中内容尽量呼应而不自相矛盾，我没有修改正文中的内容2024-08-03下文中所有“已编号节点”的编号都是“MC规定好”的，而不是我自己规定的下文中所有阶段的中文名是我综合了Wiki中的末影龙页面对末影龙行为的描述、末影龙各个阶段的类的MCP名以及各个阶段的实际作用而命名的前言近来笔者想投稿与末影龙原理相关的视频，但笔者虽然对末影龙有一定的了解，却尚未对末影龙进行较细致的分析，因此写了这样一篇文章。笔者写这篇文章既是为了给自己即将制作的视频理清思路，也是为了提供一些有关末影龙的代码层面的解读。本文代码部分较多，因此较适合对Java与Minecraft模组制作有一定的了解的读者进行阅读。当然本文对于不了解Java语言或Minecraft modding的读者也有一定的参考意义。注：使用的Minecraft版本为1.20.2，Forge版本为48.0.30，MCP版本为20230921.100330，笔者曾查看了1.16.5与1.21版本中末影龙的底层实现，总体来看均没有明显差异（当然不排除笔者有疏忽的可能）本文只是简要的分析，因而只会选择核心内容，并不面面俱到。1.20.1和1.20.2中末影龙的代码是没有区别的，但以后更新Polonium上有关末影龙的内容时笔者会写得更详细一些~在原版世界中，末影龙是驻守在末路之地的一个强大的龙形生物，也是原版Minecraft的最终boss，不少玩家将击杀末影龙作为通关MC的标准。末影龙的底层实现也相当复杂，它不仅使用了一套独立的AI系统，寻路的算法也与一般的生物有一定的区别。一年多前笔者曾经仿照末影龙在一个未发布的mod中制作了一种与末影龙相似，但行为更复杂的龙型生物作为自定义维度的一个小boss，因此对末影龙有一定的了解。本文将从末影龙的寻路系统，末影龙的AI，及末影龙的其他重要行为这三个方面进行分析。末影龙的寻路系统在分析寻路系统之前，先介绍一下末影龙的24个已编号的路径节点（下文中会把这24个路径节点称为“已编号节点”）的分布。已编号节点的分布末影龙的已编号节点共分为3圈，其中外圈12个节点，中圈8个节点，内圈4个节点。可以用以下的一张图来表示（下图中青色点表示坐标原点，淡青色细线表示坐标轴，红色、蓝色箭头所指方向分别为x、z轴正半轴方向，蓝绿色、绿色、黄绿色点分别表示外、中、内圈的已编号节点）：将外圈已编号节点用0~11编号，中圈已编号节点用12~19编号，内圈已编号节点用20~23编号，可得到下图：而查阅源代码可知，外、中、内圈的已编号节点距离原点的水平距离分别近似为60、40、20。将它们分别放在3个同心圆上可得下图（注意不一定所有已编号节点都恰好位于同心圆上，因为任何路径节点的坐标都是取整存储的）：这是一张末地的地形图（从30多张末地地形图中选出来的比较好看的一张233）：两图叠加可得：从这张叠加的图中我们可以直观地看出24个已编号节点的大致分布情况，同时可以发现中圈与黑曜石柱所在圆的位置相近（黑曜石柱中心到原点的水平距离约为42，这个数值与中圈的已编号节点到原点的水平距离40接近）。末影龙的寻路流程下面正式开始分析末影龙的寻路系统，先看EnderDragon类里声明的这样的3个与寻路相关的成员变量。private final Node[] nodes = new Node[24]; private final int[] nodeAdjacency = new int[24]; private final BinaryHeap openSet = new BinaryHeap();其中nodes是末影龙的路径节点数组，其中所有节点的x、z坐标分别是定值，但y坐标根据末地的实际地形与节点在哪一圈来确定。nodeAdjacency是邻接矩阵，用于记录与每个节点相邻的节点的编号。而openSet是二叉堆，在末影龙的寻路过程中起到作用。总的来说，末影龙的寻路过程的步骤可分为这样几步：确定起点和终点的位置寻找起点到终点的一条最短路径。这条路径中除了终点之外，其余的路径节点各自一定是已编号节点中的一个根据寻路得到的路径，一步一步按路径点飞向终点[note type="info flat"]2024-08-07更新：这里的“寻路过程”改为“寻路与沿路径飞行的过程”更合适，因为第三步实际上不是“寻路”过程中的一部分[/note]末影龙每次寻路时，都需要先确定到自己最近的节点的编号，下面两个方法则寻找了已编号节点中离末影龙自己最近的节点。publ…

面对AI图时，为什么我们可以“一眼AI”？——浅析AI图现有的不足之处
type: item
date: 2024-02-04T19:47:00+08:00
description: 注：- 本文有较强时效性，请关注本文发表时间与更新时间- 本文的创作是为了指出而不是解决问题，因此不会细致分析问题出现的原因背景最近在研究AI绘画，以前使用过Stable Diffusion WebUI，现在在尝试ComfyUI。然而不论是Stable Diffusion v1.5还是较新的SDXL，所绘制的图片均存在一定的问题。举下面一张图为例（AI直出的图，没有经过后处理）：以及用于生成这张图的Workflow（注意使用的种子不是下图中的种子）：分析这张图乍看起来似乎没毛病，但是仔细观察却能看出不少问题。当然可能不是所有的问题都被归类在这里，而且部分问题在这张图里没有体现。 将出现的问题逐类编号如下：问题1——手部缺陷众所周知，AI画不好手，尽管绘制这张图采用的模型基于SDXL训练而来，降低了坏手的概率，但仍然避免不了手部出现问题。如果AI画的图中出现了手，那么手出问题的概率在95%左右。这样的问题的出现与手部姿势极其复杂有关，一时难以解决，也很难通过Photoshop等图像处理软件后处理来补救，只能期待技术的进步能解决这一问题。问题2——窗户歪斜这也是AI绘画出现的特有问题，相似的问题还有生成水印和（在书本、电脑屏幕上）生成不可读的文字等。凡是出现直线时，均有可能出现这样的问题，好在这个概率不算太高，并且相对前者更容易补救。问题3——不合逻辑仔细看裙子的网格，会发现阴影处有1根网格线，到了有光照的地方却突变为2根网格线，显然不符合逻辑。当遇到元素间的交叉处时，出现这种问题的概率更大且问题更明显。上个问题与这个问题的出现，可以反映出AI并不理解所画的内容。问题4——头发杂糅不只是画手，由于头发的复杂性，画头发也是AI面临的一个重要难题。几乎每一张图都有这个问题，只是这个问题相对比较隐蔽，没有那么明显，第一眼很难看出来，需要细看才能发现。问题5——随机噪点这种问题出现的概率或与模型有关，有些模型噪点出现得很多，有些却很少。不过通常它们在数量不大的情况下不怎么影响观感，也很容易通过Photoshop等软件去除。结语期末考试的时候做到一篇英语阅读理解，大致是讲述了元宇宙（Metaverse）看上去很有吸引力，然而亲身体验却发现效果没那么好。AI绘画或许也处于这种状态吧，表面光鲜亮丽，大有取代人类画师的可能，可实际上还存在着诸多问题，与人类画师差距依然较大。希望未来这些问题能得到解决，使AI绘画能更好地服务人类~

召唤扩展Mod指令使用教程
type: item
date: 2023-07-14T20:36:00+08:00
description: 文章说明下文中(op)表示暂时使用的参数名[op]表示可选操作或参数op1/op2表示并列的必需操作或参数[op1]/[op2]表示并列的可选操作或参数指令格式指令名：/summoningex (op)（其中op的类型为area或summon）area提供了对召唤区域（Summoning Area）的操作格式：/summoningex area (op)（其中op的类型为define，list，query，remove，show或hide）define用于定义和命名召唤区域格式：/summoningex area define (x1), (y1), (z1), (x2), (y2), (x2) as #(name) [colored (colorop) (colorval) [in (dim)]]/[in (dim)]x1, y1, z1和x2, y2, z2定义了召唤区域的位置（以（x1, y1, z1）与（x2, y2, z2）两个方块坐标（BlockPos）为顶点）注意x1, y1, z1, x2, y2, z2为整数且x1, x2之间，y1, y2之间与z1, z2之间没有严格的大小限制（也就是说x1既可以大于x2，又可以等于或小于x2）x1与x2，y1与y2，z1与z2都相同时表示了一个但方块的召唤区域name定义了召唤区域的名称（指令中的"#"号不可省略且不能为中文）colorop（可以传入custom或preset）及colorval当color传入custom时，colorval应传入一个[0, 16777215]间的十进制整数，表示了召唤区域的RGB颜色值当color传入preset时，colorval应传入原版的一种染料颜色（DyeColor），该颜色表示了召唤区域的颜色（但这个颜色的饱和度最大值被限制在了88%）若不指定颜色则会随机为召唤区域分配一个颜色相关代码染料颜色的获取（getDyeColor(CommandContext, String)静态方法返回输入的染料颜色）：public static int getIntDyeColor(CommandContext<CommandSourceStack> context, String name) { int textColor = getDyeColor(context, name).getTextColor(); float[] hsbvals = new float[3]; Color.RGBtoHSB(textColor >> 16 & 0xFF, textColor >> 8 & 0xFF, textColor & 0xFF, hsbvals); // Restricts the saturation hsbvals[1] = Math.min(0.88f, hsbvals[1]); int color = Color.HSBtoRGB(hsbvals[0], hsbvals[1], hsbvals[2]); // Make sure the color value is positive color &= 0xffffff; return color; }颜色的随机分配private static int randomColor(RandomSource random) { // Randomly selects hue from 0 to 0.95 (step=0.05) float hue = 0.05f * random.nextInt(20); // Two types of saturation - low(0.5) and high(0.8) float saturation = random.nextBoolean() ? 0.5f : 0.8f; // Randomly selects hue from 0.5 to 1 (step=0.125) float brightness = 0.5f + 0.125f * random.nextInt(5); return Color.HSBtoRGB(hue, saturation, brightness); }dim定义了召唤区域所在的维度若不指定维度则会使用当前所在维度举例/summoningex area define 0 100 0 10 110 10 as #Example colored custom 16777215 in minecraft:overworld在主世界定义了一个名为Example，两个顶点分别为（0，100，0），（10，110，10）两个方块坐标，颜色为白色的召唤区域/summoningex area define 20 100 20 25 9…

（MC1.16.5）float的精度引起的一个渲染问题
type: item
date: 2023-04-29T08:41:00+08:00
description: 引入在世界边境附近调试Mod实体时，偶然发现了这样的问题（图中激光渲染的位置出现异常偏移）这是怎么回事呢？常用技巧在Minecraft的Mod开发中，开发者们可能常使用以下的代码辅助世界的渲染：Vector3d projectedView = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); matrixStack.translate(-projectedView.x, -projectedView.y, -projectedView.z);这样做的好处显而易见——可以在渲染中用绝对坐标替换相对坐标。不过使用这样的方式，有时也会导致一些问题，先从float和double的有效数字分析Java中的浮点数下表为float和double的一些属性比较属性floatdouble符号位/bit11指数位/bit811尾数位/bit2352占用内存空间4 Byte (32bit)8 Byte (64bit)由此可知float的有效数字位数为6~7位，而double则为15~16位float的局限性MatrixStack的translate方法以下是MatrixStack类中translate方法的源代码public void translate(double x, double y, double z) { MatrixStack.Entry entry = this.poseStack.getLast(); entry.pose.multiply(Matrix4f.createTranslateMatrix((float) x, (float) y, (float) z)); }可以发现，此方法内做了一个强制类型转换，将双精度的double转换为了单精度的float！世界的大小在World（SRG名，1.16.5）类中，有如下的私有静态方法private static boolean isInWorldBoundsHorizontal(BlockPos pos) { return pos.getX() >= -30000000 && pos.getZ() >= -30000000 && pos.getX() < 30000000 && pos.getZ() < 30000000; }由此可知，MC的世界是60000001x60000001格的，这会使得当坐标足够大时，用float表示坐标会使float的小数部分丢失，从而发现了问题所在问题发生的原因在未解决bug时，由于直接在translate中传入世界真实坐标，导致强制类型转换，进而导致double后面的小数部分丢失问题的解决translate时，传入激光起始位置的坐标与玩家坐标的差，使数字变小，以确保float的小数部分保留Vector3d cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); double x = src.x - cameraPos.x; double y = src.y - cameraPos.y; double z = src.z - cameraPos.z; matrixStack.translate(x, y, z);最后效果如下图所示激光渲染的位置的异常偏移消失了！总结float不精确，开发中无性能需求应尽量使用double（虽然也不是100%精确）Minecraft的世界坐标（x和z）的绝对值上限为30000000而不能无限增大，一定程度上与double的精度限制有关（毕竟每个世界坐标都是double的，但主要还是因为int能表示的范围有限）原版下实体的生命上限为1024，这也在一定程度上与float的精度限制有关