Wander (1974), pre-Adventure text adventure system

While a lot of people have caught this news already, I thought I’d put it here for completeness sake. Recently I caught the trail of an ancient text adventure creation system, and with the help of Peter Langston (the author) and Anthony Hope, managed to track it down.

ahopeful.wordpress.com/2015/04/ … -is-found/

bluerenga.wordpress.com/2015/04 … -answered/

Quoting from Anthony:

The second link has a ZIP that should compile out of the box. Binaries are being worked on.


Binaries would be an excellent thing indeed for some us. :slight_smile: I’ll be eagerly awaiting them.

I should point out: The source distribution won’t compile under Linux:

cc    -c -o wand1.o wand1.c
cc    -c -o wand2.o wand2.c
wand2.c:311:1: error: unknown type name ‘in’
 in           /* put wrd vals in w[0], w[1],  ... */
wand2.c: In function ‘fsize’:
wand2.c:850:10: error: ‘FILE’ has no member named ‘_file’
  fstat(fp->_file, &sbuf);
<builtin>: recipe for target 'wand2.o' failed
make: *** [wand2.o] Error 1

(Tested in Ubuntu Vivid). This is predictable, I assume someone only gave it a pass to make it compile on modern OS X? Maybe the un-massaged files would be a better starting point for people trying to get it to compile with gcc (Which would also probably be the compiler of choice for this on Windows, using cygwin). Apparently this version was written for System V, which puts it pretty much at the oldest edge of software that should still run on today’s operating systems, but I’m no C programmer so I have no idea how to get this thing to compile myself.

Just to check, which version of the download did you use? About an hour or so ago I posted a new ZIP which should compile better and also supports save/restore.

(Doesn’t mean it won’t break on a particular OS, of course.)

ADD ADD: also there was a typo on one line (“in” instead of “int”) that’s also just now has been fixed.

Nope, the “fixed” zip won’t compile on my system, but I figured it out. Starting on line 845:

fsize(FILE *fp)
	struct stat sbuf;

	fstat(fp->_file, &sbuf); /* Should be fstat(fp, &sbuf); */

Changing that line gets it to compile and run, though I haven’t checked that it won’t segfault or die halfway through itself. I don’t know if this is a legitimate difference between the libc in Linux and the libc in OS X (So you’d need some platform-specific IFDEFS in there) or just a case where OS X allows something that glibc2 doesn’t; try compiling that patch under OS X?

Jayson Smith has compiled Windows 32-bit binaries. I added it to the links at
bluerenga.wordpress.com/2015/04 … -answered/

Hi. Anthony “Ant” Hope here.

Jason, thank you for the link and the quote, and for writing about Wander in the first place.

Sequitur, I just tried compiling your patch on OS X 10.6.8 and got this:

$ make Wander cc -c -o wand1.o wand1.c cc -c -o wand2.o wand2.c wand2.c: In function ‘fsize’: wand2.c:850: warning: passing argument 1 of ‘fstat’ makes integer from pointer without a cast cc -c -o wandglb.o wandglb.c cc -c -o wandsys.o wandsys.c cc wand1.o wand2.o wandglb.o wandsys.o -o Wander
But the target does get built, and seems to run fine, at least so far. (I don’t fully understand the details of the code, I confess.)

1 Like

Surely it should be fstat(fileno(fp), …)?

Aha… yes, indeed it should.

Forgive my ignorance, but does it need to be fstat(fileno(fp), …) on OS X too?

This is a POSIX function, so I would assume yes. It should work the same way on all POSIX-compatible systems.

Yes, fileno(fp) should work everywhere. The thing with fp->_file probably happens to do the same thing as fileno(fp) on whichever system that compiles on, but fileno(fp) is the portable way that works everywhere. The thing with fstat(fp, …) where you implicitly cast the pointer to an integer and the compiler grumbles because it’s pretty sure that isn’t what you meant but lets you get away with anyway will not result in anything good happening; your address will inevitably be way too big to be a plausibly valid fd, fstat will always fail, and your function will return whatever garbage was on the stack as if it were the file size; if the resulting program seems to work, it must be because it didn’t happen to need to know the correct sizes of very many files, or something. Like maybe it’s using it to size a buffer or as a bounds check or something, and the resulting number happened to be big enough that the file fit, but not so big as to run out of memory or whatever.

Ah, thanks for the explanation, zaphod and RealNC.

I compiled wander from github with cygwin for win32 and also on Linux (64 bit), if you wish: ifiction.free.fr/index.php?id=wander

Thanks, favardin! I’ve linked to you on my blog.

I just wanted to mention that I very crudely and ignorantly hacked the source code for Wander to make it compile with DJGPP for DOS: drive.google.com/file/d/0B3AP_x … sp=sharing

But in the process, and because I didn’t really know what I was doing – I was just commenting stuff out, mainly! – I broke SAVE and RESTORE. Does anyone know the proper way to do a DOS port?

Not one to let sheer ignorance stand in the way of progress, I then packaged up my broken DOS port using em-dosbox tools to create a version of Wander that was playable online: s3.amazonaws.com/wander1974/wander.html

I wanted to bypass em-dosbox altogether and instead do a pure-emscripten version, but I know very little about emscripten, and couldn’t figure out how to create a proper text-input field, as opposed to the modal page-obscuring Javascript popup dialog box that the emscripten compiler uses by default!

If you’re interested and can help with any of this, do let me know!

I’ve just checked out the online play version above. Out of curiosity…

Wander predated Colossa Cave, right?

…is it known whether Crowther knew of this program?

I find it curious that Wander uses compass directions, and even the shortcuts we’re used to.

There seems to be a “brief” convention as well. After trying a verb, I get the response, the name of the room, and the listing of objects.

In fact, most of the conventions we associate with IF and even with IF prose are present.

It’s… surprisingly modern. Feels more like 1984 than 1974. Possibly more like 1994.

Also, if this predates Adventure, how does it understand XYZZY as a verb? And calls it an old, worn-out magic word?

EDIT - It understand “examine” as a synonim for “read”. Quite modern. Am I missing something?

From what I’ve seen in the blog posts, this is a 1980 version of the source.

Hmmm, so it’d make sense for him to have been working on the games in the meantime, updating as he went along. That would explain it. Thanks. It’s just that I expected a more retro experience; I expected to recognise very little of the conventions in use. So when the game even recognised XYZZY… well, I was surprised.

But yes, that makes total sense now. Cheers.