15 December 2025

Review of the book "Game Design Workshop" by Tracy Fullerton

Book cover
There are many ways to get into video game development. We all start from our love of playing, but some of us have a technical background and dive straight into programming with an engine, others get involved after dabbling in modding or level creation for a specific game, and some even come from the world of physical board games.

This book is for all of them because it begins with the most abstract concept of what we call a game and, although it eventually focuses on video games, it emphasizes the creative process of generating ideas, finding the most promising ones, testing them with a prototype that doesn’t have to resemble its final form, and starting an iterative refinement process until you arrive at something genuinely fun for its concept itself (and not for its implementation). Only then does development begin. In fact, the book doesn’t start addressing what we know as development until its last third, and even then it doesn’t deal with the technical side of development—there isn’t a single line of code in this book—but rather the planning and management of a group’s work.

The book adopts the perspective of the video game designer. While this is a very specific role within a development team, it is the one with the most transversal responsibilities, as the book explains, and therefore has the greatest visibility of the entire process—hence its importance.

The first two-thirds of the book explain the role of the video game designer; what we understand by a game; what its fundamental elements are; what elements enrich it to give it the desired character; what the most common gameplay dynamics are according to that character; how we can maintain player interest over time; and how we can keep the game balanced to avoid player frustration or, worse, boredom. It then moves on to how to filter and refine game ideas, giving enormous importance (and entire chapters) to the process of prototyping and testing those prototypes with real players (outside of the designer). Proof of the book’s decidedly “meta” approach is its insistence that tested prototypes start out as physical ones, even on paper and cardboard, long before creating the first digital prototype. This approach of avoiding digital prototypes until very late in the process may seem surprising to those of us who enjoy writing lines of code, but the author convincingly and refreshingly explains the reasoning behind it.

The last third deals with development itself, but with a “hands-off-the-keyboard” approach. Here, the book puts you in the shoes of a team manager who must coordinate multiple specialists to shape a game that can be sold. The entire book has a very realistic tone, but this is where it stands out the most. The author makes a notable effort to convey the day-to-day life of a video game development studio, both in its internal tasks of creating the game and in its interactions with key external actors for testing, funding, and distribution, such as testers and publishers. To do this, it explains how to structure development teams, what roles are common, and how they can interact efficiently and healthily. It then explains how agile methodologies can help humanize development and improve the product. I particularly liked how it explains the workings of the video game market and prepares you for how to approach a publisher so they choose to finance your game. It even goes as far as to discuss typical contracts between publishers and development teams, so you understand how milestone-based payment systems work during development, and later, royalties after the game’s release. It’s a fascinating reality check that demystifies the world of video game development while also showing the enormous effort behind a game that successfully sells.

All of the above is already immensely valuable, but the book is also enriched with testimonials from many game designers. You’ll find that more than one has created games you’ve enjoyed. In these testimonials, each designer shares how they entered the world of game design and development, what attracts them to it, and what creative process they follow when shaping a game. Reading them humanizes the role of the designer, puts faces to the people behind the games you’ve loved, and lets you learn about the life paths they followed to reach the point of creating the games that made them famous. Many of those paths were not easy. More than one even advises against entering the industry unless you have a clear vocation or passion, as it’s neither an easy profession nor one that will make you rich. But all of them confirm that if you truly want to make games and are willing to put in the effort and sacrifices, it’s a profession that can be deeply fulfilling.

Therefore, if you not only love games but also how they’re made, this is your book. It’s a refreshing reality check that demystifies, humanizes, and highlights the creative effort behind what you enjoy on your PC or console. A truly recommended book.

08 December 2025

Dictionary Serialization in Unity

In development, serialization consists of changing the format of an object in memory so that it can be stored on disk.

One of the most popular serialization formats is JSON, a text standard that allows you to save data in files following a key-based structure very similar to Python dictionaries.

When you serialize an object—an instance of a class—into JSON, what you do is select the key data of the object and convert them into fields and values in a JSON file. What are the key data of the object? It’s the minimum subset of data that allows you to reconstruct the object in the state you need. That reconstruction process is called deserialization and is the inverse of the other: you read the file and use its content to create an instance of the class with a state as close as possible to the original.

Unity is constantly serializing and deserializing. When we use the inspector to assign a value to a public field of a MonoBehaviour, Unity serializes that value into its own format so that you have it in the inspector the next time you start the editor. By default, Unity performs this process with all public fields of MonoBehaviours and ScriptableObjects, but you can also force it on private fields if you define them preceded by the [SerializeField] attribute. This attribute also allows us to edit private fields in the inspector. Without it, the inspector only shows public fields. Be careful—this does not mean you should use this attribute on all private fields of your MonoBehaviour. Its use only makes sense for those fields that contain base values for your class, that is, those you would configure in the inspector before the game runs. Preceding a calculated field with [SerializeField] would make no sense unless you wanted to preserve that calculated value for a later execution.

That was precisely the case that led me to write this article. I’m writing a class that allows me to analyze a scenario and generate a graph representing all its walkable areas. The graph creation process is irrelevant here, but my idea was for the graph to be generated during development, saved, and loaded at runtime. In other words, I wanted my graph to be saved in a ScriptableObject. One of the components of my graph is based on a dictionary whose keys are the integer coordinates of a rectangular grid, and whose values are nodes with links to neighboring nodes. And the problem arises because Unity does not know how to serialize dictionaries. It can serialize lists, but not dictionaries. That’s why you can edit lists in the inspector but not dictionaries.

Dictionaries are one of the most common data structures in development, so I’m not the first to encounter this problem. It’s so common that other engines, like Godot, proudly support dictionary serialization.

How can you work around this problem? Well, you can create a class that outwardly behaves like a dictionary but internally is based on two lists—one for keys and one for values. During serialization, those two lists would be saved since Unity can process lists. During deserialization, those two lists would be read and used to create an internal dictionary in memory from which the class would offer its functionality to the rest of the game components. This solution is perfectly legitimate, but by now it’s so widely used that it has already been included in a multi-type serialization tool (not just dictionaries) called Odin Serializer. So it would be like reinventing the wheel. If, despite that, you want to do it yourself, Odin’s own page explains how, although it warns that the devil is in the details and that there can be odd situations when editing prefabs that may require significantly refining the initial implementation. That path has already been traveled by the Odin Serializer team, so I’ll explain how to use it.

Odin Serializer Logo
Odin Serializer Logo

Odin Serializer is an open-source and free tool. You can download it from its website as a Unity package containing all the source code files to serialize everything Odin supports. Odin Serializer is just the free entry point to a set of tools that are paid. From the free serializer, they offer a tool to create custom inspectors and another to find errors in your projects. Both are extremely powerful. The first lets you skip the UI Toolkit step when implementing convenient and efficient inspectors. The second detects the most common errors in Unity development and provides a set of custom attributes to add semantics to your fields and detect cases where their values do not match their semantics (or even prevent you from entering those values). Although for this article I only needed the free serializer, I recommend checking out their other tools and prices. They are one-time purchases and very affordable for an indie developer.

The download page only asks for your game’s base namespace to customize the namespaces of all included code files. The package includes an OdinSerializer folder containing the rest of the tool’s folders. You need to place that folder inside your game’s Scripts folder.

Once imported into your Scripts folder, OdinSerializer provides a set of specialized classes that inherit from the usual Unity ones:

  • SerializedBehaviour
  • SerializedComponent
  • SerializedMonoBehaviour
  • SerializedNetworkBehaviour
  • SerializedScriptableObject
  • SerializedStateMachineBehaviour
  • SerializedUnityObject

You just need to replace the Unity class your component inherits from with the equivalent Odin class so that Odin handles serialization for types Unity doesn’t support. All dictionaries, for example, will be serialized by Odin without any extra effort, so if you edit their content in the editor, it will persist between executions.

However, keep in mind that even if you serialize the dictionary content with Odin, Unity’s inspector will still be unable to display it. So don’t be surprised if your public dictionary still doesn’t appear in the inspector. For that, you’d need to install Odin Inspector, which is one of the paid components. Without that component, any modification of the serialized dictionary content from the editor would need to come from custom scripts executed in the editor. That was precisely my case, as I configured a button in my graph component’s inspector to generate the grid when clicked and save the values created in the component’s internal dictionary. If I modify the scenario, I just click the button again to regenerate the graph’s grid.

Odin Serializer should cover most of your needs for serializing dictionaries, but it’s not always that simple. Although I had used Odin Serializer in simpler projects, I couldn’t get it to work in the project that inspired this article. It generated my graph correctly when I clicked the button, but the graph wasn’t there on the next editor restart or level reload. For whatever reason, the dictionary containing the graph wasn’t saved when the level was stored. I’ve thought about it a lot and don’t know if it’s because I have several levels of nested dictionaries, or because the scripts containing those dictionaries are placed in nested prefabs. It could also be because my component uses a custom editor, adding another level of indirection to data serialization. Whatever the reason, I ultimately had no choice but to implement my own serialization—the very manual serialization I warned against if Odin could solve your problem. This time, I had to reinvent the wheel, though I was lucky to rely on the method explained on Odin Serializer’s own page. I’ll tell you how, in case it helps you out sometime.

As I said before, the key is to create a class that inherits from Dictionary to preserve its functionality. To give this new class the ability to be serialized in Unity, it must implement the ISerializationCallbackReceiver interface. When Unity receives the command to serialize a class—because the field of that class is public or marked with the [SerializeField] attribute—it expects that class to implement the ISerializationCallbackReceiver interface. This interface consists of two methods: OnBeforeSerialize(), where we implement how we want to save our object’s information during serialization, and OnAfterDeserialize(), where we implement how to recover the saved information to reconstruct the object’s state.

The class I created is based on two lists: one for the dictionary’s keys and another for its values. These lists will store the data to be preserved since Unity natively serializes lists.

Fields of my customizable dictionary
Fields of my customizable dictionary

Now the interface implementation. First, for the serialization process.

Serialization process of my customizable dictionary
Serialization process of my customizable dictionary

When Unity calls OnBeforeSerialize(), it’s time to save the object’s state information. To do this, I clear the previous content of the lists (lines 42 and 43) and then refill them with the updated list of keys and values from the dictionary. When the class instance closes, the dictionary’s content will be lost, but the lists will have been serialized along with the rest of the scene’s information.

Now the inverse process. The scene opens again, and Unity calls the OnAfterDeserialize() methods of all its objects so they can restore their previous state from the deserialized information.

Deserialization process of my customizable dictionary
Deserialization process of my customizable dictionary

As shown in the listing, since the lists were serialized, they will remain intact when OnAfterDeserialize() is called, allowing us to use them to restore the dictionary’s entries. In lines 34 to 36, you can see that I iterate through both lists to regenerate the entries of the class’s internal dictionary.

Now comes something important. Unity cannot serialize generic types, and the newly created class (UnitySerializedDictionary) is generic. The solution is to specialize the generic class for each use case. Once concretized, the resulting class can be serialized by Unity. That’s why I have a separate static file with the different concretized versions of the generic dictionary.

Concrete classes derived from the generic one
Specialized classes derived from the generic one

To avoid any temptation to use the generic class directly without concretizing it, it’s best to mark it as abstract.

These specialized versions are the ones we can use in our code, with the assurance that Unity will preserve their content between executions.

Using the concretized dictionary
Using the specialized dictionary


MonoBehaviour that uses our concretized and serializable dictionary
MonoBehaviour that uses our specialized and serializable dictionary

I hope you found this useful and that it helps you feel confident about using dictionaries in your components.

28 October 2025

Implementation of a tool to measure distances in Unity scenes

For some unknown reason, Unity lacks a built-in tool to measure distances in scenes and prefabs. Godot does have one, but Unity doesn’t, even though it’s extremely useful both for building your scenes and for evaluating functionality tests. That’s why the Unity Asset Store is full of assets offering this functionality… for a price. Recently, I needed to measure distances in a Unity project I’m working on and considered buying one of these assets, but then I thought, “It can’t be that hard to implement myself.” I gave it a try, and it turned out to be very simple. In this article, I’ll explain how. First, what we want to achieve, and then we’ll move on to the implementation details.

A measuring rule is conceptually simple. It’s based on two independent variables, position A and position B, whose difference gives us the dependent variable we want to calculate: the distance. That’s the minimum. From there, we can add visual enhancements or manipulation features. For this article’s example, I wanted a visual tool that could be moved around the scene, with two grab points to adjust the positions to be measured using the mouse.

The rule to implement
The rule to implement

I also wanted to be able to have multiple rules simultaneously, to deploy them in different locations in the scene, and have them visible at all times without needing to be selected. The visual appearance of the rules had to be configurable so they could stand out appropriately in different scenes. So I needed to configure the line color, thickness, and the dimensions of the rule’s ends. Additionally, the rule had to provide the global positions of its ends to allow precise placement. With all these conditions, I wanted the rule to have an inspector like the one shown in the following figure.

