We’re Fucked, Pt. 100: AI-generated audiochapter

For a measly hundred euros, I will share all my knowledge of the Younger Dryas cataclysm. This audiochapter covers chapter 100 of my ongoing novel.

Cast

  • Leire: a vexing thief that hangs out in the sewers under Riften like a common rat
  • Alberto the blob: Argonian fellows

I have produced audiochapters for this entire sequence so far. A total of two hours, five minutes and two seconds. Check them out.

We’re Fucked, Pt. 100 (Fiction)


The mound of sentient ooze pulses with a sloshing noise, as if it were gulping down foodstuff to fuel its bloat-bound brain.

“Leire, you need to stop having a meltdown every few minutes.”

I take a deep breath as I wipe away my tears with the pad of my thumb.

“What I need to do,” I start in a slow drawl, “is grab the spare umbrella and head home, and by home I mean mommy’s apartment in the hills. The trip back there is going to feel like a journey to another galaxy, but the hot tongue of my petite amie will purge my memories of slimy, eyeball-studded freaks. After having been so thoroughly humiliated by a gelatinous mass of putrid flesh, I need to be hugged and fucked by mommy to keep the dark thoughts at bay. You can return to your realm of rotting slime, and leave me the fuck alone.”

A gloopy chuckle slurps through the blob’s bulk.

“Oh no, we ain’t done yet.”

“Sure we are.”

“You want a repeat of this evening, more hours of wasted overtime at the office, filled instead with you and I arguing? Why not? After all, you don’t care if you get fired.”

My eyelids twitch.

“By all means, please keep pestering me until I slit my wrists.”

“I’m going to force you into a lucid state by any means necessary,” the blob assures me acidly, “and I swear that we will sort this shit out before you leave tonight, because I have dealt with you as much as I can handle.”

“Why don’t you come over here and shove your ‘any means necessary’ up my ass, you quivering wad of phlegm?”

“I’m not going to punish a masochist like you with a good time. Now, I can’t expect someone who has lived a lifetime as a pile of garbage to change overnight, but I will get you to hear me out and learn the true scope of our problem.”

I groan, then run my fingers through my hair. For a second I fear that my hand will come away sticky with black ooze.

“Fuck me with a spiked dildo,” I grumble. I crack my neck, I loosen my shoulders. “You want to share a part of your universe with me?” I extend both arms, palms up, toward the interdimensional intruder, and make beckoning motions by curling my fingers. “Alright, spit it out!”

The office light fixtures are casting their cold glow on the blob’s putrid sludge and his dozens of eyeballs, that stare blankly as they bob like corks. The drumming of raindrops against the windows, along with the low rumble of thunder, have given way to an oppresive silence interrupted only by sloshing and slurping noises emanating from the bulk.

“Earth to cum monster!” I shout.

Alberto harrumphs, and a glob of slime, airborne debris that resembles a greasy pebble, splats into a puddle.

“Are you truly willing to hear me out, or are you going to pull out a fork and stab yourself in the neck again?”

An electric echo crawls up my spine. I remember that drive to dig my carotid artery, and the agony that sewed my mouth shut. It makes me shudder. I rub whatever remains of the four-holed wound from when I attempted to kill a rotten bitch.

“Of course you witnessed that as well, you unmitigated fuck-weasel. Yes, I’ve had my share of stabbings and forkings and plenty of other shit I prefer to keep to myself. I committed atrocious acts when I had to. Regardless, I will listen, as long as you have something intriguing to tell! Then I’m gone. I intend to finish off what’s left of the evening sucking on mommy’s nipples like a starved infant.”

“Can you care about anything other than yourself and your buxom lover?” the blob asks, his voice tinged with irritation.

I huff.

“I’m telling you, dude, some of the stuff that went down in this sorry excuse for a planet is, in fact, rather enticing! Do you know about the Younger Dryas cataclysm?”

“What? The Younger-what?”

“Picture this scenario: we’re in the Late Pleistocene, a period when much of North America, from the Canadian arctic down to Missouri, was buried under three-kilometers-thick glaciers. Back then, woolly mammoths, dire wolves, sabre-toothed tigers and ground sloths inhabited the frigid wilderness. They didn’t bother to build cities or write stories or any of that shit: they enjoyed the great outdoors, as well as the pleasures of eating, drinking, swimming in freshwater ponds, rolling in a mound of fresh dung to warm up, and fucking each other senseless, for thousands of generations. That megafauna may have taken delight in some of the most liberal sex positions ever practiced by the animal kingdom. They also suffered, mourned, and remembered their friends and family. Imagine these beasts in the frozen wastes of Alaska and the Yukon territory, their skulls buried in so-called ‘muck’ deposits that nowadays you can excavate from tundra and glacial soil. In the skull fragments, scientists discovered impact-related microspherules, tiny beads formed in the heat of a cosmic impact.” I take a deep breath while my heart pounds against my ribcage. “What evil force snatched such magnificent creatures from life, from our realm, leaving behind nothing but the smear of their existence? The answer lies beyond our planet, in the vast reaches of Arachne’s web, that binds the universe together. An alien spacecraft approached Earth, carrying some interstellar creep, a demigod of destruction whose mission was to crash his ship into our planet as revenge. JK, just joking, as humans like to say. A large short-period comet must have fragmented within the inner solar system. Drawn by Earth’s gravitational pull, flaming chunks of rock from another world bombarded ours. The sky flashes. The ground trembles with the shockwaves of titanic impacts, enough energy released to blast your shitpile through a hundred walls. Bursts of rocks and ash plume over hundreds of kilometers. The ice sheets melt, turning the oceans into a bloodbath of brine and slurry. Massive firestorms rage across forests and savannas and grasslands, burning ten percent of the world’s biomass to soot, while a blanket of atmospheric dust blots out the sun. In the chaos that ensued, a lone entity escaped the wreckage of his spaceship: a deity with eyes like liquid flame, with tentacles for hair. The incarnation of despair, a malevolent force from beyond time and space.” I gulp down the knot in my throat. “The region where these fossils were found, known as Beringia, was part of the largest circumarctic landmass to remain unglaciated, a refuge for Plio-Pleistocene tundra-grassland plant species, and the now-extinct megafauna. So we can assume that those noble beasts went extinct both from a cosmic bombardment and from an alien tentacle god with an egotistical cunt’s idea of fun. A fascinating albeit chilling story, don’t you think, dear Blobbert? I’m an authority on the Late Pleistocene, as I visited it briefly.”

A guttural groan reverberates from deep within the putrid bulk of ooze.

“What the hell are you prattling on about?!”

“Did I strike a nerve? I shared my knowledge of the Younger Dryas cataclysm, born from a comet and an intergalactic god-monster, as a gift to you. Imagine all the contemporary species larger than a goat, then kill off sixty-fucking-five percent of them; that’s how many of the mighty Ice Age megafauna disappeared forever. And the global sea level rose by a hundred and twenty meters. Can you comprehend such catastrophe, how much misery it brought? Can I make you, a gooey puddle of sewage, listen to the screams of the victims as they suffocated in a sludge of melted glaciers? The Younger Dryas cataclysm happened, in the grand scheme of things, yesterday. You were spawned in the post-apocalypse! Your genes are scarred with the fear that the sky will fall on your head.”

“Are you kidding me? I don’t give a flying fuck about your pet rocks and your tentacle-haired cunt god!”

I narrow my eyes. I’m getting fed up with this monstrous ignoramus.

“In Arachne’s name, I swear you must have fished your brain out of a lake filled with cat poop.”

“Your morbid obsessions are completely irrelevant to what I’m struggling to convey to you.”

I rub the bridge of my nose and sigh. I picture my right hand clenching around the handle of the office door, about to pull myself out of this hellscape. The sooner the better.

I glower at the blob as I spread my arms wide.

“Then spit it out already, sludge-for-brains! Here I am, ready and willing. Tell your story or perish!”



Author’s note: today’s songs are “The Same Old Rock” by Roy Harper, and “Waitin’ Around to Die” by The Be Good Tanyas.

I keep a playlist with all the songs mentioned throughout this novel. A hundred and fifty-six songs so far. Check them out.

Leire didn’t pull the stuff about the Ice Age (entirely) out of her ass. I recently came across this scientific paper. In addition, my protagonist attempted to kill a rotten bitch back in chapter 14, as the climax of the sequence titled “I’m Killing a Rotten Bitch.”

Do you want to hear this chilling chapter acted out by AI-generated voices? Check it out.

So, a hundred chapters of this shit, huh? I started the story back in October of 2021, attempting to pump out a novella after I abandoned my previous two ones. I’m not sure how it ballooned to such an extent. Anyway, I know that a few souls out there have followed this story from the beginning, probably out of morbid curiosity. Thank you. I won’t say that I couldn’t do this without you, because I was doing this alone until I started posting my crap on the internet a few years ago.

Still fifteen or so chapters to go.

We’re Fucked, Pt. 99: AI-generated audiochapter

Yet another entry in the saga that involves a lunatic arguing with an uglier lunatic. This audiochapter covers chapter 99.

Cast

  • Leire: the best blonde infiltrator in Riften
  • Alberto the blob: loads of scaly dudes that you met in Oblivion

I have produced audiochapters for this entire sequence so far. A total of an hour, fifty-six minutes and twenty-nine seconds. Check them out.

We’re Fucked, Pt. 99 (Fiction)


A bolt of lightning slashes the darkness, throwing the office into harsh relief. Alberto the blob, a viscous and putrid mural of shuddering goo, glistens wetly under the harsh light, and his myriad of eyeballs reflect my own dreadful image back at me.

“I wish I were riding your current high,” I say, “burning with self-righteousness, able to discharge your pent-up anger against someone else. I’d prefer, though, if you had chosen a target who did something worthy of your ire: an actual asshole.”

“You think that people can only get angry at what you do? Is that why you keep busy playing with yourself while ignoring your responsibilities, including your job and your basic needs? Your inaction can ruin lives.”

My stomach knots tighter.

“Don’t try to make me responsible for others,” I plead. “I can’t even take care of myself.”

The blob ripples like a sea of black slime and eyeballs.

“Unfortunately, the responsibility only falls on you, a weirdo who would rather be miserable than improve. You’re the one who can listen to what needs to be done, the sole person suited to stop a cosmic shitstorm. Isn’t it fitting, though? We need an aberration to beat another.”

I hunch over, and as I rub my eyelids, I seek a mental refuge from this deluge of insanity. I see her face, the glowing visage of Jacqueline, my all-encompassing muse, a pearl beyond price. Her ivory-white skin is framed by a raven-black cascade of lustrous hair. Her cobalt-blues are locked into my eyes without disgust. The rosy, wet cavity of her mouth tempts me like a fountain of potable water in a scorching day. Please come and save me from myself.

“Wh-why do I have to be the one?” I complain weakly. “Jacqueline also worked with you, for much longer, and she isn’t as eager to forget human beings as I am. She would try to understand you and help you cope. Hell, she even believes me when I open up about the otherworldly stalkers by whom I’m routinely harassed, although she’s never suffered the misfortune of gazing upon your abominable forms.”

