-2

I'm sure many of you guys know about the 1976 game Colossal Cave Adventure. I downloaded it on my Mac, and it allows you to save your progress, and it saves it in a .adv file which you can open up and resume your game where you left off. I opened it up in TextEdit (changed it to a .txt file) and it looks like a whole mess of encoded text of God-knows what language. I attached a picture

https://i.stack.imgur.com/RkBlb.png

as well as a link on google drive to the .txt file

https://drive.google.com/file/d/1Ku4QO4cpx61X8mS9bBgGK3AyViczczNl/view?usp=sharing For some reason the google drive preview looks like Chinese or some other language, but if you download the .txt you will see it's the same thing as the igmur picture.

I ran the file through python using this: import io with io.open(filename, 'rb') as f: text = f.read()

And text gave me this: https://drive.google.com/file/d/1KyjdPxUDkBy5ATZfg1GdIexeP9nK-Km6/view?usp=sharing

Just a sample of it (click on above link to see full file): b'\xc1\xdfd\x00\x84K\xfd\xcb\xff\x93\xcb\xf9\x90\\xa9\xd5\xdb\x10\xaf\xdb\xb5{_\xd1\xf9\xcaw\xd2\xc13\x8e\xd1\xd6\x06\xce\xe3V\xd0\xa8

Trying to decode it in Python gave me this error: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 0: invalid start byte

I tried decoding it many many ways and they all failed. I need to decode this into something readable. How do I, and what "text language" is it in?

Thanks

  • 0 Passing 'rb' to open tells Python to read the file as bytes. You want to read it as a string, so there is no need to pass the second argument (or pass 'r', if you want to be specific). – gmds Mar 18 '19 at 22:32
  • @MarcusLim Using just 'r' gives me this same error: `UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 0: invalid start byte` – Sam Rubanowitz Mar 18 '19 at 22:35
  • 1
    Actually, I missed something. How do you know that the file should be readable as text? – gmds Mar 18 '19 at 22:43
  • @MarcusLim I don't know, but I want to know if possible. And if possible, how? Adventure was written in FORTRAN, so there must be a way of converting it back to that or something like that. – Sam Rubanowitz Mar 18 '19 at 22:50
  • I don't see how the language the program was written in affects the save file format here. It's most likely *not* intended to be read by humans, it's just a chunk of bytes that only makes sense to the program that wrote it. See: https://en.wikipedia.org/wiki/Binary_file#Interpretation – Blorgbeard Mar 18 '19 at 22:53
  • The fact that it *cannot* be automatically decoded as text suggests that it cannot be decoded at all. Certainly, you can try decoding the `bytes` object with other encodings (ASCII, cp1252 etc.), but I doubt it. Some programs save data in human-readable formats such as JSON, but that might not be the case here. – gmds Mar 18 '19 at 22:55
  • The source code for ADVENT is on the internet, so you can figure out the format. But no, it looks like it is not text based, it's just a binary dump of a game-state struct. – Blorgbeard Mar 18 '19 at 23:01
  • Share the text files you placed on google so we can see the data which will be proprietary. – Rich Andrews Mar 18 '19 at 23:04
  • @RichAndrews I shared the files in my post. But here they are anyway: Binary file: https://drive.google.com/file/d/1KyjdPxUDkBy5ATZfg1GdIexeP9nK-Km6/view?usp=sharing and original file https://drive.google.com/file/d/1Ku4QO4cpx61X8mS9bBgGK3AyViczczNl/view?usp=sharing – Sam Rubanowitz Mar 18 '19 at 23:45

1 Answers1

1

Nothing like hacking and poking around on classic games.

Which version? The original, is written in Fortran and ran on a PDP-11. So, that isn't the one you've got.

Perhaps you have the latest OSS one? https://gitlab.com/esr/open-adventure

So, you need to look at the specific implementation of the game, and grab the data structures it uses to save out the game state.

This is what you want to do:

git clone https://gitlab.com/esr/open-adventure.git open-adventure
make
./advent

This runs game and places you in it.

Welcome to Adventure!!  Would you like instructions?

> no

You are standing at the end of a road before a small brick building.
Around you is a forest.  A small stream flows out of the building and
down a gully.

> save

I can suspend your Adventure for you so that you can resume later, but
it will cost you 5 points.

Is this acceptable?

> yes

OK

File name: saved_game

Richs-MBP:open-adventure randrews$ ls -l saved_game 
-rw-r--r--  1 randrews  staff  3192 Mar 18 19:11 saved_game
Richs-MBP:open-adventure randrews$ file saved_game
saved_game: data
Richs-MBP:open-adventure randrews$ strings saved_game
E'HTH

That's binary alright. So we go after the game source.

saveresume.c is a great place to start.

Within we find a reference to struct game_t in the code that suspend()s the game. And that struct is defined in advent.h

It looks like:

struct game_t {
    int32_t lcg_x;
    int abbnum;                  // How often to print int descriptions
    score_t bonus;               // What kind of finishing bonus we are getting
    loc_t chloc;                 // pirate chest location
    loc_t chloc2;                // pirate chest alternate location
    turn_t clock1;               // # turns from finding last treasure to close
    turn_t clock2;               // # turns from warning till blinding flash
    bool clshnt;                 // has player read the clue in the endgame?
    bool closed;                 // whether we're all the way closed
    bool closng;                 // whether it's closing time yet
    bool lmwarn;                 // has player been warned about lamp going dim?
    bool novice;                 // asked for instructions at start-up?
    bool panic;                  // has player found out he's trapped?
    bool wzdark;                 // whether the loc he's leaving was dark
    bool blooded;                // has player drunk of dragon's blood?
... it is big! ...
    obj_t link[NOBJECTS * 2 + 1];// object-list links
    loc_t place[NOBJECTS + 1];   // location of object
    int hinted[NHINTS];          // hinted[i] = true iff hint i has been used.
    int hintlc[NHINTS];          // hintlc[i] = how int at LOC with cond bit i
    int prop[NOBJECTS + 1];      // object state array */
};

And that's what's in your file. Have fun taking the game C code and using the suspend/resume functions to load your saved file and hack it so that you have drunk of dragons blood!

Rich Andrews
  • 1,590
  • 8
  • 12
  • This is great! But there's no way of telling whether the binary file I linked to in my question above is the same thing as the saveresume.c file that you posted here, right? Also, when I run `make`, terminal tells me `make: *** No targets specified and no makefile found. Stop.` What am I doing wrong? – Sam Rubanowitz Mar 18 '19 at 23:44
  • What version of the game do you have? The above example applies to only the OSS one cited in my above answer. You are not running `make` in the directory where the Makefile is located. – Rich Andrews Mar 19 '19 at 03:46