Skip to content

Instantly share code, notes, and snippets.

@willnationsdev
Last active February 13, 2018 22:46
Show Gist options
  • Save willnationsdev/372deca46a562e7fc23c9daf349d9528 to your computer and use it in GitHub Desktop.
Save willnationsdev/372deca46a562e7fc23c9daf349d9528 to your computer and use it in GitHub Desktop.
JourneyScript concept
# JourneyScript is a narrative scripting language that allows us to
# control the content, context, and flow of dialogue. It is designed
# to mimic as closely as possible the format of a screenplay, but
# it also enables writers to define custom logic and behavior.
# Content is broken up into dialogue segments. The Journey system
# simply provides an "advance" method to programmers which shifts
# the content into the next segment.
# This is a single-line comment.
# There are no multi-line comments.
# The first text of any document is a list of meta data
tags: start, protagonist intro # comma-delimited list of tags
# '---' marks the end of the meta data
---
# In JourneyScript, writers can markup their dialogue with notes.
# Notes come in many varieties.
# Notes are useful because they are "comments" that an editor can
# track and connect with editor functionality.
# A directorial note.
# Format: all caps, ends in colon, leading whitespace permitted.
FADE IN:
# A heading note.
# Format: line starts with "INT." or "EXT."
# '@' signs mark proper nouns for use in a narrative database.
# '@' signs can also be converted into hyperlinks and have
# associated signals.
INT. @JOES_OFFICE - NIGHT
# An action note.
# Format: No leading special characters.
# Note that a prefixed '@' all-caps word is assumed to be a character introduction.
# An optional parentheses can be placed immediately after with an alias.
After midnight, @JOE_WALKER(Joe), a 20-something man wearing
an exceptional suit, picks up the phone and dials a number.
# A 'reminder' authorial note.
# Format: Leads with an exclamation point (!) and a space.
! Need to come back to this and review the description.
# A 'question' authorial note.
# Format: Leads with a question mark (?) and a space.
? Should this really happen at midnight?
# '%' marks an audible source.
A phone in an adjacent office %RINGS and someone %PICKS_UP the phone.
@Joe: # declares a "speaker" for the following text. Line must start with '@', no leading whitespace. Must end with colon.
Hey, are you there? # Dialogue positioned in after a single tab or 4 spaces (pythonic). This text all appears on one line.
- excitedly # A 'parenthetical' note. Useful for voice actor notations. Leads with '-' and a space.
# An empty line here marks that the dialogue system must "advance" to produce the next content.
# Consecutive empty lines doesn't make any difference.
I... # Starts another segment, clears the previous text.
... 0.5 # Wait half a second (Leads with '...' and a space, triggering a pause). Adds "pause" parenthetical note.
> # '>' marks a segment continuation on an otherwise empty line. Useful for visual clarity.
I want to try again. # An empty line hasn't happened yet, so this is interpreted as a newline within the same segment.
# Another directorial note (all caps, ends in colon)
CUT TO:
INT. @BENS_OFFICE - NIGHT
@BEN_CHASE(Ben) stares ahead with his ear to the receiver.
He's similar in age and clothing, but has an exquisite,
thinly curled mustache.
His mouth curls into a grin.
@Ben(exp=grin): # You can provide optional named parameters to a line of dialogue.
> # Here, we are defining "exp", i.e. "expression" is "grin"
Are you su-
| # '|' indicates the next segment auto-advances once the current "advance" finishes rendering
@Joe(os): # named parameters without an '=' are simply flags. This is an "off screen" flag.
YES! I'm ready.
- muffled
@Ben:
* [I wanna ask Jared first](ask_jared) # '*' indicates choices being presented to the player.
> # Links to other JourneyScript content. [displayed text](destination script), e.g. 'accept.jns'
* We'd better not.
@Ben: # Incremented inline dialogue is only triggered if the choice is selected.
I'm sorry # Because there is no empty line between these two, they speak simultaneously.
@Joe:
Wait, what?
* Excellent!
@Ben, @Joe: # These two speakers deliver the same line of dialogue, simultaneously.
Let's go!
* Wait, let me think...
>
<% # lines enclosed by '<%' and '%>' are embedded script code. The language is whatever the .jns is being transpiled into.
var thinking = true # declared a script variable! This variable is local to the "sample.jns" script.
story.thinking = thinking # declared a story variable! The 'story' Dictionary is accessible from every JourneyScript code context.
%>
... 1
Ok, << "%s" % "let's go" if thinking else "nevermind" >> # can insert text into the story from the code context
> # The format for this line is derived from the "string formatting content in GDScript
> # You should use whatever string formatting approach is appropriate for the transpiled language.
> # the insertion tags '<<' and '>>' simply define where to insert the formatted string.
------------------------------------ # This file would transpile as GDScript into...
func jns_sample():
init("sample")
add_tag(15, 15, "office space")
add_tag(15, 15, "start")
director_note(24, "FADE_IN:")
header_note(31, ("INT. @JOES_OFFICE - NIGHT"
)).mentions("JOES_OFFCE")
action_note(37, 38, (
"After midnight, @JOE_WALKER(Joe), a 20-something man wearing
an exceptional suit, picks up the phone and dials a number."
)).mentions("JOE_WALKER", "Joe")
reminder_note(42, 42, "Need to come back to this and review the description.")
question_note(46, 46, "Should this really happen at midnight?")
action_note(49, 49, (
"A phone in an adjacent office %RINGS and someone %PICKS_UP the phone."
)).audible("RINGS").audible("PICKS_UP")
add_speaker(51, "Joe")
buffer(52, 52, (
"Hey, are you there?"
)).parenthetical("excitedly")
show()
newline()
buffer(56, 56, (
"I..."
))
sleep(0.5)
newline()
buffer(59, 59, (
"I want to try again."
))
clear_speakers()
directorial_note(62, "CUT_TO:")
header_note(31, ("INT. @BENS_OFFICE - NIGHT"
)).mentions("BENS_OFFCE")
action_note(68, 70, (
"@BEN_CHASE(Ben) stares ahead with his ear to the receiver.
He's similar in age and clothing, but has an exquisite,
thinly curled mustache."
)).mentions("BEN_CHASE", "Ben")
action_note(72, 72, (
"His mouth curls into a grin."
))
add_speaker("Joe", { "exp": "grin" })
TODO: complete (This is a WORK IN PROGRESS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment