Iron ChIF: Season One Episode 1 (lpsmith vs. Afterward, using Inform 7)

I’ve watched the video and come back to report to the general audience.

It was surprisingly compelling; there were a few points I thought the narrator would fall flat due to some mud, and some ducks make a surprise experience.

In it, the Iron Chif and his sous-chef discuss strategy. A scroll that changes the world could be a scroll that has ambient effect on the nearby room, but reading it causes a global effect. People don’t know that reading has a global effect, since reading is taboo, so they hoard scrolls for local effects, including a king hoarding a scroll for a sick daughter. Our hero is on a heist with a party.

Alternatively, scrolls could give people a diegetic save/load power. Maybe everyone. Maybe the whole world could save or load. How would that work? they ask (shades of Undertale?). Maybe people have to take turns saving and loading? They don’t figure it out. Back to scrolls!

Overall a good pre-cooking walk and concept. The role of the sous-chef seems critical here as a sounding board for our competitor and as a source of concepts.

Edit: I hadn’t noticed my esteemed fellow judge also make a summary of the contents. It’s interesting and striking to see what we both noticed and the differences between what we emphasized. It’s also striking to see my lack of perception of this thread!

13 Likes

It is, sadly, past 6:00. Fortunately, I only told my day 1 tester ‘the evening’, so it turns out giving myself a fake deadline was a good thing. Because a game… exists! And there’s a puzzle of sorts! And a bunch of descriptions, and an actual map, and worldbuilding.

There’s also a decided lack of things that the judges (rightly) worried I might be certifiably insane for adding, like NPCs that follow the PC around, and multiple puzzle solutions. I reserve the right to add both later! Part of the charm of this endeavor (especially trying to play it ‘completely open’ as I am) is that you’ll get to see all my false starts and design dead ends in real time as I discover them myself.

And while I predict that my github page will be more valuable in retrospect than as something to watch/check in real time, that doesn’t mean that anyone watching can’t…

Hang on, let me get into character again.

[adjusts wig, picks up cane]

Lucian springs up from his desk, crowing ‘Finished! Ha ha! Or, you know, finished for the nonce!’ He pulls out some sort of 3d-printed save icon, inserts it into his computer, performs an arcane ritual, then pulls it out again. "Hey! I have it! He peers into the audience, then frisbees the icon into an unlit corner of the arena where a quiet hand snatches it out of the air, and moves away. Lucian peers out at the crowd. “Hmm. You know, you don’t have to all just sit there like lumps, consuming this media circus we’re making for you. It’s a very fine media circus, but, you know… I got it!”

He runs into the wings, returning with a giant machine with a hopper at the top. He attaches a cable from it to his computer, then picks up a giant cardboard box you hadn’t noticed before, and dumps a metric ream more save icons into the hopper. He flips a switch, and icons start flying into the audience!

“Pick one up if you want! Works great, tastes terrible. You can find out what uncooked game tastes like! Or stash it for later! I don’t care. OK, I gotta get back to work. And I gotta sleep. We’ll see which one wins.”

13 Likes

This post (‘Parasocial Walkabout’) is the current leading contender for ‘thing about this competition that made me the happiest’. And it has some stiff competition!

Thank you; seriously, this is great.

6 Likes

We can see the challenger at work and get a first sense of the meal they are preparing! Just a note for those who like to check out his Inform source at the GitHub: this chef has chosen to keep his main story file very limited, and instead put most of the code in extensions. This means that going to the Iron ChIF Lucian.inform directory and then the Source directory and then the story.ni file will be of limited interest. The real stuff is happening in the Iron ChIF Lucian.materials directory, then go into Extensions, then go into Iron ChIF.

What do we see? Well, first of all, the challenger has chosen to have scrolls that affect the world around them without being read, just by existing. That’s why these scrolls are locked in tight containers that shield the world from their effect. Open the container, and a global change takes place – e.g., as we can already see, every single object in the world might unlock and open. I can’t wait to see what the other scrolls will do, and how they will interact with each other! Will the ‘open’ scroll ensure that every other scroll container is also opened? :scream: No, the chef has already thought of this and programmed in a magical excuse!

Meanwhile, this looks like it’s going to be a tight heist scenario, with mobile guards, and set in a world of bird people. Will it be forgiving and easy, or will the player end up mapping patterns of enemy movement so that they can, perhaps, optimise their strategy and win on their 376th attempt? Only time will tell. But the challenger seems off to a flying start.

