分类:Godot 引擎
学习路径:由浅入深,按顺序阅读效果最好(共 149 篇)
-
81. GDScript 字节码指令集与 dispatch 循环:callp 函数的两千行 switch
GDScript VM 的执行核心是一个两千多行的巨型 switch:每条指令从共享的 int 流里取操作码和操作数,按地址空间下标取 Variant。这篇拆这个循环的结构、分发成本模型,以及为什么不用 computed goto 和 JIT。
-
82. GDScript 类型推导与 static typing:analyzer 的双遍检查
analyzer 用两遍遍历解决"先用后声明"问题:第一遍解析继承和成员签名,第二遍才检查函数体。这篇讲两遍各自做什么、推导的边界在哪、以及类型标注为什么能让代码快一倍。
-
83. @tool 脚本与编辑器内执行:同一份代码跑在两个进程模型里
加了 @tool 的脚本会在编辑器进程里被实例化和执行,和游戏运行时共享同一个 SceneTree。这篇讲 tool 标记怎么改变脚本的生命周期、编辑器进程的崩溃隔离真相,以及 safe mode 的存在原因。
-
84. await 协程的状态机实现:函数暂停时栈帧存在哪
GDScript 的 await 是无栈协程:OPCODE_AWAIT 把指令指针和整个栈打包进堆上的 CallState,函数当场返回一个 GDScriptFunctionState 句柄。这篇追踪信号到来前后的完整状态迁移。
-
85. signal 语法糖的展开:从 connect 到 emit,编译器帮你写了什么
signal 声明、.emit()、.connect() 三件套背后没有专用指令系统:声明进脚本的信号表,emit 编译成方法调用落到 Object::emit_signal,connect 生成一次性可调用对象。这篇把语法糖逐层剥掉。
-
86. GDScript 性能瓶颈:为什么比 C# 慢一个量级
GDScript 与 C# 的差距不是"解释器写得好不好",而是解释执行、Variant 装箱、引擎调用 marshaling 三层成本叠加的结构性结果。这篇给三层的量化模型和下沉决策树。
-
87. C# 支持:从 Mono 嵌入宿主到 .NET 6+ 的迁移
Godot 4 的 C# 支持换掉了整个技术底座:3.x 把 Mono 运行时嵌进引擎进程,4.0 起改用标准 .NET hosting API(nethost + hostfxr)。这篇讲清楚两种宿主方案的调用链差异,以及互操作 marshaling 的真实成本。
-
88. ScriptServer 与脚本类注册:`class_name` 是怎么被全局看见的
写 `class_name Foo` 之后,整个工程任何脚本都能直接写 Foo.new()——背后是 ScriptServer 的全局类注册表。这篇讲注册时机、缓存文件格式,以及它和 ClassDB 的边界。
-
89. 脚本热重载:编辑器里按保存后哪些状态丢了
运行中改脚本是编辑器最顺手也最容易踩坑的能力:GDScript 的热重载靠"新编译产物替换引用",C# 靠 collectible AssemblyLoadContext。两种路线下,正在运行的实例、静态变量、signal 连接各有不同的保留规则。
-
90. GDScript 的内存模型:引用计数、树所有权与循环引用
GDScript 侧的对象分三类管生命周期:Object 手动、RefCounted 引用计数、Node 场景树所有权。三类之间的混用规则是循环引用泄漏的根源,这篇把不变式和常见泄漏模式列全。
-
91. 与 GDExtension 互操作:GDExtensionInterface 函数表怎么桥接两个世界
GDExtension 不是"加载一个 DLL"那么简单:扩展和引擎之间隔着一张 C 函数表,所有跨边界调用都经它转发。这篇讲函数表的生成、调用链的开销构成,以及 godot-cpp 在表上加了什么。
-
92. 内置脚本调试器:一个自研协议的断点、变量检查与远程通道
Godot 的脚本调试器不走 DAP,而是自研的一套消息协议:编辑器与运行实例之间一条 TCP 长连接,按消息名分发 JSON 负载。这篇讲断点在字节码层的实现方式、变量检查的序列化成本,以及 profiler 数据怎么同通道复用。
-
93. lambda 与 Callable 的捕获语义:拷贝还是引用
GDScript 的 lambda 捕获是"按值拷贝"——但 Variant 的拷贝语义让这句话有坑:int 是真拷贝,Array/Dictionary 是写时复制的共享,Object 是指针拷贝。这篇用三个实验把捕获规则钉死,并给出循环捕获和生命周期两个实战建议。
-
94. GDScript 2.0 破坏性变更清单:3.x 迁移时踩过的坑按类归档
Godot 4 的 GDScript 重写(2.0)动了四类东西:类重命名、语法语义收紧、API 拆分、内置类型重命名。项目升级器能改七成,剩下三成是语义陷阱。这篇按坑的类别归档,附迁移工作流。
-
95. 借 GDScript 的 tokenizer 练手:写一个微型脚本语言前端
读 gdscript_tokenizer.cpp 最好的收尾方式是抄一段:手写扫描器、缩进栈、续行处理这三个机制加起来不到三百行。这篇先讲引擎里的设计取舍,再给一份可运行的迷你 tokenizer。
-
96. Resource 的引用计数与 ResourceCache:资源为什么不会重复加载
从 Ref 模板到 ResourceCache 全局哈希表再到 ResourceLoader 的加载链,讲清 Godot 4.x 里一份资源从磁盘到内存、再到被共享和释放的完整生命周期。
-
97. ResourceLoader 的加载链:ResourceFormatLoader 的注册与选择
load("res://foo.tscn") 的第一个分叉点是 recognize 而不是扩展名:ResourceFormatLoader 列表按优先级询问"你认这个路径吗"。这篇拆加载链的每一环和自定义 loader 的接入方式。
-
98. 线程化资源加载:`load_threaded_request` 的状态机与令牌
load_threaded_request 把资源加载挪到后台线程,主线程靠状态轮询拿结果。这篇讲 ThreadLoadTask 的状态机、三个公开 API 的调用契约,以及它为什么解决不了"加载瞬间的卡顿"的全部问题。
-
99. UID 系统:uid:// 路径如何映射到文件
Godot 4 用 64 位 UID 取代路径做资源引用,移动文件不再断链。这篇讲 UID 的编码格式、三处存储位置、ResourceUID 单例的查表流程,以及复制文件导致 UID 撞车的踩坑现场。
-
100. 导入管线:EditorFileSystem 的扫描与 .godot/imported 目录
Godot 运行时不直接读 PNG/WAV,而是读 .godot/imported 里的转换产物。这篇讲 EditorFileSystem 的全量与增量扫描、.import 文件的字段含义,以及改一张贴图到底触发了哪些连锁反应。