FelineSystem2
FelineSystem2 copied to clipboard
An open source remake of the CatSystem2 visual novel engine.
FelineSystem2
An open source remake of the CatSystem2 visual novel engine.
Demo
A makeshift demo of the current version can be found here.

Controls
Click/Scroll - Advance text
Ctrl/Enter - Advance text, hold to skip
SPACE - Hide message window
f - Toggle fullscreen
1-9 - Select choice
Shift + Alt + 1-9 - Quick save to slot 1-9
Shift + 1-9 - Quick load from slot 1-9
Features
- Multi-platform (WASM, Windows SDL2)
- Raw KIF archive decryption
- HG-3 image decoding and caching
- Custom-built CatScene recursive-descent parser
KIF Database Structure
FelineSystem2 implements a custom database of the game's KIF archives and assets, stored as a binary file.
Archive Table
| Data Type | Value | Description |
|---|---|---|
char[len] |
ArchiveName | NULL-terminated filename of the KIF archive |
uint32 |
EntryCount | Number of entries in archive |
unsigned char |
IsEncrypted | 0x01 if archive is encrypted, 0x00 otherwise |
byte[4] |
FileKey | Blowfish key for decrypting entries (Only exists if IsEncrypted is 0x01) |
0x00 |
TableEnd | Signifies end of table |
Archive Item Entry
| Data Type | Value | Description |
|---|---|---|
char[len] |
FileName | NULL-terminated deobfuscated filename |
uint32 |
Offset | The offset to the entry's data |
uint32 |
Length | The length of the entry's data |
Notes
Parser
- If statements must contain a whitespace after the closing parenthesis of the condition
if (#300==0) #(950+#300)=512
- Operators follow C-Style left-to-right precedence and associativity
- Integers and strings are the only data types that exist
#300=0str 50 bg02
- Variable names can only be integers
- Variable names can be dynamically evaluated
#(950+#300)=512
Script
blendargument specifies the alpha value that the image will be displayed atcg 0 blend 255will display a completely opaque CG whilecg 0 blend 0will display a completely transparent CG
rdrawcommand after an image specifies the duration to fade to the target opacityrdraw 30will take30frames to fade the image from alpha0to the target alpha (e.g.255by default)- Units are likely in frames at
60fps (0.0167s/frame) regardless of the game's refresh rate setting - An
rdrawcommand will apply to all images within a script block (from a user input to the nextwaitcommand)
waitcommand without arguments will block until any time-based command completeswaitafter ardraw 30command will wait for the30frames taken to completely fade in the images before proceeding to the next command
waitwith arguments behaves differently from standalonewaitwait 60will block for60frames before proceeding to the next commandwait 60will not be aware of any time-based commands likerdrawand will not block untilrdrawcompleteswaitis sometimes used along withwait 60consecutively
cg 0 attr 1 (70+0) (80+0)cg 0 attr 2 (75+0) (85+0)- Assigns the
BaseX,BaseYvalues of the specified imagecg 0to the variables#(75+0)and#(85+0)respectively
- Assigns the
Special Thanks
- Trigger for creating such an amazingly comprehensive knowledgebase of the CS2 engine
- asmodean for being a pioneer in reversing the CS2 engine
- Dodder for Hacking the Grisaia for localization
- koestl for his impeccable translations and contributions to localization