sprig and prose docs classic docs
Authoring› State or events

State or events

Two facts about a village can feel identical and want completely different shapes.

The bench sits next to the pond. It always has. Nobody would tell you the story of how the bench came to be there, because there isn't one — it is simply where the bench is.

place Bench {
  relationships {
    isNextTo { Pond }
  }
}

The well rope, on the other hand, broke. It got replaced when the caravan came through, and the wheel that wore it down was sanded smooth afterward. Saying "the well has a rope" would be true and would throw away everything interesting.

event WellRopeBroke {
  relationships {
    occursAt   { Well }
    occursWith { WellRope }
  }
}

event WellRopeReplaced {
  relationships {
    canOccurAfter { WellRopeBroke }
    occursWith    { WellRope }
  }
}

Both are facts about the same well. One is an edge. The other is two named things with an ordering between them.

The rule of thumb

Model the state when the state is all anyone would say. Model the events when the events are the story.

A useful way to test it: imagine somebody who has just arrived and wants to know about the thing. If they would be satisfied by a single sentence in the present tense, that is an edge. If they would ask "what happened?", that is events.

If you met a married couple today, you would write down that they are married. You would not model how they met, where he proposed, or which of them moved cities — not because those aren't facts, but because nobody standing in front of them would think to say it. Describe the same two people over the two years before the wedding and you would write almost nothing but events, because for that stretch the events are the relationship.

Neither description is wrong. They are answers to different questions.

Why the shapes differ

An edge is a link between two names. Usually its word is the whole fact: isNextTo says everything there is to say about the bench.

When the fact has a reason, an edge can now carry a sentence too, in a block after its target (Relationships, under Each edge, separately). That is still experimental, and it is still only a sentence. A named thing can do more. It can be pointed at from elsewhere, put in order with other things, have connections of its own, and carry a receipt when real code refers to it. So the sharpest practical test is:

Does this fact need to be pointed at, ordered or connected?

If all it needs is a sentence saying why it is true, write the sentence on the edge. If anything else will ever want to refer to it, or it has an order or connections of its own, give the fact a name.

When a fact stops being true

An edge has no notion of when. isNextTo { Pond } is not a claim about a moment; it is a claim, full stop.

That works until something changes. A bench that was moved to the far side of the pond in the second summer cannot be described by one edge and cannot be described by two, because two would both be asserted at once and neither would be qualified. A sentence on the edge could say "until the second summer", but nothing can read a sentence, so the change still wants a name.

Named events handle it, because a change is a thing that happened and things that happen can be ordered:

event BenchMovedAcrossPond {
  relationships {
    occursAt      { Bench }
    occursDuring  { Season.Summer }
  }
}

Note what you are not doing. You are not recording where the bench is at every point in time. You are recording what changed, and letting a reader work out the rest. Asking "where was the bench in the second summer" is a question for something reading the universe, not a fact stored in it — the same way a field guide can lay out a sequence without any concept holding a position number.

That division is deliberate. Prose holds what is; working out what follows from it belongs to whatever is doing the reading.

The cost

Naming things is work, and it is the kind of work that stalls an afternoon. WellRopeBroke is easy. The moment a change has no obvious name you will sit there inventing one, and the temptation is to flatten it back into an edge and move on.

Two things make that easier to live with.

You can start with the edge and give it a name later. Nothing about isNextTo { Pond } has to be undone when the bench eventually moves; you add the event then, when you know what to call it.

And a bad name is recoverable. A concept can be described in whatever words you like, and the describe is where the meaning actually lives. BenchMoved with three sentences underneath it is worth more than a perfect name with nothing under it.