So I have no actual coding experience besides I7 (and some very slight TAG, a defunct german system back in the day).
As I understand it, some of you are actual programmers, and that made me wonder if anyone has ever written some general coding advice for IF from a programmer’s perspective? Pitfalls to avoid, best ways to organize your code, tips and tricks etc. with a special focus on IF.
I am not a professional programmer but I have found some good advices here.
Apart from that, I think it’s also worth looking into the relationship between code structure and the world model (for my part, I make a clear distinction between worldbuilding and storyweaving). Also, programming IF (I’m a newbie) has led me to explore software engineering, and there are some useful concepts to pick up there (even if not everything seems strictly applicable): the need for strong exhaustive testing, segmenting the roles of phrases, refining inheritance logic, etc.
When I was learning to code people kept giving me advice about “best practices” that I ignored, because “my way” always felt easier to understand at the time, and if it worked, it worked. But then, over time & with experience, I started to run into all of the problems that following “best practices” would have solved, which meant that I started doing things right because now I actually understood from experience why that way was better.
I guess what I’m saying is that I’m not sure there’s a good substitute for just coding a lot & slowly gaining experience/intuition? I dunno, maybe it depends on your learning style.
The data model is more important than the code. If you find yourself coding lots of workarounds and exceptions, take a step back and re-examine the data model. Can you redesign it in such a way that the exceptions are no longer exceptions?
It’s worthwhile to take an intro algorithms course online. It’s not so important to be able to implement all the algos from scratch, but being able to recognize when an algo applies is really helpful.
Every line of code will be read more times than it’s written. Focus on readability over conciseness.
Be very wary of “quick fixes”, especially if it involves circumventing a core part of the usual game machinery. (In Inform, this applies especially to parsing in “after reading a command” rules.)
As a non-programmer to another, I’d second and expand upon @draconis 's suggestion re: readability.
- Figure out a way to organize your project that makes sense to you. You need to be able to find what you’re looking for.
- Make comments.
- Write multiple rules (this is Inform 7 specific, but could apply to something else), or longer rules, if they are easier for you to keep track of and read (and therefore modify, fix, etc).
- think about what sorts of variable names make intuitive sense to you. If you had ten variables named in a similar way, could you make sense of them? Or would they all congeal into a blob?
One thing I’ve gotten into the habit of asking myself: if this broke, could I troubleshoot it?
Yes yes yes, clear file and variable names, as well as comments, are key!!
tmp1, tmp2, tmp3… /j
I do actually use variables like t and tmp, but I use them within the next few statements and only really to eliminate a subexpression or split up a really long line.
I’m certainly not a programmer, but I’ve written six or eight games. Here are some general-purpose platform-agnostic tips:
-
Comment your code extensively. A month from now you won’t remember what you were doing with that weird code.
-
Alpha-test each new item as you add it to the code. This means lots and lots of recompiling.
-
Try to think of ALL the things that the player might try. Remember: The player does not know what you intended! This applies not only to various command verbs and their synonyms but to unusual action attempts, such as eating the hat or putting the rowboat in your pocket.
-
When the game is nearing completion, write a test routine that will run through the entire game from start to finish so that you can test whether your last-minute changes have broken anything.
-
The more beta-testing, the better. Since IF is an all-volunteer hobby, some of the testers you enlist will never send you any reports. This is normal. If you sign up six testers, two or three are likely to dig in and do the testing. Maybe four. But not all six.
-
Have your testers send you not just notes but game output scripts. As much as 40% of the changes I’ve made during beta are the result of seeing things testers tried that they didn’t even think to flag as errors.
-
Always tag your beta versions so that you’ll know what version a tester was using. Keep the beta versions as separate project files so you can return to them if you can’t duplicate a bug when working from your main version.
-
You might want to keep a list of all the changes you’ve made as a result of reading testers’ transcripts. I’ve never done this, but I suspect it can save a certain amount of confusion, because one code change might get in the way of another, or three testers might spot the same problem.
-
Thank your testers effusively, and never argue with them!
I’m literally studying CS, and I’m really bad at structuring my projects beforehand. Almost everything I do ends up needing at least 1 rewrite. I think it’s because I lack the domain knowledge at the start, and once I’ve done it once, I can do it better again. The only thing that didn’t need a rewrite so far is a Settlers of Catan clone I’m working on, and that’s because the board game itself already tells me all needed data structures. The code has become a bit of a spaghetti though.
I’d say: Don’t be afraid of a rewrite, but if you end up rewriting more than progressing, that’s probably too often.
I’m guilty of not doing that, and when I come back to a project after a few months, I have no clue what’s going on lol.
Personally I use git for all my projects (IF or otherwise). It keeps a history of all changes, you can tag commits to give that point in time a name, and you can roll back and forward easily.
If that makes intuitive sense to you, who am I to argue?
No coding tips from me, but some info.
If you want to create a parser game (or engine) from scratch you have (may be a bit simplified) two parts. The world and the language parser.
The world is for example: rooms, items, persons (“characters”) content of a room or item or person (with “content” of a person I mean the inventory.
The parser could be a simple two-word parser or more complex.
Can confirm. Best practices will often save your project from yourself.
Read the Documentation (for Inform 7) as there’s a good chance it’ll answer your question before asking the forums. The one I linked can be searched with the Find command, which the IDE version can’t do (thank you Zed).
Look at other people’s code (like Bronze) to study and see how they did things. For instance, Emily Short implemented a GO TO command that can be modified for your own games.
I also have a WIP system for things I need to add later on:
[FIX]
buggy and needs to be fixed to work[ADD]
working yet incomplete code (e.g. unfinished action)[EDIT]
writing that needs to be added (descriptions, etc.)[TODO]
things to add after the FIX and ADD stuff are finished; next steps
Other than that, stuff others have said: comment your code, use meaningful variable names, organize your code, etc.
Thanka folks. This has all been great so far. I’m just reading along and I want to say how much I appreciate all the advice.
The order in which your program your game matters.
In general, start with your scaffolding (geography, descriptions, mechanics unique to your game, etc.). Then build your story on top of that (scenes, conversations, etc.) Your scaffolding doesn’t have to be perfect before you start to add your story, but you should have enough for a good foundation.
Doing it the other way can lead to spaghetti code, narratives that are more restrictive than you like, unimplemented objects, a less flexible codebase, and the unsettling feeling that you’re just tacking on features instead of building them in.
I’m reading all of this, and some of it I agree with and some of it I disagree with (even though I see that it’s reasonable), and it leads me to think: the most important thing, beyond any one best practice, is to understand how you do your work. It doesn’t really matter what that system is as long as it works for you.
For instance, I don’t comment my code. Mostly because comments get old and incorrect or they get moved to the wrong place. I rely on (in Inform 7) really explicit variable names and rule names to help me determine what’s going on later. (That and I just have the ability to read code and understand it really quickly.) The find function is also tremendously useful (which is why I don’t rely on the Volume/Book/Chapter… feature of Inform 7).
But that’s just me and it apparently is not the right thing for most people here. Which is fine. I was a software engineer for 16 years and I’ve been a computer science lecturer now for the last six years, and one thing I’ve learned is that everyone works differently. Find your way and then tailor your tools and environment and everything else to accommodate it.
Same here. I also tend to generate code with a ‘self-commenting’ aspect, using readable variables, explicit names, and so on. However, instead of comments directly in the code, I find it useful to document it at the beginning of certain sections, especially to indicate how to use it from another part of the program or to explain world model choices. Another thing I do is label the technical functions of the program (scope management, wayfinding, hidden object management, etc.) and tag my code to spot areas I need to adjust or check with each change.
In high school when we were learning PASCAL the advice was “always comment your code as if the person maintaining your code has a baseball bat and knows where you live”
With IF the person maintaining your code is you. If you’re a non-commenter like some of the others here then substitute “organize.” If you do neither of these you will forget how something works, why you did something, etc and either be mad at yourself or possibly abandon the project because you can’t be bothered to re-figure it out.
Even with one small WIP I’ve gotten mad at myself for being lazy and declaring a variable in the section where it’s used instead of with all the other variables.
Everybody has different naming conventions. Find one that works for you and stick with it. For example in I7 my truth states always include a hyphen. That works for my brain but might be maddening for somebody else. In general CamelCase names are your friend. Better to be long and easily understood than short and faster to type.
Test early and test often. I just had to rewrite a table because I didn’t notice it wasn’t updating correctly then had to rewrite all the places that check the contents of said table. If I tested it properly right after making it that wouldn’t have happened.
16 posts were split to a new topic: GitHub Discussion