This repository contains the source code to create a Visual Novel game based on minimal edits using Python if it needed.
And just setting up a few json files.
And also elements of the basic Novelist game engine.
I was inspired to develop this code by the inability to use RenPy to create a game in the form in which I want.
As well as not wanting to learn RenPy scripting language.
In addition, writing your own game, almost from scratch, is quite interesting.
Contains information about dependencies and how to install them.
This section describes step by step how to create a game using the engine, at the level of console utilities.
Just like scenes and texture data need to be described, without using any scripting languages, so that the game can be assembled.
The paragraphs in this section describe in sufficient detail how the game is structured and how to control it at the level of the contents of the configuration files.
- How to run the application
- Settings of scenes
- Characters and their sprites
- Backgrounds and its sprite
- User Interface
- Text and Localization
- The name and icon of the game window
- GamePlay
- Default game settings
- Sound System
- How the program works
- Logging
- Save and Load system
This section contains information on solving typical problems and plans for further development.
The application code is written in python and obviously depends on it.
Python version 3.6 [Python Software Foundation License / (with) Zero-Clause BSD license (after 3.8.6 version Python)]:
PyGame [GNU LGPL version 2.1]:
Used to create windows, surfaces and draw them on top of each other.
Also for flipping the screen and drawing the window icon.
pip install pygame
If you want you can change this library by first downloading it from the repository and installing your version using the command.
pip install ./path/to/modified/lib
For convenience, this utility is equipped with shell scripts that simplify its call, and a file with an example scene.
Files location:
./πUtilities
β ββββ πScreenplay_parser
β β β β β β βββ πScreenplay_source
β β β β β β | β β β ββββ πexample_scene_config.ini
β β β β β β βββ πScreenplay_Source_Parser.py
β β β β β β βββ πScreenplaySourceParser_execute.ps1
β β β β β β βββ πScreenplaySourceParser_execute.sh
Let's start with how to design the scene for this script.
An example of the scene is in the 'example_scene_config.ini' file.
In order to create your own scene, you need to create a file with any name and ini extension, and either add it to the 'Screenplay_source folder'.
Or to any directory in which you want to store your scenes.
You can store several scenes in one file, or just one.
Let's take a closer look at the components of the scene settings:
-
Basic Scene Settings:
[example_scene_name] scene_type = reading|choice past_scene = scene_name|START
- example_scene_name - This scene name will be used inside the game.
It should be written in square brackets.
And all subsequent rows assigned to this scene must be under this title. - scene_type - keep gameplay type.
Can be reading or choice. - past_scene - keep name of previous scene.
This should be a name similar to what you write in square brackets at the beginning of the scene settings.
For another configured scene - respectively.
The first scene in your visual novel must have 'START' written on it.
- example_scene_name - This scene name will be used inside the game.
-
Background:
background_sprite_sheet = background_01 background_animation = animation_01
- background_sprite_sheet - keep background sprite texture image and texture settings file.
To create a texture you can use "Texture_Source_Parser" utility. - background_animation - here you need to specify the name of the animation or static frame.
- background_sprite_sheet - keep background sprite texture image and texture settings file.
-
Reading scene settings:
next_scene = scene_name|FINISH speaker_name_color = #ffffff speech_text_color = #ffffff
- next_scene - keep name of next scene for reading gameplay.
This should be a name similar to what you write in square brackets at the beginning of the scene settings.
For another configured scene - respectively.
The last scene in your visual novel must have 'FINISH' written on it. - speaker_name_color and speech_text_color - keeps hex-code the color of the name of the character speaking in the scene and the color of the text that he speaks.
You don't have to specify colors.
They will be set to #ffffff by default.
- next_scene - keep name of next scene for reading gameplay.
-
Choice scene settings:
scene_choice.choice_01 = scene_03 scene_choice.choice_02 = scene_02 choice_text_color.choice_02 = #ffffff
- scene_choice - stores the name of the scene to be switched to as a value.
Please note that in this case the key consists of 2 parts 'scene_choice' and choice name as example 'choice_01' and 'choice_02'.
This should be a name similar to what you write in square brackets at the beginning of the scene settings.
For another configured scene - respectively. - choice_text_color - is designed on the same principle as 'scene_choice'.
Keeps hex-code the color of choice text.
You don't have to specify colors. They will be set to #ffffff by default.
- scene_choice - stores the name of the scene to be switched to as a value.
-
Characters settings:
# Left Character: left_character_animation = animation_01 left_character_sprite_sheet = left_character left_character_plan = background_plan|first_plan # Middle Character: middle_character_animation = animation_01 middle_character_sprite_sheet = middle_character middle_character_plan = background_plan|first_plan # Right Character: right_character_animation = animation_01 right_character_sprite_sheet = right_character right_character_plan = background_plan|first_plan
You can leave the characters unspecified if you want the scene to remain empty.
Or you can use one, two or three character type actors on scene.
At the beginning of each key you need to indicate what type of character you want to describe:
left_, middle_ or right_. As example right_character_animation.
Next, the keys will be listed without this prefix:- character_sprite_sheet - keep character sprite texture image and texture settings file.
To create a texture you can use "Texture_Source_Parser" utility. - character_animation - here you need to specify the name of the animation or static frame.
- character_plan - can only have 'background_plan' or 'first_plan' as value.
Obviously, the setting is responsible for how the character will be drawn.
In the foreground or background.
- character_sprite_sheet - keep character sprite texture image and texture settings file.
-
Optional scene settings:
# Special effects can be sent like list as example: "rain,noise_artifacts,snow"... scene_special_effects = rain|noise_artifacts|false music = music_file|false sound = sound_file|false voice = voice_file|false
- scene_special_effects - the option is currently under development.
- music - name of music file or false
This file will play in a loop during this scene - sound - name of sound file or false
This file plays once per scene, a moment after the switch is made. - voice - name of voice file or false
This file plays once per scene, a moment after the switch is made.
In order to use this utility, you need to call it directly, or through a shell ScreenplaySourceParser_execute script that simplifies working with it.
As an argument, you can pass the absolute path to the folder with your scene settings, if it differs from the default one.
As example:
./ScreenplaySourceParser_execute.sh /home/User/Example_Path
If the folder is standard you can simply call the script.
powershell -File ScreenplaySourceParser_execute.ps1
Below is a detailed description of how to run the utility on different operating systems:
-
Windows:
- Hold down 'Win' and 'R' keys on your keyboard.
- Enter 'cmd' in the window that opens and press 'Enter'.
- Enter the drive letter where the program was downloaded and ':'.
As example for 'D drive':
D:
- Enter 'cd' and absolute path to the script through the folder where you downloaded the program.
As example for downloaded path 'D:\Git\Novelist':
cd D:\Git\Novelist\Utilities\Screenplay_parser
- Run "ScreenplaySourceParser_execute" powershell script.
powershell -File ScreenplaySourceParser_execute.ps1
-
MacOS:
- Hold down 'Command' and 'Space' keys on your keyboard.
- Enter 'Terminal' in the window that opens and press 'Enter'.
- Enter 'cd' and absolute path to the script through the folder where you downloaded the program.
As example for downloaded path '/home/User/Git/Novelist':
cd /home/User/Git/Novelist/Utilities/Screenplay_parser
- Please note that to run a script on Unix-like operating systems, you must first explicitly make it executable with the command:
chmod +x ./ScreenplaySourceParser_execute.sh
- Run "ScreenplaySourceParser_execute" Bash script.
./ScreenplaySourceParser_execute.sh
-
Other Unix type OS: - Ubuntu, Fedora, etc.
- Open the Terminal of your operating system.
- Enter 'cd' and absolute path to the script through the folder where you downloaded the program.
As example for downloaded path '/home/User/Git/Novelist':
cd /home/User/Git/Novelist/Utilities/Screenplay_parser
- Please note that to run a script on Unix-like operating systems, you must first explicitly make it executable with the command:
chmod +x ./ScreenplaySourceParser_execute.sh
- Depending on your security settings, you may need to enter the sudo command.
And enter the password when requested if necessary.
sudo chmod +x ./ScreenplaySourceParser_execute.sh
- Run "ScreenplaySourceParser_execute" Bash script.
./ScreenplaySourceParser_execute.sh
To run the application, you need to run the 'Visual_novel_game.py' script with your shell.
Example of shell command:
python -B Visual_novel_game.py
File location:
./πData
β ββββ πVisual_novel_game.py
To adjust the scene order, you need to change the json file 'screenplay.json'.
At the same time, the first scene must have the 'past_scene' key value as 'START'.
In the last scene 'next_scene' key must be 'FINISH'.
File location:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πscreenplay.json
Example of screenplay.json file:
{
"test_scene_01": {
"gameplay_type": "reading",
"background": {
"background_sprite_sheet": "back_ground_01",
"background_animation": "default"
},
"past_scene": "START",
"actors": {
"Character_02": {
"character_animation": "1",
"character_plan": "first_plan",
"character_start_position": "middle"
},
"Character_01": {
"character_animation": "3",
"character_plan": "background_plan",
"character_start_position": "right"
}
},
"next_scene": "test_scene_02",
"speaker_name_color": "#00ffff",
"speech_text_color": "#ffffff",
"special_effects": [
"rain",
"noise_artifacts"
],
"sounds": {
"music_channel": false,
"sound_channel": "blank",
"voice_channel": false
}
},
"test_scene_02": {
...
"choices": {
"choice_01": {
"branching": "test_scene_01",
"text_color": "#ffffff"
},
"choice_02": {
"branching": false,
"text_color": "#ff0000"
},
"choice_03": {
"branching": "test_scene_03",
"text_color": "#ffffff"
}
},
...
}
Gameplay Type:
Please note that a 'gameplay_type' key value must be reading|choice strings.
Background:
The 'background' key have information about background sprite.
The 'background_sprite_sheet' key must have backgrounds name keys from 'backgrounds_sprites.json' as a value.
The 'background_animation' key must have a relevant animation name from background texture json file data.
More about this further in Β«Backgrounds and its spriteΒ» paragraph.
Past Scene:
The 'past_scene' key contains information about the previous scene.
The first scene must have the 'START' key value.
Actors:
Please note that an actors characters keys must match certain values:
character_animation - can be any key from the dictionary 'characters_sprites.json'.
More about this further in Β«Characters and their spritesΒ» paragraph.
character_plan - may have values background_plan|first_plan.
character_start_position - may have values right|middle|left.
ποΈβπ¨οΈSpecific for Reading GamePlay:
-
Next Scene:
The 'next_scene' key value contains information about the next scene to be switched to.
Last scene must have the 'FINISH' key value.
Please note that this only switches the reading gameplay scene.
As example 'test_scene_01' scene. -
Speaker Name Color:
The hex-code value of the speaker_name_color key obviously contains a color setting that will be assigned to the speaker's name while scene rendered. -
Speech Text Color:
The hex-code value of the speech_text_color key obviously contains a color setting that will be assigned to the speach text while scene rendered.
π¬Specific for Choice GamePlay:
- Choices:
The 'choices' key value contains links to text localisation as keys.
The 'branching' work like 'next_scene' key for reading gameplay.
Please note that this only switches the choice gameplay scene.
The 'text_color' key control color of text on choice button.
As example 'test_scene_02' scene.
More information about reading and choice gameplay text is specified in the Β«Text and LocalizationΒ» paragraph.
Special Effects:
Currently under development.
Sounds:
The nested dictionary of the "sounds" key contains the keys and values of the sound effects and music
that will be played at the start of the scene and will be interrupted at the transition to the next one.
Please note that the keys "voice_channel", "sound_channel" and "music_channel" can contain either a string with a name, without a file extension, or false as values.
Information about the characters is stored in a 'characters_sprites.json 'file.
It needs to list the names by which the game will look for characters.
Please note that the name specified here is how the key is used in the actors key in 'screenplay.json' file!
And this name is in no way related to the one you can set in the dialogs!
Texture data file name and animations available to the character from this file.
File location:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πcharacters_sprites.json
Example of 'characters_sprites.json' file:
{
"Character_01": {
"texture": "blank_pink",
"animations": {
"1": "animation_1",
"2": "animation_2",
"3": "animation_3"
}
},
"Character_02": {
"texture": "blank",
"animations": {
"1": "black",
"2": "pink",
"3": "blue",
"4": "green"
}
}
}
In this case, two options for implementing a character sprite are indicated:
Character_01 is the character with an animated sprite.
Character_02 is the character without animations.
The difference is that in the animation key for a static sprite, static poses are actually specified, not animations that will be played frame by frame.
Regardless of the type of animations the character has.
You must set the texture key value to the name of the texture image and the texture storyboard settings.
Please note the names of these two files must match!
Let's first discuss the sprite texture settings sprite sheet files.
Files location:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πTexture_data
β β β β β β β β β β β β β β β β β β β β βββ πCharacters
β β β β β β β β β β β β β β β β β β β β β β β β βββ π*.json (Can be your sprite sheet json)
For static sprites, the following settings are typical:
- sprite_sheet value is False.
- statick_frames simply contains the name of the frames with their x|y coordinates.
The coordinates for each frame are specified as the top left corner and the bottom right corner, respectively.
Example of such a 'statick_sprite_sheet.json' file:
{
"sprite_sheet": false,
"statick_frames": {
"black": {
"top_left_corner": {
"x": 25,
"y": 49
},
"bottom_right_corner": {
"x": 280,
"y": 618
}
},
"pink": {
"top_left_corner": {
"x": 344,
"y": 49
},
"bottom_right_corner": {
"x": 568,
"y": 618
}
}
}
}
For animation sprites, the following settings are typical:
- sprite_sheet value is True.
- animations value contains not just frames but settings for each animation.
- time_duration -animation playback time as float.
- frames - list of frames with their x|y coordinates.
The coordinates for each frame are specified as the top left corner and the bottom right corner, respectively.
Example of such a 'animation_sprite_sheet.json' file:
{
"sprite_sheet": true,
"animations": {
"animation_1": {
"time_duration": 1.0,
"frames": {
"1": {
"top_left_corner": {
"x": 21,
"y": 21
},
"bottom_right_corner": {
"x": 342,
"y": 940
}
}
}
},
"animation_2": {
"time_duration": 1.0,
"frames":{
"1": {
"top_left_corner": {
"x": 21,
"y": 1000
},
"bottom_right_corner": {
"x": 342,
"y": 1919
}
}
}
}
}
}
Sprite images must be in png format and stored in a 'Characters' folder.
Folder location:
./πData
β ββββ πAssets
β β β β β β βββ πImages
β β β β β β β β β β βββ πCharacters
β β β β β β β β β β β β β β βββ πΌοΈ*.png (Can be your image file)
Information about the backgrounds and its sprites must be entered into the 'backgrounds_sprites.json' file.
The names that will be given here are used to create scenes in 'screenplay.json' fie.
File location:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πbackgrounds_sprites.json
Example of 'backgrounds_sprites.json' file:
{
"back_ground_01": {
"texture": "blank",
"animation": "default"
},
"settings_menu": {
"texture": "blank",
"animation": "default"
}
}
As you can see from the example, names are also used for game menus.
All menu, except for gameplay, have their background plans.
All settings are similar to the settings described above for the characters.
You also need to specify the path to the file with the settings and the image of the texture.
Their names should also match.
And you also need to set the name of the animation from the settings file.
Files location:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πTexture_data
β β β β β β β β β β β β β β β β β β β β βββ πBackgrounds
β β β β β β β β β β β β β β β β β β β β β β β β βββ π*.json (Can be your sprite sheet json)
Example of statick background_sprite_sheet_texture_data.json file:
{
"sprite_sheet": false,
"statick_frames": {
"default": {
"top_left_corner": {
"x": 0,
"y": 0
},
"bottom_right_corner": {
"x": 1916,
"y": 865
}
}
}
}
You can read more about how the texture files are arranged in the Β«Characters and their spritesΒ» paragraph.
Images must be in jpg format and stored in a 'Backgrounds' folder.
Folder location:
./πData
β ββββ πAssets
β β β β β β βββ πImages
β β β β β β β β β β βββ πBackgrounds
β β β β β β β β β β β β β β βββ πΌοΈ*.jpg (Can be your image file)
However, you can change the sprite's format requirement by modifying it in the code.
Information about the standard user interface is contained in 'ui_buttons_data.json' files and 'ui_menu_text_data.json'.
Information about localisation of standard interface in Β«Text and LocalizationΒ» paragraph.
Below examples with json`s describes the code that needs to be changed if you want to supplement the standard menus with your own.
Files locations:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πUser_Interface
β β β β β β β β β β β β β β β β β β β ββββ πui_sprites.json
β β β β β β β β β β β β β β β β β β β ββββ πUI_Buttons
β β β β β β β β β β β β β β β β β β β βββ β β ββββ πui_buttons_data.json
β β β β β β β β β β β β β β β β β β β βββ β β ββββ πButtons_config_files
β β β β β β β β β β β β β β β β β β β βββ β β β β β β βββββ πui_*_buttons.json (Can be your button file)
β β β β β β β β β β β β β β β β β β β ββββ πUI_Menu_texts
β β β β β β β β β β β β β β β β β β β β β β β β βββ πui_menu_text_data.json
β β β β β β β β β β β β β β β β β β β β β β β β βββ πText_config_files
β β β β β β β β β β β β β β β β β β β β β β β β β β β β ββββ πui_*_menu_text.json (Can be your menu text file)
User Interface Buttons:
All button configurations are initially described in the 'ui_buttons_data.json' file.
This file contains an array that lists the names of configuration files for all menu buttons.
Example of buttons in ui_buttons_data.json file:
[
"ui_exit_menu_buttons",
"ui_game_menu_buttons",
"ui_gameplay_buttons",
"ui_load_menu_buttons",
"ui_save_menu_buttons",
"ui_settings_menu_buttons",
"ui_settings_status_buttons",
"ui_start_menu_buttons",
"ui_back_to_start_menu_status_menu_buttons",
"ui_creators_menu_buttons"
]
Example of buttons in ui_*_buttons.json file:
{
"start_menu_new_game": {
"type": "start_menu",
"index_number": 0,
"sprite_name": "game_menu_buttons",
"font": null,
"color": "#000000"
},
"start_menu_continue": {
"type": "start_menu",
"index_number": 1,
"sprite_name": "game_menu_buttons",
"font": null,
"color": "#000000"
}
}
'index_number' key contains the horizontal or vertical menu order of button as value.
Numbers can be negative.
Finding the order of the buttons and how it will be described in the 'UI_Button.py' file 'Button' class.
In 'coordinates' method of 'Button' class also uses the 'type' key value.
If you want to add your own menus, please note that the key values are hardcoded.
Please note that the 'sprite_name' key contains the name of the sprite, as the value.
Sprites must be in png format and stored in a 'Buttons' folder.
Folder location:
./πData
β ββββ πAssets
β β β β β β βββ πImages
β β β β β β β β β β βββ πUser_Interface
β β β β β β β β β β β β β β βββ πButtons
The button sprite texture images must be described in the 'ui_sprites.json' file.
Example of buttons in ui_sprites.json file:
{
"Buttons": [
"dialogues_choice_button",
"exit_menu_buttons",
"fast_forward",
"game_menu",
"game_menu_buttons",
"hide_interface",
"next_scene",
"past_scene"
],
"Menu_Substrate": [
"blank_big"
],
"Save_System": [
"screen_preview_empty"
],
"Text_Canvas": [
"text_canvas"
]
}
- Buttons - list of textures that can be assigned to buttons.
- Menu_Substrate - list of textures on top of which text in the menu can be written.
- Save_System - despite the fact that this is an array, there is only one possible texture option for empty save cells.
- Text_Canvas - similar but for the text that the player reads during reading gameplay.
They are treated as static images and are loaded as is, meaning each file should contain a complete image of the object.
User Interface Menu Text:
All text configurations are initially described in the 'ui_menu_text_data.json' file.
This file contains an array that lists the names of configuration files for all menu texts.
Example of buttons in ui_buttons_data.json file:
[
"ui_back_to_start_menu_status_menu_text",
"ui_exit_menu_text",
"ui_settings_status_menu_text",
"ui_creators_menu_text"
]
Example of 'ui_exit_menu_text.json' file:
{
"type": "exit_menu",
"text": "exit_menu_text",
"coordinates": {
"x": 1,
"y": 1
},
"font": null,
"color": "#FFFFFF",
"substrate": "blank_big"
}
- text key contains as value link to text in localisation.
- coordinates key contains as value dictionary with multipliers for the coordinates on which the text will be positioned, from the center.
- color key contains as value color like string.
Please note that the 'substrate' key contains the name of the sprite, as the value.
Sprites must be in png format and stored in a 'Menu_Substrate' folder.
Folder location:
./πData
β ββββ πAssets
β β β β β β βββ πImages
β β β β β β β β β β βββ πUser_Interface
β β β β β β β β β β β β β β βββ πMenu_Substrate
Learn more about coding your own interface:
Files locations:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πUser_Interface
β β β β β β β β β β β β β β β βββ πInterface_Controller.py
β β β β β β β β β β β β β β β βββ πUI_Menu_Text.py
β β β β β β β β β β β β β β β βββ πUI_Button_Factory.py
β β β β β β β β β β β β β β β βββ πUI_Buttons
β β β β β β β β β β β β β β β β|β β β ββββ πUI_Base_Button.py
β β β β β β β β β β β β β β β β|β β β ββββ πUI_*_Button.py (Can be your button file)
β β β β β β β β β β β β β β β βββ πUI_Menus
β β β β β β β β β β β β β β β β β β β ββββ πUI_*_menu.py (Can be your menu file)
Buttons for new menu:
To create new buttons, in any case, you need to update the collections of the ButtonFactory class from 'UI_Button_Factory.py' file.
If you want to use standard button coordinates.
Simply update the lists under the "Interface collections" comment.
Example:
# Interface collections:
_yes_no_menus: tuple = (
'exit_menu',
'settings_status_menu',
'back_to_start_menu_status_menu'
)
_long_buttons_menus: tuple = (
'game_menu',
'settings_menu',
'start_menu',
'creators_menu'
)
In this case, all settings will be applied automatically.
If your menu will hase a different way of calculating button positions, then
you need to create a new button class and make it inherit from the BaseButton abstract class.
You will also need to update the "button_collections" dictionary.
Example:
# Buttons collection:
_button_collections: dict = {
'yes_no_menus': {
'button_object': YesNoButton,
'allowable_menus': _yes_no_menus
},
'long_buttons_menus': {
'button_object': LongButton,
'allowable_menus': _long_buttons_menus
}
}
Where is your "button_object" key value is your new class.
And "allowable_menus" key value is tuple from under "Interface collections" comment.
New menu objects:
You will need to modify the menus_collection dictionary of 'InputCommandsReactions' in 'Reactions_to_input_commands.py' file.
Add a new item with menu settings to the dictionary.
Example:
_menus_collection: dict = {
'exit_menu': {
'object': ExitMenu(),
'menu_file': 'ui_exit_menu_buttons',
'text_file': 'ui_exit_menu_text'
},
'settings_menu': {
'object': SettingsMenu(),
'menu_file': 'ui_settings_menu_buttons',
'text_file': None
}
}
As a key for your menu collection element will act "type" key in your menus json file.
Please note that None key is reserved for reading gameplay UI.
In a nested dictionary, the 'object' key value is your menu object.
If your menu does not have static text, set the value of the 'text_file' key to 'None'.
You will also need to add your buttons to 'ui_localizations_data.json', and localization.json 'eng.json' as example.
And create and fill a new 'ui_*_menu_buttons.json' file, for your menu.
Finally, you will need to program your menu to work in a new python file.
The 'UI_Start_menu.py' as example.
Informative text for new menu:
If you need to add static text, with or without a background, to your new menu then a new menu needs to be added to 'text_menu_localization.csv'.
More information about it Β«Text and LocalizationΒ» paragraph.
You will also need to add a new menu to 'UI_Menu_Text.py' MenuText class 'scale' method`s list.
Or you can use the standard coordinates by adding a list for such text at the beginning of the MenuText class.
Example:
# Set menu lists:
_yes_no_menu_text_list: list[str] = [
'back_to_start_menu_status_menu',
'exit_menu',
'settings_status_menu',
]
_back_menu_text_list: list[str] = [
'creators_menu'
]
For convenience, all text localizations are made in the form of files with tables in CSV format.
This approach allows you to simply add a column for each new language.
Due to the specific nature of game text, tabulation is used as a separator.
Please pay attention to this fact.
This means that you cannot use the Tab character in any text, names or titles.
Files locations:
./πData
β ββββ πAssets
β β β β β β βββ πLocalisation
β β β β β β β β β β ββββ πMain
β β β β β β β β β β β β β β β βββ πbutton_menu_localization.csv
β β β β β β β β β β β β β β β βββ πscreenplay_localization.csv
β β β β β β β β β β β β β β β βββ πtext_menu_localization.csv
Button menu localization:
Example:
button_id | eng | ru |
---|---|---|
start_menu_new_game | New game | ΠΠΎΠ²Π°Ρ ΠΈΠ³ΡΠ° |
start_menu_continue | Continue | ΠΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ |
start_menu_load | Load | ΠΠ°Π³ΡΡΠ·ΠΈΡΡ |
start_menu_settings | Settings | ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ |
start_menu_creators | Creators | Π‘ΠΎΠ·Π΄Π°ΡΠ΅Π»ΠΈ |
start_menu_exit | Exit | ΠΡΠΉΡΠΈ |
- button_id keep button id from ui_*menu_buttons.json files.
- eng and ru are examples of string values which will be displayed on the buttons depending on the language settings.
Screenplay localization:
Example:
scene_id | scene_type | choice_id | eng | ru |
---|---|---|---|---|
test_scene_01 | reading | Null | Test Chan::Hello World! | Π’Π΅ΡΡΠΎΠ²Π°Ρ Π’ΡΠ½::ΠΡΠΈΠ²Π΅Ρ ΠΠΈΡ! |
test_scene_02 | choice | choice_01 | Go to Scene 01 | ΠΠ΅ΡΠ΅ΠΉΡΠΈ ΠΊ ΡΡΠ΅Π½Π΅ 01 |
test_scene_02 | choice | choice_02 | ERROR! | ΠΠ¨ΠΠΠΠ! |
test_scene_02 | choice | choice_03 | Go to Scene 03 | ΠΠ΅ΡΠ΅ΠΉΡΠΈ ΠΊ ΡΡΠ΅Π½Π΅ 03 |
test_scene_03 | reading | Null | Test Chan::New Scene! | Π’Π΅ΡΡΠΎΠ²Π°Ρ Π’ΡΠ½::ΠΠΎΠ²Π°Ρ Π‘ΡΠ΅Π½Π°! |
-
scene_id
Keep the scene names for 'screenplay.json' file.
Please note that the values in this column may be repeated depending on the gameplay. -
scene_type
Can have value reading|choice.
Scenes with "reading" type have only one line.
Scenes with "choice" can have multiple lines.
Their number depends on the number of options to choose from.
It is not recommended to make the selection text too large to avoid bugs. -
choice_id
Value can be Null or choice id from 'screenplay.json' file.
Null for reading gameplay type scenes. Choice id name for choice gameplay scenes. -
eng and ru are examples of string values which will be displayed on the choice buttons or text canvas depending on the language settings.
Please note the combination of symbols "::" in this case is a separator for the name and text that the character says in the Reading gameplay type scene.
This means that you cannot use this combination of characters in either text or character names for reading gameplay.
Text menu localization:
Example:
text_id | eng | ru |
---|---|---|
back_to_start_menu_status_menu_text | Would you like to return to the main menu?\nAll unsaved progress will be lost! | ΠΡ Ρ ΠΎΡΠΈΡΠ΅ Π²Π΅ΡΠ½ΡΡΡΡ Π² Π³Π»Π°Π²Π½ΠΎΠ΅ ΠΌΠ΅Π½Ρ?\nΠΠ΅ΡΡ Π½Π΅ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΡΠΉ ΠΏΡΠΎΠ³ΡΠ΅ΡΡ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΠ΅ΡΡΠ½! |
exit_menu_text | Would you like to exit the game?\nAll unsaved progress will be lost! | ΠΡ Ρ ΠΎΡΠΈΡΠ΅ Π²ΡΠΉΡΠΈ ΠΈΠ· ΠΈΠ³ΡΡ?\nΠΠ΅ΡΡ Π½Π΅ΡΠΎΡ ΡΠ°Π½Π΅Π½Π½ΡΠΉ ΠΏΡΠΎΠ³ΡΠ΅ΡΡ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΠ΅ΡΡΠ½! |
settings_status_menu_text | Would you like to change the game settings? | ΠΡ ΠΆΠ΅Π»Π°Π΅ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΈΠ³ΡΡ? |
creators_menu_text | Character artist - ...\nBackground artist - ...\nProgramming - ... | Π₯ΡΠ΄ΠΎΠΆΠ½ΠΈΠΊ ΠΏΠΎ ΠΏΠ΅ΡΡΠΎΠ½Π°ΠΆΠ°ΠΌ - ...\nΠ₯ΡΠ΄ΠΎΠΆΠ½ΠΈΠΊ Π·Π°Π΄Π½ΠΈΡ ΠΏΠ»Π°Π½ΠΎΠ²- ...\nΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ - ... |
- text_id - id for "text" key in 'ui_*_menu_text.json' file.
- eng and ru are examples of string values which will be displayed depending on the language settings.
Please note that the standard line break character "\n" is used here and is written together between lines.
In order to change the program name, you need to change the value of the variable 'app_name' in 'Visual_novel_game.py'.
File location:
./πData
β ββββ πVisual_novel_game.py
Example of app_name variable:
app_name: str = "Visual Novel"
In order to change the program window icons, please replace the icon files in the 'Icons' folder.
Icons images must be in png format and have the default size and titles.
Folder location:
./πData
β ββββ πAssets
β β β β β β βββ πImages
β β β β β β β β β β βββ πUser_Interface
β β β β β β β β β β β β β β βββ πIcons
All gameplay code is stored in the folder 'GamePlay'.
If you need to program your gameplay element, add it to the constructor of class 'GamePlayAdministrator' from 'GamePlay_Administrator.py' file.
'gameplay_input' method of this class control of gameplay.
Files locations:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πGamePlay
β β β β β β β β β β β β β β β βββ πGamePlay_Administrator.py
β β β β β β β β β β β β β β β βββ πGamePlay_*.py (Can be your gameplay file)
The default settings are stored in a file 'user_settings'.
The game reads them at startup and saves them there, with the consent to change by the user, after setting.
File location:
./πData
β ββββ πAssets
β β β β β β βββ πuser_settings
The SoundDirector class is responsible for working with sound.
Inside, it works with three audio channels responsible for character speech, music and sound effects.
All sounds and music files must be in MP3 format.
You can read more about installing audio tracks to game scenes in paragraph Β«Settings of scenesΒ».
Your sound files should be located in their appropriate directories.
However, there is a condition if you have multiple voice covers.
In this case, you will have to change the value of the "single_voiceover_language" attribute in the Sound_Director class from True to False.
After this, you will need to add a sub folder for your voice acting to the Voice folder.
And place sound files in it.
When this option is enabled, the audio track select from folder stored in the "voice_acting_language" attribute of the SettingsKeeper class will be automatically selected.
This attribute can be changed in the settings menu, or in the settings file.
Naturally, this voice acting does not have to be voice localization. But it is important to consider changes in the storage principle when enabling the option.
Files locations:
./πData
β ββββ πAssets
β β β β β β βββ πSounds
β β β β β β β|β β β ββββ πEffects
β β β β β β β|β β β β | β β β βββ π΅*.mp3 (Can be your sound file)
β β β β β β β|β β β ββββ πMusic
β β β β β β β|β β β β | β β β βββ π΅*.mp3 (Can be your music file)
β β β β β β β|β β β ββββ πVoice
β β β β β β β|β β β β β β β β βββ π΅*.mp3 (Can be your sound file)
β β β β β β β|β β β β β β β β βββ πeng (Optional!!!: Can be your localization folder)
β β β β β β β|β β β β β β β β β β β β βββ π΅*.mp3 (Optional!!!:Can be your sound file)
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πApplication_layer
β β β β β β β β β β β | β β β βββ πSound_Director.py
β β β β β β β β β β ββββ πJson_data
β β β β β β β β β β β β β β β βββ πmenu_sound_settings.json
To install sounds and music in the menus, you need to modify the "menu_sound_settings.json" file.
Example of menu sound settings.:
{
"start_menu": {
"music_channel": "blank",
"sound_channel": false
}
}
The values of the sound and music keys must also be either false or the name of the file located in the corresponding folder.
If you add a sound effect, it will only play once.
'Visual_novel_game.py' initializes game and call 'GameMaster' class.
During the initiation process, the script creates the 'SettingsKeeper' object that is responsible for the game settings.
The GameMaster class control game loop and generates lower-level entities that control the gameplay.
- StageDirector - Controls the actions on the stage.
Controls who and what will say as well as the appearance of the characters.
Manages the scene background.
Generates a 'Character', 'Background' and 'DialoguesWords' objects used to control staging. - SoundDirector - Play music, sound effects and speech for the scene if necessary.
- SceneValidator - controls the order of the scenes.
Stores inside itself information about the type of scene with which the StageDirector and the SoundDirector. - InterfaceController - controls all interface with which the player can interact.
Generates 'Button' instances with 'ButtonFactory' and make menus from them. - InputCommandsReactions - catches user commands inside the game and passes them inside the loop to other entities.
Generates 'GamePlayAdministrator' and all menus objects. - Render - renders the image after the calculations.
Simplified: the InputCommandsReactions processes user commands.
The SceneValidator checks for changes.
The StageDirector builds a scene.
Or the InterfaceController switches menu.
Files locations:
./πData
β ββββ πVisual_novel_game.py
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πApplication_layer
β β β β β β β β β β βββ β β ββββ πGame_Master.py
β β β β β β β β β β βββ β β ββββ πReactions_to_input_commands.py
β β β β β β β β β β βββ β β ββββ πSettings_Keeper.py
β β β β β β β β β β βββ β β ββββ πSound_Director.py
β β β β β β β β β β βββ β β ββββ πStage_Director.py
β β β β β β β β β β ββββ πGame_objects
β β β β β β β β β β βββ β β ββββ πBackground.py
β β β β β β β β β β βββ β β ββββ πCharacter.py
β β β β β β β β β β βββ β β ββββ πDialogues.py
β β β β β β β β β β βββ β β ββββ πScene_Validator.py
β β β β β β β β β β ββββ πGamePlay
β β β β β β β β β β βββ β β ββββ πGamePlay_Administrator.py
β β β β β β β β β β ββββ πRender
β β β β β β β β β β βββ β β ββββ πRender.py
β β β β β β β β β β ββββ πUser_Interface
β β β β β β β β β β β β β β β βββ πInterface_Controller.py
β β β β β β β β β β β β β β β βββ πUI_Button_Factory.py
Please note that the name of some classes does not correspond to the files where they are contained.
But according to the meaning of the names of the given files, it is still clear where they are.
The program creates a log file and writes messages about critical problems to it.
File location:
./πData
β ββββ πlogg_file.txt
Game saves are located in the 'Saves' folder.
The game save is a subfolder with a simple json file marked as 'save' format and a png image.
Please note that the subfolder and the save file must have the same name.
Files locations:
./πData
β ββββ πSaves
β β β β β β βββ πAutoSave
β β β β β β β β β β ββββ πAutoSave.save
β β β β β β β β β β ββββ πΌοΈscreen_preview.png
Example of 'AutoSave.save' file:
{
"scene": "test_scene_03",
"date": "2023-08-01_19:05:15"
}
The SaveKeeper class from 'Save_Keeper.py' file is responsible for working with saves.
File location:
./πData
β ββββ πAssets
β β β β β β βββ πScripts
β β β β β β β β β β ββββ πApplication_layer
β β β β β β β β β β β β β β β ββββ πSave_Keeper.py
The 'SettingsKeeper' class already exists.
It must be used for business logic that will work in the menu.
The 'SettingsMenu' class and its menu can be used as an external wrapper, or modified.
I planned to use it as a wrapper and make a separate menu for each type of setting.
It is planned to create template special effects for display on scenes.
- Utility for simplified texture data assembly
- Localisation parser utility
- Utility for compiling games for different operating systems.
libpng warning: iCCP: known incorrect sRGB profile
Appears due to extra information in the sRGB profile when converting to PNG.
Because of this, after the program ends, a warning message appears in the terminal.
Actually this warning is not an error.
To avoid this behavior, resave your sprites using the correct settings.
As an example of resaving in Photoshop:
- Open your png image.
- Select the "file" in the upper left corner.
- Select the "save as" in the drop-down list that appears.
- In the file saving window that opens uncheck the box opposite ICC Profile: sRGB IEC61966-2.1
- Resave your png image.
As an example of resaving in Krita:
- Open your png image.
- Around the middle of the menu at the top of the program window, select an image.
- Select the "Properties" in the drop-down list that appears.
- In the menu that opens, select the Image Color Space.
- Switch profile to sRGB-elle-V2-srgbtrΡ.icc
Usually it is marked as Default. - Select the "file" in the upper left corner.
- Select the "save as" in the drop-down list that appears.
- Resave your png image.
There are other solutions to this problem using the operating system terminal and various console utilities.
As an example these solutions from stackoverflow.
When installing Python from the official website, you may encounter the fact that the operating system or IDE cannot find it.
There are several ways to solve this problem:
- The easiest way to fix this problem is to install Python using the Microsoft Store.
You can find a program that gives access to it directly on your PC using Windows search. - Try to reinstall Python and select the checkbox "Add Python to environment variables".
- Add Python to your operating system's environment variables manually.