⚠️ WARNING: At most cases it’s not allowed to redistribute modified package files without owner’s consent! And also, this note will only give general advice, and NOT focus on any specific game.
NOTE: At most cases it’s a better idea to run your games with wine in Linux or macOS.
https://github.com/krkrsdl2/krkrsdl2 is an open source implementation of the krkr engine.
Why bother use this? There are always some people (including me) unsatisfied with visual novels which support Windows only. Running a full Windows virtual machine is always a challenge for low-memory (≤ 8GB) devices. And although wine is going great recent years, it requires a lot of 32-bit components and is somewhat energy-consuming when running these games. There should be a better solution, isn’t it?
https://github.com/UserUnknownFactor/krkr-xp3 works well with unencrypted xp3 package. It’s written in Python and thus cross-platform.
python -m xp3.xp3 -u ~/path/to/game/data.xp3 exported_folder_name
See https://github.com/krkrsdl2/kag3/tree/krkrsdl2/data
As krkrsdl2 does not implement MenuItem
, MenuItem_stub.tjs
, font.ttf
** and startup.tjs
** are required to be placed in unpacked root folder.
*: There was an implementation for macOS Cocoa (https://github.com/krkrsdl2/krkrsdl2/pull/12‣), but it got removed in main
branch.
**: Krkrsdl2 may have some issues when your system does not have Noto Sans JP. And it seems that the exceptions about fonts will not be thrown out if you load a font in startup.tjs
.
***: Check game’s original startup.tjs to make sure if something (like a global.xxx
definition) should be added.
After all submodules get downloaded, compile krkrsdl2 (Refer to .github/workflow/ci.yml
for building instructions):
meson setup build/
meson compile -C build
Test game with krkrsdl2:
./build/krkrsdl2 path/to/exported_folder_name
For simple games most functionalities are usable. Game will be stopped when uncaught exceptions occurred. You may see things like this in terminal:
==== An exception occured at yesnodialog.tjs(16)[(function) YesNoDialogWindow], VM ip = 17 ====
-- Disassembled VM code --
#(16) drawDevice.preferredDrawer = global.Window.PassThroughDrawDevice.dtDrawDib;
00000011 global %1
00000013 gpd %2, %1.*0 // *0 = (string)"Window"
00000017 gpd %3, %2.*1 // *1 = (string)"PassThroughDrawDevice"
-- Register dump --
%-11=(void) %-10=(object)(object 0x7fb99c542b40:0x7fb99c542b40) %-9=(void) %-8=(int)0
%-7=(int)0 %-6=(int)0 %-5=(void) %-4=(string)"Confirmation"
%-3=(string)"Are you sure you want to exit?" %-2=(object)(object 0x7ffee7eee7d0:0x0)
%-1=(object)(object 0x7fb99c542b40:0x7fb99c542b40) %0=(void)
%1=(object)(object 0x7fb997e07390:0x0) %2=(object)(object 0x7fb997c161d0:0x0) %3=(void)
%4=(object)(object 0x7fb99c5c6890:0x7fb99c5c6890) %5=(void) %6=(void) %7=(void) %8=(void)
%9=(void)
-----------------------------------------------------------------------------------------------
Script exception raised
Member "PassThroughDrawDevice" does not exist
trace : yesnodialog.tjs(211)[(function) askYesNo] <-- mainwindow.tjs(739)[(function) onCloseQuery] <-- immediate event