Tool Inspector
Tool Inspector

Considering all the above, we can move on to the implementation details. By the way, all the code we’ll see is available in the GitHub repository of the tool. There, it’s explained how to install the tool easily using Unity’s Package Manager. In another article, I’ll explain how I packaged the tool so it can be installed from the repository via the Package Manager.

Using the repository as a reference, the first file to explain is Assets/Runtime/Scripts/MeasuringTape.cs. This file is the MonoBehaviour component that will be mounted on a Transform to be instantiated in the scene, and it contains the tool’s data model. It couldn’t be simpler:

Assets/Runtime/Scripts/MeasuringTape.cs
Assets/Runtime/Scripts/MeasuringTape.cs

The fields in lines 8 and 9 are the two independent variables we mentioned earlier, the positions of points A and B. It’s important to note that these are relative positions to the GameObject on which this component is mounted. I wanted it this way to be able to move the rule around the scene all at once, without having to move one end and then the other. It’s also important to give both positions a default value different from zero. Otherwise, their visual handles will coincide with the GameObject’s Transform, and we won’t be able to manipulate them.

The rest of the fields refer to the tool’s visual configuration:

  • color: The color of the rule’s lines.
  • thickness: The thickness of those lines.
  • endWidth: The length of the transverse lines at the rule’s ends.
  • endAlignment: A value between -1 and +1 to shift the transverse lines at the ends to one side or the other of the rule. This is an interesting option if we want to place multiple rules in the scene like dimension lines.
  • textSize: Font size used to display the measured distance.
  • textDistance: Distance from the rule to the text showing the measured distance. It can take negative values, in which case the text appears on the other side of the rule.

Besides the above, MeasuringTape.cs offers two properties with the global positions of the rule’s ends:

Assets/Runtime/Scripts/MeasuringTape.cs
Assets/Runtime/Scripts/MeasuringTape.cs

To have two visual handles to set the values of localPositionA and localPositionB by dragging the mouse, we’ll use Unity’s Handles. Handles are visual controls that respond to user interaction, such as clicks, drags, and rotations. Every time you move an object in the scene, you’re manipulating the Handle representing the object’s position.

To show custom Handles, you need to create a script in the Editor folder with a class that inherits from UnityEditor.Editor. This class must be decorated with the [CustomEditor] attribute to indicate which MonoBehaviour the Handles are associated with. In our example, this script is in Assets/Editor/DrawMeasuringTape.cs.

It’s very important to highlight that any script like this, which uses classes from the UnityEditor namespace, must be placed in a folder named Editor. If you put the script directly in the Scripts folder alongside the MonoBehaviours, you won’t be able to compile the game. Some people place the Editor folder inside Scripts. I prefer to keep them well separated.

Assets/Editor/DrawMeasuringTape.cs
Assets/Editor/DrawMeasuringTape.cs

Look at line 6. The [CustomEditor] attribute must be passed the type of MonoBehaviour it’s associated with. It’s a way of telling the editor: “Every time you encounter a MonoBehaviour of this type, represent it in the inspector and scene as defined here.”

It’s important to note that I left this script in the default namespace. I’m not sure why, but when I tried to use a custom namespace, the drawing of Gizmos in the DrawTapeGizmos() method failed, which we’ll see later.

Handle configuration is done in the OnSceneGUI() method, which belongs to the UnityEditor.Editor class.

Assets/Editor/DrawMeasuringTape.cs
Assets/Editor/DrawMeasuringTape.cs

Handle management within OnSceneGUI() always follows the same structure. In fact, it wouldn’t be a bad idea to save a template, because you always end up doing the same thing.

You start by retrieving a reference to the MonoBehaviour associated with the Handles. In OnSceneGUI(), it’s common to use the target field of UnityEditor.Editor. That field has the reference we’re looking for, although you need to cast it (line 160) to get the exact type. This reference will be very useful for reading and setting the properties and fields of the original MonoBehaviour.

Then comes the segment where you display your Handles and retrieve their values. This segment starts with a call to EditorGUI.BeginChangeCheck() (line 162). This call detects whether the user has modified any editor control between this call and its corresponding EditorGUI.EndChangeCheck() (line 172). If the latter detects any change in the editor controls, the values are retrieved and saved in the original MonoBehaviour (lines 176 and 177). These changes are recorded in the Undo/Redo system with a call to Undo.RecordObject() (line 175). This method records all changes made to the object passed as a parameter from the moment of the call. The second parameter’s text identifies the change in the history.

Between lines 165 and 170 is where the Handles are created. There are many types, each with its own appearance and manipulation method. The ones I used here are the simplest. PositionHandles simply present a coordinate axis that we can move around the scene. If moved, the Handle returns the new position, which in our case is stored in the variables positionAHandle (line 165) and positionBHandle (line 168). These variables are used to update the fields of the original MonoBehaviour (lines 176 and 177).

In simple cases, it’s quite common to see implementations that include the object’s Gizmo visual representation in the same OnSceneGUI() method, usually after the EditorGUI.EndChangeCheck() block. I’ve done this often, but it has a couple of drawbacks. The first is that you mix the visual control management and Gizmo representation logic in the same method, which lengthens and complicates the implementation. The second problem is that all visual representation included in that method will only be shown when the source object is selected. This last point was a blocker for me, as I wanted the rule’s representation to remain visible even when another object was selected.

The alternative I discovered is to decorate a static method with the [DrawGizmo] attribute. This attribute marks a method as responsible for drawing an object’s Gizmos. On one hand, it allows you to concentrate all visual representation logic in it, leaving OnSceneGUI() for Handle management; and on the other hand, depending on the parameters passed to the attribute, you can define when the Gizmos should be shown.

Assets/Editor/DrawMeasuringTape.cs

Assets/Editor/DrawMeasuringTape.cs
Assets/Editor/DrawMeasuringTape.cs

In the example, as seen in line 108, I passed the necessary flags to the attribute so that the Gizmos are shown both when selected and when not.

To draw the Gizmos, I used the drawing functions from the Handles library. There’s some overlap with what the Gizmos library offers, which can also be used for drawing. The advantage of Handles is that it lets you set the line thickness, while Gizmos only allows drawing with a thickness of 1 pixel. Based on that, the rest of the method’s lines are very similar to when we draw with Gizmos.

