The event loop is the least interesting part of Annales, but it took the most effort and time. The basic idea is that there's a structured variable which describes the current state of, well, the state. Each year, the code runs through a loop of events (deaths, tribe activity, disasters and omens, buildings being built or destroyed, intrigues) each of which has a likelihood, based on factors like an individual's age, whether there's a ruler or not, and so on. For each of the events, a function returns a TextGenCh which generates a description of what happened, and an updated version of the state variable.
Where this got complicated was in succession and warfare. If the ruler dies, there needs to be a way to pick a succession from his heirs: if this doesn't work, we go into civil war mode, and pick a bunch of rival claimants from the current population of the court, who then battle each other until there's only one left. It wasn't until I was coding the algorithm for choosing a successor from the current list of heirs that I realised that a real-life law of succession is, in fact, an algorithm, and that which of these algorithms is the correct one to apply over a given territory or family is a question which has had world-historical significance. People fret about being ruled by algorithms now, but algorithms have ruled rulers for a long time.
There is an algorithm for inheritance in Annales: there are actually a couple, somewhere in Annales.Succession, and in theory one could extend the model to allow for the algorithm to change, or for a civil war to be waged between the rival results of different algorithms. In the end, I ran out of time to do this, or add things like a higher chance of assassination to heirs apparent, so the result is plausible but without any genuine sense of crisis.
I had to spend too much time refactoring the events code to spend enough time writing a variety of battles, assassinations, courtier activities and so on. (I really shouldn't have used TextGenChs as representations of people in the first draft, this caused endless unnecessary problems down the track.)
So it's not quite the result I hoped for. I am proud of the title page text, which I wrote at the last minute:
Being a faithful narration of the history of the realm from the reign of Fobbial Artesia I to the present day As transcribed by the algorithm annales-exe using the pseudo-random seed 1835917550 1 during the reign of Armey Engine III
The "pseudo-random seed" is a value which Haskell generates each time the program is run (from a random number source in the operating system). You can pass a value for the seed into the program at the command line, in which case it will produce exactly the same output as it did before, provided that all of the vocabulary files are also unchanged. What was really satisfying about all this was that I discovered a typo in the descriptions code after I'd published the last version before the NaNoGenMo deadline. By fixing the bug and re-running the program with the same seed, I could recreate all 50000+ words of convoluted nonsense and imaginary intrigues, all exactly the same, except that now "replete" was spelled correctly.