Extract Scene.pck with https://github.com/xmoeproject/SiglusExtract/tree/master/binary (requires game data - executable, Gameexe.dat, etc)

Dump content text with:

{{{#!python
#!python
import sys, struct

fname = ""

#suppress_print = True
suppress_print = False

def r4(f):
    return struct.unpack("<I", f.read(4))[0]

def r2(f):
    return struct.unpack("<H", f.read(2))[0]

def r1(f):
    return struct.unpack("<B", f.read(1))[0]

def print(s, end="\n"):
    if suppress_print: return
    sys.stdout.buffer.write((str(s) + str(end)).encode('utf-8'))

def dump_text(f, n):
    was = f.tell()
    
    key = (table[n][2] * 0x7087)%0x10000
    array = []
    f.seek(table[n][0]*2 + table[n][3])
    for i in range(table[n][1]):
        r = r2(f)
        r = r ^ key
        array += [((r&0x00FF)>> 0)&0xFF]
        array += [((r&0xFF00)>> 8)&0xFF]
    array = bytes(array).decode(encoding="utf-16-le", errors="ignore")
    #print(array)
    f.seek(was)
    
    return array


for arg in sys.argv[1:]:
    table = []
    code = []
    if arg.endswith(".ss"):
        #print(f"dumping {arg}")
        fname = arg
        with open(arg, "rb") as f:
            f.seek(4)
            start = r4(f)
            end = start+r4(f)
            tablepos = r4(f)
            tablelen = r4(f)
            textoffset = r4(f)
            f.seek(tablepos)
            for i in range(tablelen):
                offset = r4(f)
                table += [[offset, r4(f), i, textoffset]]
            f.seek(start)
            while f.tell() < end:
                code += [r1(f)]
            for i in range(len(code)):
                if tuple(code[i:i+5]) == (0x02, 0x14, 0, 0, 0) and code[i+9] == 0x31:
                    #print(" ".join([f"{x:02X}" for x in code[i:i+10]]))
                    which = struct.unpack("<I",bytes(code[i+5:i+9]))[0]
                    #print(f"{which:08X}")
                    array = dump_text(f, which)
                    print(array)

}}}

Yes, I tried doing it the right way by parsing the bytecode, but there's an operation (0x30) with stateful variable-length-ness, and nothing I did would fix it. I got it working for one game (hatsuyuki sakura), but it failed on another (rewrite+). At that point I gave up and did the above. 0x02 is the command for pushing stuff onto the stack, 14 00 00 00 means it's a string, and 0x31 displays the text. I have reason to suspect that 0x31 doesn't actually induce a linebreak, so this should be considered flawed, but without real engine documentation it's the best I can do. If you want the bytecode parser that worked for hatsuyuki sakura, @ me on twitter.