11 Likes

As another little Inform 7 educational infomercial, let’s check out the code that @lpsmith wrote to summon mist – a key ability of the protagonist of his game. I’m adding some line breaks for forum readability.

The grey mist is a backdrop.

A backdrop is a special kind of object in Inform that can be in many rooms at once. It is ideal for implementing things that are (a) visible from many locations, such as the sky or a distant mountain; or (b) reappearing in many rooms, but can always be handled by the same code, such as a ceiling, if you have a reason to implement ceilings. In this case, if the grey mist gets summoned, it should be visible in every location, so using a backdrop makes a lot of sense.

The grey mist can be summoned or unsummoned.
The grey mist is unsummoned.

The first line sets up two possible states for the grey mist; the second sets the initial state.

The description is "[if summoned]Grey mist swirls and surrounds you, covering you like a blanket.[otherwise]The cloud layer today is too high for a naturally obscuring mist; you'll have to summon it yourself."

I experience a lot of pain when reading this – there is no ‘[end if]’! That’s almost as bad as having an opening bracket but no closing bracket. (But apparently it is legal in Inform.

Understand "cloud/clouds/gray" as the grey mist.  The grey mist is everywhere.

Understand lines set up synonyms. ‘Everywhere’ can, I think, only be used with backdrops. It tells us that the backdrop appears in every room.

Summoning is an action applying to one thing.  Understand "summon [something]" as summoning.

Here we set up a new action. The chef could have chosen to write a summon mist action that gets called by typing “summon mist”, but instead has written a general summoning action that can be applied to any present object. It can only be applied to the mist because the mist is present even when it is not summoned; as a backdrop that is everywhere, it is also there when it is in the unsummoned state, although I presume it will then never be described. Does this choice for a general action mean that there will be other things to summon during the game? We do not yet know.

The chef will now have to give us code for summoning other objects – probably just rejecting the attempt – and that is exactly what happens:

Check summoning something:
	if the noun is not the grey mist:
		say "You're a Bostrat: you can summon mist and clouds, but nothing else." instead.

Note that a check rule runs before a carry out rule. The ‘instead’ ensures that the rule reports failure, and so the summoning never goes to the carry out stage if the noun – the object mentioned in the command – is not the mist. Note, by the way, that the current implementation of this check rule ensures that nothing but the grey mist could ever be summoned.

Carry out summoning the grey mist:
	if the grey mist is summoned:
		say "You draw even more moisture from the air, feeding it into the mist.  It's still just as obscuring as before, but you feel safer, as you always do in the midst of clouds.";
	otherwise:
		say "[one of]Calling on your heritage as a Bostrat, you summon moisture from the air, and it slowly coalesces into a creeping grey mist, obscuring you from sight.  In gentler times, you would be doing this to ensure the growth of the fields and forests; now you must use it to hide from prying eyes that would keep you from your quarry[or]You summon an obscuring grey mist to surround you and hide you from prying eyes[stopping]."

This rule merely describes the summoning, but does not change the game state. Note that the ‘one of’, ‘or’, ‘stopping’ structure ensures that you see the text before the ‘or’ only the first time you summon the mist, and the text after the ‘or’ every subsequent time. This is a good structure to use when you want to describe an effect in detail initially, but don’t want to repeat all that detail later.

Changing the game state is done by the next rule – I’m not sure why this doesn’t happen in the carry out rule, but perhaps @lpsmith and I have a different idea of what ‘after’ rules are for! It is anyway unimportant, nothing hinges on the choice here. After rules run after carry out rules.

After summoning the grey mist:
	now the grey mist is summoned;
	continue the action.

All the action does is change the mist from unsummoned to summoned. The actual impact this has on the game will be coded elsewhere; for now the game can always check whether the mist is summoned, and react accordingly.

Wait, I forgot something.

)

15 Likes

Much has already been said on the subject of Inform 7. I would like to give a quick demo using some code from my project. I will show you how you can use Inform 7 to make connections between locations, so that the player can navigate your game environment with commands like >GO EAST.

First, we will establish a coordinate system.

A room has a number called latitude [POSITION FROM NORTH TO SOUTH]. A room has a number called longitude [POSITION FROM WEST TO EAST].

All the rooms in this project will occupy positions on this Cartesian grid, unless some of them don’t. Since I’ve stipulated that higher values tend toward east and south, it may be helpful to think of positions on this grid as analogous to cells in a spreadsheet. It would be useful to refer to a room with a pair of coordinates, like “(5, 2),” if not “E2.” I can almost imagine how to do this. But it’s too hard. Instead, we will express both numbers as a single two-digit number:

