Devlog:Fungibles and Stacks
July 28, 2026
Near the end of December 2025, my attention was caught by an announcement for Text Adventure Literacy Jam 2026.
I was intrigued by enough by TALJ to want to submit a game. Though AdventureJS wasn't in a state to release to the public, it was certainly workable enough that I could make a game within its known limitations. So I worked up an idea that I liked, did a little research, and started roughing in a small game. And then, I decided that my very first puzzle, a desert sandstorm faux-maze, needed an infinite sack of pistachios to use as faux-breadcrumbs. But I hadn't yet gotten around to supporting fungible assets, aka identical items like coins or nuts or grapes or breadcrumbs. This was a feature I had put on the back-burner for years, and always considered a simple problem...
I immediately got started on a fungible system:
- I wanted authors to be able to set built-in classes to be fungible, which meant I had be able to dynamically add a static fungible flag to an already built-in class so every new instance would be fungible.
- For better or worse, the AdventureJS parser doesn't acknowledge words for classes until there's an instance of the class in the game world, so I created a new, abstract Platonic class, so that a Platonic instance could act as a stand-in for fungible assets that hadn't been created yet, and then at startup copied all of a fungible class's language to a platonic instance which sat off stage (so to speak).
- I had to revise all my asset listing routines (i.e. for inventory, room content, disambiguation prompts, etc) to handle multiple identical instances, so as not to say things like "you have a pistachio and a pistachio and a pistachio" or "which pistachio did you mean, the pistachio or the pistachio?".
- Samesies for pronouns/contractions/verbs (ie
it'svsthey'redepending on number of objects) - Then, because keeping track of multiple identical assets was becoming problematic, I implemented a special Bundle class which could stand in for multiple instances for certain handlers.
And at that point, after going down that path for two or three months, I finally realized how stupidly over-complicated it all was.
So I ripped it all out and started over.
This time I started with a new state class, Stack, which could be added to any asset. State classes are not assets but get appended to assets and contain specialized properties and functions. I use this pattern frequently, for things like Asset.Is, Aspects, Vessels, etc. Stack adds quantity management to assets: one asset can represent many. The Stack class owns all the methods to handle quantity, merge multiple stacks, spawn new stacks, divide among new stacks, delete empty stacks, and control options for how to handle enumeration, like "you have 3 pistachios" vs "you have three pistachios" vs "you have several pistachios".
Then I had to revise all my object listing methods and pronoun/verb/contraction handling – again – to handle stacks; show stack counts on inventory lists; update name and pronoun handling to reflect singular or plural status; and ensure that placeholders like {it's} and {they're} render accordingly. Though this went more smoothly now that I didn't have to account for relationships between three interlocking classes.
In the end I wound up with an object definition that looks like this:
MyGame.createAsset({
class: "Pistachio",
name: "handful of pistachios in the pouch",
place: { in: "small pouch" },
description: `The small handful of pistachios isn't much, but it's about all {we've} got. `,
stack: {
use_stack_name: false,
dispenser: true,
quantity: -1, // infinite
max_quantity: -1, // infinite
max_per_take: 3,
max_stacks_in_game: 20,
max_quantity_in_game: -1, // infinite
spawn_properties: {
max_quantity: 10,
},
},
})
That's all an author has to know about. All the Stack logic is handled automatically under the hood. If you take three pistachios from the pouch, now "you have a pouch and three pistachios". The spawned set of pistachios are distinct from the original dispenser, but they're both pistachios. Disambiguation has per-verb preferences to decide which type of pistachio object you're likely to be referring to, so there's no "which pistachio did you mean?" nonsense.
Anyhow, TALJ long ago disappeared into my rear view mirror. But overall, the stack system seems much more rational than the fungible/platonic/bundle system, so it was worth the time to remake it.