avatar
Articles
415
Tags
259
Categories
26

Theqiqi_blog
Search

Theqiqi_blog

04-引擎组装
Created2026-08-10|架构|游戏•引擎组装
引擎组装——引擎有哪些子系统,怎么组装一句话 引擎本身是一个多子系统协作的系统,组装方式类似通信程序的网络系统:每个子系统有独立的生命周期和运行方式,由引擎统一调度;引擎负责「怎么运行」,不知道游戏规则。 一、引擎可能包含的子系统123456789101112引擎可能包含的子系统:├── 渲染系统 ← GPU 交互、Draw Call、渲染管线├── 物理系统 ← 碰撞检测、刚体模拟、约束求解├── 音频系统 ← 声音播放、3D 音效、混音├── 输入系统 ← 键盘/鼠标/手柄/触摸├── 资源系统 ← 加载、缓存、异步加载、引用计数├── 场景系统 ← 场景图、节点管理、摄像机├── 脚本系统 ← Lua/Python 绑定、脚本执行├── UI 系统 ← 控件树、事件处理、布局├── 动画系统 ← 骨骼动画、状态机、混合├── 粒子系统 ← 粒子发射、更新、渲染└── 网络系统 ← 同步、预测、回滚(游戏专用) ECS 只 ...
03-趣味设计
Created2026-08-10|架构|游戏•趣味设计
趣味设计——核心机制、反馈密度与受控自由一句话 「有趣」不等于「机制越多越好」,而更像是核心机制产生的反馈价值 × 玩家愿意持续接收这个反馈的成本。一个机制就是一台「趣味发生器」,关卡负责让玩家在受控自由里反复触发它。 游戏系统论把趣味浓缩成一句话(趣味 = 认知闭环的密度);本线展开 11 篇的完整内容:Bug 即机制、核心机制可探索、反馈密度、教学曲线、内容不完整与交互闭环、开发者疲劳与新手测试、第三关陷阱、AI 测试与玩法涌现、关卡设计公式、受控自由与甜点区。 一、为什么充满 Bug 的游戏反而有趣 会觉得它「有趣」,恰恰可能不是因为它做得好,而是因为它暴露出了游戏系统本身的趣味性。 即使角色、敌人、平台、金币全都像 Bug 产物一样乱七八糟,玩家仍然能够看懂:我是谁 → 我能怎么移动 → 什么东西会伤害我 → 什么东西可以收集 → 我要怎么到达右边。这说明游戏的核心乐趣并不完全来自画面。 趣味来源六因素 Bug 反而制造了「探索感」:正常游戏是「开发者设计规则 → 玩家学习规则 → 玩家利用规则」;Bug 游戏变成「玩家看到异常 → 猜测规则 → 尝试 → 发现 ...
02-游戏类型演化
Created2026-08-10|架构|游戏•游戏类型演化
游戏类型演化——赛车、马里奥、格斗、冒险格斗各自的演化流程一句话 游戏系统论讲通用演化(空窗口→方块→角色→关卡→完整游戏);本线讲具体游戏类型的演化分支——每类游戏的核心对象不同,演化顺序也不同:赛车先有世界和相机,格斗先有动作和判定,冒险格斗先让角色走起来再打起来。 一、四类游戏的核心演化区别1234赛车: 方块 → 车 → 赛道 → 驾驶 → 相机 → 比赛马里奥: 方块 → 角色 → 地面 → 地图 → 敌人 → 关卡格斗: 方块 → 角色 → 动作 → 攻击 → 判定 → 对战冒险格斗: 方块 → 角色 → 地图 → 动作 → 战斗 → 探索 → 成长 格斗游戏最重要的第一个「不是车也不是地图」,而是先让两个方块在屏幕上产生攻击和反馈。 冒险格斗最核心的开发顺序:先让角色在世界里走起来,再让角色打起来,最后让世界丰富起来。 二、赛车游戏赛道流式加载:近景赛道怎么做赛车游戏里「往前只有近景的赛道」通常不是把整条赛道提前建出来,而是采用动态加载 + 视野范围内生成的方式。 不是没有远处,而是不让远处作为高成本对象存在。 通常组合 ...
01-游戏系统论
Created2026-08-10|架构|游戏•游戏系统论
游戏系统论——从想法到引擎:一个游戏如何从零演化、建模、设计、组织 游戏开发不是「写一个 Game Loop」。它是一个完整系统:先有分析→设计的演化(想清楚做什么),再有实现的演化(从窗口到引擎一点点做出来);游戏世界是一个「实体+状态+规则+交互+时间演化」的模型;工程的推进遵循一条十二阶段的完整流程;而技术架构回答「对象是什么、谁负责运行、怎么计算、谁提供底层能力」。 四条线串在一起,就是游戏系统的完整图景。 一、两条演化:设计与实现的独立路线游戏开发不是一条线,而是两条演化同时在走: 12上层:灵感 → 核心玩法 → 玩法循环 → 设计 → 分析 → 技术 → 验证 → 迭代(先做什么)下层:窗口 → 方块 → 移动 → … → 物理/AI/UI/音频/存档(怎么从零做出来) 它们互相独立:想法不写代码也能演进,引擎没有玩法也能演进。真正的开发是两条线在可玩核心处汇合——围绕一个核心玩法(移动/跳跃/攻击)不断迭代,每加一个系统都反过来调整前面的设计。 一·A、设计演化:从灵感到技术设计的 12 阶段第 1 阶段:灵感(Idea)只有一句话,甚至没有 ...
06-工程目录的组织
Created2026-08-10|架构|模块与构建单元•工程目录的组织
工程目录的组织 前面几篇解决了「模块内部怎么构成」:功能函数 = 数据结构 + 算法 + 接口,模块 = 一个功能的完整组合。这一篇解决下一个问题:模块怎么组织成一个工程的目录? 答案不是「按技术分层堆目录」,而是「按功能组织模块,模块内部再按职责拆分」——并由此得到 Utils 与 Infrastructure 的判断标准、Core 层的定位,以及一套可以从需求一路映射到文件的大一统工程目录。 一、两种组织方式:按层堆目录 vs 按功能组织1.1 按层堆目录(错误示范)有人把「功能 = 算法 + 数据结构 + 接口」直接翻译成三个顶层目录: 12345678910Application├── UI├── ViewModel├── Service├── Domain├── Infrastructure├── Interface ← 所有接口├── Algorithm ← 所有算法├── DataStructure ← 所有数据结构└── Utils 问题在于:算法、数据结构、接口并不是一个功能,而是一个功能的三个组成部分。 一个 ...
05-模板-同功能不同类型的抽象
Created2026-08-10|架构|模块与构建单元•模板•同功能不同类型的抽象
模板:同功能、不同类型的抽象 封装解决了「很多地方做同一件事」的重复;但还有另一种重复——同一件事,只是类型不同。写十个几乎一样的函数,只因为参数是 int、float、string、结构体……模板把「类型」也变成参数,让一个函数覆盖所有类型。这是和原子化接口正交的另一条线。 一、先看一种被忽略的重复原子化接口线解决了这种重复: 12open(path); // 到处都是close(fd); 到处复制的是同一个调用。封装一次,处处复用。 但还有另一种重复,形态完全不同——同一段逻辑,参数类型不同: 1234567891011121314151617181920// 从文件偏移处读一个 intint32_t read_i32_at(int fd, size_t off) { int32_t v; if (pread(fd, &v, sizeof(v), off) != sizeof(v)) throw ReadError(); return v;}// 从文件偏移处读一个 float —— 函数体几乎一样float read_f32_ ...
04-从现实问题到数据结构
Created2026-08-10|架构|模块与构建单元•从现实问题到数据结构
从现实问题到数据结构 数据结构不是凭空发明的一堆容器名字。它是对现实问题的分析、抽象的产物:先有现实中的事物和关系,抽出共同结构,才落成数据结构。而且数据结构不止一种——领域数据(业务对象)、通用结构(Core)、平台数据(Infrastructure)是三类完全不同的东西,各有各的来源和用途。 一、数据结构从哪里来教材常按容器讲:数组、链表、栈、队列、树、图、哈希表……好像它们是独立存在的知识。 但它们其实是从现实问题里长出来的。每个数据结构背后都有一个现实场景在逼它出现: 1234567现实问题 抽象出来 数据结构──────────────────────────────────────────────────────一排人按顺序排队,先来的先服务 先进先出 队列一叠盘子,后放的先拿走 后进先出 栈点名册按学号排好,快速找某个人 编号 + 查找 数组 / 哈希表家族谱:父 → 子 → 孙 层级归属 树城市间的路 ...
03-算法类型与描述形式
Created2026-08-09|架构|模块与构建单元•算法类型与描述形式
算法类型与描述形式 算法不只是「一段逻辑」。不同类型的算法,表达重点完全不同:有的重点在执行步骤,有的在状态变化,有的在递归关系,有的在数学关系。表达形式必须匹配表达重点——流程图、状态图、递归树、公式推导各有适用场景。「一个算法必须有流程图」是错的,形式由类型决定。 一、从两个算法开始同样是「一个函数实现的算法」,二分查找和快速排序画成流程图,观感完全不同。 二分查找——重点是步骤: 123456789101112131415开始 ↓设置 left=0, right=n-1 ↓left <= right ? ├─ 否 → 返回 -1 └─ 是 → mid=(left+right)/2 ↓ a[mid]==target ? ├─ 是 → 返回 mid └─ 否 → a[mid]<target ? ├─ 是 → left=mid+1 └─ 否 → right=mid-1 ↓ 回到 left<=right 判断(循环) 流程图画 ...
02-接口先行
Created2026-08-09|架构|模块与构建单元•接口先行
接口先行——先设计接口,再写实现 接口有两种形态(函数导出 / 类封装)。但还有一个更深层的问题:接口应该先于实现存在吗? 接口先行的答案是「是」——先定义「能做什么」,再写「怎么做」。接口先行本身只需要函数声明与空实现就足够了;虚函数是另一个问题的产物——当多套接口(多套实现)同时存在时,运行时怎么决定调用哪一套。不要把两者混为一谈。 一、先有实现,后有接口最初的编程方式是先写实现,再给使用者看头文件: 1234567891011// 先写实现// search.cScanResult search_pattern(const uint8_t* data, size_t len, const uint8_t* pattern, size_t pat_len) { // 具体搜索算法}// 后有接口// search.hScanResult search_pattern(const uint8_t* data, size_t len, const ...
01-接口形态演化
Created2026-08-09|架构|模块与构建单元•接口形态演化
接口形态演化——状态决定接口形式 库或组件对外暴露接口,但接口有两种本质不同的形态:无状态的用函数导出,有状态的用类封装。这不是风格偏好,而是由「有没有状态」这个客观事实决定的。 一、函数导出:无状态的接口最简单的接口形式——导出一个函数: 123// math.hint add(int a, int b);double sqrt(double x); 调用者只需要知道函数名和参数,不需要知道内部实现。函数没有状态——每次调用都是独立的,不依赖上次调用的结果。 123调用者 → add(1, 2) → 3调用者 → add(3, 4) → 7两次调用之间没有任何关联 函数导出的特征: 1234✅ 无状态:每次调用独立✅ 无需初始化:直接调用✅ 无需生命周期管理:调用完就结束✅ 简单直接:调用者负担最小 函数导出的前提:无状态。 二、当状态出现需求变了——需要一个「搜索器」,它打开一个文件,在文件中搜索多次: 1234// 如果用函数导出:Searcher* searcher_open(const char* path);SearchResult searcher_find( ...
1…567…42
avatar
Theqiqi
Articles
415
Tags
259
Categories
26
Follow Me
Announcement
This is my Blog
Recent Post
03-反馈流2026-08-21
02-错误流2026-08-21
01-控制流2026-08-20
05-多系统协作的十条流2026-08-19
04-多层系统的十条流2026-08-18
Categories
  • C with Socks16
  • C_Sound10
  • C_Windows_Graphi9
  • Cpp5
  • Cpp_Socket4
  • C语言在Windows中实现抓包4
  • C语言的万种用法9
  • Debian1
Tags
十阶段 接口先行 Qt主题架构 WindowsDriver python 从输入到交互 select LinuxDriver 入口系统 UDP服务器与可靠性 微服务与组装边界 DLL javascript 多系统组成的网络通信软件 Piano 拆解资源 游戏类型演化 Kali 建模与逆向 BSD Sockets x86汇编程序 IPV4 Drvier 认知能力分解 技术流 qemu Ninja 业务流程到功能点 用头文件验证依赖 引擎组装 Sound 从状态到系统 epoll QEMU 依赖接口 shell 依赖关系 Graphi 拆解美术 只有组件的子系统如何被加载
Archives
  • August 2026128
  • January 20261
  • April 20251
  • March 202595
  • February 202523
  • September 20242
  • August 202471
  • June 20242
Info
Article :
415
UV :
PV :
Last Update :
©2020 - 2026 By Theqiqi
Framework Hexo|Theme Butterfly
Search
Loading the Database