自研、可自行编译的 Artemis Engine 兼容运行时:产出安卓 libartemis.so,
保留原有 JNI 导出和 NativeActivity 入口。Tyranor-Next 及原始 Android 壳的
接口要求、已知缺口和验证状态见嵌入指南。
开发约束:按文件格式、接口、标签语义和输入/输出行为定义兼容范围; 不复制或改写未经许可的第三方实现。不含 emote(M2 闭源中间件)等闭源组件, 不分发任何游戏资产;第三方代码按其许可证保留来源和署名。
目前实测游戏:《闪亮女友》 《常轨脱离Creative》 《常轨脱离Creative 凸》 《常轨脱离ReReCall》 《甜蜜女友3》
处于初期,希望各位能够参与建设,帮助完善。整个项目代码基于DeepSeek-V4f与Glm-5.3f产出。原谅我的囊中羞涩。
| 模块 | 能力 |
|---|---|
| 包层 | pf8 读取器 + 自动派生密钥(SHA1(file[7:7+index_size]),20B 周期 XOR)+ 多包补丁链(.000/.001/… 覆盖);链条未命中时回退读取包旁散装文件(movie/*.mp4 等,拒绝绝对路径与 ..) |
| 配置 | system.ini 全平台节(WINDOWS/ANDROID/IOS/WASM/SWITCH/PS4) |
| 脚本 | Lua 5.1.5 嵌入 + e 桥表;system/init.lua 启动链、adv 框架;.iet 解释器([lua]/标签/文本);可重入原生 .asb runner(ExecuteLine + 事件返回帧 + 脚本栈、跨文件 call/return);$ 表达式求值(32 位整数/比较/逻辑短路/位运算/字符串/变量引用);按键 override 与逐帧边沿派发;事件过滤器;auto-read |
| 文本 | 消息层 chgmsg/print/rt → stb_truetype 多行栅格化;按层 font rect + wrap 折行;对齐/描边;ruby 注音与横排基本禁则/悬挂;逐字入场与批量字形绘制;点击补全再推进;按层多页 |
| 图层 | lyc/lyprop/lydel/lyevent;z 按官方 spec/layer.md 图层 ID 排序;父子变换(位移 + 锚点缩放/旋转/翻转,逆矩阵命中测试);draggable/dragarea 拖拽;真实 lytween 补间与 trans 过渡(rule 阈值擦除 + vague 羽化);lyshader 移动端 GLSL 与中间层蒙版/裁剪 |
| 渲染 | GLES2 层合成器(stage 坐标 + SIDECUT letterbox 视口);保留场景 FBO 供过渡与截图;takess/savess 快照 PNG(原子替换);draw[] 层诊断日志 |
| 音频 | stb_vorbis 分块流 + OpenSL ES 播放器:BGM(循环)/SE/语音(splay/seplay/voplay);_a→_b 曲目接续;逻辑声道 + 定时增益/声像与交叉淡化(sfade/sxfade/sepan…);[wait se=]、setonsoundfinish;生命周期静音 |
| 视频 | **FFmpeg(可选)**解复用/解码:全屏或指定图层、循环、等待与取消键 |
| 存档 | Pluto 值图原生编解码;BOWS/1003 变量/图层日志与 BOWG 全局银行导入(经游戏 onLoad 恢复);save 写独立 ARCV 兼容检查点(原子写入 + 校验);场景 PNG 缩略图 |
| E-mote | PSB v2–v4(加密头、v2 指定 body 区间、宿主 seed)、MDF/zlib 与有限 lzfs LZ4 frame;RL/raw/CI8/DXT1/DXT3/DXT5/BC7、16bit(RGBA4444/5551/5650)/A8L8/RGBX8、mip 链(仅 level 0)、win/common 共享图集裁切;有限场景求值与 GLES 绘制(src/icon、motion 级 parameterize、帧色/priority、部分容器节点、stencil 标签与 stage alpha mask、有限网格形变);EmotePlayer + Lua 代理支持变换/tint/灰度、变量、自动眨眼/选择器/attrcomp 移除、时间轴淡入淡出/blend 及几何命中。并非完整 SDK;具体证据、未知项与不实现边界见能力说明 |
| 输入 | 归一化键事件(isDown/isPush/isDecide/边沿)、触摸/tap、slider 拖拽、事件过滤器 |
| JNI | 六接口导出 + ANativeActivity + DebugBridge.nativeInstall 引导 |
| 日志 | OutputLog(level,msg) → Artemis tag / stderr;宿主 SetLogSink 次级输出钩子;tag[trace] 便于移植排障 |
依赖:CMake ≥ 3.16、C++17 编译器、zlib(存档/PSB/截图)。FFmpeg(libavformat/ libavcodec/libavutil/libswscale/libswresample)为可选项——未找到时视频解码编译为桩。
cmake -B build-host -DCMAKE_BUILD_TYPE=Release
cmake --build build-host -j8合成夹具(自绘矩形字体 + 生成音调),不含任何商业游戏资源:
cmake -B build-test -DCMAKE_BUILD_TYPE=Release -DARTC_BUILD_TESTS=ON
cmake --build build-test -j8
ctest --test-dir build-test --output-on-failureCocoa 窗口 + legacy OpenGL 2.1 上下文,用真实 GL 渲染运行游戏。GLES2 入口与
GLSL ES 源码在 src/render/gles2_headers.h / src/render/shader_compat.h 中适配到
桌面 GL。该目标把核心以 ARTC_HAS_GLES 重新编译;artemis_core(CLI/回归)保持
无 GL 的数学实现,二者互不影响。
cmake -B build-mac -DCMAKE_BUILD_TYPE=Release
cmake --build build-mac --target artemis-mac -j8
./build-mac/artemis-mac "/path/to/game" # 目录或 root.pfs;默认 --os windows鼠标左键=点击/拖拽,方向键/回车/退格/Esc 映射官方 key id。
NDK=$HOME/Library/Android/sdk/ndk/<version>
cmake -B build-android \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-21 \
-DARTC_BUILD_JNI=ON -DARTC_BUILD_CLI=OFF
cmake --build build-android -j8
# 产物: build-android/libartemis.soartc list <pack> [--key <hex>] # 列出包内文件(不传 key = 自动派生)
artc verify <pack> # 抽验首文件解密魔数
artc ini <pack> system.ini # 打印包内 ini
artc extract <pack> <name> [-o out] # 抽取单个文件
artc runlua <pack> system/init.lua # 试运行启动脚本
artc runiet <pack> <script> # 运行 iet 剧本
artc asb <pack> <name> # 解码编译脚本
artc drive <pack> --frames N --tap x,y@f # host 帧循环驱动器(注入触摸复刻移动端)| 包 | 结果 |
|---|---|
闪亮女友 root.pfs(安卓) |
真机可玩闭环:标题→故事→台词(坐标/折行)→点击推进→CG 切换→BGM/语音/SE 出声 |
RealHentaiSituationDT reaanidt.pfs(PC,1047 文件) |
自动派生 ✓;ini 全平台节干净;148 个 .ast 多语言行格式完整解码 |
カラーマリス main.16.*.obb(Android OBB,829 文件) |
自动派生 ✓;TTF/JPG 魔数全对 |
把 build-android/libartemis.so 放入官方模板 app/src/main/jniLibs/arm64-v8a/(替换官方库),
并在入口调用:
com.ies_net.artemis.debug.DebugBridge.nativeInstall(
getExternalFilesDir(null).getPath(), // 数据目录(pf8 包所在)
null); // 密钥 hex;null = 自动派生
nativeInstall是本项目自有的引导入口(官方 jar 之外的附加类,随本项目提供)。
原生 [dialog] 输入框(主人公取名等)由 src/jni/java/com/ies_net/artemis/debug/NativeInput.java
提供:把该文件一并放入 app 模块(与 DebugBridge 同级包路径)即可。缺少它时 [dialog]
会被当作取消,游戏改用默认名继续(不会卡死)。
- E-mote 非完整 SDK 等价:有有限网格形变、部分模板/容器遍历与 stencil alpha mask 合成,但不保证任意模板实例化、所有 stencil 模式、复杂继承/深度/混合或独立阴影/光照模型;帧曲线
zcc/ccc/cc仅接受、不应用,粒子/物理未实现。多文件 PSB 仍拒绝,ETC1/PVRTC 仍不支持 - E-mote 加密仅覆盖上述 PSB/seed 路径,不保证任意整包结构过滤或
EmoteFilterTexture纹理 callback 等价;lzfs不支持字典、链接块及拼接帧。差分变量、flags/Pass/Step 的官方语义,复杂模型视觉、真实游戏命中与当前源码设备矩阵仍待验证;不能由已有合成测试或历史冒烟宣称 E2/E3/E7/E9/E14/E16 全部完成 - E-mote 控制元数据已恢复多项官方 normal-path runtime 消费者,但静态归属确认不等于项目实现:transition/immediate/clamp/eyebrow/mouth/orbit/profile 及三个精确 face 默认名的项目支持与未知算法分开排期(其中 transition/immediate/orbit/profile 已接入,clamp/eyebrow/mouth 未实现),不能由眨眼/选择器/attrcomp 三项代表齐全。
CalcLayerFrameInfo不向 Lua 暴露且 native 输出结构未知;serialize/unserialize按需延期,自有onLoad不保证表情/timeline/blend 精确恢复,也不证明所有游戏均无需求。见逐键证据与排期 - E-mote 当前进度见验收账本,全计划(E1–E17)未全部完成:ordered pair/getter、mirror 三态(有效 = metadata XOR 用户状态,
setMirror为项目扩展)、flags/Step/Skip/Pass、独立setQueuing/getQueuing已有实现与合成回归,PlayingTimelineFlagsAt仍返回 stored flags(官方为|1,未改);有效 Z 通道、完整 affine + shape leaf、meshSync 有限作用域、meshCombinator 与同域 meshCombine 已接入。低位 sync、cc、屏障 anchor 补偿、异域等降级加载并记录 UnsupportedFeatures(不应用,非已支持);真实 132 个 fg 模型的 Load 全部成功仅是加载级观察,仍非完整模型/官方兼容验收 - 固定官方 Android 样本的 Lua 表不注册 skipToSync/contains/hitTest(仅 isAnimating);项目
contains/hitTest是自有扩展。旧 SyncFrame/C++ SkipToSync 仅为 legacy 扩展,官方 native 使用 motion.tag sync 查询/lastTime fallback、独立 eventwait,不能照搬三来源结束优先级;TagSync 只读查询(NextMotionSyncFrame)已实现,Lua 不注册,真实等待流程未验,见静态证据边界 - E-mote 格式/行为证据见格式证据。E10 的 transition/immediate/profile/orbit 已接入模型/播放器(有限、合成回归);clamp、stereo、eye edge、eyebrow nodes、mouth shape 未实现。当前本机合成与构建时点:
build-test28/28、build-cgl30/30(compositor 回归连续 5 次通过),build-mac/build-android/build-consumer/build-consumer-android构建通过,Android 12 个入口导出检查通过——这些不代表游戏、设备或官方一致,导出/链接不等于 JNI 行为兼容 - E-mote 增量(分层,见验收账本“增量补记”):读档后 783 层场景 Mac 自研内核约 11→58fps(不带快照区间,单机观察;惰性 id 索引 + 变换记忆,回归
compositor_index_regressions),EmoteScene::Load约 4.2s→约 50ms;蒙版缓存缺陷已修;眨眼闭眼帧不绘制shirome中段 type-0 是由资产结构推断的语义,无官方静态证据。手机官方内核 save0001 对照仅为 say_6 同场景不同帧的视觉一致观察(shi_36 未对照、0138 未闭环),不是同变量同帧逐像素验收;Android 宿主合同实机验收与插件重新构建发布(TyranorNext 内仍为旧 v29)未完成 - E14:Mac 读档复现(
artemis-mac --os android --save-dir <隔离目录> --tap … --snapshot …,标题约第 1500 帧才可交互)与隔离采集工具已就绪;标题 1200 帧 exit0 无立绘,newgame 2600 因取名 modal 超时,未通过流畅游戏/完整矩阵验收;Mac 真实游戏已观察到自动眨眼并拍到完整闭眼帧(见主计划顶部“增量补记”;不等于官方逐像素一致) - 仍缺:官方内核同状态逐像素对照(手机,进行中)、0138 闭环、Android 宿主合同(官方壳与 Tyranor-Next 各自 Activity/插件)验收、插件重新构建发布(Tyranor-Next 内
libartemis-clean.so仍是旧版本,需更新 manifestpluginVersion);E6 真实 v2 body 样本、E7 拆分样本、E8 移动端压缩格式样本缺;E13 不启动(无 Windows 运行环境) - 原版任意 VM 状态快照、BOWS/BOWG 双向写出、内嵌截图导入(自身 ARCV 检查点已可重启回读)
- HLSL 仅覆盖已验证游戏用到的 Artemis 运行时子集(register sampler、
ps()、tex2D、常用内建),非通用 D3D HLSL 编译器 - 混合字体/嵌套样式、竖排、复杂 ruby 分配与完整字形塑形
.050+.051…巨大数据卷(pf6旧代格式)读取器(pf2/明文 PF6 布局已支持)- 密钥派生算法为独立课题;个别标题自定义魔数/密钥不在自动派生范围
- 本仓库源代码(
src/、CMakeLists.txt、docs等):GNU GPL v3(见LICENSE) third_party/lua-5.1.5:MITthird_party/stb_vorbis/stb_vorbis.c:public domain / MIT(见文件头)
部分引擎行为修补与新增模块(音频分块流/声道、图层变换与补间、表达式求值、文本
/ruby、存档、视频、GLSL、E-mote 基础)吸收自 NextScene
对 artemis-compat 的 vendor 修补(其 cpp/artemis/upstream/UPSTREAM.md)。
GPL 不涵盖第三方组件——各组件按其自身许可分发(见 THIRD_PARTY_NOTICES.md)。
不含任何游戏资产、官方二进制或按标题的密钥。
src/
pack/ pf8 读取器 + 多包链 + 散装文件回退 · PSB/MDF
config/ system.ini 解析
script/ Lua 引擎 + iet/asb 解释器 · 表达式 · Pluto 编解码
· 原生存档(BOWS/BOWG/ARCV) · 输入状态 · auto-read
render/ GLES2 合成器 + stb_truetype 文本 · 补间/过渡 · ly shader
· 快照 PNG · 视频解码/播放(FFmpeg 可选)· E-mote(PSB/场景/播放器)
audio/ 声道混音 + Vorbis 分块流 + OpenSL ES 播放器(host 为桩)
log/ OutputLog 管线 + 宿主 sink
jni/ Android JNI 六接口 + ANativeActivity
cli/ artc 宿主工具
host/ macOS 原生宿主(Cocoa 窗口 + GL)
tests/ 宿主回归(合成夹具)
third_party/ lua-5.1.5 (MIT) · stb_vorbis (public domain)