# SurvivalcraftSuAPI **Repository Path**: SC-SPM/survivalcraft-su-api ## Basic Information - **Project Name**: SurvivalcraftSuAPI - **Description**: Survivalcraft 2 SuMod 开发框架,用于创建第三方 Mod。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-10-02 - **Last Updated**: 2026-05-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Survivalcraft MAUI 移植指南 > 版本: 2.4.10.8 > 目标框架: net10.0-android + net10.0-windows10.0.19041.0 > 公开仓库: https://gitee.com/SC-SPM/survivalcraft-su-api ## 项目结构 ``` P:\UGIT\Survivalcraft\ ├── Engine/ # 引擎库(MAUI class library) │ ├── Graphics/Bindings/ │ │ ├── GL.cs # Android DllImport 实现 (#if !WINDOWS) │ │ └── GL.Windows.cs # Windows Silk.NET.OpenGL 代理 (#if WINDOWS) │ ├── Input/ │ │ ├── Mouse.cs # 鼠标输入(含 PollMousePosition 轮询) │ │ ├── Keyboard.cs # 键盘输入 │ │ ├── Touch.cs # 触摸输入 │ │ └── GamePad.cs # 手柄输入 │ ├── Platforms/ │ │ ├── Android/ │ │ │ ├── Input/ # Touch, GamePad, Mouse, Keyboard │ │ │ ├── EngineActivity.cs # Android Activity(Dispatch 输入路由) │ │ │ ├── Window.cs # Silk.NET 窗口 + GLES 2.0 上下文 │ │ │ └── Valve.VR/ # VR 支持(仅 Android) │ │ └── Windows/ │ │ ├── Input/ # Keyboard, GamePad, Touch, KeyboardInput │ │ ├── Window.cs # Silk.NET 窗口 + GL 3.2 上下文 + 鼠标事件 │ │ ├── Storage.cs # WinRT Storage API │ │ └── Utilities.cs # WinRT 工具类 │ ├── Audio/ # OpenAL 绑定(条件编译库名) │ └── Engine.csproj # Microsoft.NET.Sdk + 平台条件编译 ├── EntitySystem/ # 实体系统库 │ ├── GameEntitySystem/ # 游戏实体系统 │ ├── TemplatesDatabase/ # 模板数据库 │ ├── XmlUtilities/ # XML 工具 │ └── Platforms/Android/ # Android 平台文件 ├── Survivalcraft/ # 游戏主程序(MAUI app) │ ├── Game/ # 游戏逻辑 │ ├── SimpleJson/ # 内置 JSON 库 │ ├── Platforms/ │ │ ├── Android/ │ │ │ ├── Game/ # Android 平台游戏代码 │ │ │ └── Valve.VR/ # VR 支持 │ │ └── Windows/ │ │ └── Game/ # Windows 平台游戏代码 │ ├── Resources/ # Content.pak 等嵌入资源 │ │ ├── AppIcon/appicon.png # SC 应用图标 (144×144) │ │ ├── Splash/splash.png # SC 启动画面 │ │ └── Images/ # 图片资源 │ ├── Resources.icon.ico # Windows exe 图标 (9256B) │ └── Survivalcraft.csproj # MAUI 应用 + 版本信息 └── doc/ # 项目文档 ``` ## 编译 ### 前置条件 - Visual Studio 2022 (18.x Enterprise) - .NET 10.0 SDK - MAUI 工作负载 - Android SDK (API 21+) ### 编译命令 **⚠️ 必须使用 MSBuild,禁止 `dotnet build`**(与 Engine.csproj 不兼容) ```powershell $msbuild = "d:\Program Files\Microsoft Visual Studio\18\Enterprise\MSBuild\Current\Bin\MSBuild.exe" # Windows & $msbuild "P:\UGIT\Survivalcraft\Survivalcraft\Survivalcraft.csproj" ` -t:Build -p:TargetFramework=net10.0-windows10.0.19041.0 -v:minimal # Android & $msbuild "P:\UGIT\Survivalcraft\Survivalcraft\Survivalcraft.csproj" ` -t:Build -p:TargetFramework=net10.0-android -v:minimal ``` ### 版本信息 ```xml 2.4.10.8 2.4.10.8 24108 com.candyrufus.survivalcraft2 ``` 游戏内版本号由 `VersionsManager.Version` 从程序集版本自动读取,格式 `Major.Minor.Build.Revision`。 ⚠ `ApplicationDisplayVersion` 不能按平台条件设置——会导致 NU1105 `PackageVersion` 不一致错误。必须用统一的 `` 属性。 ## 条件编译 | 符号 | 定义条件 | 用途 | |------|---------|------| | `WINDOWS` | net10.0-windows 目标框架 | GL.Windows.cs, Window.cs, 库名选择 | | `ANDROID` | net10.0-android 目标框架 | EngineActivity, Touch, 库名选择 | **WINDOWS 由框架自动定义**;ANDROID 需在 csproj 中手动添加 ``。 ## OpenGL 绑定 ### 双平台架构 | 平台 | 实现文件 | 方式 | GL 上下文版本 | |------|---------|------|-------------| | Android | `GL.cs` (`#if !WINDOWS`) | DllImport `libGLESv2` | GLES 2.0 | | Windows | `GL.Windows.cs` (`#if WINDOWS`) | Silk.NET.OpenGL 代理 | GL 3.2 | ### Windows 端为什么不能 DllImport `opengl32.dll` 只导出 GL 1.1 核心函数。`glCreateShader` 等 GL 2.0+ 函数必须通过 `wglGetProcAddress` 动态获取函数指针,DllImport 不支持此机制。Silk.NET.OpenGL 自动处理扩展加载。 ### 枚举映射 | Engine 枚举 | Silk.NET 枚举 | |-------------|--------------| | EnableCap | GLEnum 强转 | | ClearBufferMask | **uint**(特殊,非 GLEnum) | | BufferTarget | BufferTargetARB | | BufferUsageHint | BufferUsageARB | | FramebufferSlot | FramebufferAttachment | | ProgramParameterName | ProgramPropertyARB | ### 铁律 1. **opengl32.dll 只有 GL 1.1** — GL 2.0+ 必须 Silk.NET 2. **Clear() 接受 uint** — `G.Clear((uint)mask)`,其他大多数用 `(SGLE)cap` 3. **int↔uint 中转** — Gen/Delete 系列用 `stackalloc uint[]` 4. **ShaderSource 差异** — Silk.NET 接受 string,Engine 用 string[]+int* 5. **NativeLibrary resolver 不可行** — 函数级解析不走 resolver 6. **GLES 上下文版本必须显式指定** — `new APIVersion(2, 0)`(Android)/ `new APIVersion(3, 2)`(Windows) ## 输入系统 ### Windows 鼠标输入 **核心问题**:游戏从 Android 移植,Mouse.cs 的 `SetMousePosition`/`BeforeFrame` 均为空方法。Android 不需要隐藏系统光标,Windows 第一人称模式需要。 **修复架构**: ``` Silk.NET IMouse.Position (轮询) │ BeforeFrameAll() │ Mouse.PollMousePosition(pos) ├── MouseMovement = pos - m_pollLastPosition └── MousePosition = IsMouseVisible ? pos : null Silk.NET IMouse 事件 (MouseDown/Up/Move/Scroll) │ Window.OnSilkMouseXXX() │ Mouse.ProcessMouseXXX() ├── ProcessMouseDown/Up → 按钮状态 ├── ProcessMouseMove → MousePosition (UI光标) + MouseMove 事件 └── ProcessMouseWheel → MouseWheelMovement (累加) BeforeFrameAll → CursorMode 切换 IsMouseVisible=true → CursorMode.Normal (系统光标可见) IsMouseVisible=false → CursorMode.Raw (隐藏+原始输入) ``` **为什么用轮询而非纯事件**:CursorMode.Raw 下光标锁定在窗口中心,MouseMove 事件传的 position 可能始终在中心附近不变。轮询 `IMouse.Position` 则使用 Silk.NET 内部维护的位置(在 Raw 模式下通过 WM_INPUT delta 累加),值正确。 **DLL 搜索注意**:.NET DLL 元数据用 UTF-8 编码存储标识符,不是 UTF-16LE。用 `[Encoding]::Unicode.GetString()` 搜索会找不到。 ### Android 输入 详见参考仓库的 Android 输入文档。核心架构: - Dispatch 级别路由(非 On 级别) - ConcurrentQueue 线程安全缓冲 - 源过滤(InputSourceType 位掩码) - BeforeFrame 批量消费 ### TranslateKey 修复 `Engine\Platforms\Windows\Input\Keyboard.cs` 中 `TranslateKey` switch 表达式无 default 分支。必须返回 `Key?` 加 `_ => null`,调用方用 `.HasValue` 检查。 ## 运行时目录 ### Windows ``` Survivalcraft\bin\Debug\net10.0-windows10.0.19041.0\ ├── Survivalcraft.exe ├── Engine.dll ├── EntitySystem.dll ├── Content.pak ├── Mods/ # Mod 放置目录 └── Logs/Game.log ``` ### Android ``` APK: Survivalcraft\bin\Debug\net10.0-android\com.candyrufus.survivalcraft2.apk 运行时根目录: /data/data/com.candyrufus.survivalcraft2/files/Documents/ 日志: .../files/Documents/Logs/Game.log ``` ## 常见陷阱 | 问题 | 根因 | 修复 | |------|------|------| | NU1105 PackageVersion 不一致 | ApplicationDisplayVersion 按平台条件设置 | 统一 `` 属性 | | NETSDK1022 重复编译项 | 平台文件未 Compile Remove | 先 Remove 再条件 Include | | Content.pak 找不到 | RootNamespace 不匹配 | 改回 `Game` | | 鼠标视角不动/极慢 | CursorMode.Raw 下事件 delta 极小 | PollMousePosition 轮询 | | SwitchExpressionException | TranslateKey 无 default | 返回 Key? + _ => null | | Debug.WriteLine 卡顿 | 每帧输出 | 禁止热路径中写日志 | | InlineArray 残留 | 反编译器生成 | 改为普通 string.Format | | Lit.psh/vsh 加载失败 | 被识别为立陶宛语卫星程序集 | `false` | | 静态 UnlitShader 崩溃 | GL 上下文未就绪时类初始化 | lazy-loading GetShader() | | Windows 窗口无图标 | GLFW 不自动继承 exe 图标 | SendMessage(WM_SETICON) + LoadImage fallback | | MAUI 模板图标残留 | 新项目未清理 SVG + dotnet_bot | 删除 SVG 替换为 PNG + 修改 csproj | | WinUI 语言文件夹膨胀 | SatelliteResourceLanguages 不控制 .mui | Build Target PowerShell 删除 | | GLES 1.1 SIGSEGV | APIVersion() 默认 (0,0) | 显式 `APIVersion(2, 0)` | ## 参考文档 - [PROJECT-LOG.md](PROJECT-LOG.md) — 详细修复日志 - [OPENGL-BINDING.md](OPENGL-BINDING.md) — OpenGL 绑定详解 - 公开仓库: https://gitee.com/SC-SPM/survivalcraft-su-api