In line 112, I set the color of the lines to be drawn, while in line 113 I draw the line between the two ends of the measuring tool. Note that the third parameter passed to the DrawLine() method is precisely the thickness of the line to be drawn.

To highlight the ends and their visual handles, in lines 116 and 121 I draw a circle around the ends. To finish these, I drew perpendicular lines to the main one. If I wanted my rule to only measure in 2D game scenes, I could have calculated the perpendicular to the main line, but since I want to use it in 3D environments, I need the lines crossing the ends to also be perpendicular to the camera’s viewing direction. Otherwise, there could be moments when the camera moves and the end lines disappear because they’re aligned with the viewing direction. To calculate the perpendicular to two vectors, we use the cross product, which I calculate in line 133. With that done, the perpendicular vector helps calculate the half-length of the ends (line 146) and to draw them, incorporating the endAlignment shift (lines 147 and 150).

The perpendicular vector is also very useful for separating the text from the main line, starting from its center. That center is calculated in line 138, and from it the separation is calculated in line 142. Once we have the location, I draw the text in line 143. The “F2” in the ToString() call ensures the distance is shown with two decimal places.

At this point, I already have a measuring rule whose ends I can manipulate and that is drawn as shown in the image at the beginning of the article. What remains to be clarified is how I made the inspector show the global position in read-only fields. Although the MeasuringTape MonoBehaviour has two properties that provide the global position of the ends, Unity cannot display properties in the inspector (which is a shame because Godot can). To display these properties as read-only, you need to use a custom inspector. To do this, you must create a class that inherits from UnityEditor.Editor, just like the one we already used for Handles and visual representation, but to represent custom inspectors you must use the CreateInspectorGUI() method.

This method is based on reading the serialized values of the original object’s fields to be represented in the inspector. These values are passed to the class through a field called serializedObject. What I usually do is use the OnEnable() method to get references to each of the original object’s fields.

Assets/Editor/DrawMeasuringTape.cs
Assets/Editor/DrawMeasuringTape.cs

To get each reference, you must call the serializedObject.FindProperty() method and pass it a string with the name of the original object’s field you’re interested in. I don’t like using strings because it’s easy to make mistakes, but that’s how it works.

Once we have the references to the original object’s fields, we can use them in CreateInspectorGUI().

Assets/Editor/DrawMeasuringTape.cs

Assets/Editor/DrawMeasuringTape.cs
Assets/Editor/DrawMeasuringTape.cs

In line 38, the panel where all the inspector fields will be represented is created. I didn’t want to make a big deal about the field order, so I just organized them in the classic vertical layout.

Remember when in OnSceneGUI() I got a reference to the original MonoBehaviour using the target field? Well, you might be tempted to do the same in this method, but Unity’s documentation advises against it and requires that in this method you use serializedObject.targetObject, as seen in line 47. I don’t quite understand the reason for this peculiarity, but I preferred to follow the documentation’s recommendation rather than go against it and run into strange problems later.

Since I’m fine with the default visualization of the first two fields (the local positions), I simply created two default fields and populated them with the original object’s values (lines 50 and 52). Then, I added the fields to the panel (lines 51 and 53).

In my particular case, I usually use custom inspectors when I want to show or hide fields depending on the value of a previous one (e.g., a boolean). In those situations, I like to place the variable fields (those that can be shown or hidden) on a separate panel from the main one. That separate panel is created in line 56 and added to the main one in line 57. Then, in line 60, we pass that panel to the UpdateGlobalPositionFields() method to create the read-only fields with the global positions. In a moment, we’ll see how UpdateGlobalPositionFields() works internally, but to not lose the thread of CreateInspectorGUI(), let’s finish reviewing how it works.

Once the fields where the global positions will be shown are added, I want them to stay updated. To do this, I linked UpdatePositionFields() to the local position fields so it runs every time the local position values change (lines 64 to 67). This will update the global positions.

Since I'm fine with the default visualization for the remaining fields, I simply add their respective PropertyField to the main panel (lines 70 to 75).

Note that CreateInspectorGUI() must return the main panel so the editor can display it in the inspector. That’s what I do in line 77.

As promised, let’s now look at what happens inside UpdateGlobalPositionFields().

Assets/Editor/DrawMeasuringTape.cs
Assets/Editor/DrawMeasuringTape.cs

Remember I just mentioned that this method receives, as its first parameter, the subpanel where the fields we want to manually update are drawn—either to insert values or to show/hide them.

The first thing I do with that subpanel, in line 91, is clear its contents to start with a blank canvas.

In line 93, I define that I want to stack the elements I add to the subpanel in a descending column.

Finally, I add the fields with the global positions (lines 96 and 101). In both cases, I do the same: I create a field specialized in displaying positional values (Vector3Field). Then, I assign values to those positional fields using the MeasuringTape properties that return the respective global positions (lines 97 and 102). Since I want the fields to be read-only, and therefore not manually editable, I disable them with SetEnabled(false) (lines 98 and 103). Lastly, I add the newly created and configured fields to the subpanel (lines 99 and 104).

With this, we now have a fully functional distance measuring rule… although rather inconvenient. To use it, we’d have to create an empty GameObject in the scene and then add the MeasuringTape component to it. Certainly tedious. We could simplify things by creating a prefab that only includes the MeasuringTape component. That way, we’d just drag the prefab into the hierarchy whenever we want a rule in the scene. However, that would require us to search for the prefab in our folders every time we need to measure something. That’s why I created an entry in Unity’s main editor menu to instantiate the prefab whenever needed. Let’s see how I did it.

To add entries to Unity’s main menu, you simply decorate a static method with the [MenuItem] attribute. This attribute receives the path, within the main menu, of our entry. What happens then is that every time that menu entry is clicked, the static method is called.

In my case, I implemented the static method in the file Assets/Editor/InstanceMeasuringTape.cs. Note that the [MenuItem] attribute is in the UnityEditor namespace, so any script using it must be placed in the Editor folder.

Assets/Editor/InstanceMeasuringTape.cs
Assets/Editor/InstanceMeasuringTape.cs

The first thing the method does, in line 15, is call LoadAssetAtPath() to load the prefab with MeasuringTape we mentioned earlier. The path to search will depend on how you run the tool. If you copy-paste all the code directly into your project, you’ll need to specify the path where you place the prefab (with Assets as the root of the path). In my case, I configured everything to run as a package downloaded from GitHub using Unity’s Package Manager (I’ll explain how to do this in another article). So the path must be that of the folder where the package is installed. Packages are installed in the Packages folder, so my path starts from that root, as shown in line 9.

Once the prefab is loaded as a GameObject, it can be instantiated in the scene using the method PrefabUtility.InstantiatePrefab() (line 23). The result of this call is that the prefab instance appears in the scene, hanging from the root of the hierarchy.

Finally, since it’s logical that you’ll want to operate on the newly created rule, line 32 selects that rule in the hierarchy so you don’t have to search for it to click on it.

And that’s it. I hope you found it interesting and that it gave you some ideas for creating your own tools within Unity. As I mentioned earlier in this article, I hope to find time soon to explain how to publish your tools on GitHub so they can be loaded and kept updated using Unity’s Package Manager.

10 September 2025

Tools for creating visual novels

Article cover
In a previous article, we reviewed some of the tools available to create your game's storyline. In this one, we’ll look at some of the tools you can use to turn that storyline into one of the simplest and most addictive types of games: visual novels.

Visual novels are a genre of video games that focus on interactive storytelling, where the player makes decisions that affect the narrative. They typically feature static visual art (such as 2D or 3D character illustrations) and are presented as a combination of text, images, and sometimes music or voice acting. Gameplay mainly involves reading dialogue and descriptions, making choices at key moments, and occasionally solving small puzzles.

It’s a technically simple genre, but it requires a strong, complex storyline that hooks the player despite the simplicity of the gameplay mechanics. That’s why these games must offer deep narratives with complex stories that often have multiple endings, depending on the player’s choices.

Conceptually, this type of game should feel familiar to anyone who grew up reading “Choose Your Own Adventure” books. Visual novels are the video game counterpart of that book category. As video games, they first gained popularity in Japan but have since spread worldwide thanks to gaming platforms like Steam and itch.io.

You can find examples of this genre in games like Phoenix Wright: Ace Attorney, The House in Fata Morgana, or Fate/stay night.

This makes visual novels a very interesting genre if you have the ability to create a captivating story and can support it with good illustrations and fitting sound, but lack the resources required for other types of games (such as programmers, animators, modelers, or visual effects specialists).

In this article, we’ll explore some of the tools you can use to create a visual novel using only those three ingredients—story, illustrations, and sound—while minimizing (or completely eliminating) the need for other skills, such as programming.

Ren'Py

Ren'Py is a free and open-source development engine specifically designed for creating visual novels and interactive narrative games. It’s one of the most popular tools for this genre, especially among indie developers, due to its ease of use, flexibility, and active community.

Ren'Py logo
Ren'Py logo

Once installed, it works by creating text files with the .rpy extension. These files use a combination of Ren'Py’s own scripting language (similar to Python) and standard Python. Ren'Py scripting is intuitive, with simple commands for dialogue, choices, and transitions, while Python allows for more advanced customization. The result is highly self-descriptive text files that often read almost like natural language.

To work with these text files, you can use any editor or the one integrated into the Ren'Py environment, which also offers real-time preview, speeding up development. It’s a tool that allows you to create visually appealing visual novels without needing deep technical knowledge.

To enrich the storytelling, it supports images (PNG, JPG), animations, transitions, music, and sound effects. It also allows for character sprites with variable expressions. It includes an automatic system for saving games and checkpoints.

The integration of Python within the engine allows developers to create custom menus, point systems, mini-games, or unique mechanics using Python.

To reach the widest possible audience, Ren'Py lets you create multiple translations of your games and export them to various platforms, including Windows, macOS, Linux, Android, iOS, and web browsers.

Ren'Py’s website features detailed official documentation, and there are also plenty of forums, templates, tutorials, and community-shared assets to enhance and simplify game development with this engine.

Thanks to all these advantages, Ren'Py has been used to develop hits like Doki Doki Literature Club, Katawa Shoujo, and Long Live the Queen.

Of all the options we’ll cover in this article, this is the one I recommend by default. It’s hard to go wrong with it. And since it’s free, the experiment won’t cost you anything. Only if this engine falls short for some reason would I consider the other options I’ll now describe.

Tyrano Builder

TyranoBuilder is a visual novel development software based on a drag-and-drop interface, ideal for those who prefer to avoid programming or who want an intuitive interface. It allows you to create interactive games with dialogue, images, music, and choices without writing code, although it offers advanced options for those who want more customization.

Tyranno Builder logo
Tyranno Builder logo

Its typical workflow involves using its visual editor to build your visual novel by adding “components” (like dialogue, images, sounds) from a menu. If you want to add advanced features, custom game mechanics, or complex effects, you can use TyranoScript, a scripting language heavily based on JavaScript. Its main advantage over Ren'Py is this visual component that lets you create simple stories without writing anything resembling code. However, once you cross a certain threshold and want to do more sophisticated things, you’ll have to use TyranoScript, which I find a worse option than the Python offered by Ren'Py.

It supports multiple image and audio formats, as well as video (for cutscenes or transitions). To enhance the game visually, the tool allows basic effects like fades, character movements, zooms, or transitions. It also supports “speech bubbles” to bring the dialogue style closer to comics.

As with any visual novel, the gameplay mechanics you can implement with this tool are based on displaying dialogue with text and character names. These dialogues are adjustable in speed and style. The tool allows you to create choices that branch the story based on the player’s decisions. These branches can be enriched with simple variables (without code) to track choices or unlock content.

The tool’s editor lets you test the game as it takes shape, making it extremely fast to reach a functional prototype and then a final version.

The resulting game can be exported to Windows, Mac, HTML5, and mobile devices, both iOS and Android.

TyranoBuilder is not free, although its cost is very low (around €15) and is a one-time purchase. It has plugins to extend its functionality, although most of them seem to come from Japan, where this tool appears to be especially popular.

It has a community, but it’s much smaller than Ren'Py’s, making it harder to find tutorials for it, especially in Spanish. The official website tyranobuilder.com and discussions on Steam offer support, but they’re not as extensive. YouTube tutorials (in English) are helpful but less abundant.

Unlike Ren'Py, TyranoBuilder doesn’t have any major hit games to its name. It’s more common in lesser-known indie projects published on platforms like Itch.io.

In general, TyranoBuilder is used by creators who want quick results without programming. Which is perfectly fine if that’s your case. Just keep in mind that if you want to make your game more sophisticated, Ren'Py is probably the better choice.

Visual Novel Maker