To decide what number is the coordinates of (loc - a room):
	let lat be latitude of loc;
	let long be longitude of loc;
	now lat is lat times 10;
	let add-coord be lat plus long;
	decide on add-coord.

By this method, the coordinates of the room with latitude 3 and longitude 4 will be expressed as the single number 34. This method only works if your grid doesn’t extend beyond 9 units in either dimension. And you can’t use negative values. And using 0 as either coordinate might turn out to be problematic. I don’t think this method will turn out to be very useful at all, actually.

For simplicity’s sake, let’s say we are restricting these coordinates to a 5x5 grid. Maybe we’d like to be able to refer to a room by its number in reading order across the grid—the one in the top left/northwest is room number 1, and the one in the bottom right/southeast is room number 25:

To decide what number is the counting-place of (loc - a room):
	let lat be latitude of loc;
	let long be longitude of loc;
	decrement lat;
	now lat is lat times 5;
	let add-coord be lat plus long;
	decide on add-coord.

That might be more useful. Maybe.

Anyway, with the latitude and longitude properties, we can say things like

Locker Room is a room. Latitude of Locker Room is 1. Longitude of Locker Room is 1.
Pool is a room. Latitude of Pool is 1. Longitude of Pool is 2.

It is easy to imagine how this pair of rooms would look from a bird’s-eye view:

LOCKER ROOM    POOL

However, when we compile this code (if it compiles), we find that using the command >GO EAST in the Locker Room area does not cause us to move into the Pool area. This is because we have not stipulated that the locations are connected to each other. To begin doing this, we can introduce a relation:

Leading relates various rooms to various directions. The verb to lead means the leading relation.

Locker Room leads east.

Pool leads west.

Now, when we picture an overhead view of those two rooms in our mind’s eye, we will see the connection between them:

LOCKER ROOM -- POOL

We are very close to being able to move between locations. All that remains is to combine the notions of “coordinate position” and “leading” into a notion of “navigable adjacency.” (One of the shortcomings of Inform 7 is its inability to synthesize these concepts without being explicitly instructed.)

Carry out an actor going: [generate exits when moving into a new room...]
	check exits;
	
Before looking: [...as well as when looking, I guess. this might not be necessary]
	check exits;

A direction has a rule called the connection-checker rule.
	
To check exits:
	repeat with dir running through {north, east, south, west}:
		follow the connection-checker rule of dir;

Connection-checker rule of east is the east-checker rule.

This is the east-checker rule:
	now nothing is mapped east of location;
	if location leads east:
		let this-coordinate be coordinates of location; [our current coordinates]
		let that-coordinate be this-coordinate plus 1; [the coordinates that would be directly to the east]
		repeat with loc running through rooms:
			if coordinates of loc is that-coordinate:
				if loc leads west:
					now loc is mapped east of location;
				rule succeeds;

Hey, the “coordinates” thing did come in handy! Well, now you see how you can let a player walk from one room to another using only thirty or forty lines of code. You may be able to guess how we’d formulate a corresponding “west-checker rule” allowing players to walk back in the other direction. Such a rule would have to say let that-coordinate be this-coordinate minus, of course. And we know the north-checker and south-checker rules would have to modify the current coordinate by ±10, since we recall how the coordinates property was assigned.

But you might wonder: Is it possible to construct similar connections in more exotic directions, such as southeast? What about “directions” like up, or down? It is good that you are wondering about such questions. Unfortunately, I am too busy to answer them right now.

16 Likes

I once followed a programming class in university which was taught by a rather eccentric professor. The first task he gave us, in an attempt to teach us Java, was to implement addition. Now you might think: but surely, Java comes with an addition operator? Yes, it does. But our professor had us use object-oriented methods to reimplement the axioms of Peano arithmetic, an extremely roundabout, memory intensive and slow method of getting the same results as the built-in addition operator!

I don’t know why this memory suddenly came back to me.

Looking now at the code of our esteemed Iron Chef Inform 7, it behooves me to say that there are indeed scrumptious possibilities being teased here. Putting rooms on coordinates with dynamically allocated directions between them is not something you would do every day… but you would do it in a game where the map can change radically during play. I did it in Kerkerkruip, which builds a random map each time you start a new adventure. Could @Afterward be working on a game where the magic scroll reshuffles the geography of the game world?! I guess we’ll have to wait and find out…

11 Likes

7 Likes

I think he might be – and think of the possibilities! Will this be a puzzle game where the player must rearrange the rooms until certain conditions are met? A psychological horror story where you have to survive in an ever-shifting maze? Or some kind of dreamscape where the usual rules of time and space simply do not apply, as @Afterward’s last statement seems to hint at?

Either way I hope the Keyboard Stadium is well stocked with graph paper, because I have a feeling we’re going to need it!

8 Likes

It appears to feature a Locker Room and a Pool, at the very least! Suggesting something like a gym as an environment?

Unlike the Challenger, whose commitment to total transparency extends to even a Github repository, our Iron ChIF is keeping his cards characteristically close to his chest! We only have a few crumbs to consider. Only a few hints to guess at the larger picture.

Will the Iron ChIF’s devotion to technical elaboration extend to player’s experience of the gameplay? Are we looking at something like The Wand or Inside the Facility here – games that require extensive outside-the-game mapping to manipulate? Perhaps something like the swampy maze in the Iron ChIF’s own Crocodracula: What Happened to Calvin is a better point of comparison. Or will all this technical complexity disappear beneath a smoothly elegant room-swapping mechanic, facilitated almost outside our notice by a magic scroll? I would personally guess that some puzzle is being served by these longitudinal and latitudinal room connections, and that the player will have to wrestle with it a bit, but one never knows…

9 Likes

2 posts were merged into an existing topic: Iron ChIF: Season One Episode 1 (Audience Commentary)

FINE

10 Likes

I did it this way because That’s The First Way I Tried That Worked.

I tried it in the first place because whatever I did first never actually printed the ‘if unsummoned’ code, and instead behaved as if the mist was already summoned even if ‘summon mist’ was the very first thing you ever did.

Possibility 1: There was a bug in my code.

Possibility 2: Inform 7 likes to run code twice as it executes ‘say’ statements and sends the resulting text to different text streams. It’s very possible to write code that both says something and changes the world state, and if the say statement depends on that world state, the second time it is run (the version that gets sent to the player) it’ll behave as if the world state was changed.

Thus: say things to the player in one stage of execution (carry out), then change the world state in another (after). Everything’s cleanly separated, and I don’t have to worry about I7 running things multiple times in the background.

Also, in all probability, it just fixed my actual bug.

9 Likes

The reason for the previous code is that it guarantees that the end of the quote is a period, which Inform uses to determine line returns. I have had issues in the past ending a quote with an “[end if]”, because sometimes, Inform then *doesn’t* put in the extra line return it does everywhere else.

The Challenger has my sympathies. I have wrestled with this exact quirk of Inform 7 many times myself. It can be a real hassle to wrangle all the periods and minimize the spacing issues!

6 Likes

Another day dawns on Keyboard Stadium, and I find it abuzz with activity while I slumbered! I suspect this dynamic will be a constant feature for me, which I will blame on the globe-spanning geography of this field of battle, enslaved to the relentless rotation of the Earth, and NOT my lackadaisical biorhythms. Does anyone else hear a portentous gong alongside each of the Chairman’s countdown posts?

I am impressed by the composure of our Competitors - going about their work with little (visible) sense of stress or pressure. The Iron ChIF announced himself with little fanfare and immediately launched into an explication of the early preparations for his dish. The Challenger concurrently displayed his table setting for the world to sample.

Their respective focus is fascinating: our Challenger jumping straight to PC magic; our Iron ChIF meticulously crafting hidden machinery on which to lay out his dish’s geography. Both engaging directly with the most technically challenging aspect of the Secret Ingredient - their worlds’ magical malleability!

And then there is our Middlebrow Horseman whose impulses echo my own:

TO DIVE INTO ALL THIS EXPOSED CULINARY CRAFT, AND SAVOR IT LINE BY LINE.

I find myself drawn like a moth to the flame of Inform’s novel syntax and constructions, contrasting it to more familiar programming paradigms and watching the code bloom like a sunflower before my eyes. I am simultaneously wishing to slow time to digest all this code, and aching for time to accelerate to provide more of it!

Regarding the teasing glimpses these provide of the final dishes, our War Rider’s observation on the Iron ChIF’s dish rings true:

This immediately jumped to my mind as well! As to our Hungry Horseman’s casual questions, this one in particular created some mild vertigo for me:

