My inclination for this untitled game, is to sketch out the kind of interface I want for it, and sketch out even simpler "games" that basically just need that bit of interface.
From a UI perspective, a shop interface needs the ability to input numbers in various places.
Because it needs many numbers, I believe I shouldn't try to have the "shopping" logic handled in Ink. I'm leaning towards the idea of an Ink-based setup that uses no external functions, it's just driven by the host application in a somewhat odd way. So, instead of Ink running comparisons based on user input, the "shopping" logic would run outside of Ink, then give back control, possibly after updating some variables, possibly not.
It seems to me that one of the things I want to nail down early is whether to hold most of the data in Ink, or not. One approach I could take would be to base conditionals in Ink on external functions with a default implementation of always returning true. That way, the data can be arbitrarily complex, I can try to avoid state in the story json, and only my stuff can break on saving and updating. But it's clear to me that I need some kind of design sketch if I'm going to figure this out. Maybe the right solution is to work my way up to a prototype that stores all data in the story, and I just see how far I can get. But, again, this needs a design to work towards.
Since this is a diary entry, and I didn't get much towards that part of thing, I'll mention one of the other things I've been doing that I kind of alluded to. I've been messing around with Crafting Interpreters; I've gotten up through chapter 6. The catch is, I'm so burned out on Java, I'm porting the code to Lua as I read. This is an interesting exercise, and I'd recommend it to people familiar with Lua and the source language of whatever they choose to port. It basically forces you to consider, when the source leans on some language feature, which part of it is actually necessary to accomplish the goal. I have yet to actually define anything that acts like a concrete superclass, so that's cool. I'm kind of slowing down for chapter 7, because it's becoming clear that I need to take a step back and define something similar to exception types, and an equivalent of catch blocks.
Thinking about it in detail, something that looks good would be, like, there's a function that takes pcall arguments, but instead of returning the result, it returns a function that takes a message type and a function. If the message matches the type, then pass it to the function and return the result, otherwise propagate the error. If, shock of shocks, everything actually works, pass the result. Now, should it be possible for the calling code to easily tell that an error occurred? I don't see any reason having the information would hurt code quality, except that it would always have to be handled if it were present. I could try defining it both ways and see which one I use. That was quick to throw together; I'll try it out tomorrow.