Friends! Hello. Welcome back. You may recall from last fortnight’s entry that I was unfortunately Not Having A Good Time, and I’m pleased to say that things have improved overall on that front. The injury’s pain level and the degree to which the injury was stopping me doing stuff (both physically, and mentally in the sense of distracting me and massively lowering my spirits) have both declined. They have not yet declined to zero, but they have improved markedly in these past two weeks. Pain levels are lower, mobility and everyday physical stuff has improved, and my mood has gone up as well. As such, it is with pleasure that I can say I’ve actually been able to do some work on URR again. While this entry is going to be a much shorter one than I normally aim for, shorter is still better than zero, and I’ve really enjoyed it and actually made some serious advancement in just the few days I’ve been able to give it during this past fortnight. I decided the thing to work on here was quest generation architecture. This is a huge, major thing, but I’ve often found in the past that when I’m below full strength, I find it very hard to finish off something in progress, but much easier to just work on something completely new. I’m not sure why that is, but somehow the latter is just less mentally taxing to me than the former. So, I’ve spent some time laying down the groundwork for quest generation, and it’s actually really cool what I’ve been able to put together with even a relatively low amount of time and low amount of energy. The game cannot yet generate a quest, but it has actually moved a striking distance towards that target in just this one block of dev, and I’m excited to talk about it. There honestly aren’t too many screenshots this time around, as a lot of this work is under-the-hood stuff, but it’s cool and exciting nevertheless.

Without further ado:

Quest Generation Architecture

At the start of this fortnight’s progress, I sat down and defined make_a_quest. This was itself something of an exciting milestone, and once I’d done so I actually found myself sitting back, trying to gather all my brainpower and everything I’ve learned in 15 years of programming (and 15 before that of very active modding) to make this function as clean, crisp, and efficient as I possibly could. Indeed, quite a lot of my time in this block of work was honestly spent just staring at this function, trying to figure out to process the required complexity. Multiple times I just stared at the file, listening variously to the soundtracks to La-Mulana, One Must Fall: 2097, and Halo 2, pondering what the hell I was actually supposed to write here in order to make this thing come to life. One half of the required complexity, as I’ve talked about before on the blog, comes from inputs. What’s the information the player has to solve this step in a quest? In 0.11 it’s all going to be notes that you’ll be collecting along a quest, but in the future it’ll be books, scrolls, tablets, the appearances of things you might find all over the world, and conversations with NPCs. While we’re only going for the notes option now, I felt it was important to have the structure in place later for other information sources to be easily added, rather than just building it for notes-only now (i.e. nothing that cannot be immediately given to the player) and then having to go back at some point in 2027 and rebuild the whole thing. I’ve often lamented how (in my earlier coding days) I probably didn’t think quite far enough ahead, and I’m trying to avoid making the same mistake here. As such, I started from the foundations and began by asking myself what this function needed to begin with, and the answer was the selection of a difficulty, and the creation of a quest that would consist of multiple steps, and each step would be generated using inputs and outputs to move the player onto the next section, and to scale appropriately according to difficulty – so a high-difficulty one would have more steps, and harder steps, and I’d be able to adjust the difficulty for each type of step separately.

Difficulty will, of course, percolate down through all steps, with how the difficulty is actually implemented differening for each thing. So, a “high” difficulty quest might have a larger number of steps; then a “high” difficulty quest might select tougher steps; then each of those steps might be generated at “high” difficulty, so if for example it’s a rhyming riddle which is looking at the world map to find things to talk about to triangulate a location, it might look further afield (i.e. more map tiles away) than might be the case otherwise. Equally, if it’s describing a nation, the “high” difficulty step (as part of a high difficulty quest) might pick more obscure traits of a nation to use in the rhymes rather than simpler traits. Anyway, I started off here designing a quest option that is simply starting at one map tile location – where you get the clues – and taking you another nearby(ish) location, as the outcome of the clues. Each of these options is variable, however, so you could have a quest that is starting you off in a nation, or “in” a religion (from the point of view of the generator), rather than in a specific map tile. But as is often the case with these things, it’s good to get one version generating first without much variation, and then extend and widen the variation more and more – so we’re starting with that model, which is probably realistically going to be the model for every quest generated in 0.11. As such, I implemented some values for how far from a single map tile another single map tile the quest is pointing towards could be (easy = 10, normal = 25, hard = 50, ultra = anywhere on the map) and then just as I’d set the “starting” form to a single basic type in order to first implement and test things, i.e. you are setting off from a single map tile, I also then developed code for that being one of the potential quest outcomes, i.e. that you are being pointed towards a single tile. As above, this will be varied later into other things, e.g. being pointed towards a particular religious building type, for instance, in which case any building of that type would be wholly valid. Next, I set up a system for setting up requirements and exclusions, within this “point the player to one map tile” quest type, that would be required – e.g. maybe it has to be a city, or it has to be a mountain, or whatever it might be. This then yielded a set of potential spots within the area being checked by the difficulty level, and suddenly I was part-way through a very basic and streamlined version of the quest generator: taking the player from one map tile, to another, via riddle.

At this point I needed to develop how the clue components for “Find A Single Spot”, as I’m calling it in the code, would be handled. This, again, will be massively expanded later on, but I want to get all the pieces in place now for 0.11 and for options in the future. So for my initial testing I decided on three possibilities – a four-stanza rhyming riddle, a two-stanza rhyming riddle with a local map clue alongside (so those stanzas would tell you the world map part), and a two-stanza rhyming riddle with a world map clue alongside (so those stanzas would tell you the local map part). This is the kind of key variation I want to get into 0.11 because it will use all the existing time I’ve spent working on the generators for, well, the rhyming location riddle pieces, the world map clues, and the local map clues. This means that it’s finally time to conclude polishing and finishing off the final remaining pieces of some of these riddle generators – but first, because the two world map riddle generators work absolutely perfectly, I would be able to do a first full quest generation test! Very exciting. Except, er, actually it turned out that the specific location riddle generator had an issue I hadn’t discovered before. This was a frustrating moment and I had to spend quite a bit of time debugging what was actually going awry here before I was able to pin it all down, but soon I had the quest generator able to successfully generate the foundation of a step in this one-step test-quest, i.e. taking you from one select spot to another, and actually giving you correctly the first two stanzas of the riddle in question (for the nation, and the specific location in that nation). So far so good! This generation element was taking account of all these questions about difficulty, distance, trying a few times to generate something and then giving up and trying something else, and all these various important pieces that need to be in place. That said, some work needed to be done here to fix a few errors and imperfections in the generation of the second stanza – pointing you to a single place – and so I spent a while polishing this and making sure it produced slightly crisper and cleaner outcomes than it had previously been doing.

‘Where many walls bear hanging strips of precious cloth,’

‘And with deadly sharp wrist-blades these warriors cut a swath…’

‘Where a great downpour pools in a shade beryl, in the near east,’

‘And the femur of a bird of flames climbs high, northward without cease’…

I then decided I wanted to get this first half generating in the quest generation for the map instead of the riddle variant too, so went over to fully integrating world maps into the main game rather than the testing file. This took a little bit of time because of some slight (slight, I swear!) ineptitude in setting up the generator in the first place, but it didn’t ultimately take too long, and I soon had the game able to select a location in the quest generator, throw up a world map for it at the appropriate difficulty, and add that (for the sake of testing) straight into my inventory so that I could take a look at it. This was an excellent development but also highlighted that something really needed work here – specifically, the imposition of symbols into the notes. I realised at this point that I’d only left this as a placeholder from previous work, and right now it basically picked a random symbol from a relatively small set to insert into the map, rather than a specific symbol which actually made sense. Er… whoops. So, this then became quite a substantial piece of work, but I’m now excited to say that I think this system is working correctly! To implement this I needed to work through the entire symbol database and figure out which symbols could be used in what possible contexts. For example, the “camel” symbol should be an option to appear on a map if the entire area’s name contains “camel” in it (e.g. the Red Camel Sands or whatever). Eqaully, certain symbols should reflect the civilization that controls that part of the map, e.g. a pair of chains on the map might tell you the civilization in that area practices slavery, while a shuriken might show that their preferred throwing weapons are shuriken (the latter being much more obscure than the former, and so being something that might be for higher-difficulty world map clues). This is no small job, but it needs doing for 0.11 and I’m now really happy that this system will be successfully and consistently able to select symbols which are actually logical and appropriate for the area! It’ll be really cool, and while I’m still actually not sure whether these make the maps easier or harder, amusingly (I think they make them easier…?) that’s something playtesting will have to tell us. For now, though, the first half of each quest step can now be made as a map note, or as a riddle note.

