Pre-release

Devlog:Updating doVerbAction

July 29, 2026

Across 7 years of development, I've left ever so many TODO notes, and seemingly left many features at about 95% complete. I offer this anecdote to illustrate how even long term stable features can eventually reveal themselves to be incomplete or poorly thought through.

Verb action hooks is a feature that's been stable for years. It allows authors to inject custom code when specific verbs act on specific assets. Now, AdventureJS can handle up to three assets in a sentence, such as: "throw rock at window with slingshot". In verb logic, these are generally referred to as direct object, indirect object, and indirect object2. But at a deeper level in the parser, they're just asset1, asset2, asset3. Verb actions can be called on direct objects or indirect objects. When a verb action is called, that call is made to whichever asset contains the custom code, which might be direct or indirect. Along with the function call, a parameter object is passed that contains references to the other assets in the input. So, for the longest time, when an asset reference was passed, it was called asset2, not to indicate its position in the sentence, but just because the asset hosting the function was considered asset1 and therefore any other asset, whether direct or indirect, must be asset2.

Then, I started working on a real game, Desert Drifter. In the pistachio breadcrumb example outlined in Fungibles and Stacks, the pistachios need to be whipped away when dropped in a particular room. To achieve this, I took advantage of the doMoveThatToThis verb action. This was the first time I had ever tested verb actions with a real world example, and the first thing I discovered was how confusing that asset2 was. Why is it asset2? Where's asset1? Of course I know why, but I didn't like the answers for other users.

Here is a truncated sample of that doMoveThatToThis function.

doMoveThatToThis: {
  pistachio: function (action) {
    const pistachio = action.asset2; // why asset2?
  }
}

I thought about this for a while and came around to the term target (and if there's a third asset, target2). It's a tiny change (apart from updating about two dozen files), but I think, a significant one, in terms of making it easier to explain the purpose of the parameter to other users.

doMoveThatToThis: {
  pistachio: function (action) {
    const pistachio = action.target;
  }
}

Though this is a small thing, it speaks to the constant effort to polish AdventureJS and make it a smooth tool for other authors to use.

← Fungibles and Stacks | All Posts | Cloak of Darkness →