VisualNovelTemplate
A simple template for web-based visual novels. Written in javascript, easily customizable.
Install / Use
/learn @diane1f0cd/VisualNovelTemplateREADME
Visual Novel Template Documentation
Code and documentation: @ker0chanFR
Characters and background art: @LtEmi
Demo/Tutorial/Example (yes, it's everything at once)
Table of Contents
- Disclaimer
- Getting started
- Lexicon
- Scripting syntax
- Customization
Disclaimer
Keep in mind that this was intended as a template/boilerplate code base to get a project started on the right tracks, rather than as a full-fledged engine. If your project needs features that differ completely from those presented here, you might want to dig into the code and add them yourself (or with the help of a programmer). Custom actions and stylesheets can give pretty good results to some extent, but reworking the core of the engine will probably be more stable/scalable/optimized in the long run.
It's also largely untested, most of the code was recycled from a previous project of mine, and cleaned up/reorganized to be more user-friendly and easy to dive into. Some features have been added in the process, but I haven't had the chance to test them for a real project yet. Expect bugs, missed opportunities and a positive amount of disappointment.
Getting started
The engine currently handles stories written in Yarn, and exported as a JSON file. Yarn is a dialogue editor that helps you build nodes and branching trees in a visual way, similar to Twine. In this template, a specific script syntax (that slightly differs from the standard Yarn syntax) is used, in order to provide an easy access to the features needed in a visual novel game. Check out the scripting syntax below for more information. The characters and places data are stored as JSON files that need to be edited by hand. Using a JSON editor (like http://www.jsoneditoronline.org/) or a text editor with syntax highlighting (Notepad++, Sublime Text) is strongly recommended.
Quickstart instructions
- Download this project as a zip file, or clone the repository
- Create a story using Yarn and save it in
data/story.json - Define your characters in
data/characters.json - Define your places in
data/places.json - Add images for your characters and places, probably in the
imgfolder - Edit
css/scene.cssto define the appearance (position, size) of your characters (optional) - Edit
index.htmlandend.htmlto create your own menu and ending screens (optional for now, but you should at least give a name to your game!)
Testing your game
- If you are creating your game in an offline environment ("I am not a coder"):
- Launch
build.bat(Windows) orbuild.sh(Mac, Linux). This will compile your JSON files into a single javascript file that will be loaded in the page. You will need to do this every time you change the content of the JSON files or your story for the changes to appear in the game. - Open
index.htmlin your web browser to start the game, or opengame.htmlto skip the menu page.
- Launch
- If you are creating your game in a server environment ("I am a coder" or "I'm tired of launching the build script every 5 seconds"):
- Edit
main.jsand follow the instructions to enable asynchronous data loading. - Go to
your_server_address/index.htmlin your browser to start the game, oryour_server_address/game.htmlto skip the menu page.
- Edit
Distributing your game
Once you're done creating your game (🎉🎉🎉 congratulations 🎉🎉🎉), you might want to make it available online and show it to the world. As a web-based game, it simply needs to be hosted somewhere: a personal website or a game hosting website like itch.io or Gamejolt or even GitHub Pages, for example.
Specific instructions for these platforms can be found on their respective website, but the usual steps will require you to package all your files in a zip archive. Make sure you put all the game files in the archive. You don't have to include build.bat or this instructions file, the game will run without them.
Lexicon
Node: The building block of your story. This is the visual thing you see in Yarn, it's a block that has a title, and some content. The content spans multiple lines, each of them representing a Scene, Action, or Choice. Nodes hold all the narrative content of the game in a single branching path, and can be linked to and from other nodes, in order to build a conversation tree.
Scene: The state of the game at a given moment: background, character, text. Clicking on a choice usually moves the player to another scene, which means the scene is "that thing that exists between two clicks". Scenes contain one or more choices, and can contain one or more action. Scenes have an identifier that is either the title of the node they are in (for the first scene in a node), or an automatically generated identifier. You probably don't need to access that, or if you do, you probably know how to find it anyway.
Action: Something that happens when entering a scene. This is usually used to move to a different Place or changing some variable state, but with some custom code, it can do anything! Shaking the screen, changing parts of the stylesheet, playing a sound...
Choice: The link between to scenes. Some scenes may have only one choice, and that's okay. When creating a branchig path in the narrative tree, multiple choices will be used. Choices can also contain one or multiple Conditions. If conditions are not met, the choice will simply not appear on the player's screen. As such, a scene with no available choice will result in a dead end. This is usually not an intended behaviour, so make sure there is always one or more choice that has no condition, or that at least one of your conditions will be evaluated to true.
Identifier: Places, characters, variables and pretty much every piece of data in your game can be referenced by its identifier. It's their "name in the code". They are case-insensitive (bobby, Bobby, and BOBBY will all reference the same character, named "Bobby") and need to start with a letter. They can contain numbers and symbols like - or _. These names are used inside of the code, so keep it simple and avoid dangerous characters like line breaks or emojis (it might work okay, I haven't tested it extensively, but I can't think of a single situation where you'd want to do that anyway). Seriously just type anything-like-that, likeThat, or even_that and you're good to go.
Variable: A box that holds a value for later use. String and Number variables respectively hold strings (ending_unlocked, open, true, fancy) or integer numbers (0, 100, -5, 200000). String values can't contain spaces. Number values will be parsed as integers, 10.0 is not allowed, neither is -3^10. Variables have an identifier that is used to reference them in actions or conditions.
Condition: Controls the circumstances under which a choice is made available to the player. Some examples include:
- Checking if a string variable holds a given value ("Is the door locked?")
- Comparing the value of a number variable to some other value ("Does the player have more than 200 coins?")
- Checking the approval level of a character ("Does Bobby hate the player?")
A single choice can contain multiple conditions, in which case they ALL need to be true for the choice to be available.
Place: A place where scenes are happening. Places can be changed using an Action. They contain a name and an image, that are usually both displayed on screen during the game. This does not provide a player movement system (though you could probably add it with some custom code), it is only a way to change the background of the game during a playthrough. Places have an identifier that is used to reference them in actions.
Character: Each scene contains a character that will be displayed on screen, along with their name and their current dialog line(s). Characters can have multiple poses, with one pose used at a time during a scene ({{alice,happy}} I'm so happy!). The hidden pose can be used on any character, allowing for a character to not appear on screen at all. When no pose is mentioned, the default pose will be used. When no character is mentioned, a default character ("The Narrator") w
