From 13042afb3a184892f751513dc7097c68e2bc5ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=A8=E8=90=BD=E5=9F=BA=E5=9B=B4=E8=99=BE?= <3161880837@qq.com> Date: Thu, 30 Jul 2026 22:30:04 +0800 Subject: [PATCH] docs: add project development specification document create the full SPEC.md with directory, naming, code sorting rules and best practices --- SPEC.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 SPEC.md diff --git a/SPEC.md b/SPEC.md new file mode 100644 index 0000000..58cacaf --- /dev/null +++ b/SPEC.md @@ -0,0 +1,70 @@ +# 开发规范 + +注意:**本项目是godot46创建的,虽说附近版本号可以向下兼容,但是最好不要改编辑器版本。** + +## 目录该放什么 + +- components/ 游戏中的所有场景,除了world主场景,不要有其他场景散在工作区里 + - Abstracts/ 抽象场景,虽然说godot的场景不能抽象但是看做抽象! + - Bullets/ 子弹,其下所有场景都继承于BaseBullet + - Characters/ 角色,其下所有场景都继承于BaseCharacter + - Interactables/ Menus/ 同理 +- resources/ 资源文件,注意.tres .res不属于资源,这里更应该说是assets,就是Unity生态里的资产概念,就是媒体(图片、视频、音频)、字体、骨骼 +- scripts/ 所有脚本,不要把脚本散在工作区 + - Content/ 游戏内容的高层实现,比如交互体、角色等的AI + - Statemachine/ 状态机,不一定是某个模式FSM或者UtilityAI才算 + - Abstract/ 抽象对象,但不一定是抽象类,比如说所有“角色”都有的复用代码 + - BaseXXX.gd 比如BaseCharacter BaseMenu + - Component/ UI组件的状态机 + - Data/ 继承RefCounted的类,就是纯数据不和引擎交互 + - Struct/ 数据结构,但和Statemachine/Data不同,指的是可以作为游戏内容但是本身不参与节点树,也没有状态机说法的数据 + - Util/ 这个就是工具类了 + - [T].gd 类名就是class_name [T]Util,仅静态类,提供一些最底层的工具,比如随机从数组里选择 + - Manager/ 管理器,一般要和节点树交互,也可以不交互 + - [T]Manager.gd 类名就是class_name [T]Manager,只能继承Node(或者不继承),不能更深,否则请作为Statemachine + +## 命名规范 + +1. 对于一切符号,用小驼峰命名法,就是写js用的那种,常量除外,采用全大写 +2. 对于游戏内容[T extends Character|Bullet|Menu|...],其行为脚本的类名写成“内容名+[T]”,比如角色A的类名就是ACharacter +3. 对于节点,场景根节点写大驼峰,下面的树写小驼峰 +4. 对于资源文件,用连字符命名 +5. 对于脚本文件,大多数情况下可以直接写类名,但是游戏内容`[N][T]`也可以写成N.gd +6. 对于着色器文件,用小驼峰写清楚实现的特效是什么 + +## 代码排序规范 + +### 对于行为类 + +1. extends +2. class_name +空行 +3. @export +空行 +4. @onready +5. 普通var +空行 +6. 节点的虚方法_ready、_physics_process等 +空行 +7. 抽象方法(或者对基类抽象方法的实现) +空行 +8. 工具方法(但不是工具类里的底层方法!!!是这个对象的高层实现,比如BaseCharacter里的getHealthPercent方法,而不要在这个类里写getRandomInt) + +### 对于管理器 + +如果这个管理器是一个Node而且是单例,推荐写一个static var instance: XXManager,然后在ready时赋值,注意单例类不要写其他静态变量 + +1. extends Node +2. class_name +空行 +3. static var instance +空行 +4. 其他变量 +空行 +5. 方法 + +## Best Practice + +1. 所有直接继承Object或者没写继承的类不许去new,要么就继承RefCounted,不然会内存泄漏 +2. 游戏对象的分类有很多,比如说角色A就写一个场景A.tscn,脚本就是A.gd,class ACharacter extends BaseCharacter(这个只是伪代码,建议写成一个单独的文件) +3. 比如玩家的技能(Skill),应该放在Struct里写成Skill.gd,类名BaseSkill,因为这个类只负责表示玩家的技能卡对应的行为,并不耦合于节点树和角色的行为类