标签:GDScript
-
GDScript 类型推导与 static typing:analyzer 的双遍检查
analyzer 用两遍遍历解决"先用后声明"问题:第一遍解析继承和成员签名,第二遍才检查函数体。这篇讲两遍各自做什么、推导的边界在哪、以及类型标注为什么能让代码快一倍。
-
lambda 与 Callable 的捕获语义:拷贝还是引用
GDScript 的 lambda 捕获是"按值拷贝"——但 Variant 的拷贝语义让这句话有坑:int 是真拷贝,Array/Dictionary 是写时复制的共享,Object 是指针拷贝。这篇用三个实验把捕获规则钉死,并给出循环捕获和生命周期两个实战建议。
-
RPC 的实现:从 @rpc 注解到字节流,一次远端调用被编码成什么样
@rpc 声明只是元数据,真正发送时函数名被压成整数索引、参数走 Variant 压缩编码。这篇跟一遍 Node::rpc 到 SceneMultiplayer 的编码链,讲清包格式、method 索引为什么必须配 checksum 校验、以及带返回值的 RPC 是怎么实现的。
-
借 GDScript 的 tokenizer 练手:写一个微型脚本语言前端
读 gdscript_tokenizer.cpp 最好的收尾方式是抄一段:手写扫描器、缩进栈、续行处理这三个机制加起来不到三百行。这篇先讲引擎里的设计取舍,再给一份可运行的迷你 tokenizer。
-
ScriptServer 与脚本类注册:`class_name` 是怎么被全局看见的
写 `class_name Foo` 之后,整个工程任何脚本都能直接写 Foo.new()——背后是 ScriptServer 的全局类注册表。这篇讲注册时机、缓存文件格式,以及它和 ClassDB 的边界。
-
GDScript 的内存模型:引用计数、树所有权与循环引用
GDScript 侧的对象分三类管生命周期:Object 手动、RefCounted 引用计数、Node 场景树所有权。三类之间的混用规则是循环引用泄漏的根源,这篇把不变式和常见泄漏模式列全。
-
GDScript 性能瓶颈:为什么比 C# 慢一个量级
GDScript 与 C# 的差距不是"解释器写得好不好",而是解释执行、Variant 装箱、引擎调用 marshaling 三层成本叠加的结构性结果。这篇给三层的量化模型和下沉决策树。
-
内置脚本调试器:一个自研协议的断点、变量检查与远程通道
Godot 的脚本调试器不走 DAP,而是自研的一套消息协议:编辑器与运行实例之间一条 TCP 长连接,按消息名分发 JSON 负载。这篇讲断点在字节码层的实现方式、变量检查的序列化成本,以及 profiler 数据怎么同通道复用。
-
await 协程的状态机实现:函数暂停时栈帧存在哪
GDScript 的 await 是无栈协程:OPCODE_AWAIT 把指令指针和整个栈打包进堆上的 CallState,函数当场返回一个 GDScriptFunctionState 句柄。这篇追踪信号到来前后的完整状态迁移。
-
自定义 ResourceFormatSaver/Loader:让引擎认一种新资源类型
想让 load() 直接读你的存档格式或关卡数据文件,就要实现一对 ResourceFormatLoader/Saver。这篇给一套可运行的存档格式代码,讲清加载链怎么把请求路由到你的 loader,以及缓存和递归加载两个坑。
-
脚本热重载:编辑器里按保存后哪些状态丢了
运行中改脚本是编辑器最顺手也最容易踩坑的能力:GDScript 的热重载靠"新编译产物替换引用",C# 靠 collectible AssemblyLoadContext。两种路线下,正在运行的实例、静态变量、signal 连接各有不同的保留规则。
-
@tool 脚本与编辑器内执行:同一份代码跑在两个进程模型里
加了 @tool 的脚本会在编辑器进程里被实例化和执行,和游戏运行时共享同一个 SceneTree。这篇讲 tool 标记怎么改变脚本的生命周期、编辑器进程的崩溃隔离真相,以及 safe mode 的存在原因。
-
GDScript 2.0 破坏性变更清单:3.x 迁移时踩过的坑按类归档
Godot 4 的 GDScript 重写(2.0)动了四类东西:类重命名、语法语义收紧、API 拆分、内置类型重命名。项目升级器能改七成,剩下三成是语义陷阱。这篇按坑的类别归档,附迁移工作流。
-
GDScript 字节码指令集与 dispatch 循环:callp 函数的两千行 switch
GDScript VM 的执行核心是一个两千多行的巨型 switch:每条指令从共享的 int 流里取操作码和操作数,按地址空间下标取 Variant。这篇拆这个循环的结构、分发成本模型,以及为什么不用 computed goto 和 JIT。
-
GDScript 编译管线:从 tokenizer 到字节码 VM
一行 print() 从源码文本到被执行,要经过 parser、analyzer、compiler 三段管线,最后变成 GDScriptFunction 里的 int 数组字节码。基于 4.2 源码拆解每个阶段产出什么。
-
signal 语法糖的展开:从 connect 到 emit,编译器帮你写了什么
signal 声明、.emit()、.connect() 三件套背后没有专用指令系统:声明进脚本的信号表,emit 编译成方法调用落到 Object::emit_signal,connect 生成一次性可调用对象。这篇把语法糖逐层剥掉。