Code structuring - Primarily in Inform


#1

I love looking at other’s source code, almost to a fault as I spend more time reading others code rather than writing my own sometimes, so I’m always interesting in reading commentary on the decisions made and why they were made.

So my first question along those lines involves, the overall structure of an Inform application (for the most part I’m interested in Inform 7, but there are good things to learn from all languages).

  • How do you break down your headings? What rhyme and reason do you use? And how does it help you work through your code?

  • When do you decide to break part of your game out into an extension? Obviously if you have something that could be reused elsewhere or by others, but I’ve extensions that are very specific to the individual game. What would be the motivation there?


Inform IDE
#2

I seldom use “Part” headings but always make use of the others. Volume One, Book I, Chapter 1, Section A, like an outline. If a section gets to about two screens of code I try to break it off into another section if possible, though that doesn’t always work.

Usually I don’t make an extension until I find myself needing that same code in another project, or someone else requests it. Until then it goes in the “Volume Zero” of that particular work.


#3

I thought it was just me who forgot about “part!” But it makes sense.

I know that I try to start with organization but it soon falls apart if I’m not careful. So I wrote a PERL script that flags what is where. I know the Inform IDE has it, but it’s useful to be able to cut and paste stuff and pull it around.

However, I’ve found that looking at outlines IMMEDIATELY helped with organization for this project and future projects. It’s also neat to see which volumes are bigger or smaller. I also find I prefer to use volume more aggressively than I used to. Each volume should be critical for something. But it’s amazing still to see how things are misorganized or could be done better.

My new outline would be

volume browsing notes globals and types
volume verbs and actions
  book redefining (e.g. the block buying rule is not listed in any rulebook)
  book standard regular verbs (take etc)
  book standard irregular verbs (jump etc)
  book nonstandard regular verbs (credits/about etc, maybe even XYZZY)
  book nonstandard irregular verbs (stuff specific to the game, like ANALYZE or whatever)
volume big tables (random or otherwise)
volume region 1
  book any region specific verbs
  book room 1
    chapter NPC 1
    chapter item 1
    chapter room specific verb 1
  book room 2, etc.
volume region n
volume npc interactions like talking
volume parser errors and abuse (this is worth a volume as it's important to direct the player--"abuse" may be the wrong term, but stuff like modifying the player's input)
volume end of story options (like AMUSING list, or restarting narrative mode)
volume beta testing - not for release (I have a script that strips out the "not for release" and builds the file elsewhere. This is for testers to jump around without risking players having those loopholes.)
volume hints (very important to me. Justify the game to yourself and the player)
volume testing - not for release (this is for me to hyperspace around)

Anyway, this is a rough outline. In fact, I didn’t really use it before, but poking through my Roiling and Shuffling source code was instructive enough, I think I realized how much the organization helped.


#4

Did you see Ryan Veeder’s mnemonic for this? https://twitter.com/rcveeder/status/632344324626235392


#5

That’s just great! Though I forgot to mention, I like to think of a favorite author’s works. Volume 1 of O Henry’s Short Stories contains 2 books he published, and they’re divided into parts (rural and urban.) Or, well, any long book you liked–it probably has parts then chapters.

It’s a bit ponderous, but it’s an example where, yes, a book does have a part.

Also, Very big plans can soar.

Or if you’re a total extreme programmer type, Visual Basic, Perl, C#.

Ryan’s is probably easiest, but hey, mine works for me.

EDIT TO ADD: I probably used “VBCS” as a mnemonic unintentionally since a product I test has both VB and CS code.


#6

I have to use sections since for some reason on Mac I don’t get the “jump to error” link arrows in the IDE.

I am totally using RV’s Very Bad People Choose Sin to remember, but since I couldn’t remember the heirarchy I make everything a Volume with an occasional Chapter.

When I was writing Transparent I ended up sort of accidentally organizing kind of by room.

Volume 1 - Release and Setup
Volume 2 - Help and About
Volume 3 - Figures
Volume 4 - Sound
Volume - Startup
Volume 5 - Global Backdrops and some adjectives
Volume 6 - Knocking
Volume 7 - Electricity
Volume 8 - Lighting
Volume 9 - Doors
Volume 10 - Photography
Volume 11 - Darkness/Flashing
Chapter 1 - Images
Volume 12 - XYZZY
Volume 13 - Mansion
Volume 14 - Sunset
Volume 15 - Front Entrance (start)
Volume 16 - Phantasms
Volume 17 - Camera Equipment
Volume 18 - Peristyle
Volume 19 - Bottom of Ramp
Volume 20 - Entryway
Volume 21 - Foyer Gallery
Chapter 1 - Door Sounds
Volume 22 - Bottom of Stairs
Volume 23 - Top of Stairs
Volume 24 - Corridor
Volume 25 - Hidden Statue Garden
Volume 26 - Elevated Window Passage
Volume 27 - Visitor Entrance
Volume 28 - Ticket Counter
Volume 29 - Stable
Volume 30 - Stone Steps
Volume 31 - Portico West
Volume 32 - The Kitchen
Volume 33 - Cellar
Volume 34 - North Upper Hall
Volume 35 - West Upper Hall
Chapter 1 - Door and Chair Madness
Volume 36 - Library
Volume 37 - Study
Part 1 - Guest Code by PaulS
Volume 38 - Sitting Room
Volume 39 - Parlour
Volume 40 - Dining Room
Volume 41 - Ballroom
Volume 42 - Conservatory
Volume 43 - Nursery
Volume 44 - ButlersQuarters
Volume 45 - Boudoir
Volume 46 - Attic
Volume 47 - Master Bedroom
Volume 48 - Playroom
Volume 49 - Drawing Room
Volume 50 - Vault
Volume 51 - Studio
Volume 52 - Master Bath
Volume 53 - Servant Quarters
Volume 54 - Garage
Volume 55 - The player
Volume 56 - Ghostcalls
Volume 57 - Butler
Volume 58 - Earnings
Volume 59 - Standard Ending
Volume 60 - Alternate Ending
Volume 61 - Not for release
Volume 62 - Library Messages and Stupid Commands
Volume 63 - Okay, fine FEEL AROUND
Volume 64 - Exit Helper


#7

I think there’s enough to skip over “parts” for the most part, too. In fact, 3 divisions may be enough. At some point, too much organization becomes counterproductive.

Volume = region
  book = general rules etc. specific to the region
  book = room
    chapter = a single person
    chapter = an important object
    chapter = all scenery (note: each scenery could have a chapter too)
      section = unimportant scenery
    chapter = particular rule special cases for this room

Now that I’ve written this out I see how so much of my code violates this simple organization. Fixing it will probably turn up some small things, too…seriously, a complete code review can turn up so much neat small stuff in the way playing through the game again can’t. And it’s pretty quick, since I’m mainly looking for game text and bad goofs. 500 lines a day is a good pace. So I recommend it.

EDIT: being able to search for "chapter (person/thing name) is really awesome, too. So I recommend organizing code totally. Also, this helped me get along with refactoring the smallest section of Roiling, so yay.


#8

One more thing, because I’m posting…here is my shell program in perl. If it’s not super clean code, it works, and it indents/spaces things too.

open(A, "story.ni");

$spc{"volume"} = 0;
$spc{"book"} = 2;
$spc{"part"} = 4;
$spc{"chapter"} = 6;
$spc{"section"} = 8;

while ($a = <A>)
{
  $line++;
  if ($a =~ /^(book|chapter|part|volume|section) /i)
  {
    chomp($a);
        $ash = $a; $ash =~ s/ .*//g;
    $b = $a; $b =~ s/ .*//g; $c = " " x $spc{$b}; #print "$spc{$b} spaces for $b.\n";
        $inc{lc($ash)}++;
    print "$c$a ($line)\n"; }
}

for $x (sort keys %inc) { print "$inc{$x} of $x.\n"; $total += $inc{$x}; }

print "$total total breaks.\n";

close(A);

#9

I agree, I have a tendency to over organize my stuff and then find myself spending too much time trying to organize and then find some.

I try to limit my organizations to 3 (Volume, Books and Chapters), occasionally throwing in a Section if something just “needs” it’s own section.

Perhaps this could be another thread, but there are some things in the standard Inform editor that could be improved upon to make the code much easier to navigate around…I’m thinking a go to definition, find usages, maybe even some break points and the ability to step through code? This may be difficult to do, but it would be an interesting problem to try an solve and I could see where it would be very helpful to development.


#10

I think a new topic would be a good idea. I know I don’t even use the Inform editor much unless I really need to test something. I use the command line to build things, and I use the “go to” feature of notepad++. (e.g. go to line X.) But I don’t have the oomph to write out a proper good first post.


#11

One of the more challenging parts of organization I find is trying to arrange things consistently so I can find things. I’ve taken to putting cross-reference notes so if a rule could reasonably fit in more than one section, the notes will remind me where to go, so I don’t end up with pieces of related code scattered all over.

I tend to use a lot of headings because it makes it faster to find what I want from the table of contents. When a part/chapter/whatever starts to get a lot of sections in it or a lot of rules with no clear way to organize them (for example, a chapter with all the new kinds, or all the special verbs) I will sometimes put the subsections in alphabetical order.


#12

Interesting topic. I never used “volumes”, “parts”, or “chapters”. Instead I opted for “sections” In my first Inform7 game, I tried to actually have these sections in order of the player progressing through the game. In contrast, my 2nd Inform7 game I created sections for organizations, but sections exist for nothing but certain actions, etc and follow no certain order.

Hallow Eve main source page listing sections: http://retrolab.servebeer.com/lab/projects/if/HallowEve/Release/source.html

Lunar Base I main source page listing sections: http://retrolab.servebeer.com/lab/projects/if/LunarBase1/Release/source.html


#13

I go back and forth in how I structure mine…I think secretly, I enjoy refactoring and restructuring my code so much I change my structure every few days. :smile: In reality, and to @AndrewS point earlier, the process of reorganizing things, often reveals issues or improvements that would have been missed otherwise.


#14

So apparently there’s a “renumber all sections” menu option in the Inform IDE, which I didn’t realize was there until fairly recently. Nice. I have gotten used to not using numbers, though.


#15

Oh my lord…I never saw that there…that’s pretty awesome…I’ve always avoided numbering them myself as well.


#16

In the Mac IDE, I don’t get those hyperlink shortcut arrows in the error messages, so I have to find the error myself. I’ve gotten good at it.

I do really like how if you add a volume/chapter into the middle of a source text divided into numbered sections, it renumbers on the fly for you!


#17

Does it only do this in the Mac version? I couldn’t get that too work.


#18

Now that you mention, it seems like I might have had to check a box to enable it. Yep. On Mac under “preferences” then editing tab, check “Auto Number Sections”.


#19

Just checked the windows version and that doesn’t appear to be an option under preferences…bummer.