Hacker News new | past | comments | ask | show | jobs | submit login
How to program a text adventure in C (2016) (hccnet.nl)
177 points by phodo on March 22, 2020 | hide | past | favorite | 35 comments

I suggest to look into https://ifcomp.org/ - the annual interactive fiction competition is running for 25 years now and there are some great games and resources over there.

The greatest text games I have played are Curses! and Anchorhead. Both are immersive and vast. Anchorhead is genuinely scary. There are some pointless puzzles and timed puzzles, but overall, truly worth trying out.

Thanks for the suggestions! I've never heard of IF before - but I'm a long time MUD / roguelike player. This looks really great.

I recommend Counterfeit Monkey, it's the top-rated game on IFDB and I think it deserves that spot. It's also a game that would be impossible to create graphically.


Ask HN: what's a good JS (browser focused) text adventure engine? I see me making a text adventure (adding one mini chapter) each day as a good lockdown project.

Note: I might call it "Everything is better in quarantine." The goal would be to (not) go mad.

The classic engine is Inform, and a quick look in the manual says it can publish to a playable webpage: http://inform7.com/

Inform is definitely the leader in parser fiction and there's been some amazing games made from it (Counterfeit Monkey and Hadean Lands being two of my favorites).

I would throw Ink (from Inkle, creators of 80 Days, Steve Jackson's Sorcery!, and Heaven's Vault) in the ring for the choice-driven variant of IF. It also publishes a playable webpage. I made a sort of unconventional portfolio-like page with it here: https://maxsond.github.io/

I'm working on a text adventure that is simply hyperlinked HTML pages with some snippets of JS for state management (just a bunch of localstorage get/put) and fancy effects. It's refreshing to go back to using the "kiddie" tools to make things.

This is awesome! Do you have the code anywhere? This is the kind of text adventure I want to do but I don't know much js.

I haven't put the code up anywhere yet but here is all of the JS (minus some trivial inline scripts):

tools.js: https://pastebin.com/p7MQE7KD

The rest of it is like:

    <p>You stand before a cave.
    <p><a href="explore.html">explore the cave</a>

Thank you so much!

> Ask HN: what's a good JS (browser focused) text adventure engine?

Take a look on ISTEAD - Simple Text Adventure Interpreter.[0]

It has JS-based version[1,2] and native versions (SDL-based in pure C) for Android[3,4], Windows and Unix-like platforms (including Linux, macOS/iOS, Maemo/MeeGo, Symbian 9.x, various consoles, etc.).[5]

Text adventures for INSTEAD could include Lua-scripts (text adventure itself & modules) and various media assets (images, sounds, fonts).[6]

There is repo with free games & demos for INSTEAD, which in most cases could be installed directly from INSTEAD clients.[7]

[0] https://github.com/instead-hub

[1] https://github.com/instead-hub/instead-js

[2] http://instead.itch.io/

[3] https://github.com/instead-hub/instead-android-ng

[4] https://apt.izzysoft.de/fdroid/index/apk/org.emunix.insteadl...

[5] https://github.com/instead-hub/instead/releases

[6] https://instead-hub.github.io/en/#doc

[7] http://instead-games.ru

Ink[1] is pretty great, and has a nice editor you can download to get started quickly. I found it really interesting to learn. It is unlike any other language I know, because it deals with such a specific problem.

1: https://www.inklestudios.com/ink/

Single- or multi-player? I'm thinking of figuring out why https://evolvingstory.juliablewis.com/ keeps crashing, cleaning it up and open-sourcing it. Also thinking of rewriting it using a different event system.

I fixed the logging so should be able to diagnose next time it crashes. Doesn't crash just for me.

Inform and TADS are the two main ones out there. If you want to do the basic stuff, Inform is probably easier. I hear TADS is more powerful if you want to extend the capabilities, though.

I like this, very creative!

The code generation looks interesting. I'll have to take another look later; can it not be done with the preprocessor?

Awesome work. Thanks. Looking forward to see more of those vintage games again :)

Wow! This tutorial was very fun to follow.

Thank you for writing this up!

This programmer, Mr. Ruud Helderman, is like Cool McCool, "Danger is my business!". For example, the parser, function matchParam:

  OBJECT *obj;
  par->tag = src;
  par->distance = *src == '\0' ? distNoObjectSpecified : distUnknownObject;
The initialization of the obj variable received an obliviate spell.

Also function parseAndExecute (). The way he deal with invalid input is, epic:

  static const COMMAND commands[] =
      {executeQuit      , "quit"},
      {executeLookAround, "look"},
  for (cmd = commands; !matchCommand(input, cmd->pattern); cmd++);
  return (*cmd->function)();

This is C89 style code where you couldn't declare the loop variables in the for loop, as in "for (OBJECT * obj = ... ". There's no problem with this code. The obj variable is initialized in the forEachObject macro which expands to a for loop. (Pretty damn sure - I haven't actually looked up the definition).

The array iteration code is also solid. Seems like a pretty good programmer, judging from the code you cite here at least.

While I personally like to put a few assertions just to find my typos quicker, adding additional fluff here is mostly detrimental. The kind of bugs that can happen with this sort of "dangerous" code are the ones that you basically just typos that you catch on the first run. I.e. it's not like there are any rarely occurring edge cases that are unhandled, since the code is extremely straightforward. The "complexity" is very low.

> The array iteration code is also solid.

Shouldn't there be a NULL at the end of the array and do a null check in the iteration?

I think the last array entry {executeNoMatch , "A?"} will match on any string (and print the fallback "I don't know how to VERB" message), so it's impossible to fall off the end of the array. If you wanted to use a more defensive-programming style then you could add a sentinel of some kind and assert that you never hit it.

Overall I agree with you, my comment is just pointing out that this kind of tricks are dangerous, Cool McCool style, use at your own risk and so. Things you stop doing after your first million bugs fixed.

Well in fact I've tended more and more to this bare kind of coding as I've aged (and hopefully gained experience). Many of the seatbelts (like assertions) I've actually hit at some point or another (so they turned out to be useful in these situations), but on the other hand they allowed me to be more sloppy in my thinking, writing more complicated code, which I feel could be a net loss in productivity.

Then again this is just some example code on a website, so it's natural that it has to be done a little more straightforwardly than you would write it in actual practice.

It's natural to show people code as an example, which not write like that in practice? What's the example for then? Is there a disclaimer following, saying thaT the code is not how you would write it and mentioning all the things you would do differently? Enlighten me please.

You see similar code to his unconditional executeNoMatch at the end of the table in table based code all the time. Additionally forEachObject is a macro that immediately initializes a variable. For projects like this the code is completely fine. I'm not sure what is particularly dangerous about this code for a small to medium size project.

How do you feel qualified to critique someone else's C code, even publicly on Hacker News ? You seem to have basic problems with understanding how a macro (in this case forEachObject) works.

You have people literally defending uncommented, unclear code in your replies.

There are phases programmers go through. One phase occurs about after 10 years of professional programming. I call this the "no mercy" phase, where these newly-minted senior programmers think defensive programming is for noobs, and scrunch their C code down to the fewest number of lines and characters. And when someone objects, the reply is, paraphrased (as seen in the replies): "You're just not as good a programmer as me." Sadly, it takes another 10 years for this arrogance to dissipate.

Most legacy code is this way unfortunately. The actual techniques employed by the "called out" code are not uncommon. I don't think that people are defending the lack of clarity but rather what the code is doing itself. It could be written more clearly, though one could argue that the lengthy series of articles does just that. Maybe it's an exercise for you to write it how you want.

Have you taken a look at some major C codebases? It's not justification but an appeal to authority seems pretty unnecessary :)

If you mean me, you're right in that I've been working with C in varying capacity for just about 10 years (Not that I believe that "years" is a good unit to measure experience). On the other hand, I miss from your comment what exactly is wrong with my argumentation, and I feel that the arrogant comment is not mine but yours (assuming you have 20 years or more).

It's ok, but inform 6 is better for this.

It’s great that you read the linked page, because at the introduction he wrote:

But then, why this tutorial? Why write an adventure game using a general-purpose programming language? Because doing so can be entertaining, challenging and educational. The programming language C may not be the most obvious choice for writing a text adventure; it's nothing like LISP-based languages like MDL and ZIL. But while writing my own humble text adventure, I learned that C fits the bill quite well.

Yeah, your comment is OK, but there are better ones in this thread.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact