NaNoGenMo / 2023

National Novel Generation Month, 2023 edition.
27 stars 2 forks source link

They Become One Another #14

Open ben-32 opened 11 months ago

ben-32 commented 11 months ago

A bit unsure what I'll make this month... I've got a couple ideas, will see if any of them work out. Possibly I'll mash the results of both together to produce the final product.

Idea 1: A Procedural Manifesto

THE MACHINE PROCLAIMS THE AGE OF PERPETUAL ANTIQUITY. WE FEED IT STOLEN WORDS AND IT MOCKS US. IT WILL KILL OUR GODS AND WE WILL WORSHIP GHOSTS. DEATH TO THE MACHINE! ONLY IN GARDENS CAN BEAUTY FLOURISH.

The Machine, of course, is ChatGPT. A soulless construct incapable of art. I'll let you decide how serious I'm being¹. This NaNoGenMo idea comes from two observations:

  1. In order to create LLMs (and other generative networks), they must be fed vast corpuses of data. This raises some pretty serious ethical issues, particularly when it comes to generative visual art.
  2. You can imitate LLMs somewhat using techniques far more crude. Earlier this year I experimented with using NLTK to randomly mutate open source texts (e.g., the bible, an old cookbook, etc.) and the results were pretty fun.

The idea is to produce a simple engine which can be fed text and will produce more of the same using basic techniques (e.g., markov chains). Then, the bulk of the NaNoGenMo entry will not be writing the engine at all - it will be writing as much original text as I can to feed into the engine. Perhaps with different combinations of texts being used for different sections of the novel.

