A cross-platform reimplementation of Plants vs. Zombies by the community. Aiming to bring 100% authentic experience of GOTY edition.
See the codeA cross-platform community-driven reimplementation of Plants vs. Zombies: Game of the Year Edition, aiming to bring the 100% authentic experience of Plants vs. Zombies to every platform.
| 🌿 Authentic | 🎮 Portable | 🛠️ Open |
|---|---|---|
| Almost 100% gameplay recreation | Support for 32/64 bit systems Run on Linux, Windows, macOS, Android, iOS, WebAssembly, Switch... | OpenGL ES 2.0 & SDL |
🌐 No install wanted? Try directly in your browser! (You still need your own game data files.)
⚠️ Notice:
main.pak and properties/ folder from a legally purchased copy of Plants vs. Zombies: GOTY Edition.user*.dat)
.v4 support (share mid-level saves between Windows, Linux, macOS, Android, Switch, etc.)
.v4 save files to/from human-readable YAML format for easy editingstd::thread for cross-platform threading supportstd::filesystem for cross-platform file system supportThis project supports the following platforms (including but not limited to):
| Platform | Data path | Status |
|---|---|---|
| Linux | Executable dir (resources); per-user app-data for writable files | Works |
| Windows | Executable dir (resources); per-user app-data for writable files | Works |
| macOS | Executable dir (resources); per-user app-data for writable files | Works |
| BSD Family | Executable dir (resources); per-user app-data for writable files | Works (verified at least on FreeBSD) |
| Haiku | Executable dir (resources); per-user app-data for writable files | Partially works: no music |
| Android | Android/data/io.github.wszqkzqk.pvzportable/files/ | Works |
| iOS / iPadOS | App Documents directory (Files app) | Works (sideload only; unsigned IPA) |
| Web (WASM) | Browser IndexedDB (saves); resources uploaded at runtime | Works (requires a HTTP server) |
| Nintendo Switch | sdmc:/switch/PvZPortable | Works on real hardware. Kenji-NX crashes on boot. |
To play the game, you need the game data from PvZ GOTY. Place main.pak and the properties/ folder next to the pvz-portable executable (the game will search for resources relative to the executable's directory). You can also use extracted data instead of main.pak if you prefer.
Note about writable data and caches:
main.pak and properties/) from the executable directory by default, so you can launch the binary from any working directory and it will still find them.io.github.wszqkzqk/PvZPortable and include subfolders such as:
userdata/ — Player save files.cache64/ if you use the 64-bit version or cache32/ if you use the 32-bit version — Compiled binary caches (reanimation / compiled definitions). These caches are local startup artifacts (native layout), not portable files; when cache/schema checks fail, the game transparently recompiles from source data.registry.regemu — Settings/registry emulation.Examples:
~/.local/share/io.github.wszqkzqk/PvZPortable/%APPDATA%\io.github.wszqkzqk\PvZPortable\~/Library/Application Support/io.github.wszqkzqk/PvZPortable/You can customize these paths via command-line parameters:
-resdir <path> / -resdir=<path>: Set the resource directory (where main.pak and properties/ are located). This only affects where the game looks for resources, not where it saves data.-savedir <path> / -savedir=<path>: Set the save data directory (where settings, savegames, caches, and screenshots are stored). This overrides the default OS-recommended application data path.Download the APK from the Releases page or build it yourself. Because this project does not include any game assets, you will need to import the game resources from a legally purchased copy of Plants vs. Zombies: GOTY Edition.
main.pak and properties/ (either at the ZIP root or inside one wrapper directory, e.g. PvZ/main.pak).main.pak and properties/, or whose immediate subfolder does.Long-press the app icon on your launcher to access the Manage Data shortcut, which opens the resource management screen where you can re-import resources, export saves, or import saves.
Android/data/io.github.wszqkzqk.pvzportable/files/. No extra storage permissions are needed — the app uses the Storage Access Framework (SAF) for all imports and exports.Download the unsigned IPA from the Releases page or build it yourself with ios/build-ios.sh. The IPA must be sideloaded — common methods include AltStore, TrollStore, or deploying directly from Xcode with a free Apple ID.
The app's Documents folder is exposed via iTunes/Finder file sharing and the iOS Files app (UIFileSharingEnabled). Place main.pak and the properties/ folder directly into the app's Documents directory (shown as "PvZ Portable" in the Files app).
▶ Play Online — open the link, load your legally purchased game resources either from a ZIP package or from main.pak plus the properties/ folder, then click Start Game. All files stay in your browser locally and are never uploaded to any server (the hosting site is purely static). Save data is stored in your browser's IndexedDB and can be imported from ZIP or folder, or exported as a ZIP via the on-screen buttons.
You can also download the WASM build and self-host it. Note that the HTML file must be served over HTTP (e.g. python3 -m http.server) — opening it directly as a local file will not work due to browser security restrictions.
This project is designed and tested against Plants vs. Zombies GOTY Edition 1.2.0.1073 EN (the standalone PopCap release). Non-English GOTY editions (1.2.0.1093 DE/ES/FR/IT or 1.1.0.1056 ZH based on 1.2.0.1073) and the Steam GOTY Edition 1.2.0.1096 are also fully playable — all game mechanics work correctly. The only differences are minor cosmetic UI text issues caused by renamed string keys across versions, and these can be easily fixed by the user via a custom properties/pvz-portable.xml.
For 1.2.0.1096 and non-English GOTY editions, generate compatibility and translation overrides with:
python3 scripts/make-compat-overrides.py "/path/to/main.pak"
The script writes pvz-portable.xml to the properties/ directory beside main.pak. Use -o to choose a different output path or --force to overwrite an existing file.
Recommendation: use the 1.2.0.1073 EN asset package for the best out-of-box experience.
| Issue (Non-1.2.0.1073 EN only) | Cause |
|---|---|
| Almanac blue description text missing | In 1.2.0.1096, the plain-text introductory paragraph was split out from [XXX_DESCRIPTION] into a new [XXX_DESCRIPTION_HEADER] key. The engine only reads [XXX_DESCRIPTION], so the header text is never displayed. |
| "Restart" button label missing | The key [RESTART_LEVEL] (used for the button label) was renamed to [RESTART_LEVEL_BUTTON] in 1.2.0.1096. |
Unencountered zombie shows ??? instead of (not encountered yet) | The string [NOT_ENCOUNTERED_YET] changed its value to ??? in 1.2.0.1096; the old text was moved to a new key [NOT_ENCOUNTERED_YET_DESCRIPTION]. |
| Crazy Dave's plant sell price shows 1/10 of the correct value | In 1.2.0.1073, the string template [CRAZY_DAVE_1700] contains a trailing 0 after {SELL_PRICE} (i.e. ${SELL_PRICE}0) because the engine passes the price divided by 10. In 1.2.0.1096 the trailing 0 was removed, so the displayed price becomes 1/10 of the intended amount. |
Before building on PC, ensure you have the necessary dependencies installed:
CMake, Ninja, A C/C++ compiler (e.g., gcc, clang, MSVC) supporting C++20 (Also need a standard library implementation like libstdc++, libc++ or MSVC STL that supports C++20)OpenGL ES 2.0 or OpenGL 2.1+ (auto-detected at runtime via SDL2)libopenmptlibpng, libjpeg-turboSDL2You can install the required dependencies using the following command:
sudo pacman -S --needed base-devel cmake libjpeg-turbo libopenmpt libpng ninja sdl2-compat
You can install the required dependencies using the following command:
sudo apt install cmake ninja-build libjpeg-dev libopenmpt-dev libpng-dev libsdl2-dev
You can install the required dependencies using the following command:
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-libjpeg-turbo mingw-w64-ucrt-x86_64-libopenmpt mingw-w64-ucrt-x86_64-libpng mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-SDL2
You can install the required dependencies using Homebrew with the following command:
brew install cmake dylibbundler jpeg-turbo libopenmpt libpng ninja sdl2
Run the following commands (assuming you have CMake and other dependencies installed) where the CMakeLists.txt file is located:
cmake -G Ninja -B build
cmake --build build
It is recommended to use the Release build type for the best performance, as it usually implies compiler optimizations:
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release
For advanced users, you can also specify CFLAGS and CXXFLAGS to enable architecture-specific optimizations (e.g. -march=native to fully utilize your CPU's instruction set):
cmake -G Ninja -B build -DCMAKE_C_FLAGS="-march=native" -DCMAKE_CXX_FLAGS="-march=native" -DCMAKE_BUILD_TYPE=Release
You can customize the game features by adding options to the first cmake command:
| Option | Default | Description |
|---|---|---|
PVZ_DEBUG | OFF( ON if CMAKE_BUILD_TYPE is Debug) | Enable cheat keys, debug displays and other debug features. |
DO_FIX_BUGS | OFF | Apply community fixes for "bugs" of official 1.2.0.1073 GOTY Edition.1 However, these "bugs" are usually considered "features" by many players. |
CONSOLE | OFF( ON if CMAKE_BUILD_TYPE is Debug) | Show a console window (Windows only). |
BUILD_STATIC | OFF | Link dependencies statically (Windows with MinGW-based toolchains, glibc-based Linux). Use a vcpkg -static triplet for MSVC. |
Example: Manually enable PVZ_DEBUG in Release build so that you can use cheat keys while having optimized performance:
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release -DPVZ_DEBUG=ON
If running these commands does not create a successful build please create an issue and detail your problem.
PvZ-Portable uses two distinct types of save data:
Global User Data (users.dat, user1.dat, etc.):
Mid-Level Save States (game1_0.v4, etc. legacy game1_0.dat, etc.):
*.v4 files by default:
*.v4 files: Portable format. Sharing these files to transfer progress between different platforms is fully supported.*.dat files: Legacy dump from old versions. Contains raw memory dumps. Do not share this file across platforms as it will cause crashes due to architecture differences..v4; *.dat is fallback-only for migration compatibility.*.dat, the game automatically re-saves it to *.v4 and removes the legacy *.dat after successful migration.The original game's mid-level save format (.dat) effectively dumps raw memory structures to disk. This is fast but fragile, as it relies on specific memory layouts that break across:
As a result, legacy saves are generally not guaranteed to load across those variants. To solve this, Format v4 serializes game objects field-by-field using Type-Length-Value (TLV) tags. This ensures that a level saved on a x86_64 Linux machine can be loaded on a LoongArch or ARM (Switch) machine without crashing.
There's a Python script scripts/pvzp-v4-converter.py to inspect and modify .v4 save files.
Features:
.v4 files to human-readable YAML to view/edit gameplay-relevant data..v4 format with correct checksums.Usage:
# Modify these paths as needed
# View basic info
python3 scripts/pvzp-v4-converter.py info ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4
# Export to YAML for editing
python3 scripts/pvzp-v4-converter.py export ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4 level.yaml
# Import back to savegame
# **BACKUP** your original .v4 file fist!
mv ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4 ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4.bak
python3 scripts/pvzp-v4-converter.py import level.yaml ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4
The game can record a gameplay session into a .dmo demo file and replay it deterministically later. Automatically named demo files are written to the current working directory:
-record [<path>] / -record=[<path>] — record to a file named after the current local time, in the form pvzp-YYYYMMDD-HHMMSS[-N].dmo, or to an explicit <path> if given; an explicit target disables automatic retention.-play [<path>] / -play=[<path>] — play back the first matching pvzp-*.dmo recording in descending timestamp/name order, or an explicit <path> if given.-playnum <N> / -playnum=<N> — play back the N-th recording in descending timestamp/name order; 1 selects the first.-recnum <N> / -recnum=<N> — record and keep the first N files matching the automatic timestamp pattern in descending timestamp/name order; other pvzp-*.dmo files are left untouched.This feature is primarily designed for debugging and regression testing.
When contributing please follow the following guides:
Copyright (C) 2026 Zhou Qiankang [email protected]
This project is licensed under the terms of the GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later).
LICENSE — LGPL-3.0 textCOPYING — GPL-3.0 text, referenced by LGPL-3.0The SexyAppFramework directory may contain code originally based on the PopCap Games Framework. This code is subject to the permissive PopCap Games Framework License. To the extent that original code remains, the following acknowledgment applies:
"This product includes portions of the PopCap Games Framework, © 2005-2009 PopCap Games, Inc. All rights reserved. (http://popcapframework.sourceforge.net/)."
Note that this code has been heavily refactored, optimized and modernized by the community over time under the LGPL-3.0-or-later license.
Current DO_FIX_BUGS includes the following fixes:
A cross-platform reimplementation of Plants vs. Zombies by the community. Aiming to bring 100% authentic experience of GOTY edition.
See the codeA cross-platform community-driven reimplementation of Plants vs. Zombies: Game of the Year Edition, aiming to bring the 100% authentic experience of Plants vs. Zombies to every platform.
| 🌿 Authentic | 🎮 Portable | 🛠️ Open |
|---|---|---|
| Almost 100% gameplay recreation | Support for 32/64 bit systems Run on Linux, Windows, macOS, Android, iOS, WebAssembly, Switch... | OpenGL ES 2.0 & SDL |
🌐 No install wanted? Try directly in your browser! (You still need your own game data files.)
⚠️ Notice:
main.pak and properties/ folder from a legally purchased copy of Plants vs. Zombies: GOTY Edition.user*.dat)
.v4 support (share mid-level saves between Windows, Linux, macOS, Android, Switch, etc.)
.v4 save files to/from human-readable YAML format for easy editingstd::thread for cross-platform threading supportstd::filesystem for cross-platform file system supportThis project supports the following platforms (including but not limited to):
| Platform | Data path | Status |
|---|---|---|
| Linux | Executable dir (resources); per-user app-data for writable files | Works |
| Windows | Executable dir (resources); per-user app-data for writable files | Works |
| macOS | Executable dir (resources); per-user app-data for writable files | Works |
| BSD Family | Executable dir (resources); per-user app-data for writable files | Works (verified at least on FreeBSD) |
| Haiku | Executable dir (resources); per-user app-data for writable files | Partially works: no music |
| Android | Android/data/io.github.wszqkzqk.pvzportable/files/ | Works |
| iOS / iPadOS | App Documents directory (Files app) | Works (sideload only; unsigned IPA) |
| Web (WASM) | Browser IndexedDB (saves); resources uploaded at runtime | Works (requires a HTTP server) |
| Nintendo Switch | sdmc:/switch/PvZPortable | Works on real hardware. Kenji-NX crashes on boot. |
To play the game, you need the game data from PvZ GOTY. Place main.pak and the properties/ folder next to the pvz-portable executable (the game will search for resources relative to the executable's directory). You can also use extracted data instead of main.pak if you prefer.
Note about writable data and caches:
main.pak and properties/) from the executable directory by default, so you can launch the binary from any working directory and it will still find them.io.github.wszqkzqk/PvZPortable and include subfolders such as:
userdata/ — Player save files.cache64/ if you use the 64-bit version or cache32/ if you use the 32-bit version — Compiled binary caches (reanimation / compiled definitions). These caches are local startup artifacts (native layout), not portable files; when cache/schema checks fail, the game transparently recompiles from source data.registry.regemu — Settings/registry emulation.Examples:
~/.local/share/io.github.wszqkzqk/PvZPortable/%APPDATA%\io.github.wszqkzqk\PvZPortable\~/Library/Application Support/io.github.wszqkzqk/PvZPortable/You can customize these paths via command-line parameters:
-resdir <path> / -resdir=<path>: Set the resource directory (where main.pak and properties/ are located). This only affects where the game looks for resources, not where it saves data.-savedir <path> / -savedir=<path>: Set the save data directory (where settings, savegames, caches, and screenshots are stored). This overrides the default OS-recommended application data path.Download the APK from the Releases page or build it yourself. Because this project does not include any game assets, you will need to import the game resources from a legally purchased copy of Plants vs. Zombies: GOTY Edition.
main.pak and properties/ (either at the ZIP root or inside one wrapper directory, e.g. PvZ/main.pak).main.pak and properties/, or whose immediate subfolder does.Long-press the app icon on your launcher to access the Manage Data shortcut, which opens the resource management screen where you can re-import resources, export saves, or import saves.
Android/data/io.github.wszqkzqk.pvzportable/files/. No extra storage permissions are needed — the app uses the Storage Access Framework (SAF) for all imports and exports.Download the unsigned IPA from the Releases page or build it yourself with ios/build-ios.sh. The IPA must be sideloaded — common methods include AltStore, TrollStore, or deploying directly from Xcode with a free Apple ID.
The app's Documents folder is exposed via iTunes/Finder file sharing and the iOS Files app (UIFileSharingEnabled). Place main.pak and the properties/ folder directly into the app's Documents directory (shown as "PvZ Portable" in the Files app).
▶ Play Online — open the link, load your legally purchased game resources either from a ZIP package or from main.pak plus the properties/ folder, then click Start Game. All files stay in your browser locally and are never uploaded to any server (the hosting site is purely static). Save data is stored in your browser's IndexedDB and can be imported from ZIP or folder, or exported as a ZIP via the on-screen buttons.
You can also download the WASM build and self-host it. Note that the HTML file must be served over HTTP (e.g. python3 -m http.server) — opening it directly as a local file will not work due to browser security restrictions.
This project is designed and tested against Plants vs. Zombies GOTY Edition 1.2.0.1073 EN (the standalone PopCap release). Non-English GOTY editions (1.2.0.1093 DE/ES/FR/IT or 1.1.0.1056 ZH based on 1.2.0.1073) and the Steam GOTY Edition 1.2.0.1096 are also fully playable — all game mechanics work correctly. The only differences are minor cosmetic UI text issues caused by renamed string keys across versions, and these can be easily fixed by the user via a custom properties/pvz-portable.xml.
For 1.2.0.1096 and non-English GOTY editions, generate compatibility and translation overrides with:
python3 scripts/make-compat-overrides.py "/path/to/main.pak"
The script writes pvz-portable.xml to the properties/ directory beside main.pak. Use -o to choose a different output path or --force to overwrite an existing file.
Recommendation: use the 1.2.0.1073 EN asset package for the best out-of-box experience.
| Issue (Non-1.2.0.1073 EN only) | Cause |
|---|---|
| Almanac blue description text missing | In 1.2.0.1096, the plain-text introductory paragraph was split out from [XXX_DESCRIPTION] into a new [XXX_DESCRIPTION_HEADER] key. The engine only reads [XXX_DESCRIPTION], so the header text is never displayed. |
| "Restart" button label missing | The key [RESTART_LEVEL] (used for the button label) was renamed to [RESTART_LEVEL_BUTTON] in 1.2.0.1096. |
Unencountered zombie shows ??? instead of (not encountered yet) | The string [NOT_ENCOUNTERED_YET] changed its value to ??? in 1.2.0.1096; the old text was moved to a new key [NOT_ENCOUNTERED_YET_DESCRIPTION]. |
| Crazy Dave's plant sell price shows 1/10 of the correct value | In 1.2.0.1073, the string template [CRAZY_DAVE_1700] contains a trailing 0 after {SELL_PRICE} (i.e. ${SELL_PRICE}0) because the engine passes the price divided by 10. In 1.2.0.1096 the trailing 0 was removed, so the displayed price becomes 1/10 of the intended amount. |
Before building on PC, ensure you have the necessary dependencies installed:
CMake, Ninja, A C/C++ compiler (e.g., gcc, clang, MSVC) supporting C++20 (Also need a standard library implementation like libstdc++, libc++ or MSVC STL that supports C++20)OpenGL ES 2.0 or OpenGL 2.1+ (auto-detected at runtime via SDL2)libopenmptlibpng, libjpeg-turboSDL2You can install the required dependencies using the following command:
sudo pacman -S --needed base-devel cmake libjpeg-turbo libopenmpt libpng ninja sdl2-compat
You can install the required dependencies using the following command:
sudo apt install cmake ninja-build libjpeg-dev libopenmpt-dev libpng-dev libsdl2-dev
You can install the required dependencies using the following command:
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-libjpeg-turbo mingw-w64-ucrt-x86_64-libopenmpt mingw-w64-ucrt-x86_64-libpng mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-SDL2
You can install the required dependencies using Homebrew with the following command:
brew install cmake dylibbundler jpeg-turbo libopenmpt libpng ninja sdl2
Run the following commands (assuming you have CMake and other dependencies installed) where the CMakeLists.txt file is located:
cmake -G Ninja -B build
cmake --build build
It is recommended to use the Release build type for the best performance, as it usually implies compiler optimizations:
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release
For advanced users, you can also specify CFLAGS and CXXFLAGS to enable architecture-specific optimizations (e.g. -march=native to fully utilize your CPU's instruction set):
cmake -G Ninja -B build -DCMAKE_C_FLAGS="-march=native" -DCMAKE_CXX_FLAGS="-march=native" -DCMAKE_BUILD_TYPE=Release
You can customize the game features by adding options to the first cmake command:
| Option | Default | Description |
|---|---|---|
PVZ_DEBUG | OFF( ON if CMAKE_BUILD_TYPE is Debug) | Enable cheat keys, debug displays and other debug features. |
DO_FIX_BUGS | OFF | Apply community fixes for "bugs" of official 1.2.0.1073 GOTY Edition.1 However, these "bugs" are usually considered "features" by many players. |
CONSOLE | OFF( ON if CMAKE_BUILD_TYPE is Debug) | Show a console window (Windows only). |
BUILD_STATIC | OFF | Link dependencies statically (Windows with MinGW-based toolchains, glibc-based Linux). Use a vcpkg -static triplet for MSVC. |
Example: Manually enable PVZ_DEBUG in Release build so that you can use cheat keys while having optimized performance:
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release -DPVZ_DEBUG=ON
If running these commands does not create a successful build please create an issue and detail your problem.
PvZ-Portable uses two distinct types of save data:
Global User Data (users.dat, user1.dat, etc.):
Mid-Level Save States (game1_0.v4, etc. legacy game1_0.dat, etc.):
*.v4 files by default:
*.v4 files: Portable format. Sharing these files to transfer progress between different platforms is fully supported.*.dat files: Legacy dump from old versions. Contains raw memory dumps. Do not share this file across platforms as it will cause crashes due to architecture differences..v4; *.dat is fallback-only for migration compatibility.*.dat, the game automatically re-saves it to *.v4 and removes the legacy *.dat after successful migration.The original game's mid-level save format (.dat) effectively dumps raw memory structures to disk. This is fast but fragile, as it relies on specific memory layouts that break across:
As a result, legacy saves are generally not guaranteed to load across those variants. To solve this, Format v4 serializes game objects field-by-field using Type-Length-Value (TLV) tags. This ensures that a level saved on a x86_64 Linux machine can be loaded on a LoongArch or ARM (Switch) machine without crashing.
There's a Python script scripts/pvzp-v4-converter.py to inspect and modify .v4 save files.
Features:
.v4 files to human-readable YAML to view/edit gameplay-relevant data..v4 format with correct checksums.Usage:
# Modify these paths as needed
# View basic info
python3 scripts/pvzp-v4-converter.py info ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4
# Export to YAML for editing
python3 scripts/pvzp-v4-converter.py export ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4 level.yaml
# Import back to savegame
# **BACKUP** your original .v4 file fist!
mv ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4 ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4.bak
python3 scripts/pvzp-v4-converter.py import level.yaml ~/.local/io.github.wszqkzqk/PvZPortable/userdata/game1_13.v4
The game can record a gameplay session into a .dmo demo file and replay it deterministically later. Automatically named demo files are written to the current working directory:
-record [<path>] / -record=[<path>] — record to a file named after the current local time, in the form pvzp-YYYYMMDD-HHMMSS[-N].dmo, or to an explicit <path> if given; an explicit target disables automatic retention.-play [<path>] / -play=[<path>] — play back the first matching pvzp-*.dmo recording in descending timestamp/name order, or an explicit <path> if given.-playnum <N> / -playnum=<N> — play back the N-th recording in descending timestamp/name order; 1 selects the first.-recnum <N> / -recnum=<N> — record and keep the first N files matching the automatic timestamp pattern in descending timestamp/name order; other pvzp-*.dmo files are left untouched.This feature is primarily designed for debugging and regression testing.
When contributing please follow the following guides:
Copyright (C) 2026 Zhou Qiankang [email protected]
This project is licensed under the terms of the GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later).
LICENSE — LGPL-3.0 textCOPYING — GPL-3.0 text, referenced by LGPL-3.0The SexyAppFramework directory may contain code originally based on the PopCap Games Framework. This code is subject to the permissive PopCap Games Framework License. To the extent that original code remains, the following acknowledgment applies:
"This product includes portions of the PopCap Games Framework, © 2005-2009 PopCap Games, Inc. All rights reserved. (http://popcapframework.sourceforge.net/)."
Note that this code has been heavily refactored, optimized and modernized by the community over time under the LGPL-3.0-or-later license.
Current DO_FIX_BUGS includes the following fixes: