Open ikarth opened 1 year ago
Of course, my secret motivation is that I think it's funny to make a novel generator that looks like this.
Cool idea! I worked on a similar idea for last year using the card game "War" a much simulation for sure. Can't wait to see how yours turns out!
Your "War" was one of the inspirations! Along with things like Hannah and The Twelve-Disk Tower of Hanoi and the National Opera Generation Month project that turned a basketball game into an opera.
go mints
Welcome to Kalamazoo Koalas vs. Saskatoon Steelmen.
That's a steal as Kate Bones takes control of the puck from the Saskatoon Steelmen!
Kate Bones steals the puck from Shawn Wolfenstein of the Saskatoon Steelmen!
A pass to Jacob Pattern
Jacob Pattern steals the puck from Shawn Wolfenstein!
None of you are free of sin.
Kate Bones does the give-and-go, Jacob Pattern picks it up.
Jacob Pattern steals the puck from Shawn Wolfenstein!
Shawn Montgomery steals the puck from the Kalamazoo Koalas!
That's a steal as Shawn Montgomery takes control of the puck from the Kalamazoo Koalas!
Shawn Montgomery steals the puck from Kate Bones! The Saskatoon Steelmen have the puck!
Shawn Montgomery steals the puck from Kate Bones; now the Saskatoon Steelmen are on the offense!
A pass to Shawn Montgomery
Shawn Montgomery steals the puck from Jacob Pattern of the Kalamazoo Koalas!
That's a steal as Shawn Montgomery takes control of the puck!
Shawn Montgomery steals the puck from the Kalamazoo Koalas!
Shawn Montgomery steals the puck from Kate Bones! The Saskatoon Steelmen have the puck!
Keeping the momentum going, Shawn Wolfenstein goes tape to tape to Shawn Montgomery.
And now for a word from our sponsor: The National Hlockey League.
Yeesh. That's gonna leave a mark.
Shawn Wolfenstein steals the puck from Jacob Pattern!
Shawn Wolfenstein steals the puck from the Kalamazoo Koalas!
Shawn Wolfenstein steals the puck from Kate Bones; now the Saskatoon Steelmen are on the offense!
That's a steal as Shawn Wolfenstein takes control of the puck!
Looks like it'll be a long game for Saskatoon Steelmen.
Kate Bones steals the puck from the Saskatoon Steelmen!
That's a steal as Kate Bones takes control of the puck!
Kate Bones steals the puck from Shawn Montgomery of the Saskatoon Steelmen!
Jacob Pattern makes a pass to Kate Bones.
That was exceptional.
Kate Bones does the give-and-go to Kate Bones.
That's a steal as Kate Bones takes control of the puck!
That's a steal as Jason Kreminski takes control of the puck!
Jason Kreminski steals the puck from Shawn Montgomery!
Jason Kreminski steals the puck from Shawn Montgomery!
And now for a word from our sponsor: The Association for the Awareness of Seasonal Aggression Disorder.
Yeesh. That looked painful.
Kate Bones sends the puck laterally. Picked up by Jason Kreminski.
Jason Kreminski steals the puck from the Saskatoon Steelmen!
Shawn Wolfenstein steals the puck from Jason Kreminski!
Shawn Wolfenstein steals the puck from the Kalamazoo Koalas!
I can hardly keep up!
The Saskatoon Steelmen are keeping the pressure on!
Shawn Wolfenstein steals the puck from Jacob Pattern of the Kalamazoo Koalas!
That's a steal as Shawn Wolfenstein takes control of the puck!
Shawn Wolfenstein steals the puck from the Kalamazoo Koalas!
Shawn Wolfenstein steals the puck from Kate Bones! The Saskatoon Steelmen have the puck!
And now for a word from our sponsor: The Toronto Dentists Guild.
Jacob Pattern steals the puck from the Saskatoon Steelmen!
Jacob Pattern steals the puck from Shawn Wolfenstein! The Kalamazoo Koalas have the puck!
Jacob Pattern steals the puck from Shawn Montgomery; now the Kalamazoo Koalas are on the offense!
Jacob Pattern steals the puck from Shawn Montgomery of the Saskatoon Steelmen!
Let's see if that works out for them!
Oof! That looked painful.
Jacob Pattern steals the puck from Shawn Wolfenstein of the Saskatoon Steelmen!
Jacob Pattern hits the puck, but the puck goes in the other team's net! A point for the Saskatoon Steelmen!
Current score, Kalamazoo Koalas 0, Saskatoon Steelmen 1.
Stella Phoneme steals the puck from Kate Bones; now the Saskatoon Steelmen are on the offense!
That's a steal as Shawn Montgomery takes control of the puck!
Saskatoon Steelmen is on the move
Youch! That's gonna leave a mark.
That's a steal as Tammy Lancaster takes control of the puck!
A pass by Tammy Lancaster
Saskatoon Steelmen is on the move
Youch. Looks like that hurt.
Shawn Montgomery steals the puck from the Kalamazoo Koalas!
Good pass from Shawn Montgomery to Shawn Montgomery.
A pass to Shawn Montgomery
Saskatoon Steelmen is on the move
The Saskatoon Steelmen are keeping them off balance!
That's a steal as Shawn Montgomery takes control of the puck!
A pass to Shawn Montgomery
They're on their game tonight!
Shawn Montgomery steals the puck from Kate Bones!
Shawn Montgomery makes a filthy pass.
Shawn Montgomery does the give-and-go.
You saw it here, folks!
Stella Phoneme passes to Jacan Montgomery.
That's a steal as Jacan Montgomery takes control of the puck from the Kalamazoo Koalas!
The Saskatoon Steelmen's Jacan Montgomery passes to Shawn Wolfenstein.
You don't see that every day!
The Saskatoon Steelmen's Shawn Montgomery makes a pass to Shawn Wolfenstein.
The Saskatoon Steelmen are keeping them off balance.
Shawn Wolfenstein steals the puck from the Kalamazoo Koalas!
And now for a word from our sponsor: The Birds. This is for'em.
I can hardly keep up!
A pass to Tammy Lancaster
You don't see that in videogames!
And now for a word from our sponsor: It's Alex's birthday! Happy birthday Alex!
Tammy Lancaster steals the puck from the Kalamazoo Koalas!
Jason Kreminski steals the puck from the Saskatoon Steelmen!
Jason Kreminski steals the puck from Shawn Wolfenstein! The Kalamazoo Koalas have the puck!
Jason Kreminski steals the puck from Jacan Montgomery! The Kalamazoo Koalas have the puck!
That's a steal as Jason Kreminski takes control of the puck from the Saskatoon Steelmen!
Jason Kreminski steals the puck from Shawn Montgomery; now the Kalamazoo Koalas are on the offense!
Jason Kreminski steals the puck from Shawn Montgomery! The Kalamazoo Koalas have the puck!
Jason Kreminski steals the puck from Tammy Lancaster!
Jason Kreminski steals the puck from Shawn Montgomery of the Saskatoon Steelmen!
Jason Kreminski steals the puck from Stella Phoneme! The Kalamazoo Koalas have the puck!
And now for a word from our sponsor: The Maple Syrup Distillers Association: We Stab Trees.
Stella Phoneme steals the puck from Jason Kreminski of the Kalamazoo Koalas!
The Saskatoon Steelmen's Shawn Wolfenstein makes a clean pass to Stella Phoneme.
And now for a word from our sponsor: It's Alex's birthday! Happy birthday Alex!
And now for a word from our sponsor: The Film Board of Canada.
Shawn Montgomery goes tape to tape to Stella Phoneme.
Let's see if that works out for them!
Saskatoon Steelmen is on the move
That's a steal as Stella Phoneme takes control of the puck from the Kalamazoo Koalas!
And that's the end of this period; the score is Kalamazoo Koalas 0, Saskatoon Steelmen 1.
Game over. Final score, Kalamazoo Koalas 0, Saskatoon Steelmen 1
It's always a good idea to spend two weeks on international travel in the middle of a project with a deadline!
In actual progress, I've hooked up a winnow implementation of story sifting, so it can search for patterns in the events and turn them into commentary.
There's also actual teams, player rosters, and a tournament structure, though that isn't surfaced in the commentary as much as it could be.
There's also a bunch more names and additional commentary, thanks to Max Kreminski's suggestions/contributions/sins.
Completed novel (62,565 words): https://ikarth.github.io/pasttime/novel.html Generate your own: https://ikarth.github.io/pasttime/
OK, now that I've recovered from all that, how does the thing work? And how close did I get to my original idea?
I knew going in that I'd effectively only have two weeks (at the start and end of the month) and that the original idea would probably be scoped down pretty heavily. Project management tip: when you're exhausted at the end of the month, killing your darlings becomes a lot easier. (Note: do not apply this project management strategy to literal children.) What I ended up with has a lot of room to be built on into something slightly more interesting, or at least more complicated. Having done NaNoGenMo before, I wasn't surprised by this.
The basic simulation (implemented in Phaser) turned out to be a really solid foundation: in theory the players have no idea how to play effectively: their AI is pretty simple and the physics are deliberately tuned so that they end up gliding all over the place. In practice, the different player attributes and traits affected their performance enough that the result was still entertaining.
The game reports the events that happen. This is mostly by checking the collision logics; my design was deliberately leaning on the academic analysis of how videogames operate, albeit in a relatively obvious way. But the basic theory was that collision logics could be translated into something that communicated with the narrative system.
The recording angel of history keeps a list of all of the events, and runs story sifting patterns on them. Extracting narratives from text has been a long-running AI goal; story sifting (or "story recognition") is specifically "the selection of events that constitute a compelling story from a larger chronicle." Some previous discussion of story sifting is in James Ryan's dissertation with Sheldon/Talk of the Town/Bad News, Max Kreminski's Felt and Winnow, Caves of Qud's backstory generation, and Shi Johnson-Bey's Centrifuge.
I probably should have used Felt to do the story sifting, but I went with the slightly more complicated Winnow because my original intent was to generate the commentary as the games were being played. Real-time commentary was cut due to time, so the generator's implementation is more complicated than is actually justified. For some NaNoGenMo novels, the extra complication is the point, but in this case it was just that I ran out of time.
Sadly, the sifting patterns that are currently implemented are relatively simple. While the system is perfectly capable of finding more complicated relationship between events, the ones that are implemented are relatively straightforward. Though the ability to bind data from the event database to variables for the commentator grammar was very useful. The simplest next step would be to add the player information to the database and bind it to the queries as well, though that's still a relatively trivial use case.
Something that did get implemented was the violence, which was added relatively late in the project. When the players collide hard enough, their collision turns violent. It took some tuning to find the exact right number of teeth that should be lost.
The sifted patterns get sent to the commentator, which turns them in to a Tracery grammar and handles them slightly differently based on which pattern was invoked. The grammar has a bunch of variables that were filled in from information in the database, making it a flexible way to report what happened.
The story really started coming alive when the players got names. (I want to thank Max Kreminski for supplying many of the player names and collaborating on the team names.)
I ended up making the tournament structure a 3-elimination knockout. At the last minute, the novel was still far too short, so I did the time-honored sports league move and added a bunch of expansion teams. A more complicated league structure with teams being regulated between different leagues would be dramatically interesting, but that'd make the data structure and reporting way more complicated and the existing tournament manages to be fairly dramatic on its own.
Blaseball was a pretty good demonstration that the basic structure of a sport in motion is a compelling dramatic experience. It's a bit better live, of course, but I like to think that the novel turned out pretty well. You certainly won't know the ending until you get there.
It's not quite at the scope I was envisioning, but that's true of all my NaNoGenMo novel generators. It's a complete dramatic narrative (if a little dry) with uncertainty about how it will end. I've got lots of ideas for building on top of it, but NaNoGenMo being time limited gives me an excuse to take a break from it for a while.
Technically you can infer the repository location from the novel's url, but for completeness' sake, the source code is at https://github.com/ikarth/pasttime
Can I request a slider to slow down the generation? I'd like to watch the games play out but it's so fast that I can't tell what is happening.
It's the tenth NaNoGenMo, and I'm finally free of academic writing obligations. Which doesn't mean I have a lot of time to work on a project, but at least I've got an idea.
I think the key to a NaNoGenMo project is having an idea to structure the project around. So the idea I'm going for this time is inspired by my interpretation of the Oulipo idea of the clinamen: the automated clockwork needs the unpredictable swerve (with the term stolen from Lucretius). I can code a clockwork automaton to produce a story of some sort, but for it to be interesting to me I need it to be unpredictable enough to surprise me.
Emergent systems can be unpredictable in the right way, so I wanted to build an emergent system that would be the core of the unpredictability in the narrative.
Blaseball (RIP) fits that description pretty well. A sports simulation is inherently unpredictable, in that you don't know who will win or even what will happen in the middle of the game. That gives me something to hang the rest of the narrative on. My impression is that sports narratives are slightly more common in film than in novels, but there are a few literary examples. My thinking is that it'll be more interesting to incorporate drama both on and off the playing field, but first I need the game.
I thought about basing it on baseball, on the grounds that I know enough about baseball to write a convincing simulation. But my friend convinced me that hockey would be a more interesting choice, on the grounds that: 1. Blaseball already did baseball. 2. It's probably better if the simulation isn't concerned about accuracy because that's actually kind of a distraction from the novel-generation point. 3. It would be amusing to have the team rosters gradually attrition over the course of the game through violence. Violence is cheap drama, and it's a lot easier to have interesting stories if the novel's characters have some obvious ways to express their passions.
So what we have here is a physics-based simulation of something that might look like hockey if you squinted at it through the wrong end of a poorly-made telescope. In other words, a perfect simulation for our purposes.
Now, all of this needs to be turned into an actual novel with characters and scenes and so forth. Or at least a couple of colorful announcers. But one step at a time.