“Sure, your girlfriend slash mommy would have done a bang-up job, if only for reminding me of the most carnal pleasures of my former world.” The blob snickers. “But nope, we are stuck with a self-defeating sack of shit, a pathetic wreck with more anxiety attacks than brain cells, who can barely accomplish the most basic of tasks, who’s never had the guts to start living, who can’t see farther than her own disgusting orifices. The perfect package for a universe on its last leg!”

I gulp down bitter acid, then take a lungful of stinging toxins.

“Again, why me?”

“Because your mind was open and ready for a trip through the cosmic craphole, Leire. What, you want me to make it simpler? You’re a walking heap of psychological garbage. In the old days, you’d have been locked up in an asylum. I had the inkling that you wouldn’t go crazier even when contacted by sentient abominations, but you still surprised me by taking the visits in stride, as if some people just happened to be accosted by teleporting horses.”

I grind my teeth.

“I’ve done nothing but rage against you fuckers.”

The blob’s legion of eyeballs catch the erratic flicker of lightning, shimmering like tiny stars caught in a sea of filth.

“Hey, cheer up, girlie! In these enlightened times, you can become the champion of interdimensional gods, which is what I’ve fancied myself to be since I escaped your realm of rot and decay.”

“If people actually worshipped you,” I grumble, “I would understand if they also persecuted anybody who depicted your image.”

The blob chokes on a chuckle, glugging noisily. My gaze wanders from my former coworker’s grotesque bulk to the black screen of my computer. Leire the Demented Seer, the Chosen Paladin of Interdimensional Gods. Sounds better than being a struggling office worker that has to curb her intrusive thoughts about shoving random penis-shaped objects into her orifices.

“Enough bullshit,” the blob barks out. “You’re going to wake up right now. You’re going to open your eyes and start taking life seriously. Time has been running out for everyone since you disregarded my warning back in your defunct car.”

I cross my arms over my chest.

“You creeps have done an atrocious job of convincing me that these supposed warnings were urgent. Perhaps you left your brains behind in some other dimension, where you should have stayed for all I care. Besides, I can’t shake the feeling that you’re lying about a cosmic threat, that you just want to fuck with me.”

The wall-wide mucus-and-eyeball-ridden monstrosity stirs like an organic tide.

“Look here, you clit-loving lunatic,” the blob snaps back in a wet gurgle. He coughs up a glob of tar onto the carpet. “An impossible message flashing across your Renault Laguna’s dashboard would have disturbed any other human being into lucidity.”

“Didn’t we discuss that already? No, we ended up arguing about my car’s supernatural powers. What did you write across the dashboard, then? ‘A horse with a dick for a head will fuck you before you die’? Such a warning might have sent me running to the psych ward.”

Gooey innards ripple and slosh in the gelatinous bulk.

“‘We’re fucked,’ damn you!”

“What was that?”

“The message I wrote on your dashboard, which you ignored as if it were junk mail, was ‘We’re fucked’!”

I grimace.

“That’s all the fuck you wrote?”

“How much clearer could I be?” he snarls. “It means that you’re fucked, that I’m fucked, that the universe is fucked!”

A knot expands in my throat, and I lower my gaze to the puddles of black goo seeping into the carpet. The slanted rain is drumming on the windows. Thunder crackles. The absurdity of it all bubbles up inside me, shoots up my esophagus, and bursts out into laughter that ricochets off the office walls. Mine is a despairing laughter tinged with madness, the sole human sound amidst the rainstorm and the blob’s otherworldly gurgles.

“Do you recall that message, then?” Alberto asks impatiently.

I raise my gaze to meet the wall-wide mass of putrid slime. His countless eyeballs are scrutinizing me like a cop eyeing a perp.

“Nope,” I say in a strained voice, “you may as well have made it up.”

The blob heaves as if I had punched his gut.

“Again with your self-imposed amnesia?!”

“Doesn’t matter. I get your point: we’re fucked.” I slide my palm down my face as the back of my eyeballs grows hotter. “That’s what you wretched snot-fondler sent as a message of utmost urgency? As eloquent as a dead rat’s turd. Of course we’re fucked, you oversized cum-sack! That much I understood since I crawled out of the womb broken, since my parents failed to behave towards each other like human beings, let alone raise a functional, healthy child. Billions of people born to struggle daily in this cesspool only to be rewarded with decrepitude and death. How many are loved along the way?” Tears well up, hot and stinging, but I press on. “I don’t need some interdimensional pus-clown to remind me of the achingly obvious fact that we’re all fucked. We never stood a fucking chance.”



Author’s note: today’s songs are “Karma Police” by Radiohead, “Game of Pricks” by Guided by Voices, “The Plan” by Built to Spill, and “Miss Misery” by Elliott Smith.

I keep a playlist with all the songs mentioned throughout this novel. A hundred and fifty-four songs so far. Check them out.

Were you looking forward to the audiochapter for this entry? Well, I was. Check it out.

It took me ages to work through this chapter. I’ve been distracted programming, and my mood has been let’s say quite low. Anyway, GPT-4’s API has been broken for days, who knows why, so I’ll likely write more prose than code in the coming days.

Intelligent agents for simulations (using LLMs) #2


The previous entry ended in a sour note because I had become frustrated by a problem with the navigation system: when updating the nodes of the environment tree after the changes that some agent had caused, other agents were losing the parent and/or children of the nodes they were currently in. Although Python’s casual way of handling references contributed, it was my fault: I was replacing nodes in the main tree and disconnecting them, but other agents were ending up with the disconnected copies because they had already stored them. Oops. These are the kind of errors that Rust was made to prevent.

Anyway, I rewrote that whole part of the code; now instead of replacing the whole node, I just modify the values of the Location or the SandboxObject the nodes contain. Not sure why I thought that replacing the whole node was a good idea.

Here’s the GitHub repository with all the code.

In addition, I was getting annoyed because running the unit tests took several seconds, as some of the tests made requests to the AI models. There was no reason to keep testing those calls, because I know they work, so I refactored the calls to functions passed by parameter. A cool thing about (outrageously slow) garbage-collected languages like Python is that you can do crazy shit like casually passing functions as parameters, or duck-typing (passing any kind of object to a function and the code working as long as the object responds to the same calls). Regardless, now the unit tests run in less than a second.

I also figured out quickly how to implement human-handled agents. If you set “is_player”: “true” in the corresponding agent’s section of the agents.json file, whenever the code attempts to call the AI model, it prompts you to answer with your fingers and keyboard. That means that in the future, when the simulation involves observations, planning, reflections, and dialogue, AI handled agents could stop the player to have an in-character conversation. Very nice.

The biggest change to the architecture involved separating environment trees into a main one for each simulation, then agent-specific environment trees that come with their own json files. A bit more annoying to set up, but that allows agent-specific knowledge of the environment. For example, an agent knows of their house and some nearby stores, but not of the interior of other houses. I could implement without much issues the notion of an agent walking to the edge of his or her world and “getting to see” an adjacent node from the simulation’s tree, which would get added to that agent’s environment. Therefore, that new location would become a part of the agent’s utility functions that choose the most suitable locations and sandbox objects. Dynamic environment discovery almost for free.

ChatGPT writes an episode of Friends

Tonight a thought crossed my mind: “What if ChatGPT wrote an episode of Friends?” Of course, it needed to involve a dinosaur.

My prompt:

Question. Write a script for the TV show Friends. The script should be about the group of friends coming across a live dinosaur. Answer: Let’s try to work out the answer step by step:

GPT-4’s answer:


Sure, let’s go through this in steps:

Step 1: Establishing the Scenario

First, we need to establish how our beloved group of Friends would come across a live dinosaur. One possible scenario is that Ross, being a paleontologist, is invited to a top-secret experiment where scientists have managed to clone a dinosaur, and he decides to bring the whole group along.

Step 2: Character Reactions

Next, we need to determine how each character would react to seeing a live dinosaur:

  • Ross: He would be thrilled and fascinated, trying to explain everything about the dinosaur to the others.
  • Rachel: She might be scared at first but then would probably try to make friends with the dinosaur.
  • Monica: She could be worried about the dinosaur making a mess.
  • Chandler: He would likely make sarcastic remarks and jokes about the dinosaur.
  • Joey: He might be excited and curious about the dinosaur, potentially trying to communicate with it or even ride it.
  • Phoebe: She would likely be concerned about the dinosaur’s feelings and well-being.

Step 3: Dialogue and Plot

Once we have established the setting and character reactions, we can start writing the script. Here’s a brief example:

INT. SECRET LAB – DAY

ROSS excitedly gathers the group around a large, secure enclosure. Inside is a small, surprisingly cute dinosaur.

ROSS: You guys, meet Dino – the world’s first living dinosaur clone!

CHANDLER: (sarcastically) Oh, because Jurassic Park worked out so well.

MONICA: (worriedly to Ross) You promise it’s safe, right? And… clean?

JOEY: (excitedly) Can I ride it?

ROSS: No, Joey! This is a delicate scientific breakthrough, not a petting zoo.

PHOEBE: (concerned) But is he happy here? What about his dinosaur family?

RACHEL: (to the dinosaur) Hi, Dino. I’m Rachel. Do you want to be friends?

Dino ROARS, causing the group to jump back.

CHANDLER: (dryly) Well, that went well.


GPT-4 stopped the output there, but I prompted it to continue.


Suddenly, Dino RAMS against the enclosure, breaking it open. The group SCREAMS and backs away.

ROSS: (panicked) Everyone stay calm! Dinosaurs can sense fear!

CHANDLER: (sarcastically) Oh, well, in that case, we’re totally fine.

Monica is HYPERVENTILATING, clutching Chandler’s arm.

MONICA: (terrified) Ross, do something!

Joey suddenly makes a bold decision.

JOEY: (determined) I got this!

He steps forward, trying to wrestle Dino back into the enclosure. Dino, however, is unimpressed and flicks Joey away with his tail.

Phoebe steps forward, singing a calming song.

PHOEBE: (singing softly) Smelly cat, smelly cat, it’s not your fault…

Dino seems to calm down a bit, but is still out of the enclosure.

Rachel, seeing Dino calmed by Phoebe’s singing, steps forward cautiously.

RACHEL: (gently) Dino, it’s okay. You’re safe here.

Dino seems to respond to Rachel’s soothing voice, but he’s still nervous.

ROSS: (to Rachel) Rachel, keep talking! He seems to like you.

Rachel nods, continuing to speak softly to Dino.

Meanwhile, Joey gets up from the floor, dusting himself off.

JOEY: (to Chandler) You know, I thought that would go differently.

CHANDLER: (deadpan) Really? Because I think we all saw that coming.

Suddenly, a GROUP OF SCIENTISTS rush into the room, panicked. They manage to coax Dino back into his enclosure with some food.

ROSS: (relieved) Thank goodness.

MONICA: (still shaking) Can we please go somewhere less…prehistoric now?

PHOEBE: (to Dino, sadly) Bye, Dino. I hope they let you out to play sometimes.

The group, still a bit shaken, leaves the lab.

CHANDLER: (sarcastically) So, Ross, when’s your next show and tell?


That was a success.

Intelligent agents for simulations (using LLMs) #1

Next part (2)


A week ago I came across this damned paper (Generative Agents: Interactive Simulacra of Human Behavior). Also check out this explanation of the paper and its implementation. I called the paper damned because the moment I understood its possibilities (creating intelligent virtual agents has always been a dream of mine), the spark of obsession flared up in me, and for someone this obsessive, that could only mean one thing:

I figured that I was capable enough of implementing that paper using the Python programming language. In my first try, I thrust ahead, with very few unit tests, to implement the memories database, the planning and reflective functionalities, as well as the navigation system. It was when I hit the paper’s promise that GPT-3.5-turbo was going to be able to output the name of the chosen destination when I realized that the writers of the paper must have simplified the process of navigation (if not finagled it quite a bit), because large language models don’t work like that. And without the agents being able to move around in the environment tree, this system wouldn’t work remotely as intended.

I gave it some thought and I ended up opting for utility functions. Used in basic AI for decades, utility functions output a rating value between a bunch of options, from which the code ends up choosing the best rated option (with some room for randomness). Thankfully, if you ask GPT-3.5-turbo to give a rating for how well a “farmhouse” would fit the purpose of “eating lunch”, then that location may be chosen, and from there you could ask the AI to rate the individual locations of the farmhouse to continue the path.

Implementing the navigation of the agents in such a way gave me the opportunity to start the code from scratch. This time I relied mostly on test-driven development (meaning that one or more unit tests support the part of the code you are working on), very important for a system that can suffer from plenty of regressions. I have 51 unit tests supporting the code so far.

Before I delve into further details, here’s the link to my GitHub repository with all the code I have written.

Here’s as far as I’ve gotten:

  • The user writes the environment of the simulation in a json file. I’m using the Python library ‘anytree’ to represent the graph, which also comes with this fancy command-line method of displaying any given graph:

Location: plot of land (plot_of_land)
├── Location: barn (barn)
│ └── Sandbox object: tools (tools) | description: lots of tools for farming
├── Location: field (field)
│ ├── Sandbox object: crop of corn (corn_crop) | description: a crop of growing corn
│ └── Sandbox object: crop of potatoes (potatoes_crop) | description: a crop of growing potatoes
└── Location: farmhouse (farmhouse)
├── Location: bedroom (bedroom)
│ ├── Sandbox object: bed (bed) | description: a piece of furniture where people sleep
│ └── Sandbox object: desk (desk) | description: a piece of furniture where a person can read or write comfortably
├── Location: kitchen (kitchen)
│ └── Sandbox object: fridge (fridge) | description: an appliance that keeps food cold
└── Location: bathroom (bathroom)
├── Sandbox object: toilet (toilet) | description: a simple toilet
└── Sandbox object: bathtub (bathtub) | description: a tub in which to take baths

  • For this test, I pictured a farmhouse, a nearby barn, and a couple of nearby crops.
  • I added in the corresponding json file the needed information for the agents involved:

{
“Joel”: {
“age”: 38,
“planned_action”: null,
“action_status”: null,
“current_location_node”: “farmhouse”,
“destination_node”: null,
“using_object”: null
},
“Betty”: {
“age”: 24,
“planned_action”: null,
“action_status”: null,
“current_location_node”: “farmhouse”,
“destination_node”: null,
“using_object”: null
}
}

  • As depicted, agents can have a planned action, an action status, their current location, their destination, and what object they are using, apart from their age and name.
  • As the paper says, each agent’s memories are seeded from a few memories that are written in a simple text file.

Betty started living with Joel six years ago;Betty enjoys planting crops and tending to them;Betty wishes that she and her boyfriend Joel could afford to buy a few horses;Betty wishes she didn’t have to travel to the nearby town often;Betty loves peace and quiet;When Betty feels overwhelmed, she lies down on her bed and listens to ASMR through her noise-cancelling headphones;Betty wants to have a child, hopefully a daughter, but Joel told her years ago that he didn’t want children;Joel and Betty saw strange lights in the skies in the 11th of May of 2023;On the 11th of May of 2023, the local news broadcast was cut off in the middle of a transmission as they were reporting on the strange lights in the sky;Joel and Betty have heard ominous explosions in the distance throughout the morning of the 12th of May of 2023

Joel is a farmer who has lived in his plot of land for ten years;Joel is living with his girlfriend, Betty, whom he loves;Joel enjoys listening to music from the sixties;Joel wishes he and Betty could buy a few horses, but he doesn’t think they can afford them;Joel and Betty saw strange lights in the skies in the 11th of May of 2023;On the 11th of May of 2023, the local news broadcast was cut off in the middle of a transmission as they were reporting on the strange lights in the sky;Joel and Betty have heard ominous explosions in the distance throughout the morning of the 12th of May of 2023

  • These seed memories are inserted into a memories database. Its implementation is one of the most important parts of this system. The database is composed of a vector database (which stores values according to some eldritch, multidimensional distance between them), and a json file that records readable values of those memories. You can query the vector database with simple text, and it will return the most relevant text it contains regarding the query you sent it. Sort of like a recommendation system.
  • In addition, when a query is made to the agents’ memories, they are rated according to the memory’s importance and recency. The recency is a normalized value in the range of [0.0, 1.0] depending on when that memory was accessed last, and importance is a rating that the AI itself gave to how poignant the memory was.
  • Once the agents are loaded in the simulation, a character summary is created for each agent. The AI is prompted to write all the segments of these summaries only from the memories present in their vector databases.

Joel’s AI-written character summary

Joel (age: 38)

Innate traits: Hardworking, resilient, curious, observant, caring, nostalgic, pragmatic.

Joel is a farmer who has lived in his plot of land for ten years and wishes he and Betty could buy a few horses, but he doesn’t think they can afford them. He enjoys listening to music from the sixties and is living with his girlfriend, Betty, whom he loves. They have experienced ominous explosions in the distance and saw strange lights in the skies on the 11th of May of 2023, and the local news broadcast was cut off in the middle of a transmission as they were reporting on the strange lights.