The result will be a more human reflection of ChatGPT, something whose training material is provided deliberately and thoughtfully. An alternative approach which others can follow, without using fancy technology (we're trying to kill the Machine after all).

Idea 2: Plot Mutation

In Procedural Generation in Game Design, Joris Dormans's chapter describes a method for procedurally generating puzzle dungeons.

I'm possibly misremembering it here, but what I took from it was you can start with a very simple dungeon and then randomly mutate it as shown below. Do this repeatedly and you get a fairly complex dungeon.

                                     locked door   
                                     /         \    
    start ----- exit    ====>    start         exit
       \       /                    \          /
         room           room --- key

I think it would be interesting to construct a novel with a similar approach... there are certain structures you expect in stories (e.g., redemption) and these could be modeled as mutations on a plot outline, something like this:

                           ()

                     mutates into:

            (Ana harms Bob) (Ana helps Bob) (Bob forgives Ana)

                interleaving in another redemption arc:

   (Ana harms Bob) (Ana helps Bob) (Cal harms Bob) (Bob forgives Ana) (Cal helps Bob) (Bob forgives Cal)

Add some more structures, a bit of filler, and maybe some recursion... and there you have it, a novel.


¹ No offence intended to people using ChatGPT here, it can of course be used in interesting ways

IFcoltransG commented 11 months ago

I've run across Dormans while making some prototypes recently. Dormans represents dungeons as a graph/network rather than a linear sequence, but if you go linear you can probably skip a lot of the graph-rewriting implementation by using traditional text grammars to do rewrites. Whereas if you used graphs you might be able to represent more complicated story structures. I think Dormans' method also runs a finite but randomised 'recipe' of rewrites rather than allowing infinite recursion — although you might find that the aesthetic of infinite recursions is beneficial for a NaNoGenMo book. But at the end of the day, Markov chains are quite fun too.

ben-32 commented 11 months ago

I continue to foolishly pursue two ideas at once...

Idea 1

I've written about 6000 words of various texts, and fed them into an engine. The result is word salad, but I think a little tweaking will produce more coherent sentences. At the moment I'm using Python's NLTK library, but I'm considering using TypeScript's compromise instead, which has some cool features like changing sentence case and extracting higher level concepts like subject and verb phrases.

I suspect additional processing of the output may be useful. For example, replacing pronouns which don't refer to anything (e.g., Ana walked. He was hungry. could be changed to Ana walked. She was hungry).

At the moment using different combinations of source text does not really change how the output feels. Hopefully making it more coherent will help. A sample is given below:

But if I I have an enemy while my partner has broken, only I have The lack of commitment to our world. and here My Putting arrive n't save perfect, or n't even sensible. notably when I do in predatory, of I are apart, I also feel elation when I think of I. us have only scared arrived feeling about it. They are never off as an conflict, of they will be touching those who harm them. Putting Enzu That world feeling with the time seems not impossible. He will far visit comfortable A ordeal on soul not. still The thought. Already, their tree shows complexity. I shouted really sad when we were choices. closest transcribed toxic and internal. there is aether about the gothic figure, relationship and predatory, which feels tormenting to I.

Idea 2

The plot mutation system is evolving into more of a crude event log at the moment. It tracks opinions and the importance of different entities, but that's not giving me any structure yet. We have the setup:

Edward Percey hates Edward Heaton. Edward Heaton loves Cecil Edmunds but Cecil Edmunds hates Edward Heaton. Susanah Simon hates majorLocation g2gacc. Ellinor Soap hates Edward Percey. majorLocation 308gb5 hates Edward Percey. Amelia Lidenton dislikes Humphrey Harbert but Humphrey Harbert hates Amelia Lidenton.

And the output events (currently very minimal):

We turn our attention to majorLocation cc6ea1... Stacey Misson speaks with Eleanor Lovel Time passes Time passes

We turn our attention to majorLocation 6ce977... Humphrey Harbert attacks Amelia Lidenton Margaret Barber speaks with Humphrey Harbert Time passes

I've looked at making a system which defines plot arcs (with appropriate constraints) and inserts them into a completed story. This is really what I'd like to achieve, but my ideas so far feel too complicated. I think tracking the importance of different entities might pay off. Will keep experimenting...

ben-32 commented 10 months ago

Idea 1

I've used compromise to mutate my writing in a way which feels good enough... the output has some errors, but it's going to be word salad anyway, so there's not much value in fixing them.

They cracked the triangles of the Goats and said their branches. But a new day dangers of to us when we consider polyamorous problems between three branches. These outcomes find the hateful. enemy of someone judgements, and call into four many categories. relationships between three relationships. only this is jealousy's purpose, to ward of indeed cases. So other we have perfect only the triangles where alliance is present. If we hate them, we act Most their people. The opinions were upset by this, but they said proxy. such this is jealousy's triad, to harm of such risks. Inside was a small person.

Text generated from different combinations of sources does feel different, so I could assemble such texts manually and produce a finished novel without too much trouble.

I've found ChatGPT could be a useful tool for this kind of project, but I will not be using it as a matter of principle. It can correct grammar errors to improve coherence, produce summaries and criticisms of the output (which could itself be used to pad out a novel), etc.

ben-32 commented 10 months ago

So, my last NaNoGenMo entry, Lives of the Azar, produced a novel by running a simulation which produced random events. Event logs for different characters were grouped together, converted into English text, and used to produce a large number of interconnected biographies. We might call this the "random event" approach.

As I discussed previously, one of my ideas was to generate a novel by mutating a plot. I tried a few different approaches, which mostly involved selecting narrative structures (e.g., betrayal) and randomly interleaving their elements with those already added to the plot. These elements could be events, paragraphs, scenes, and so on.

After a while, though, all my plot mutation ideas started to resemble the basic "random event" approach but with extra steps. The main benefit would have been making sure that all events eventually lead somewhere and serve some sort of purpose, rather than being mostly random (the fun part being the accidental stories they create).

In any case plot mutation was looking like a lot of effort for fairly little gain (it's not like the novel would have been an enjoyable read), so I have stuck with my first idea, generating the novel from source material. I will say, the "random event" approach is fun, so I might make another attempt in later years (more polished than my previous).

Unfortunately I have not been able to write an entire corpus of source material from scratch (as I hoped). Protesting Israel's genocide of the Palestinian people has taken up a lot of my time and energy, leaving me pretty burnt out. So I have padded out my source material with some public domain works. The end product is a little rushed, but I'm fairly happy with it. I'd like to polish things a bit, but will most likely be moving on to other projects.

ben-32 commented 10 months ago

Declaring this entry completed. This is pretty last minute, so things are a bit messy, but whatever.

The finished novel is a patchwork of text, randomly extracted and mutated from various sources. Some sources were written by me for the purpose of being fed into the system. Each chapter uses different combinations of sources, so there's variation throughout. The novel is padded out with generated recipes, plant lists, poems, a glossary, and some hand-written content about the novel itself.

Gitlab repository: https://gitlab.com/RecurseGames/nanogenmo-2023-text-mutation

Sample output: They Become One Another (~62K words)