Would he dare DEMAND Inform fluency just to solve puzzles in the game?? Fold the technical explorations of the next four days into the dish’s player experience itself??? I don’t think this is actually what my fellow judge meant (nor, after saner thoughts prevailed, where I suspect the Iron ChIF is actually going), but for a mad moment the ground fell out beneath me considering the possibilities.

To regain my footing, let me just warn you all. At some point the impulse to contrast Inform and TADS will overpower the HEROIC resistance I am so far mustering. I don’t know when my mental dams will collapse under the pressure. Please have your eyes on nearby high ground, for your own safety.

11 Likes

Also, I did not want this comment to vanish, unexplored.

In the crucible of Keyboard Stadium, this may well be Survival Rule #1. The fact that my much more leisurely coding pace ALSO adheres to this tenet is immaterial.

11 Likes

Not Inform fluency! Heavens, no! I don’t think the Iron ChIF is that devious. But I wouldn’t put it past him to design some mind-twisting mechanic that propels the player through a labyrinth of dizzying logic. Alternately, I wouldn’t put it past him to design something incredibly fluffy and genuinely pleasant and non-confrontational!

But the intricacy of this particular design… the sheer lengths he has taken to re-engineer one of Inform 7’s most basic systems, one of its easiest-to-implement systems… does seem to suggest something devious is brewing.

9 Likes

Our challenger has invited us to his brainstorming and is developing in public, and taking this fearless transparency to even bolder heights, the project’s README features a tally of his open browser tabs!

As others have noted, the story file itself is fairly bare, leaving the heavy lifting to extensions.

Inform authors perenially ask What’s the best way to structure your project / organize your code?. The question’s recurrence no doubt owes something to a feeling like it never really gets answered.

Because the inevitable answer is it depends. And however dissatisfactory it may seem, it’s still the correct answer.

What’s most important in your story? How are you implementing things? What parts of the world model or Standard Rules in general are you changing and how? How big is it? How are the elements of your story similar to or different from each other and when? How big is your story? What makes sense to you?

Have a separate file on a per room basis? Sure, maybe. Or per region or scene or significant new command? The answers are “sure, maybe” all the way down.

Once you have an idea for how you want to separate things, using extensions to do so is a tried-and-true practice (though the current development version of Inform offers a new way to place code in separate files).

At the time of writing, I see these custom extensions:

  • Map
  • PC and Rucksack
  • Rules and New Actions
  • Scenes

or, places, the player character and their things, custom actions, and scenes. Or, perhaps, if one squints, setting, character, conflict, and plot structure.

Things move quickly in Keyboard Stadium, so I’ll refrain from attempting commentary on the content… for the moment.

10 Likes

This morning, I have rediscovered for the umpteenth time that if, as a writer, you’re not happy with your Writing Plan, you will find ways to avoid it. I knew I had to implement a Getting Chased scene. It’s the obvious next step. I didn’t like it.

Instead, I futzed with stuff, fixed small bugs, reimplemented things that were already working, implemented a post-chased scene (the one actually useful thing I did), and considered just avoiding it entirely and implementing more later-in-the-game scenes where I already knew what I wanted, figuring that’d give me time to ruminate on the Chase in the back of my mind for a while.

Then I remembered that I have to send this to @Sargent tonight, and if I’ve worked on stuff he can’t find, that’s a waste of a fresh beta-tester; he’ll only see the same things that Sarah already commented on.

So I finally buckled down and filed my own bug report. I just free wrote what my problems were and what my vague ideas were. Then, happily, I drifted to an actual solution that I liked. One that feels the same as my feeling yesterday, when I knew what I had to do and how to do it.

It took like ten minutes. Why didn’t I do this earlier? This competition is accomplishing one of the things I had already hoped it would, namely: point out to myself where I was failing.

With any luck it’ll now morph into ‘point out to myself how to do better’, but I’ll take what I can get.

And now I have a dentist appointment, but at least I can think forward instead of thinking in circles.

13 Likes

The siren song of code to paw through proved too great, and I am now in quandry. It is clear that the more I paw through, the giddier I become and also the MORE SPOILERED I become!! I need to mull over my competing impulses: to gratify my OWN fleeting joy, or honor some platonic ideal Judging responsibilities. That is usually a completely unfair fight. Buuut presumably the code will still be there after the lights in Keyboard Stadium dim?

While I grapple, might @Zed or my fellow Horsemen enlighten me on Inform’s “Test” construct? I have not successfully aliased that yet.

2 Likes