Joel is a farmer who has lived in his plot of land for ten years.

It is difficult to accurately describe Joel’s overall feeling about his recent progress in life based on these statements alone. However, we can infer that he enjoys listening to old music, has heard ominous explosions and seen strange lights with Betty, is a farmer, loves his girlfriend, and wishes they could afford to buy horses. These statements do not provide enough information to determine his overall feelings about his recent progress in life.”

Betty’s AI-written character summary

Betty (age: 24)

Innate traits: resilient, domestic, nurturing, longing, introverted, anxious, curious, intuitive, calm

Betty is a woman who enjoys living a peaceful and simple life with her partner Joel. She is interested in farming and wishes to own horses. Betty also has a desire to have a child, but this conflicts with Joel’s wishes. She dislikes having to travel to nearby towns and finds solace in listening to ASMR when she feels overwhelmed. Betty is aware of strange occurrences happening around her, such as explosions and lights in the sky, but she seems to maintain a calm and composed demeanor.

Betty is a homesteader or a farmer.

Betty is feeling somewhat unsettled and uncertain about her progress in life, as indicated by her mixed feelings about her living situation with Joel, her desire for a more stable and fulfilling life with horses and a child, and her occasional need for escapist relaxation techniques like ASMR. She enjoys the sense of purpose that comes from tending to her crops, but is also wary of the potential dangers and disruptions of the outside world, as shown by the ominous sounds and sightings of explosions and strange lights in the sky. Overall, she seems to value the simple pleasures of a quiet country life, but is also aware of the limitations and difficulties of this lifestyle.

  • If the simulation detects that the agents haven’t decided upon an action, it generates one through a complicated process.

2023-05-13T09:30:00 Joel produced action: Saturday May 13 of 2023, 9 AM. Joel is going to check with his neighbors to see if they have any information about the strange lights and ominous explosions they have been experiencing. The length of time it takes for Joel to check with his neighbors is not specified, so it is impossible to provide an answer in minutes.

2023-05-13T09:30:00 Betty produced action: Saturday May 13 of 2023, 9 AM. Betty is going to talk to Joel about their conflicting desires regarding having a child and try to come to a mutual understanding or compromise. The duration of this action is not specified in the given information. It can vary based on the discussion and resolution reached by Betty and Joel.

  • The AI model (GPT-3.5-turbo in this case) went over each agent’s memories and decided what action the agents would take, according to their circumstances. A problem with the paper’s original implementation already comes up: the agents decide a plan, then they search for the most fitting location, and then object, to fulfill that plan. But in this case, the AI decided that Joel should check with his neighbors to see if they have any information about weird happenings. But there are no neighbors in this environment. In addition, Betty decided that she wants to talk to Joel, but the paper doesn’t offer a system of locating other agents that may not be in the immediate surroundings. There’s a system for dialogue, but I haven’t gotten that far.
  • Through the rating system for locations and objects (going from the root of the environment tree deeper and deeper), Joel came to this conclusion about what should be his destination given the action he came up with:

2023-05-13T09:30:00 Joel changed destination node to: Node(‘/Location: plot of land (plot_of_land)/Location: farmhouse (farmhouse)/Location: kitchen (kitchen)/Sandbox object: fridge (fridge) | description: an appliance that keeps food cold’)

  • Apparently Joel (therefore, the AI model) thought that the neighbors could be found in the fridge. From the root of the environment tree, between the choices of “farmhouse”, “barn” and “crops”, obviously farmhouse was the most adequate option to find people. Inside that house, it opted for the kitchen between all the possible rooms. Inside there was only a fridge, so the navigation system had no choice but to choose that. If I had added a telephone in the kitchen, the AI model likely would have chosen that instead to communicate with the neighbors.
  • Regarding Betty, to fulfill her action of talking to Joel, she chose the following destination:

2023-05-13T09:30:00 Betty changed destination node to: Node(‘/Location: plot of land (plot_of_land)/Location: barn (barn)/Sandbox object: tools (tools) | description: lots of tools for farming’)

  • Interestingly enough, the AI model believed that her farmer husband was more likely to be in the barn than in the farmhouse. Once the barn was chosen, the tools were the only option as to which object would help the agent fulfill her action.
  • The navigation system detected that the agents weren’t at their destination, so it started moving them:

2023-05-13T09:30:00 Joel needs to move to: Node(‘/Location: plot of land (plot_of_land)/Location: farmhouse (farmhouse)/Location: kitchen (kitchen)/Sandbox object: fridge (fridge) | description: an appliance that keeps food cold’)
2023-05-13T09:30:00 Joel changed the action status to: Joel is heading to use fridge (located in Location: kitchen (kitchen)), due to the following action: Saturday May 13 of 2023, 9 AM. Joel is going to check with his neighbors to see if they have any information about the strange lights and ominous explosions they have been experiencing. The length of time it takes for Joel to check with his neighbors is not specified, so it is impossible to provide an answer in minutes.

2023-05-13T09:30:00 Betty needs to move to: Node(‘/Location: plot of land (plot_of_land)/Location: barn (barn)/Sandbox object: tools (tools) | description: lots of tools for farming’)
2023-05-13T09:30:00 Betty changed the action status to: Betty is heading to use tools (located in Location: barn (barn)), due to the following action: Saturday May 13 of 2023, 9 AM. Betty is going to talk to Joel about their conflicting desires regarding having a child and try to come to a mutual understanding or compromise. The duration of this action is not specified in the given information. It can vary based on the discussion and resolution reached by Betty and Joel.

  • The simulation advances in steps of a specified amount of time, in this case thirty minutes, and the navigation system will move the agents a single location each step. This means that an agent would take thirty minutes to move from a bedroom to the entrance of the same house, but whatever.

