As I mentioned in About Sands of Steel, the scriptwriting system in Sands of Steel was built around giving me fairly strict authorial control over what happens in a scene. Here’s how the editor tool I do that authoring in ended up looking:
I tried to write each segment to be sort of a natural coherent chunk of a scene, averaging maybe 30 seconds or so of conversation or action. The actors involved in a segment are referred to abstractly as a0, a1, etc, which will then get a real character plugged in (using the settings under ’Actor Specifications’ above) as the episode script is built.
To start making a script out of these segments, I first put in place rules to ensure that scenes progressed with at least the barest consistency: there should be one onscreen actor for each of the a0/a1/etc called for by the segment. If the segment is a private conversation between a pair of lovers, require exactly two people to be onscreen at the moment it’s slotted into the script. If one storms out at the end of the segment, that means your next segment has to require no more than one person in the scene. The only other constraint was non-repetition — segments were pulled out of the bag of segments when used, and the bag would only get refilled when no valid segments remained.
So far not so bad — I was building scenes by just pulling any random segment, then appending any random segment whose Actors In was consistent with the first segment’s Actors Out, and so on. I also quickly got fancy with specifying ‘Intro’ and ‘End’ segments that could strictly only take place as the first and last part of a scene (for those oh-so-TV-ish swooping establishing shots, and for situations that really feel like a natural end to a scene, e.g. a dramatic murder or two characters starting to have sex).
https://www.youtube.com/watch?v=8UqSC6OhpPA
<aside> <img src="/icons/directional-sign-right_gray.svg" alt="/icons/directional-sign-right_gray.svg" width="40px" /> (Mmm. So establishing.)
</aside>
The next issues that cropped up pushed me to add some more complexities. Scenes felt tonally dissonant and confusingly paced with the fully random selection of segments. I figured that a TV scene most often begins with a calm setup, before building up toward some final climax moment. So each segment got assigned an Intensity value of 1-6, and segments were then required to be of equal or greater intensity to the previous one in the scene to be considered.
Most troublingly, I also found the generator was just getting into ruts. The distribution of the segments I’d written, and the overlapping effects of the increasingly many hard constraints on what segments could be used, meant that familiar patterns kept happening, e.g. a single character ending up onscreen and then running through a whole bunch of single-character segments repetitively. The intuitive ‘bag random’ approach I’d started with could run into trouble this way because so many segments were getting ruled out — the more constraints were in place, the more rapidly you’d hit the ‘no valid segments left’ fallback and have to refill the bag. It was getting harder to decide exactly how to logically prioritize between my various different competing hard constraints — as well as many more that would have been nice to be able to include.
So I overhauled the whole system to turn these all into soft constraints instead. In the reworked scriptwriter I’d assign a score to each segment which would then get adjusted for a series of different reasons. The segments then get picked using a weighted random choice from those scores. Here’s a video demonstrating the end product, going through building a whole episode:
https://www.youtube.com/watch?v=0F0BRPlUaFI
<aside> <img src="/icons/directional-sign-right_gray.svg" alt="/icons/directional-sign-right_gray.svg" width="40px" /> The left side shows the total set of segments/characters/settings it’s choosing from and their weightings, and the right shows the current scene or segment it’s populating. At the end (1:03) I pop open the finished script and check out which characters have been assigned to each segment’s roles.
</aside>
This got rid of the ‘bag’ concept entirely. Each possible segment starts out equally likely, and then has its % likelihood decreased based on any inconsistencies. Now a segment increasing the intensity and even matching in character count was strongly encouraged but not a hard limiter. I could still narrow out extremely disallowed segments by multiplying their weight to 0 — still needed for situations such as deciding whether a dead character can participate in a scene — but where possible I tried to just gracefully cope with inconsistencies instead, e.g. by having a character wordlessly walk in / out of frame when a character count mismatch occurs between the segments I picked. Constraints could stop being binary this way; a segment that wildly lowers the intensity is more sharply discouraged than one that only slightly takes it off course. And I could now also add/remove layers of constraints in a pretty routine, uniform way, rather than requiring a bunch of tangled logic to get rewritten.
This way hopefully the best match could be found along numerous different dimensions at once, with a much less predictable result. The visualization was also a useful way to assess why things were happening, whether a bad outcome was a fluke or a predictable result, etc. As you can see in the vid, I also used the same weighting system to assign characters to roles in the segment (purple bars) and to choose the scene’s location (green bars), though those choices are way less involved.
Here’s another example of the final episode script that might result:
Some things to note in here: