Page 1 of 1

A script that tells you what secrets you missed

Posted: Mon Sep 30, 2013 6:47 pm
by ali1234
I have written a small script which analyzes your Grimrock save file, and then lists all the secrets, Toorum notes, treasures, and skulls that you have not yet touched. You can use this if you get to the end of the game and are just missing a couple of secrets, but you have no idea which ones. In theory it should even work on saves from custom dungeons, but this is not tested.

Usage: python secrets.py <savefile00.sav>

Output: (level) (x,y coordinate) (secret type) (secret name) for each secret you haven't found yet.

Code: Select all

#!/usr/bin/env python

import struct
import sys
import zlib

secret_items = [
  'ancient_apparatus', 
  'golden_chalice', 
  'golden_crown',
  'golden_dragon',
  'golden_figure',
  'golden_goromorg',
  'golden_orb',
  'note',
  'skull'
]

def enty(raw):
    offset = 0
    (a,b) = struct.unpack('<II', raw[offset:offset+8])
    offset += 8
    name = raw[offset:offset+b]
    offset += b
    (a,b) = struct.unpack('<II', raw[offset:offset+8])
    offset += 8
    type = raw[offset:offset+b]
    offset += b

    (a, level, b, x, c, y, d, facing) = struct.unpack('<IdIdIdId', raw[offset:offset+48])
    offset += 48

    level = int(level)
    x = int(x)
    y = int(y)

    assert(a == 1 and b == 1 and c == 1 and d == 1)

    unfound = False

    if type == 'secret':
        if ord(raw[-1]) == 0:
            unfound = True

    elif type in secret_items:
        (a,b) = struct.unpack('<II', raw[offset:offset+8])
        offset += 8
        where = raw[offset:offset+b]
        offset += b

        if type == 'note':
            if ord(raw[offset+0xa6]) == 0x30:
                unfound = True
        else:
            if ord(raw[offset+0xa6]) == 0x00:
                unfound = True

    if unfound:
        print 'Level:', level, '('+str(x)+', '+str(y)+')',  type, name if type == 'secret' else ''


def save(filename):
    data = open(filename).read()
    (magic, version, size) = struct.unpack('<4sII', data[:12])
    assert(magic == 'GRIM')
    assert(version == 6)

    raw = zlib.decompress(data[12:])
    assert(size == len(raw))
        
    offset = 0
    while offset < size:
        (type,csize) = struct.unpack('<4sI', raw[offset:offset+8])
        offset += 8
        data = raw[offset:offset+csize]
        offset += csize
        if type == 'ENTY':
            enty(data)

        
save(sys.argv[1])
Example output:
SpoilerShow
Level: 1 (2, 10) secret entranceSecret
Level: 2 (20, 2) skull
Level: 2 (23, 6) golden_chalice
Level: 3 (1, 17) note

Re: A script that tells you what secrets you missed

Posted: Mon Sep 30, 2013 7:40 pm
by Komag
I have nothing against posting such a thing. But how can you figure out those things? Is the script an executable that we might be wary of?

Re: A script that tells you what secrets you missed

Posted: Mon Sep 30, 2013 7:50 pm
by ali1234
Just some python code which unpacks the save file. I will post it and you can read it before running it ;)