2023-05-13T10:00:00 Joel changed the current location node to: Node(‘/Location: plot of land (plot_of_land)/Location: farmhouse (farmhouse)/Location: kitchen (kitchen)’)
2023-05-13T10:00:00 Joel changed the current location node to: Node(‘/Location: plot of land (plot_of_land)/Location: farmhouse (farmhouse)/Location: kitchen (kitchen)/Sandbox object: fridge (fridge) | description: a piece of furniture that keeps food cold’)

  • Joel moved from the entrance of the farmhouse to the kitchen, and once the agent is in the same location as his or her destination sandbox object, he or she starts using it. In this case, the fridge.

2023-05-13T10:00:00 Betty changed the current location node to: Node(‘/Location: plot of land (plot_of_land)’)

  • Betty has moved from the farmhouse to the root of the environment tree.
  • In the next step of the simulation, Joel continues using the fridge, while Betty moves further to the barn, where she starts using the tools:

2023-05-13T10:30:00 Joel continues using object: Node(‘/Sandbox object: fridge (fridge) | description: a piece of furniture that keeps food cold’)
2023-05-13T10:30:00 Betty changed the current location node to: Node(‘/Location: plot of land (plot_of_land)/Location: barn (barn)’)
2023-05-13T10:30:00 Betty changed the current location node to: Node(‘/Location: plot of land (plot_of_land)/Location: barn (barn)/Sandbox object: tools (tools) | description: lots of tools for farming’)

  • From then on, the agents will continue using the tools they have chosen to perform their actions:

2023-05-13T11:00:00 Joel continues using object: Node(‘/Sandbox object: fridge (fridge) | description: a piece of furniture that keeps food cold’)
2023-05-13T11:00:00 Betty continues using object: Node(‘/Sandbox object: tools (tools) | description: lots of tools for farming’)
2023-05-13T11:30:00 Joel continues using object: Node(‘/Sandbox object: fridge (fridge) | description: a piece of furniture that keeps food cold’)
2023-05-13T11:30:00 Betty continues using object: Node(‘/Sandbox object: tools (tools) | description: lots of tools for farming’)
2023-05-13T12:00:00 Joel continues using object: Node(‘/Sandbox object: fridge (fridge) | description: a piece of furniture that keeps food cold’)
2023-05-13T12:00:00 Betty continues using object: Node(‘/Sandbox object: tools (tools) | description: lots of tools for farming’)

That’s unfortunately as far as I’ve gotten with my implementation, even though it took me a week. The paper explains more systems:

  • Observation: as the agents use the objects, they are prompted with observations about what other objects in the same location are doing, and about the other agents that may have entered the location. That gives the busy agent an opportunity to stop what they’re doing and engage with other objects or agents.
  • Dialogue: the paper came up with an intriguing dialogue system that became one of my main reasons for programming this, but it requires the Observation system to be implemented fully.
  • Planning: once a day, the agents should come up with day-long plans that will be stored in memory, and that will influence the actions taken.
  • Reflection: when some condition is triggered, the agents retrieve the hundred most recent memories from their databases, and prompt the AI model to create high-level reflections of those memories. The reflections will be stored in the memory stream as well, so that they influence their planning, their decision-taking, as well as the creation of further reflections.

That’s as far as I remember of the paper at this moment. I wanted to get the navigation system done as early as possible, because I considered it the hardest part, and it annoyed the hell out of me partly due to how Python handles references (at one point I was losing the list of ancestors and descendants of the agents’ destination nodes between simple function calls to the same instance of Simulation, for no fucking reason that I could determine). I may move directly onto the Observation system, or take a rest. I already feel my sanity slipping quite a bit, likely because I took a sabbatical from my ongoing novel to do this.

AI news #3


If you are interested in what GPT-4 can do in games, check out part two of this series, because it showed how people are using ChatGPT for Skyrim and Fallout. Things have developed a bit further. The following video shows someone’s modded companion with whom the player can interact naturally, and who is aware of the world around her.

Truly amazing. As long as the world doesn’t end, imagine how amazing games will become in a few years. At least how amazing modders will make those games, if their companies can’t be arsed.

The following unassuming entry represented a turning point in how I use GPT-4:

Turns out that some clever people out there have proved that some prompts can squeeze significantly more intelligence out of GPT-4. The author of the video had the idea of pushing it a bit further by implementing the following architecture:

  • Given a prompt, ask GPT-4 through the API to give you three separate answers.
  • Send those three answers to GPT-4, asking it to act like a researcher and point out the flaws in those answers.
  • Send the answers along with the researcher’s analysis to GPT-4, and ask it to act like a resolver to determine which answer is more valid (according to the researcher’s analysis), improve it a bit, and present it as the final answer.

I have implemented that system in Python. It was very easy to do, as well. Although it takes significantly longer than just asking regular ChatGPT a question, the results are much better.

I thought about how mini-AGIs (Auto-GPT and BabyAGI) use GPT-4 to simulate artificial general intelligence, and I realized that if you can get GPT-4 to develop a list of tasks in a similar way the previous algorithm is structured, you can then link those tasks to the previous algorithm so that it executes each task in a loop.

I’m not that interested in programming an Auto-GPT at the moment; I’m happy enough getting a list of tasks that I can then send to GPT-4 at my leisure. However, I did code an addition to the previous program, one that sends an objective to GPT-4 and tells it to act like a manager developing a prioritized task list. In fact, as in the previous algorithm, it sends that request thrice, and then those answers are passed to a researcher, whose answer gets passed to a resolver as per the previously displayed algorithm.

