Month: June 2015

Combining Text

As I wrote before, I started the second draft of Shapes on Monday.

I’ve been working in text files for the most part, with the original draft text in one file with labelled lines and the outline form of that text in another. That outline has been changed quite a lot, with lines re-ordered, added to, and generally modified to match the new vision of how this story works.

So I have two files, but I want one to work on the text of: one file with the original text and the outline content on one line.

As I do in this situation, I wrote a script to do this (included at the end). It’s called combine-outline and it imposes some requirements on the files –

  1. the text file can have labelled lines. The labels look like <label>:, but if they’re omitted then the script will use the line number.
  2. the outline defines the order of the combined content. An outline line consists of an optional label and a piece of outline text.

What the script does is to walk the outline, looking for labels. The label is used to extract the corresponding line from the text file, then it prints out the text and any outline string enclosed in square brackets.

For example, if we combine this text file –

1: There once was a frog.
2: Billy the Frog lived in a house made of mud and leaves.
3: The frog was named Billy.
4: Next door to Billy's house was an earwig nightclub.
5: Yellow wasps invaded Billy's dreams, like sharp-fingered thieves.
6: The nightclub was no trouble, though, because earwigs dance to smell.

… and this outline file –

1: introduce the frog.
3: give the frog's name first
2:
4: talk about the nightclub next door.
The earwigs danced through the day.
6: explain why the nightclub was no bother

… then this script call –

combine-outline text outline combination

… produces this combined output –

There once was a frog. [introduce the frog.]
The frog was named Billy. [give the frog's name first]
Billy the Frog lived in a house made of mud and leaves.
Next door to Billy's house was an earwig nightclub. [talk about the nightclub next door.]
[The earwigs danced through the day.]
The nightclub was no trouble, though, because earwigs dance to smell. [explain why the nightclub was no bother]

Tracking work on this needs word count for the actual text, and I get that on the command line thus –

cat second-draft-text | sed 's/\[[^]]*\]//' | wc

Anyway, back to making words.

Here is the script –

#!/usr/bin/ruby

# Combines content of outline and text files into a single output file.
# The outline file must have line numbers while the text need not, 
# Both the outline and text files are numbered. The outline numbers reference
# those of the text, ordering the text lines according to the line numbers.

help_text = <<END_HELP
Usage:
    combine-outline   
                --force

... where:
     is the original text whose lines are used as labels
     is the outline referencing those labels
     is the file where the combined output should be
        written. This will abort if the file already exists.
    --force will overwrite an existing 
END_HELP

show_help = false
source_file = nil
outline_file = nil
target_file = nil
force_target_write = false

# Read text and map lines by label
# Read outline.
# For each outline line:
# - if there is a label, find corresponding text line.
# - print outline line number, text in braces, and outline as annotation

ARGV.each do |arg|
  if (arg == "--force")
    force_target_write = true
  elsif arg == "-?" || arg == "-h" || arg == "--help"
    show_help = true
  elsif source_file.nil?
    source_file = arg
  elsif outline_file.nil?
    outline_file = arg
  elsif target_file.nil?
    target_file = arg
  else
    $stderr.puts "*** Unrecognised arg '#{arg}'"
    show_help = true
  end
end

# Validate
if !source_file.nil? && !File.exists?(source_file)
  puts "Cannot find text source file #{source_file}"
  show_help = true
end
if !outline_file.nil? && !File.exists?(outline_file)
  puts "Cannot find outline file #{outline_file}"
  show_help = true
end
if !target_file.nil? && File.exists?(target_file) && !force_target_write
  puts "Target text file #{target_file} is already present; aborting."
  show_help = true
end

if show_help
  puts help_text
  exit 1
end

# Read inputs
source_lines = File.read(source_file).split("\n")
outline_lines = File.read(outline_file).split("\n")

# Read text, and map text lines by label
text_by_label = {}
File.foreach(source_file).with_index do |line, line_num|
  if !(matches = line.scan(/^([^:]+:)?\s*(.*)$/)).empty?
    m = matches[0]
    label = m[0]
    text = m[1]
    if label.nil? || label.empty?
      label = (line_num+1).to_s
    end
    text_by_label[label] = text
  end
end

# Open target file
File.open(target_file, 'w') do |f|
  # Read outline
  # For each outline line:
  # - if there is a label, find corresponding text line.
  # - print outline line number, text in braces, and outline as annotation
  File.foreach(outline_file).with_index do |line, line_num|
    if !(matches = line.scan(/^([^:]+:)?\s*(.*)$/)).empty?
      m = matches[0]
      label = m[0]
      outline = m[1]
      text = if !label.nil? && !label.empty?
        text_by_label[label]
      end
      result = []
      result << text unless text.nil? || text.empty?
      result << "[#{outline}]" unless outline.nil? || outline.empty?
      f.puts result.join(" ")
    end
  end
end

Leave a Comment

The Other Drafting

Monday night was Magic night at the day job: we had a booster draft after work using a box of Dragons of Tarkir.

Booster drafting is a social format for Magic, where each player starts with three booster packs. The players break up into groups of 5-8 sitting around a table and then everyone opens a pack, selecting the card you like best and then passing the pack to the left until that first pack is exhausted. The second and third packs are opened in the same way, but the passing direction alternates so that the second pack is passed to the right. Once all the cards are picked, you can build a deck and then play.

It’s a fascinating format, featuring difficult decisions in the choice of cards, opportunities for signalling, and then even harder choices when trying to make a deck from your ill-chosen assortment of cards. Dragons is a good set to draft with – anything with dragons in it is intrinsically interesting, and there are some strong synergies between cards (some faint echoes of which emerged in my deck).

I enjoy drafting but I am certainly no expert – this was only my second booster draft. I did better than last time though I was not disciplined enough in my choice of cards: I picked some cards because they were cool*, and some because they would fit into a standard deck I’m building, and others because I just didn’t want to face them. What I completely failed at was keeping in mind what I already had in my pack – I had only the very vaguest notion of a plan, and that evaporated in the avalanche of choices I had to make.

When it came to deck-building, I didn’t have enough cards that went together. My early picks had pointed towards a blue/black control strategy, but with my random picking of white, green and especially red cards I ended up with a three colour aggro deck. Khans of Tarkir was all about three colour decks, but Dragons is a set which doesn’t support three colours at all. I think the best that could be said is that it had a short mana curve: most of the creatures and spells cost two or three mana to cast, which meant at least I usually had something to do.

Despite those reservations, I won a couple of games: my first two match-ups both went my way quite quickly, and I was feeling confident about how the deck worked, but the problem with a three-colour collection of disjointed singles is that it’s inconsistent: the other games were less successful, and I got flattened a couple of times.

Here’s the deck list for what I played –

  • creatures:
    • 1 x Atarka Efreet – strong but fragile. Most useful for the damage-causing ability when it turns face up.
    • 1 x Blood-Chin Rager – he’s a warrior, and he makes all warriors harder to stop.
    • 2 x Elusive Spellfist – not a powerful creature, but unblockable if you play a non-creature spell.
    • 2 x Hand of Silumgar – small, but has deathtouch which is always useful. Also, a warrior.
    • 1 x Kolaghan Skirmisher – undistinguished**, but has dash and is a warrior.
    • 1 x Necromaster Dragon – big, flying, makes zombies. A bomb if it can stay in play for a couple of turns.
    • 1 x Qarsi Sadist – solid blocker, and can be used to drain your opponent.
    • 2 x Screamreach Brawler – dashes in cheaply.
    • 1 x Sidisi’s Faithful – good blocker with a bonus exploit ability. I like mostly because it’s cheap to cast.
    • 1 x Ukud Cobra – big blocker with deathtouch.
  • non-creatures:
    • 1 x Impact Tremors – causes damage whenever a creature drops onto the battlefield. A tent-pole card: when this came out early, it made it hard for my opponent to stabilise.
    • 1 x Dragon Fodder – makes two goblins. See Impact Tremors above.
    • 1 x Silumgar’s Command – multi-mode utility spell, useful for clearing away troublesome creatures; it can also counter a spell, but too expensive to do that consistently.
    • 3 x Foul-Tongue Shriek – causes X damage where X is the number of attacking creatures.
    • 1 x Glint – surprisingly useful card to save a creature you like. Saw one of these in foil and it’s practically psychedelic.
    • 1 x Silumgar’s Scorn – counter spells are useful, but this is too conditional.
    • 1 x Twin Bolt – two points of damage isn’t much, but it’s enough to remove a morph creature.
    • 1 x Encase in Ice – disables a creature permanently, but this was a useless card in all my games because it only works on red and green.
  • land:
    • 6 x Swamp
    • 6 x Island
    • 5 x Mountain – only five red cards, but I bumped up the proportion of mountains to increase the chances my red splash would fire.

The way this deck was supposed to work was to cast Impact Tremors early, then play out lots of creatures (chipping away one point of life for each). Once the army is assembled, attack en masse and cast foul-Tongue Shriek to do more damage. This happened, more or less, twice.

It failed to go off the other times, though – I didn’t get Impact Tremors early enough for whatever reason, or the army of creatures didn’t materialise, or my big creature would be killed early. However, this theme of lots of creatures ganging up is one I like a lot. The deck I am making for Standard has a lot of these kinds of interactions.

And that’s Magic.

[*] why yes they were dragon cards. How did you guess?

[**] just a 2/2, commonly called a bear whether the creature depicted is actually a bear or not.

Leave a Comment

Drafting Again

I’m starting the second draft of Shapes of Chance today.

The outline is not as fully-formed as I would like, but all of the structural issues that I had with the story have been resolved. To be honest, I am starting today more because it’s the beginning of a new month than because it’s the right day to start, but sometimes you just have to begin.

My goals for this draft are to finish in two months. I am not setting daily word count goals, because I will be reusing some of the existing text. I will measure progress by counting scenes completed. I don’t know how many scenes there are in total, though – this is one of the things unresolved in the outline, as is the reintegration of the outline text with the first draft text.

One last unresolved issue is where I am going to work on this draft. Scrivener is of course my tool of choice for drafting in, but the detailed outline work has all been in vim. I am not completely clear how beat to shift back to Scrivener, or whether I actually should at all.

I will figure that out today, though. Onward!

Leave a Comment