<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.frictionalgames.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tigersong</id>
	<title>Frictional Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.frictionalgames.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tigersong"/>
	<link rel="alternate" type="text/html" href="https://wiki.frictionalgames.com/page/Special:Contributions/Tigersong"/>
	<updated>2026-04-12T14:04:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://wiki.frictionalgames.com/page?title=HPL3/Scripting/Level_Scripting_-_Best_Practices&amp;diff=6828</id>
		<title>HPL3/Scripting/Level Scripting - Best Practices</title>
		<link rel="alternate" type="text/html" href="https://wiki.frictionalgames.com/page?title=HPL3/Scripting/Level_Scripting_-_Best_Practices&amp;diff=6828"/>
		<updated>2024-06-10T22:23:51Z</updated>

		<summary type="html">&lt;p&gt;Tigersong: Some grammatical fixes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{wip}}&lt;br /&gt;
&lt;br /&gt;
= Scripter's Guide =&lt;br /&gt;
&lt;br /&gt;
== Intro ==&lt;br /&gt;
&lt;br /&gt;
This guide will serve as a knowledge base for what to do and not do when scripting a map. It will go through what is important to think about and will include lists with various tips and advice on how to approach this.&lt;br /&gt;
&lt;br /&gt;
== Programming ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
&lt;br /&gt;
When you need to implement something in script there are a few things you need to first consider:&lt;br /&gt;
&lt;br /&gt;
''' Whatever you make will probably go through several iterations.&lt;br /&gt;
''' There will be people besides you that will mess with the code.&lt;br /&gt;
''' Making something functional according to design is only the first and simplest of your problems.&lt;br /&gt;
&lt;br /&gt;
What this means is that you should always try and do something as fast as possible by using available solution. Also make sure that whatever you do is open to manipulation and not only working for a very specific behavior. The best way to go about is to always use some entity type that already exist and change its properties to fit your needs. If what you are doing with require some extra features, then either make it specific to this map (in the maps' script) or add it to the entity's code. When adding it to the entity make sure that it is something that can be useful elsewhere and also think carefully so what you add a generic version of your wanted feature. That is: do not make up something extremely specific.&lt;br /&gt;
&lt;br /&gt;
Remember [http://en.wikipedia.org/wiki/KISS_principle KISS]! &amp;lt;br /&amp;gt;This lecture is a must view: [http://the-witness.net/news/2011/06/how-to-program-independent-games/ http://the-witness.net/news/2011/06/how-to-program-independent-games/]&lt;br /&gt;
&lt;br /&gt;
Also important is that you structure your code in a way so that other people can easily see what does what. It is very common that other people will want to tweak something or just add some extra effect. It must be easy to see where your different events occur. The engine supports TODO message pop-ups (''cLux_AddTodoMessage(..)''), so use that in all places where some effect/sound/whatever is required to be added. Despite adding a todo, you should still have your own temp assets when possible. For instance, sometimes sounds are vital to see if an event works or not.&lt;br /&gt;
&lt;br /&gt;
=== Philosophy for level scripting ===&lt;br /&gt;
&lt;br /&gt;
A level script should not be thought of as file for programing. A level script should be written and read as though it is a story (or a sequence of events if you wish).&lt;br /&gt;
&lt;br /&gt;
In the level script you are crafting the experience for the user and the script should be read as the manuscript of that experience.&lt;br /&gt;
&lt;br /&gt;
If the level script file contains rows of code that does not match the above description, then the rows of code does not belong in the level script, they belong in a helper file or even deeper down in the hierarchy of script files (or even in the c++ code!).&lt;br /&gt;
&lt;br /&gt;
This primarily means that when working to solve a problem of how to implement an event (activity, puzzle, challenge, character interaction etc) in a level, the first approach is not that of a programmer. The correct approach to take is:&lt;br /&gt;
&lt;br /&gt;
''' Begin by examining and configuring the resources (entities, sounds, graphics) that is used in the event. This to make best use of what is already available (in terms of prop types, configurations and so on).&lt;br /&gt;
''' Move on and make sure that the area in the level used for the event is created in a way that works. If not, you tweak it to be better. This can be as simple as renaming entities in a way that simplifies the scripting of them. You also make sure you to add in whatever new things you need (such as script areas).&lt;br /&gt;
''' Finally you can begin scripting. This you do by making use of all the existing helper functions to create a short and easy to read solution for the event implementation.&lt;br /&gt;
&lt;br /&gt;
Only when or if the above will not accomplish the task at hand you continue and create helper functions, new states or other changes and additions to the lower level scripts.&lt;br /&gt;
&lt;br /&gt;
However, You should also consider the functions and entities that are at hand. Do they really solve your problem in the easiest way possible? If not, then you should consider adding or extending the functionality of them.&lt;br /&gt;
&lt;br /&gt;
When doing the actual level editing the focus must never be on a technical level. It should not be complicated to add something, rather it should be easy. The hard part should be making the gameplay and atmosphere good, it should not be making the game do what you want. If this is not true, then you probably need to add some more functionality yourself or contact a friendly programmer to do so for you.&lt;br /&gt;
&lt;br /&gt;
Beware though, we do not want to have thousands of object types and functions, we still want it all to feel comprehensible. Make your additions and changes as generic as possible, meaning that it does not only fit your very specific need, but can be used for a multitude of purposes.&lt;br /&gt;
&lt;br /&gt;
== Work-flow ==&lt;br /&gt;
&lt;br /&gt;
The game has been made to make feedback when scripting as frequent as possible. First of all, with the basic settings the script will be reloaded every time you task switch from the editing program (usually [[:hpl3:3rdparty:codelite|CodeLite]]). So when making smaller changes in code that are constantly updated, then simply task switch to see your new code in action. Inside the F1-menu you can also turn on &amp;quot;Update script constantly&amp;quot; which checks for script updates as soon as you save the code. So if you have two monitors (or one really large) you can have the game running next to the code and every time you save you see updates and see if there are any compile errors.&lt;br /&gt;
&lt;br /&gt;
If there are any updates that require the map to restart, meaning any init function or properties in the map, then you of course need to reload. Do this by pressing F5 or the reload button in the F1-menu. It is only very seldom that you actually need to turn off the application.&lt;br /&gt;
&lt;br /&gt;
Here are some other tips:&lt;br /&gt;
&lt;br /&gt;
''' Press F3 to speed up the update rate in the game. This is especially useful to quickly playing through conversations, long events, etc when testing.&lt;br /&gt;
''' Press F7 to go into spectator mode. This allows you to easily move around in the map. Hold down shift to go extra fast.&lt;br /&gt;
''' Press F2 to pauses the game. This is nice to use with Spectator mode and you can closely inspect something to look for bugs and make sure it plays out like it should.&lt;br /&gt;
&lt;br /&gt;
== Code Structure ==&lt;br /&gt;
&lt;br /&gt;
Since a lot of people will be working on the same piece of code it is important that the same structure is maintained. This way it makes it easier for people to find what they need to do to change something.&lt;br /&gt;
&lt;br /&gt;
''Note: In the code below, spaces are used to indent, do NOT use this, use tab instead!''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;//--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
/*Place any global values here. These must be const variables as they will not be saved*/&lt;br /&gt;
/*This is also the place for enums and classes, but these should be avoided whenever possible*/&lt;br /&gt;
&lt;br /&gt;
//--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
class cScrMap : iScrMap&lt;br /&gt;
{&lt;br /&gt;
	//--------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
	// ==============&lt;br /&gt;
	// MAIN CALLBACKS&lt;br /&gt;
	// ==============&lt;br /&gt;
	//{///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
	//-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	/*OnStart, OnEnter, OnLeave, Update (avoid this), OnAction (debug only), OnPlayerDead, etc are here.*/&lt;br /&gt;
&lt;br /&gt;
	//-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	//} END MAIN CALLBACKS&lt;br /&gt;
&lt;br /&gt;
	//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
	// ==============&lt;br /&gt;
	// MAIN FUNCTIONS&lt;br /&gt;
	// ==============&lt;br /&gt;
	//{///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
	//-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	/*Put any variables that are used in more than one scene here.*/&lt;br /&gt;
&lt;br /&gt;
	//-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	/*Put any functions that are used in more than one scene here.*/&lt;br /&gt;
&lt;br /&gt;
	//-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
	//} END MAIN FUNCTIONS&lt;br /&gt;
&lt;br /&gt;
	//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
	// ==============&lt;br /&gt;
	// SCENE X *NAME OF SCENE*&lt;br /&gt;
	// ==============&lt;br /&gt;
	//{//////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
		 /////////////////////////////////////////&lt;br /&gt;
		 // Scene X GENERAL&lt;br /&gt;
		 //{//////////////////////////////////////&lt;br /&gt;
                 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		/*Put any variables that are used by many events in Scene X here.*/&lt;br /&gt;
&lt;br /&gt;
		//-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		/*Put any functions that are used in more than one event in Scene X here.*/&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
                 //} END General&lt;br /&gt;
&lt;br /&gt;
		 /////////////////////////////////////////&lt;br /&gt;
		 // Event *Name Of Event*&lt;br /&gt;
		 //{//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 /*Put any variables that are only used in Scene X, Event X here.*/&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 /*Put any functionsthat are only used in Scene X, Event X here.*/&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 //} END Event *Name Of Event*&lt;br /&gt;
&lt;br /&gt;
	 //} END SCENE X&lt;br /&gt;
&lt;br /&gt;
	 /////////////////////////////////////////&lt;br /&gt;
	 // ==============&lt;br /&gt;
	 // TERMINALS&lt;br /&gt;
	 // ==============&lt;br /&gt;
	 //{//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 /////////////////////////////////////////&lt;br /&gt;
		 // Terminal *Name Of Terminal*&lt;br /&gt;
		 //{//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 /*Put any variables that are only used Terminal here.*/&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 /*Put any functions that are only used Terminal here.*/&lt;br /&gt;
&lt;br /&gt;
		 //-------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
		 //} END Terminal *Name Of Terminal*&lt;br /&gt;
&lt;br /&gt;
	//} END TERMINALS&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note1:'''   &amp;lt;br /&amp;gt;It is OK if terminals use variables that are scene or event specific!&lt;br /&gt;
&lt;br /&gt;
'''Note2:'''   &amp;lt;br /&amp;gt;Have snuck in some { and } to make code folding for sections possible.&lt;br /&gt;
&lt;br /&gt;
'''Note3:'''   &amp;lt;br /&amp;gt;Remember to always separate functions with a comment line, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;void Func1()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//-------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void Func2()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Naming Conventions ===&lt;br /&gt;
&lt;br /&gt;
A few naming conventions for map scripting and level building:&lt;br /&gt;
&lt;br /&gt;
==== Areas ====&lt;br /&gt;
&lt;br /&gt;
Name trigger areas in the level Trigger_xxxx to make them easier to find.&lt;br /&gt;
&lt;br /&gt;
==== Sequences ====&lt;br /&gt;
&lt;br /&gt;
Name sequence functions in your map script Seq_xxxx&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
&lt;br /&gt;
=== Intro ===&lt;br /&gt;
&lt;br /&gt;
Remember, when you script maps you are a designer. Your job is not just simply to replicate the descriptions in the design doc. Your job is to use that as a base and create an engaging experience in each level. Sometimes this means just making slight alterations. Sometimes it requires huge changes to the first design. You need to have in mind what we want to achieve with the level you are working on, and then make sure that is the end experience.&lt;br /&gt;
&lt;br /&gt;
A good mantra is: ''If you simply copy the design, the game will suck.''&lt;br /&gt;
&lt;br /&gt;
=== Tour ===&lt;br /&gt;
&lt;br /&gt;
So lets have a little tour of DO's and DON'T's of design. Start this video and then check the time-stamps below: [http://www.youtube.com/watch?v=6sEyzilwfAE http://www.youtube.com/watch?v=6sEyzilwfAE]&lt;br /&gt;
&lt;br /&gt;
'''0.30''' &amp;lt;br /&amp;gt;Notice the fly particles systems and stuff like that? Try and add stuff like that where you think it works in order to increase the mood. This of course not your first priority but I want to mention it because stuff like this is part of your work.&lt;br /&gt;
&lt;br /&gt;
'''0.36''' &amp;lt;br /&amp;gt;Never, ever take away the player's control like this! The player must always be able to move and feel as if they are in control of the actions. Even if you move the camera for something like sitting down on chair, the player must still be able to move their heads. Keep the immersion-loop of interaction going at all times! &amp;lt;br /&amp;gt;If the player needs to spot something, use other tricks than taking the control away. This is cheap.&lt;br /&gt;
&lt;br /&gt;
'''0.46''' &amp;lt;br /&amp;gt;Another bad thing here. We never want to tell the player outright what to do next. The player should feel free to do what they please and the design should lure them into going in the right direction.&lt;br /&gt;
&lt;br /&gt;
'''1.06''' &amp;lt;br /&amp;gt;Here you use the same basic controls for doing a new kind of activity. This is a good thing! If you can think up things like this to have in the level; add it! Keeping balance on a log might not be good in first person though ;)&lt;br /&gt;
&lt;br /&gt;
'''2.04''' &amp;lt;br /&amp;gt;Never ever show the player what controls they need to use. We will have some kind of (optional) help popups at the very beginning (chapter 0 basically) and after that there is none of that!&lt;br /&gt;
&lt;br /&gt;
'''2.30''' &amp;lt;br /&amp;gt;The metal breaks as you climb it, this is good stuff for the engagement and also make the world feel more alive. Feel free to add unexpected (but realistic) events to the player's interaction. The plane falling down afterwards is also good. But if you do it in cut scene, you are doing it wrong!&lt;br /&gt;
&lt;br /&gt;
'''2.50''' &amp;lt;br /&amp;gt;Laura holds her hand against the wall. To change the player's movement/posture/etc has they move through specific environments is really good stuff. See if you can fit something like that in. Might be as simple as more heavy breathing or shorter footsteps in some section.&lt;br /&gt;
&lt;br /&gt;
'''3.20''' &amp;lt;br /&amp;gt;If the player finds a bag or similar, try and not just have a &amp;quot;click to open&amp;quot;-interaction. Instead have some form of analog input to do this instead. Always best if the player can use mouse movements to perform an action.&lt;br /&gt;
&lt;br /&gt;
'''6.10''' &amp;lt;br /&amp;gt;Birds that fly when you approach. This kinda stuff is nice. If you add it make sure to make it generic so we can use it many times and for different things!&lt;br /&gt;
&lt;br /&gt;
'''7.05''' &amp;lt;br /&amp;gt;Introducing new controls like this is not good! This does not come intuitively from the basics and thus not something we should have.&lt;br /&gt;
&lt;br /&gt;
'''7.30''' &amp;lt;br /&amp;gt;When the game opens up like this it is important that there is not only a single hotspot for the player to find, but that one can complete the task or find interesting info in many places. I think this is done nicely here with the deers showing up wherever you are.&lt;br /&gt;
&lt;br /&gt;
=== Foundational Rules ===&lt;br /&gt;
&lt;br /&gt;
'''No Puzzles''' &amp;lt;br /&amp;gt;Do not think of our puzzles as such. Think of them as ''Activities''  in stead. This is very important to keep in mind as they are not meant to pose a challenge but to make the player feel more part of the world. The player might still be required to think, but we do not want to end up in a &amp;quot;guess the designer&amp;quot; type of gameplay. It should feel natural and the player should &amp;quot;solve&amp;quot; any activity by simply just trying enough. For instance in Amnesia you can break down a wall by throwing a rock at it or simply clicking on it a lot. In either case the player has made a proper attempt at breaking down the wall and needs to be rewarded. Being streamlined, intuitive and coherent comes way ahead of being a satisfying problem to solve.&lt;br /&gt;
&lt;br /&gt;
'''Always Interactive''' &amp;lt;br /&amp;gt;Whenever possible, the objects in the environment needs to be interactive. For instance, a locked door should be able to move so the player can notice, by interacting, that it cannot be opened. Another examples is that the player might be able to grab and swing lamps that hang down from the ceiling. We want the player to feel part of a real living world and the interaction is the way we do this. Never waste an object that can be made interactive.&lt;br /&gt;
&lt;br /&gt;
'''No Trial and Error''' &amp;lt;br /&amp;gt;Never have challenges where failure means restart. Examples of this is just about any puzzle in Limbo. We want the player to a smooth narrative experience that always moves forward. We do not want to to be stuck repeating the same actions over and over.&lt;br /&gt;
&lt;br /&gt;
'''Physics When Possible''' &amp;lt;br /&amp;gt;Do not &amp;quot;hard-code&amp;quot; behaviors, but try and use physics when ever possible. This will also allow the player to experiment more and to allow a great set of possible solutions to activities. Beware that physics can be very unruly and make sure that there are restraints on what can be done. When using physics you really need to test a lot.&lt;br /&gt;
&lt;br /&gt;
=== Specific Guidelines ===&lt;br /&gt;
&lt;br /&gt;
'''Readable items must have consistent placement''' &amp;lt;br /&amp;gt;When placing things that can be read, such as notes, books, newspapers, pamphlets, etc, it is very important to follow strict rules on this. We want the player to figure out by simply looking, what is possible to read and what is not. The player should not need to go pixel hunting. Here are the two basic rules for this: &amp;lt;br /&amp;gt;1) Readables lying by themselves can always be interacted with. &amp;lt;br /&amp;gt;2) Readables that can not be read, bust be in groups; piles, stacks, rows, etc. &amp;lt;br /&amp;gt;Also make sure that the colors on the readables that are slightly more saturated than the group ones. The only exception for this is scraps of paper, which are possible to have lying by themselves. But these can not have any longer text, but only pictures, diagrams, etc with some small written notation. They must also feel crumbled and fairly useless.&lt;br /&gt;
&lt;br /&gt;
'''Longer must be confined to single lang entry''' &amp;lt;br /&amp;gt;Any longer text for notes, descriptions, books, etc must be inside a single lang entry. They cannot be spread out over several entries for any reason. When having a single lang entry, it makes it a lot easier to maintain and translation gets easier.&lt;br /&gt;
&lt;br /&gt;
==== Books ====&lt;br /&gt;
&lt;br /&gt;
For books, we can show the front, the back, or an interesting page in the middle (swapping the model lets us show an 'open' version).&lt;br /&gt;
&lt;br /&gt;
''' If the back, then we show text of blurb&lt;br /&gt;
''' If the front, then we just show title, author &amp;amp; whatever&lt;br /&gt;
''' If somewhere in the middle, then we show an extract from the book.&lt;br /&gt;
&lt;br /&gt;
The key thing to remember here is: &amp;quot;If the protagonist picked up this book, which bit would he be most interested in?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
i.e. it's unlikely we'd show an extract from the middle, unless it's critical to the protagonist's current plans e.g. the instruction manual for a device he's interested in or something.&lt;br /&gt;
&lt;br /&gt;
=== Further information ===&lt;br /&gt;
&lt;br /&gt;
What follows is a collection of articles that are good to read:&lt;br /&gt;
&lt;br /&gt;
[http://frictionalgames.blogspot.se/2013/02/puzzles-what-are-good-for.html http://frictionalgames.blogspot.se/2013/02/puzzles-what-are-good-for.html]&lt;br /&gt;
&lt;br /&gt;
[http://frictionalgames.blogspot.se/2013/03/puzzles-and-causal-histories.html http://frictionalgames.blogspot.se/2013/03/puzzles-and-causal-histories.html]&lt;br /&gt;
&lt;br /&gt;
[http://frictionalgames.blogspot.se/2013/01/goals-and-storytelling.html http://frictionalgames.blogspot.se/2013/01/goals-and-storytelling.html]&lt;br /&gt;
&lt;br /&gt;
[http://frictionalgames.blogspot.se/2012/12/introduction-i-recently-started-to-play.html http://frictionalgames.blogspot.se/2012/12/introduction-i-recently-started-to-play.html]&lt;/div&gt;</summary>
		<author><name>Tigersong</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.frictionalgames.com/page?title=HPL3/Amnesia:_Rebirth/Tutorials/Notes&amp;diff=6812</id>
		<title>HPL3/Amnesia: Rebirth/Tutorials/Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.frictionalgames.com/page?title=HPL3/Amnesia:_Rebirth/Tutorials/Notes&amp;diff=6812"/>
		<updated>2024-05-23T06:23:40Z</updated>

		<summary type="html">&lt;p&gt;Tigersong: /* Other entry parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial will tell you how to manage notes in the game.&lt;br /&gt;
&lt;br /&gt;
== About the sketchbook system ==&lt;br /&gt;
&lt;br /&gt;
All notes, or rather: readables (notes are only one case of these) in the game can have a FrontEntry and a BackEntry. These are simply the text that appears on both sides of paper. When a note is picked up, it is added to a category in the sketchbook, where both sides can be read again.&lt;br /&gt;
&lt;br /&gt;
== Setting up ==&lt;br /&gt;
&lt;br /&gt;
First, we're going to need a &amp;lt;code&amp;gt;readables.cfg&amp;lt;/code&amp;gt; file. In this file, readables can be grouped into sketchbook categories. FG mostly grouped them by map, but you can group them as you want (e.g. &amp;quot;Journal&amp;quot;). In this tutorial we're going to stick to a map category for the sake of simplicity.&lt;br /&gt;
&lt;br /&gt;
In our category we're going to create entries and assign lang entries to them. That means that the FrontEntry and the BackEntry themselves will be in another file. The ID is what we will put in the note in the Level Editor. Other parameters will be discussed later.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
'''Readables.cfg''':&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Readables&amp;gt;&lt;br /&gt;
	&amp;lt;Categories&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;Category ID=&amp;quot;sample_map&amp;quot; Name=&amp;quot;sample_map_sketchbook_category&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Notes&amp;gt;&lt;br /&gt;
				&amp;lt;Note ID=&amp;quot;NoteTest1&amp;quot; VoiceSubject=&amp;quot;&amp;quot; FrontEntry=&amp;quot;NoteTest1_FrontEntry&amp;quot; BackEntry=&amp;quot;NoteTest1_BackEntry&amp;quot; ImageEntry=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;Note ID=&amp;quot;NoteTest2&amp;quot; VoiceSubject=&amp;quot;&amp;quot; FrontEntry=&amp;quot;NoteTest2_FrontEntry&amp;quot; BackEntry=&amp;quot;&amp;quot; ImageEntry=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;/Notes&amp;gt;&lt;br /&gt;
		&amp;lt;/Category&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;Category ID=&amp;quot;another_map&amp;quot; Name=&amp;quot;another_map_sketchbook_category&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Notes&amp;gt;&lt;br /&gt;
				&amp;lt;Note ID=&amp;quot;NoteTest3&amp;quot; VoiceSubject=&amp;quot;&amp;quot; FrontEntry=&amp;quot;NoteTest3&amp;quot; BackEntry=&amp;quot;&amp;quot; ImageEntry=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;/Notes&amp;gt;&lt;br /&gt;
		&amp;lt;/Category&amp;gt;&lt;br /&gt;
				&lt;br /&gt;
	&amp;lt;/Categories&amp;gt;&lt;br /&gt;
&amp;lt;/Readables&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As mentioned previously, the FrontEntry and the BackEntry need to point to a &amp;lt;code&amp;gt;english.lang&amp;lt;/code&amp;gt; entry - and those entries need to be in categories that fit the ID set in the &amp;lt;code&amp;gt;readables.cfg&amp;lt;/code&amp;gt; category. So, if we had a category with ID &amp;quot;sample_map&amp;quot; in &amp;lt;code&amp;gt;readables.cfg&amp;lt;/code&amp;gt;, we're going to make a category with such a name in the lang file.&lt;br /&gt;
&lt;br /&gt;
'''English.lang''':&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;LANGUAGE&amp;gt;&lt;br /&gt;
  &amp;lt;CATEGORY Name=&amp;quot;sample_map&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;Entry Name=&amp;quot;NoteTest1_FrontEntry&amp;quot;&amp;gt;My first readable&amp;lt;/Entry&amp;gt;&lt;br /&gt;
		&amp;lt;Entry Name=&amp;quot;NoteTest1_BackEntry&amp;quot;&amp;gt;First readable's backside&amp;lt;/Entry&amp;gt;&lt;br /&gt;
        &amp;lt;Entry Name=&amp;quot;NoteTest1_FrontEntry_Name&amp;quot;&amp;gt;This is the title of the note which will show in the sketchbook. It seems to need to be called the same as the FrontEntry + &amp;quot;_Name&amp;quot;.&amp;lt;/Entry&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;Entry Name=&amp;quot;NoteTest2_FrontEntry&amp;quot;&amp;gt;Second readable. This one has only one side&amp;lt;/Entry&amp;gt;&lt;br /&gt;
        &amp;lt;Entry Name=&amp;quot;NoteTest2_FrontEntry_Name&amp;quot;&amp;gt;Second readable note&amp;lt;/Entry&amp;gt;&lt;br /&gt;
  &amp;lt;/CATEGORY&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;CATEGORY Name=&amp;quot;another_map&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;Entry Name=&amp;quot;NoteTest3&amp;quot;&amp;gt;Another one-sided note, so we're not even going to add &amp;quot;_FrontEntry&amp;quot; in its name this time&amp;lt;/Entry&amp;gt;&lt;br /&gt;
        &amp;lt;Entry Name=&amp;quot;NoteTest3_Name&amp;quot;&amp;gt;Third readable note&amp;lt;/Entry&amp;gt;&lt;br /&gt;
  &amp;lt;/CATEGORY&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
   &amp;lt;CATEGORY Name=&amp;quot;Levels&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;Entry Name=&amp;quot;sample_map_sketchbook_category&amp;quot;&amp;gt;This is the category name in the sketchbook. Normally it should be quite short, like the next example&amp;lt;/Entry&amp;gt;&lt;br /&gt;
        &amp;lt;Entry Name=&amp;quot;another_map_sketchbook_category&amp;quot;&amp;gt;Notes from Another Map&amp;lt;/Entry&amp;gt;&lt;br /&gt;
  &amp;lt;/CATEGORY&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/LANGUAGE&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you probably noticed, there is quite a lot going on. Let's break it down:&lt;br /&gt;
* Each note needs a _Name entry to display in the sketchbook&lt;br /&gt;
* Categories also have titles; these are for the sketchbook too. Remember the categories from &amp;lt;code&amp;gt;readables.cfg&amp;lt;/code&amp;gt;? They had a &amp;quot;Name&amp;quot; parameter, and that's exactly it.&lt;br /&gt;
Once you have set up your categories, you only need to add entries to the two mentined files.&lt;br /&gt;
&lt;br /&gt;
Once you place a note in a map, you only need to select it and go to Entity/Readable/ID and set it to one of your IDs from &amp;lt;code&amp;gt;readables.cfg&amp;lt;/code&amp;gt;, such as &amp;quot;NoteTest1&amp;quot; in this example.&lt;br /&gt;
&lt;br /&gt;
== Custom notes ==&lt;br /&gt;
&lt;br /&gt;
As you might have noticed, pretty much all notes from Rebirth have more-or-less clearly visible text in English. That means you will need to use the notes that are least legible for your custom ones.&lt;br /&gt;
Ideally, there would be generic notes like in The Dark Descent, but these need to be made or ported first. If that happens, a download should appear here.&lt;br /&gt;
&lt;br /&gt;
== Special readables ==&lt;br /&gt;
{{stub}}&lt;br /&gt;
&lt;br /&gt;
Some readables are going to need a bit more set-up than regular notes, such as:&lt;br /&gt;
* [[HPL3/Amnesia: Rebirth/Tutorials/Tablets| A Dark World tablet]]&lt;br /&gt;
* Memory Cylinders (coming soon)&lt;br /&gt;
* More coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding voiceovers ==&lt;br /&gt;
{{stub}}&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Other entry parameters ==&lt;br /&gt;
{{stub}}&lt;br /&gt;
These can be configured in &amp;lt;code&amp;gt;readables.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
*Note:&lt;br /&gt;
**ID: Readable's ID. It must be unique.&lt;br /&gt;
**VoiceSubject: The audio voice file that will be played while reading the physical version of the note.&lt;br /&gt;
**FrontEntry: Readable's front side text as defined in .lang files.&lt;br /&gt;
**BackEntry: Readable's back side text as defined in .lang files.&lt;br /&gt;
**ImageEntry: An image file to show alongside text in the sketchbook.&lt;br /&gt;
**AddToSketchbook: Whether this entry should be added into the sketchbook or not.&lt;br /&gt;
*Memory Cylinder:&lt;br /&gt;
**ID: Memory Cylinder's ID. It must be unique.&lt;br /&gt;
**FrontEntry: Memory Cylinder's front text entry.&lt;br /&gt;
**IsMemoryCylinder: Whether this is a memory cylinder.&lt;br /&gt;
**MemoryCylinderLinesCount: The number of voices the referenced cylinder subject holds.&lt;/div&gt;</summary>
		<author><name>Tigersong</name></author>
		
	</entry>
</feed>