A DSL to write visual novels games in Ruby using TyranoBuilder.
TyranoBuilder is a good tool has many features like native web export but I don't like to click-heavy interface to write.
The goal is to provide a simple syntax you can use directly or you can build upon.
You create your TyranoBuilder project with the specific options and the library is used to modify the content without touching the other things.
The project is a WIP: I add things as I need them, if you have any issue or need something please ask me.
If you use it for a published VN, please tell me: it would make me happy and I'll add a link to it in this page.
Example:
declare_character 'Shinji',
'default' => 'default_stance.jpg',
'angry' => 'angry.jpg'
declare_background 'School', 'background/school.jpg'
set_title_screen_background 'School'
start_scene 'First scene'
set_background 'School'
show_character 'Shinji', 'default', 434, 128
show_message_window
display_text 'Shinji', 'Hello!'
set_character_stance 'Shinji', 'angry'
display_text nil, 'Do you want to go in the eva ?'
ask_question [
{
'text' => 'Yes!',
'left' => 200,
'top' => 200,
'scene' => 'Second scene'
},
{
'text' => 'No!',
'left' => 200,
'top' => 300,
'scene' => 'Third scene',
'label' => 'a label'
}
]
start_scene 'Second scene'
The simples use case :
- Install TyranoBuilder
- Create a project in it
- Install the gem
- Execute
tyrano-dsl dsl tyrano PATH_TO_YOUR_RUBY_CODE.rb PATH_TO_YOUR_TYRANO_PROJECT
in your project directory.
PATH_TO_YOUR_TYRANO_PROJECT
should look like /Users/u/Library/Application\ Support/Steam/steamapps/common/TyranoBuilder/myproject/Test
If everything is OK it should update the files in your TyranoBuilder project.
You can then reopen the project in TyranoBuilder and see the changes.
If there is an error it should be displayed and the message should help you to fix the problem.
tyrano-dsl import-format export-format import-path export-path
dsl
the Ruby DSL,import-path
must be the path to the main Ruby filetyrano
import from a Tyrano project,import-path
must be the path to the Tyrano project
dsl
the Ruby DSL,export-path
must be the path to the directory to export tograph
print the game as a graph in the console in the Graphviz format so you can visualize ittyrano
export the game to replace the current content of the Tyrano project,export-path
must be the path to the Tyrano projecttext
print the text content of the game in the console so you can easily proofread it, in this caseexport-path
is not used
declare_background(name, images_path)
name
is aString
representing the background's nameimages_path
is aString
indicating the path to the background images
declare_background 'School', 'background/school.jpg'
show_background(name)
name
is aString
representing the background's name
set_background 'School'
declare_character(name, stances)
name
is aString
representing the character's namestances
is aHash{String => String}
providing a list of stances with the path to their corresponding images
declare_character 'Shinji',
'default' => 'default_stance.jpg',
'angry' => 'angry.jpg'
hide_character(name)
name
is aString
representing the character's name
hide_character 'Shinji'
set_character_stance(name, stance)
name
is aString
representing the character's namestance
is aString
defining the stance nameduration
(optional) is anInteger
defining the duration of the transition, default is600
set_character_stance 'Shinji', 'angry'
set_character_stance 'Shinji', 'angry', 300
show_character(name, stance, left, top)
name
is aString
representing the character's namestance
is aString
defining the stance nameleft
is anInteger
defining the left positiontop
is anInteger
defining the top position
show_character 'Shinji', 'default', 434, 128
ask_question(possible_answers)
possible_answers
is a list of possible answers with the corresponding targettext
is aString
representing the text of the answerleft
is anInteger
defining the left positiontop
is anInteger
defining the top positionscene
is aString
indicating the name of the scene to jump if the answer is selectedlabel
(optional) is aString
indicating the name of the label in the scene to jump if the answer is selected
ask_question [
{
'text' => 'Yes',
'left' => 200,
'top' => 200,
'scene' => 'Second scene'
},
{
'text' => 'No',
'left' => 200,
'top' => 300,
'scene_name' => 'Third scene',
'label_name' => 'a label'
}
]
declare_label(name)
name
is aString
representing the label's name
declare_label 'my label'
conditional_jump(variable, operator, value, scene, label)
variable
is aString
indicating the name of the variable to be testedoperator
is aString
indicating the comparison operator to use:<
,==
(equal),>
,!=
(different)value
is aString
or aFloat
indicating the thing to compare the variable to, it can be a numerical value or the name of another variablescene
is aString
indicating the name of the scene to jump tolabel
(optional) is aString
indicating the name of the label in the scene to jump to
conditional_jump 'variable_1', '<', 10, 'Scene two'
conditional_jump 'variable_1', '=', 'variable_2', 'Scene two', 'Label three'
jump(scene, label)
scene
is aString
indicating the name of the scene to jump tolabel
(optional) is aString
indicating the name of the label in the scene to jump to
jump 'Scene two'
jump 'Scene two', 'Label three'
declare_variable(variable_name, initial_value)
variable_name
is aString
representing the variable nameinitial_value
(optional) is aFloat
or aString
representing the variable initial value
declare_variable 'happiness', 25
update_variable(variable_name, operation, value)
variable_name
is aString
representing the variable nameoperator
is aString
indicating the operation to apply=
set the variable with the value+=
add the value to the variable-=
substract the value from the variable*=
multiply the value with the variable/=
divide the value with the variable%=
set the variable with the reminder of the division with the value
value
is aString
or aFloat
indicating the thing to use as a value, it can be a numerical value or the name of another variable
update_variable 'happiness', '=', 25
update_variable 'happiness', '+', 'calmness'
clear_messages
clear_messages
hide_message_window
hide_message_window
include_file(file_name)
name
is afile_name
representing the file to include
include_file 'other_scene.rb'
show_message_window
show_message_window
start_scene(name)
name
is aString
representing the scene's name
start_scene 'First scene'
The tool works like a compiler:
- the first pass parse the initial version into an intermediate version
- the intermediate pass create the world and validate the content
- the last pass generate the result
- the content is applied to disk
Bug reports and pull requests are welcome on GitHub.
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The code is available as open source under the terms of the MIT License.