With that done… well, unfortunately, my fuel and time for the fortnight began to run out. But the quest generator is now functioning, in a basic sense, and can produce partial quests, within quite tightly bound constraints! This might not sound like much, but in a sense, all major features start here – produce a small possibility space successfully (I mean, “small” in a given sense…) and then expand up rapidly from there. While I’ve of course previously been able to generate these rhyming riddles, and generate world maps clue, the key point here is that only now are they generating within a quest generation architecture rather than just as free-standing things I’ve been testing. That’s the real step forward this fortnight, although it was also useful to – in the process – identify a number of issues with all these generators I’d actually missed first time around. This means I’m only a little bit of work away from generating the second half of a quest step, and that is only a little bit of work away from making one of these generated quest steps solvable (i.e. the game will recognise when you do whatever it is you’re being told to do), and then suddenly… well, suddenly we’re off, at that point.

What next?

And that’s all this time, friends. Even though this last fortnight has been genuinely tough and featured barely any days or times in which I was able to find space, and mental space, to get coding done – I’m actually pleased and excited by what I’ve got in here. While a lot of my URR time was honestly spent staring at a blank screen trying to figure out just how to create and manage the information required in this architecture, I do think I’ve been able to come up with the foundations of something really robust and impressive here. It will certainly serve our purposes for 0.11, but will also be something that I’ll be able to add to later in a modular manner by consistently and gradually adding new information sources – such as books, or NPCs, or whatever it might be – and by adding new clue types, and by adding new outcome types (i.e. what you actually need to do for the game to register a riddle or clue as “solved” and thus activate whatever is meant to happen, e.g. a lock unlocks, a chest is unearthed, a secret door or staircase is revealed, and so forth). Right now, therefore, the game can produce the first “half” of a clue for a quest (i.e. the “where in the world?” part) that is pointing the player towards a specific single spot (the only type of quest step I’m implementing right so), and do so appropriately while keeping things like difficulty, proximity, complexity, and all those kinds of things in mind. The overall architecture and infrastructure for make_a_quest is also one of the key deliveries of this fortnight, even if I can’t really “show” anything for it at this point since it’s all about data management, but what’s in place here should absolutely get the job done. Given how genuinely vile the last few weeks have been, I feel glad I was able to get something done, and make a push towards the “beginning of the end” – i.e. the start of the quest generator, which is 0.11’s last substantial thing. More broadly, though, I think it is realistic to assume a 0.11 release now in the first quarter of next year instead of the final quarter of this year. This sucks, but I have to be realistic – I’ve lost the better part of a month to this injury and its fallout, unfortunately, and that was a month I really, really, needed, to push for a 0.11 release this year. Nevertheless, so much of the release is done; all we really need now is the quest generator (which is suddenly now really coming along!), a few polishes to a handful of systems, playtesting… and then that’s it. We’re really, really close – even if it’s going to be a couple of extra months, I suspect, until it’ll be time to launch.

Anyway, that’s all for this fortnight, aside from one important piece of housekeeping – I hope to send out the first demo versions to test in the coming week or two! This will have the tutorial quest and everything except the main quest generator in it – if you’re not already on the list but would like to be a part of this playtest, please send me an email at the main body of this website between “www.” and “.com”, and do so at gmail.com, and let me know you’d like to be included :). I’d expect those emails to go out before the end of November, assuming things continue to improve and stabilise at their current rate. With that said, thanks so much for reading this week’s entry; please do let me know your thoughts; and I’ll see you next fortnight, where I hope to deliver a finished quest generator for 0.11, which would be a milestone amongst milestones.

Fingers crossed.

Leave a Reply

Your email address will not be published. Required fields are marked *