Visual Novel Maker (VNM) is a commercial software developed by Degica (the creators of RPG Maker) specifically designed to create visual novels.


Visual Novel Maker logo
Visual Novel Maker logo

Like TyranoBuilder, it combines a drag-and-drop visual interface with scripting options (JavaScript), making it accessible to beginners but also allowing customization for more advanced users. In this sense, it’s very similar to TyranoBuilder, but it has several distinctive capabilities.

To start with, it integrates support for Live2D animations, which allow characters to have fluid movements and dynamic expressions (like blinking, head movements, or gestures) without external setups. This is ideal for projects with a more professional or visually dynamic focus.

It also offers a real-time preview feature that lets you quickly test changes, even in large projects. This speeds up the design and correction process, reducing frustration during creation. TyranoBuilder also has a preview feature, but complaints about its slowness and other issues (like delays or bugs when previewing complex scenes) are common.

The visual editor is more sophisticated than TyranoBuilder’s and lets you implement more complex mechanics (like variable systems, conditions, or advanced transitions) without programming. For example, you can set up point systems or conditional choices directly in the interface. It’s true that TyranoBuilder allows the same functionalities, but to do so you have to use TyranoScript.

Another advantage is that Visual Novel Maker comes with several pre-installed assets (images, music, etc.) that can be useful for building your prototypes.

Additionally, the general consensus is that Visual Novel Maker’s user interface is polished and modern, with a design inspired by RPG Maker. If you’re already an RPG Maker user, you’ll feel right at home. Another connection to RPG Maker is that it offers compatibility with certain plugins and resources from that tool, which can be useful if you plan to incorporate RPG elements or use assets designed for that platform.

The visual effects it can offer from the visual editor are much more advanced than TyranoBuilder’s, which needs scripting to achieve similar results.

It exports to Windows, Mac, Linux, Android, iOS, and browsers (HTML5). Exporting to mobile requires additional setup (like Android SDK or Cordova), which can be complicated for beginners.

As for the community, it’s small, although perhaps slightly larger than TyranoBuilder’s thanks to RPG Maker’s popularity.

The conclusion is that with Visual Novel Maker, it’s easier to achieve a professional look for your visual novel compared to TyranoBuilder. Of course, everything comes at a price, and Visual Novel Maker’s is higher (around €60) than TyranoBuilder’s (€15), although it’s still a one-time purchase.

In the end, if budget isn’t an issue and you have good artists who can take advantage of the Live2D functionality, Visual Novel Maker is the safest option.

Is it worth it compared to Ren'Py? Well, Ren'Py is free. It doesn’t come with preloaded assets, but its community is so huge that it’s easy to find all kinds of assets and plugins. It’s true that Ren'Py is based on text files, but that can be an advantage if you plan to work in a team using a code repository. On the other hand, I’m a convinced hater of JavaScript (sorry, it’s just a language I can’t stand, and I’ve given it plenty of chances), while Ren'Py’s use of Python seems ideal to me. It’s true that Ren'Py doesn’t offer Live2D animations out of the box, but its community comes to the rescue, and thanks to it, there’s a plugin that allows it, with even greater control over effects and transitions thanks to Python. Perhaps the biggest advantage of Visual Novel Maker is its preview feature that lets you test changes quickly without exporting the game, while Ren'Py has to run the full game, although you can jump to specific sections using tags, which is less convenient.

03 September 2025

Tools for Developing a Video Game's Storyline

Guy thinking about the storyline
The importance of the storyline depends on the type of game and its target audience. There are games like Tetris or Among Us, where the narrative is minimal and the fun lies in the mechanics. These types of games do not require a complex storyline.

However, the storyline is a fundamental pillar of the experience in narrative, RPG, or adventure games. In these games, the storyline is important for multiple reasons. A good storyline creates a believable world and characters with whom players can empathize, increasing immersion. Well-developed stories generate emotions, motivating players to continue to discover what happens next. The storyline provides a narrative framework that gives meaning to the player's actions. Without a story, the mechanics can feel empty or repetitive. For example, in games like The Last of Us, the storyline drives decisions and gives emotional weight to the mechanics. A solid narrative offers clear objectives and reasons to move forward, whether it's saving a world, avenging a character, or unraveling a mystery. This keeps interest high, especially in long games. In a saturated market, an original or well-executed storyline can make a video game stand out from others with similar mechanics. Titles like Hollow Knight or Disco Elysium are examples where the narrative elevates the experience. A storyline with branches, moral choices, or multiple endings (as in Mass Effect or The Witcher 3) encourages replayability, as players want to explore different outcomes.

Therefore, the process of developing the game's storyline is as important as programming or asset modeling. In this article, we will look at some specialized tools that can be useful for creating the storyline of our game, as well as designing its dialogues.

Obsidian

Obsidian is a note-taking and knowledge management application designed to create and organize content through interconnected notes, using a Markdown-based system and a "knowledge graph" approach that visualizes relationships between ideas. Although it is not specifically designed for video game development, its flexibility, customization, and ability to handle large amounts of information make it a valuable tool for writers, narrative designers, and developers working on story planning, lore, scripts, and project documentation.

Obsidian Logo
Obsidian Logo

Obsidian stands out as a lightweight and versatile solution for pre-production and organization, especially for indie projects or small teams. Each note can be linked to others via bidirectional links (similar to a personal wiki). Its graph view shows visual connections between notes, making it easier to explore complex ideas. Therefore, it is an ideal tool for mapping relationships between characters, events, and quests.

When editing, you have two main modes: a plain text editor using Markdown formatting, and a Canvas mode that offers a visual canvas to connect notes with arrows, similar to an idea board. When creating a new note, links to other notes are made using Markdown links. In Canvas, you can create two types of nodes: cards, which are small nodes with just a title, and notes that contain full Markdown text (you can even import a separately created note). Ultimately, Canvas is a visual space to organize notes as connected nodes, ideal for mapping branching stories or narrative flows.

Editing notes in Obsidian
Editing notes in Obsidian

Obsidian canvas mode
Obsidian canvas mode

A possible workflow could be brainstorming and collecting loose ideas in notes, then structuring them in a Canvas. Additionally, outside of Canvas, if you need a high-level view of all your notes, you can open the graph view that shows a note’s tree and its links to other notes.

Another powerful feature is the ability to tag elements, which facilitates advanced searches using Boolean operators.