Here’s the list of tasks that resulted from sending to my program the objective of programming a particular card game, one I’m developing, in the Rust programming language:

  1. Initialize the game engine, including a GUI that supports displaying cards and decks on screen.
  2. Create data structures to represent the different card types: Exploration Zone, Biomes, Encounters, Events, Resources, Afflictions, Player cards, and Portal cards.
  3. Load card data from toml files into the appropriate data structures.
  4. Develop a function to generate a random Exploration Zone card from the available Exploration Zone cards.
  5. Display the randomly selected Exploration Zone card on the top right corner of the screen.
  6. Develop a function to create the Biomes deck, selecting the matching Biome types as specified in the chosen Exploration Zone card.
  7. Ensure the first Biome card of the Biomes deck is displayed face up next to the Biomes deck.
  8. Develop a function to create the Encounter, Events, Resources, and Affliction decks based on the Feature icons from the chosen Exploration Zone card.
  9. Implement player classes (soldier, medic, scientist, scout) with their respective attributes and abilities.
  10. Design the player decks for 4 players, each with a unique role, and include a Portal card to allow escaping to the Hub.
  11. Design the Hub and implement the card drafting system for the Hub, allowing players to choose cards to add to their decks while trading resources.
  12. Develop a system for players to rebuild their decks while in the Hub between explorations.
  13. Design the goal cards that specify objectives required for each Exploration.
  14. Implement a system that tracks combos and interactions between cards, such as activating abilities based on certain conditions.
  15. Create a data gathering and analysis system for role combinations, deck compositions, and card interactions to identify balance issues and adjust card values and abilities accordingly.
  16. Test the game extensively, iterating on card mechanics, balance, and player engagement.
  17. Polish graphics, UI, and overall user experience to ensure an enjoyable gaming experience.
  18. Incorporate playtesting, gather feedback, and make improvements to game mechanics, card designs, and balance based on feedback and data-driven insights.
  19. Create game documentation, tutorial, or in-game help system to provide instructions and guidance for players on how to play the game and understand its mechanics.
  20. Market and promote the game, develop marketing materials and promotional events to raise awareness about the game, attract players, and grow the community.

As you can see, you could pass most of those tasks to the first algorithm, which would come up with a good answer.

I found myself at times copy-pasting ideas from a working document to the prompt I was sending to GPT-4. I thought that there must be some automated system that would pick the most appropriate domain knowledge for whatever prompt I wanted to send to GPT-4. I asked ChatGPT if it could come up with an answer, and it suggested vector databases. I had no fucking clue what vector databases were, but now I know.

Vector databases translate information into “webs” of data according to the distance between the elements, or something to that effect. What’s important is that if you query the database with some information, it will return the most similar information it contains related to what you asked. Sort of like a recommendation system.

The ‘annoy’ crate for Python seems to be one of the most commonly used systems for implementing vector databases, so that’s what I used. Now I just have to paste all the domain knowledge into a txt file, then run a simple program that registers the knowledge into the appropriate vector database. When I’m ordering the other couple of programs to either develop a task list or perform a task, they query the vector database to retrieve the most relevant domain knowledge. Pretty cool.

Interdimensional Prophets – Deckbuilder (Game Dev) #2


If someone had told me a few years ago, when I was obsessed with board and card games, that in a few days I would have developed a Python program that generates game cards effortlessly, I would have jumped for joy. Working with Python, coming from Rust in particular, is like going from aerospace engineering to building toy rockets; thankfully, a card generating program doesn’t require the speed and multiprocessing that Rust provides.

Anyway, check out the current cards I’m working with as I keep developing the program:

This is an Encounter card, which represent the weird shit that the team of explorers come across as they explore alternate Earths. The name of the card and the image are self-evident. The tree icon indicates that this encounter can only happen in a biome with an icon that matches that type. The row of icons below are the Struggle icons. In the game, the players should match those icons with their player cards to consider the encounter beaten. Those struggle icons depicted are Emotional, Cognitive and Environmental respectively.

Images courtesy of Midjourney, of course.

Here are some Biomes:

I know that the icon designs don’t match each other, but whatever.

I must thank again the most powerful large language model we have access to: GPT-4. It’s like having an extremely knowledgeable veteran programmer ready to help you at all times. For example, an hour ago I thought that the icons could use some subtle drop shadows. I had no clue how to even begin programming that, so I just asked GPT-4. After a short back and forth (in the first attempt it dropped shadows for the invisible part of the alpha channel), the icons now drop perfect shadows. How about that?

I have already started working on the Rust version of the game, using the Bevy crate, which seems to be the most advanced game development engine in that language. I have displayed a few encounter cards that move smoothly to the center of the screen for no particular reason other than that I wanted to figure out how to move stuff smoothly on screen.

Next up, I’ll focus on developing the necessary cards and Rust systems to make the following happen:

  • Design and generate an Exploration Zone card, which are the cards that determine which types of Biomes and Encounters can show up during an exploration (only those with matching icons can).
  • Display the Exploration Zone card in Rust.
  • Write the code to build the Biomes deck with only matching Biomes.
  • Display the Biomes deck on screen in Rust.
  • Write the code to build the Encounters deck with only matching Encounters.
  • Display the Encounters deck on screen in Rust.

We’re Fucked, Pt. 98: AI-generated audiochapter

No matter how grimy the material, AI voices will dutifully perform my chapters to completion, in this case chapter 98.

Cast

  • Leire: a greedy thief who offers you jobs at the Ragged Flagon in Riften
  • Alberto the blob: best voiced Argonians, from back in Cyrodiil
  • Jacqueline: the real Triss, redhead goddess

I have produced audiochapters for this entire sequence so far. A total of an hour, forty-nine minutes and nineteen seconds. Check them out.