CorsixTH让1997年的医院模拟游戏跑上4K屏的开源引擎【免费下载链接】CorsixTHOpen source clone of Theme Hospital项目地址: https://gitcode.com/GitHub_Trending/co/CorsixTHCorsixTH 是 1997 年 Bullfrog 商业模拟游戏《Theme Hospital》的完整重写实现解决的核心问题是 DOS 时代游戏在现代操作系统上的兼容性。技术路线一句话C/SDL2 写引擎负责图形、音频和原版专有资源格式全部游戏逻辑放进 Lua 脚本引擎保持薄逻辑可整体替换。为什么 1997 年的游戏需要一个重写引擎动机不是情怀是三个具体的技术死结原版基于 DirectDrawWindows 旧图形 API和专有加密资源在 Win10/11 上只能靠运气启动且画面锁死 640x480原版数据是私有格式.tab/.pal/.dat外加自研的 RNC 压缩——原版用来压缩游戏数据的私有算法没有任何公开的修改接口原版代码已停更二十余年社区想要的新功能只能等风来。对比一下三条路维度原版1997DOSBox 式模拟CorsixTH引擎维护现状停更 20 年只维护模拟器本体游戏零改动持续维护Linux/Windows CI 双平台跑测高分辨率与 UI 缩放锁死 640x480拉伸放大像素糊1080p/4K 原生 UI 缩放Mod 改造成本不可能不可能内存级修改直接改 Lua 脚本原版数据依赖必需必需同样必需版权原因引擎不打包游戏资产注意最后一行它不是更干净的复刻而是更干净的引擎——图形、声音全部仍来自原版光盘这一点后文会再提。5 行命令完成构建与启动构建走 CMake仓库自带 CMakePresets.json 预配置开发向的linux-devpreset 默认开启源码目录读资源、Catch2 单元测试和 sanitizer。完整路径git clone https://gitcode.com/GitHub_Trending/co/CorsixTH # 拉取源码 cd CorsixTH cmake --preset linux-dev # 一条命令带上 Ninja 生成器、测试与调试开关 cmake --build build/dev -j4 # 编译 C 引擎产物在 build/dev/ 下 ./build/dev/CorsixTH # 启动首次运行要求指向原版游戏数据目录没有原版数据会直接卡在启动前——这是硬依赖不是提示。跑起来后主菜单按屏幕分辨率自动挑选资源CorsixTH/Bitmap/目录里备有 480/720/1080 三套菜单位图这是它支持高分屏的直接证据。内部怎么搭的事件泵与 tick 心跳整套架构可以概括为两层心跳C 负责事件泵把 SDL 的输入、定时器、帧回调逐一喂给 LuaLua 的World负责模拟心跳推进游戏时间。C 侧的主循环在 CorsixTH/Src/sdl_core.cpp关键设计是每个回调是否触发重绘由 Lua 函数的返回值决定引擎本身不判断游戏状态——if (do_timer) { last_dispatch dispatch_timer; push_app_dispatch(L, last_dispatch); int res lua_pcall(L, 2, 1, -4); if (res ! LUA_OK) { std::fprintf(stderr, Error in timer callback: %s\n, lua_tostring(L, -1)); } do_frame do_frame || (lua_toboolean(L, -1) ! 0); lua_pop(L, 2); } if (do_frame || !fps.limit_fps) { last_dispatch dispatch_frame; do { if (fps.track_fps) { fps.count_frame(); } push_app_dispatch(L, last_dispatch); int res lua_pcall(L, 2, 1, -4);注意两处lua_pcall是带错误保护的调用Lua 抛错不会把引擎打崩只打印到 stderr以及do_frame的或累积——任何一个回调认为画面变了本帧就重绘。Lua 侧的入口是 CorsixTH/Lua/app.lua 的App:onTick约 1282 行它把 tick 分发给world和ui真正的模拟推进在 CorsixTH/Lua/world.lua 的World:onTick约 909 行。构造函数里tick_rate 3、hours_per_tick 1也就是说每个 tick 对应游戏内一小时几天后发工资这类时间逻辑全部建立在这个节拍上for i 1, self.hours_per_tick do self.anims:tick() for _, hospital in ipairs(self.hospitals) do hospital:tick() end -- A patient might arrive to the player hospital. local spawn_count self.spawn_hours[self.game_date:hourOfDay() i - 1] if spawn_count and self.hospitals[1].opened then for _ 1, spawn_count do self:spawnPatient() end end for _, entity in ipairs(self.entities) do if entity.ticks and not entity.to_destroy then self.current_tick_entity entity entity:tick() end end self.map:onTick() self.ui:onWorldTick() self.dispatcher:onTick() end按小时查spawn_hours表决定来多少病人再统一驱动实体、地图和 UI——数据流到这里一目了然。整体依赖关系如下节点均为真实文件Lua/下 80 余个脚本共用一套自研类系统 CorsixTH/Lua/class.lua它用 metatableLua 的元表机制可理解为给表挂上继承和构造规则实现class Name (Superclass)语法文件头注释里有一句值得玩味的话C code does not use this file, but does use the same syntax——连 C 侧的持久化层都沿用同一套实例化约定序列化逻辑才能无缝工作。拿到手能改什么Lua 是 Mod 的主战场扩展点几乎全在 Lua 层改动不需要碰 C。以疾病为例CorsixTH/Lua/diseases/ 下 35 个文件每个疾病就是一张纯数据表disease.id bloaty_head disease.name _S.diseases.bloaty_head.name disease.cure_price 850 disease.contagious false disease.diagnosis_rooms { general_diag, x_ray, cardiogram, scanner, } disease.treatment_rooms { inflation, } disease.requires_machine true先去哪几个科室确诊、再去哪个治疗室、治愈费多少全部声明式表达新增一个疾病就是照这个模板加一个文件。同级的rooms/23 种房间、objects/机器、家具、门、humanoid_actions/29 个行为状态机文件走路、排队、呕吐都是其中一项都是同样的一文件一实体组织方式。除此之外还有四类入口本地化Lua/languages/20 余种语言文件缺译或旧译都可以补README 明确点名需要更新翻译自建关卡与战役Levels/、Campaigns/存放 .map/.level 数据游戏内置地图编辑器CorsixTH/Lua/dialogs/resizables/map_editor.lua仓库里另有 Java 写的独立关卡工具LevelEdit/分析工具链CMake 选项BUILD_ANIMVIEW产出动画查看器BUILD_TOOLS产出 tools/rnc/rnc_decode_cli.cpp 的命令行解码器专门用来研究原版 RNC 数据贡献流程CONTRIBUTING.md 要求 PR 标题带状态标签WIP/RFC/无标签即 Ready合并时再打类型标签PR:Feature、PR:Bugfix、PR:Translation 等新手可从 Good First Issue 起步。测试分 C 的 Catch2 用例CorsixTH/CppTest/和 Lua 的 spec 文件CorsixTH/Luatest/spec/两套。它没做到什么官方缺失清单README 的 Whats missing 一节很坦诚挑四条最实质的多人/局域网没有。代码层面也能看到痕迹world.lua里患者生成处硬编码self.hospitals[1].opened旁边就挂着TODO: Multiplayer support注释AI 医院是空壳。world.lua构造函数里创建AIHospital时标注 Right now theyre only names——对手医院目前只有名字不实际经营原版动画有缺口Pregnancy、Alien DNA、女性 Fractured Bones 三类患者缺少完整原版画集开启常规刷人设置后可能出现动画异常这是受制于原版资源而非引擎能力部分物体与墙体存在穿插 glitchREADME 原样列出未修。还有一个贯穿始终的取舍引擎不打包任何游戏资产每位玩家必须自备原版数据。这既是被版权逼出来的也意味着完整可运行永远比开源项目常规要求多一道门槛。收尾回到开头那个问题一个停更二十多年的 DOS 游戏为什么今天能在 4K 屏上完整跑通整个战役答案不在原版引擎有多好而在于 CorsixTH 把不可改的部分图形格式、原版资产隔离进 C 兼容层把可改的部分全部游戏规则搬进了 Lua——引擎薄逻辑厚所以它既跑得动 1997也改得动明天。【免费下载链接】CorsixTHOpen source clone of Theme Hospital项目地址: https://gitcode.com/GitHub_Trending/co/CorsixTH创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考