By default, Obsidian saves everything locally in plain text files, ensuring portability and low resource consumption. These files can be exported to Markdown, HTML, PDF, or Word. It syncs with Dropbox, iCloud.

Obsidian is free, but if you want synchronization across all your devices, you’ll need to pay a small subscription. If you want to publish notes on the Obsidian Publish website, another subscription is required.

All of the above already makes it a very interesting option for what we’re looking for in this article, but additionally, Obsidian has a hyperactive community on forums, Discord, and Reddit, where they offer templates, examples of specific workflows (e.g., for video game narrative). This activity has already produced more than 2,600 community plugins, such as:

  • Dataview: Creates dynamic tables to manage characters, quests, or items (e.g., “show all NPCs with status ‘ally’”).
  • Obsidian Tasks: Task tracking for development planning.
  • Kanban: Boards to manage sprints or milestones.
  • Excalidraw: Drawings for storyboards or maps.

In the end, no two Obsidian installations are alike. Each user customizes it with multiple plugins to suit their particular tastes, making it a tremendously powerful tool.

Ink

Inkle Studios is an independent video game development studio. They specialize in interactive narrative games, i.e., titles focused on branching stories, player decisions, and non-linear narratives, where text and user choices are key elements to advance the plot.

Their work is not limited to video games; they have also created tools for development. Among them is Ink, an open-source narrative scripting language (under MIT license), specifically designed to write highly branching stories in games. Ink is not a traditional programming language but a simple and elegant markup that allows writers and developers to create dialogues, choices, and complex plots efficiently. Ink integrates easily with engines like Unity (via a free plugin), Unreal Engine, and Godot, and has been adopted by both large and independent studios.

Ink logo
Ink logo

To put it simply, Ink is what the authors of the popular “Choose Your Own Adventure” book series would use today to write their stories. With it, you can offer choices to the reader and let the story branch out as those choices unfold.

Ink offers an easy-to-learn syntax for non-programmers but is powerful for advanced structures (like loops, lists, and conditional logic). It is also very lightweight, so the workflow is fast, allowing you to see changes almost as you write.

Ink syntax
Ink syntax

All these advantages have led to its widespread use in many games (Haven, NeoCab, Sable, Sea of Thieves, The Banner Saga 3, for example) and there are plenty of online resources to learn how to use it.

To make its use even easier, Inkle also offers a free editor called Inky, available on the same page as Ink. It’s a minimalist editor that offers a preview window where you can test the options and branches you write. It also alerts you to Ink syntax errors you make while writing. It has versions for Windows, Linux, and Mac. And finally, most importantly, it allows you to export to JSON so you can load all the story information into the game you’re developing.

Inky logo
Inky logo


Twine

Twine is a free and open-source tool designed to create interactive fiction and text-based narrative games, especially non-linear stories where player choices determine the course of the narrative. Created in 2009 by Chris Klimas, it is widely used by both beginner developers and professionals in video game development, creative writing, education, and artistic projects. What it offers is similar to Ink, in the sense that it allows you to create interactive stories in hypertext format, where the player navigates through text nodes (called “passages”) connected by links. Each passage contains text, options, and optionally, code to handle logic, variables, or multimedia.

The downside is that there is no clear and easy path to import the story into a game engine (as there is with Ink), so Twine is more suitable for shaping the game’s script or creating a very simple prototype to show possible branches of the script.

Twine logo
Twine logo

Twine is known for its simplicity, accessibility, and flexibility. Its visual editor allows you to drag and connect nodes, creating a map of the narrative. It also has a code mode to customize game logic.

Interactive stories created in Twine are published as HTML files, playable in web browsers, making them highly portable. They can also be exported to other platforms with additional tools. The output files can be dumped into various supported formats for further processing and customization of the story.

Using a visual editor makes text editing much easier than in Ink. Ultimately, writing is limited to typing text and adding simple links (e.g., [[Go to the cave]]) to connect passages. Although you can also use JavaScript and macros for more advanced features.

Twine editor
Twine editor

With all this, you can create highly branching stories, from “choose your own adventure” tales to complex narratives with variables (e.g., health points, inventories) and conditional logic.

The tool and its code are available under the open GPL-3 license. It can be used online (twinery.org) or downloaded for Windows, macOS, and Linux. It also has an active community, tutorials (like those on twinery.org), forums, and templates on platforms like itch.io. There are also extensions and add-ons created by the community.

Yarn Spinner

Yarn Spinner is a tool originally developed by the Australian studio Secret Lab (creators of Night in the Woods), although part of the team later split from the video game studio to focus on developing the tool, becoming known by the same name.

Halfway between Ink’s scripting language and Twine’s visual tool, it uses a simple scripting language called Yarn, inspired by formats like film or theater scripts, which allows you to write dialogues in plain text with flow control elements, variables, and commands. Then, a plugin integrated with the engine acts as an interpreter that executes these scripts during gameplay, sending dialogue lines, options, and commands to the engine.

Yarn Spinner webpage cover

Some games made with Yarn Spinner include Night in the Woods, A Short Hike, DREDGE, Lost in Random, Frog Detective, Button City, and Escape Academy.

For script editing, they have a Visual Studio Code extension that offers a text editor with highlighting to create Yarn scripts, as well as a graph window to view story branches.

Yarn Spinner extension for Visual Studio Code
Yarn Spinner extension for Visual Studio Code

They also have a website where you can edit and test simple scripts.

The main advantages of Yarn Spinner are:

  • Narrative Flexibility: Supports highly branching stories, with memory of previous choices (by default), storylets (dynamic content based on salience), and groups of nodes/lines for organization.
  • Customization: Integrates multimedia (images, audio, video) via commands. Includes pre-made UIs (e.g., dialogue bubbles, option wheels) and samples for customization.
  • Localization: Robust support for translations, extracting strings to separate files (e.g., JSON or CSV) for tools like Unity Localization or I2 Localization, facilitating multilingual workflows.
  • Debugging and Tools: Errors with line numbers, browser preview, and voice-over support (line synchronization). Active community on Discord and GitHub.

If you use Unity, you’re in luck, because it’s the only engine with an official integration plugin. The plugin code for Unity is available on GitHub under the MIT license, so you can download and install it in Unity for free. Another option is to use the Unity Asset Store to purchase the Unity plugin; the cost is not very high and helps fund the tool’s development. They also offer other Unity add-ons, such as one that displays conversation text in comic-style bubbles, and another that allows decisions to be made using a selection wheel.

There are also plugins for Unreal and Godot, but they are still in Beta and not recommended for production.

Articy Draft

Articy:draft (now primarily known as articy:draft X in its latest version) is a professional tool for narrative design and interactive content organization, developed by Articy Software GmbH, a German company founded in 2009.

It is a visual software that acts as a centralized database for creating, managing, and planning branching stories, dialogues, quests, characters, and other narrative elements in interactive projects, with a special focus on video game development. Unlike pure scripting tools like Ink or Yarn Spinner, Articy:draft is more of an integrated visual environment (similar to a "narrative CMS" or content management system for games), combining story flow editing, object databases, and team collaboration.

Articy Draft logo
Articy Draft logo

It is widely used in the industry by indie and AAA studios to handle complex narratives and has been key in titles such as Disco Elysium, Suzerain, HipWitch, Saint Kotar, Garden Scapes, and Spell Force III.

It features a non-linear visual editor for designing interactive content, unifying specialized editors (for dialogues, quests, objects, locations) into a single interface. It allows graphical representation of game entities (such as NPCs, items, or quests) with automation, variables, and conditional logic, acting as a "visual frontend" for game data. It does not generate executable code directly but exports structured data for integration into game engines.

Articy Draft visual editor
Articy Draft visual editor

It uses nested views (Flow View) to map high-level stories (chapters) to fine details (dialogue lines). It includes a flexible template editor for game objects, a simulator to test logic (with voice and localization support), and tools such as a vector location editor to plan 2D maps.

Views nested in Articy Draft
Views nested in Articy Draft

It offers a simulation mode that plays the story with voice, languages, and logic, ideal for iterating before exporting. The simulation mode allows checking the evolution of variables linked to dialogues and choices, as well as the effect these variables have on the story path.

Articy Draft simulation mode
Articy Draft simulation mode

Other additional tools include a storyboarding panel; a location editor (useful for planning levels or quests); voice-over support (TTS generation for prototypes and synchronization); integrated localization (exports strings for translation and reimports); and AI extensions to generate dialogues, images, or automatic translations (e.g., with DeepL).

Storyboarding in Articy Draft
Storyboarding in Articy Draft

Location editor
Location editor

It also serves as a database to store the configuration of all NPCs and game objects. The idea is that game designers can manipulate the data from the Articy Draft interface, then export all the data at once and load it from the game engine.

Assets and character database in Articy Draft
Assets and character database in Articy Draft

Regarding integrations with game engines, Articy Draft has official assets to integrate with both Unity and Unreal. For other engines, Articy Draft also allows export to XML and JSON. If that’s not enough, they also offer a NuGet package to build your own integration package.

Articy Draft follows a subscription licensing model but has a free version, with all functionalities, which can even be used for commercial projects, with the only limitation of a maximum of 700 objects per project. Still, that object count is very generous and probably more than enough for most medium and small projects. In any case, it’s more than sufficient to try the tool and decide if it’s worth it. If you need more than 700 objects in your game, you can opt for any of the paid licenses (individual ones are quite affordable).

Dialogic

The previous tool only had direct integration with Unity and Unreal, so to balance things out, now we’ll talk about one that exists only for Godot: Dialogic.

Dialogic is a plugin for Godot aimed at creating interactive dialogue systems, visual novels, RPGs, and character management. Initially developed by Emilio Coppola in 2021 as a solution to easily add branching conversations, it has evolved into a mature and popular tool in the Godot community, especially for indie developers looking to integrate complex narratives without writing extensive code from scratch. It is available under the MIT license, allowing free commercial use and modifications.

Dialogic logo
Dialogic logo

It provides an integrated editor in Godot to design "timelines" (dialogue timelines), which are sequences of events such as text, player choices, animations, logical conditions, and signals. These timelines run during gameplay to display dynamic conversations with branches, events, and choices. Conditions (if/else with variables), signals (for in-game triggers), animations, and backgrounds can be added to these conversations.

Dialogic timeline editor
Dialogic timeline editor

It includes a character management system with portraits, expressions, and custom colors, and supports extensions for custom events.

Dialogic character editor
Dialogic character editor

Visually, it is fully customizable, with editable themes (colors, fonts, text bubble styles), audio support (voice-over, SFX), animations (e.g., screen shake), and custom events with minimal GDScript code. It includes pre-made styles like "text bubble" for visual novels.

It also supports localization, allowing integrated translations with translatable glossaries.

It has a very active community that has created extensions to interact with other plugins like SmartShape2D for terrain or Godot Steamworks for achievements.

If you’re developing with Godot, Dialogic is the simplest and most cost-effective option since it’s packed with features, well-tested in many Godot games, and free.

Scrivener

All the previous tools, except perhaps Twine, consider some level of integration or compatibility with game engines. Scrivener is something very different. It is a tool 100% designed for writers and screenwriters.

Developed by the company Literature & Latte, although not specifically created for video game development, it is a versatile tool that can be extremely useful for writing and structuring video game scripts, especially for narrative projects like RPGs, graphic adventures, visual novels, or any game with branching stories.

Scrivener logo
Scrivener logo

It takes the form of an advanced word processor and project management tool that combines writing with note organization, research, and non-linear structuring. It allows dividing a project into manageable sections (chapters, scenes, etc.), managing reference materials (images, PDFs, notes), and exporting in multiple formats. Additionally, each piece of content created with Scrivener can be enriched with metadata, notes, tags, and references.

To plan narrative arcs, it offers a corkboard-like visualization mode where each section is displayed as a card.

Scrivener corkboard
Scrivener corkboard

The entire interface is very flexible, and by using it properly with tags, you can configure timelines to develop parallel storylines.

Scrivener timelines
Scrivener timelines

Don’t expect formatting tools. In that sense, Scrivener is very simple, almost primitive. It’s actually designed to focus on generating content and then exporting it for formatting in other tools. For example, many people configure Scrivener to export the generated content to LaTeX and then, from a LaTeX editor, export to PDF with the formatting of the chosen LaTeX template.

Therefore, Scrivener is an excellent tool for writing and organizing a video game script in the pre-production phase, especially for structuring complex narratives and keeping lore organized. However, it is not designed to simulate interactivity or integrate directly with game engines, so you’ll need to combine it with tools like Twine (for quick prototypes), Dialogic (for Godot), Yarn Spinner (for Unity), or Articy:draft (for AAA projects). If your focus is writing a detailed script before technical implementation, Scrivener is a great choice; if you need immediate interactivity, opt for a tool specific to video games.