Story-Editor.md 13 KB

Story Editor

There could be confusion with Script Writer.

Story Editor is the Note Editor for story organization. It's a 2D world of your project. Think about an infinitely large Desktop but only for things in the project. With an ability to plot story lines.

Chapters:

User Guide

I would love to start explaining the large middle part of it. But you would get lost on your project since it's probably empty for you. So instead I gonna go over the various buttons around the main view. So you could start building your story. And then as it goes. I gonna explain the reasons for each thing. And how to use them.

In the top you can see the Analytics progress bar. Starting with icon. This is a button that will give you analytics about the project. More about this in the Analytics page. Then you have the icon. Followed by the currently scheduled task. It will get you to an asset or a scene in which the task should be done.

For those of you who want to use VCStudio without building a story. But just to organize assets. In he right side you can see the following 4 icons.

, , and

These are the folders for various types of assets. I didn't want vehicles and characters to be piled up in the same folder. So you have different folders for Characters, Vehicles, Locations and Other Assets.

Looking little below it is a folder for music and sound effects. And at the very bottom opens the project's folder.

On the left you can see a set of icons too. So let's go over them too.

adds a new Scene node to the Story Editor Space. There are 2 nodes already in the scene. They are marked Red usually. And have the titles of Start and End. If you used the Blender's node editor. There is usually an input node and an output node. Story also has a start and the end.

So in order to have a story you need to connect the Start node to the first scene node. And the first scene node to the second scene node. And this way through all the story. The last scene connect to the End node.

If any scene will be out of this "Main Chain" it will not be recognized by the Analytics. So you can have multiple drafts of any scene. And have testing scenes. And they will not effect the main story.

To enter the scene double click it.

will create a link to an asset inside the Story Editor space.

will create a link to a file inside the Story Editor space.

Now you probably gonna see that some files have an output dot. And the Assets links have input dots. These are meant for copying files into different asset's folders.

Main Asset's folder. Meant for Blend Files. References folder. Textures folder. Renders folder.

They are also buttons. Clicking on which will give you to link a file from such a folder. Dragging the file into a dot like this will copy that file over to the other folder. I was considering linking the file. But I ended up using this feature to copy over textures that I will re-paint somewhat for a different asset.

is a feature to organize the Story Editor space. It's a marking tool to mark a place so at any moment you could go to that place by clicking on it's icon. They never go off screen. They stay on the edges of the screen at all times. Making them handy.

is a feature to visually group together various elements in the Story Editor Space. Select a few elements and press this button to make a box around them. It's just a visual thing. It's similar to Frames in Blender's Node editor.

is a list of currently active animation renders. You set them up from with in the scenes.

is a list if Blend-files for video editing. Blender contains a very powerful Video Editor built in. I'm using it for the editing of my movies.

is the MultiUser window. It's used when you have more then one computer on the project.

is the settings dialogue.

The following chapter is not scary. Source code is not scary. It's Free Software here. You are free to educate yourself.

Source Code

The best documentation is to read the code of the software directly. For the story editor I recommend:

Is there any difference between Project Manager and Story Editor?

Yes. If you look closely at project_manager/pm_gtk.py and studio/studio_gtk.py you can see that most of the code is the same. But some stuff is different. Mainly because inside of the project I use a lot more stuff. A lot more rendering logic. That is just not necessary in a simple project chooser.

For example. When rendering windows on top of the main layer in project manager I still draw the main layer on each frame. Then the blur() is applied to it. Then the top layer is drawn.

To do the same inside the project when the main layer is the story editor is quite computationally expensive. In other words. It's slow. So when the current layer is not story editor. I'm not redrawing the story editor. I cash the last frame it drawn and add the blur() on top of the cashed version.

You can see it in action by resizing the window while something is drawn on top. In the Project Manager the background will resize with the window. In the studio the background will stay the same and be cut off.

Of course there are other little things like variables for project's analytics, story and other logic related to it.

How do you draw the nodes?

Short answer read this. Long answer: It's complicated. There is a block of data inside the win object. Which is actually the Gtk.Window() object. I just used the ability to assign variables to it in order to have some truly global variables. For example win.current and win.previous are all the variables that I might need to compare between 2 frames. Like for example the key presses are stored in keys in win.current. And I can know what keys were pressed on previous frame by looking in keys in win.previous.

But there are also things like win.story for example. This variable contains a very large dictionary. You can look at the /pln/story.vcss file to see what I mean. ( It's secretly a JSON file. ) This dictionary contains an entire data-base of every item in the story editor space. Names, link-types, coordinates, sizes. Everything is there. For scene. The entire scene text is also there.

To draw the nodes I iterate over for example scenes in win.story and read what name and where each is should be drawn. And send this data to the studio/studio_nodes.py. But I have to always add the camera in win.story to every coordinate. Or else travelling through the story space will not be possible. Everything will just stay static.

How do connections between nodes work?

There is a variable called arrows in win.story which stores data of connections between 2 nodes. Each node has an input and an output dot. They are rendered using the same node_dot() function. But the function is very complex. Basically if it's an output node it will record it's position on the screen into a variable called win.out_dots and when an input node comes by. It will look through the arrows in win.story see if it's connected to anything. See if this anything is in win.out_dots. And if yes. Draws a line.

Sometimes tho it finds the output dot after the input dot. And when this happens you can see slight disjointedness when traveling in the Story Editor Space.

For the logic of dragging one into another think about both of them being little tiny buttons. If you press on the output dot it will start a special operation with it's coordinates and some metadata. And if you press the input button while this operation is running. This input dot will add an instance into arrows in win.story using it's own metadata and the metadata of the output node that started the operation. It's a bit simplified. So if you want to know exactly how it works. Just read the node_dot() function.

How do events change their shape with the contents inside?

I'm using for this a little function called rectangle_surround() from UI/UI_math.py. And simplified explanation will be... There is a global variable. Some kind of list of 4 coordinates X, Y, SizeX, SizeY. This will represent either the event box. Or the selection box. Or anything like this. And you add to the function each coordinate of everything inside this box. You compare whether one is already inside the other or not. And if the thing that should be inside actually outside. We move the coordinate of the surrounding box out a little to include that object.

Now keep in mind that this is all done before a single frame is rendered and presented to the user. So from the user's perspective the surrounding box always outside of the items. But behind the scenes there were few iterations before it was outside all of the items.

How does collision of 2 rectangles work for the selection?

In order to detect intersection. Or collision of 2 rectangles I use a very primitive method. Look at rectangle_overlap() from UI/UI_math.py. Basically I'm checking two 1D lines for intersecting. The X axis of both rectangles and the Y axis of both rectangles. Look at line_overlap() from UI/UI_math.py.

I could use some math to check how far the intersection is. But I found it to be unnecessary in this application. ( Maybe I will do it eventually ). So the idea is to check whether first point of the line 0 is anywhere between the points of the line 1. If yes. Detected. If not. Check the second point. If not yet. Swap the lines and do another 2 checks. So at most for 2 rectangles I'm checking 8 times.

Are images read from the file each time?

No. They are not. Look at image() and loadimage() from /UI/UI_elements.py. There is a global variable win.images which is a dictionary of various cario surfaces. Cashed 1 time from the image files. For each cell in the dictionary. Basically the function image() is called. A filename is given to it. It looks into the dictionary and checks whether this image is there already in the given cell or not. If not. It loads the image. If yes it draws the image.

Now for images from the internet. Like ones used in the documentation. It's also checking if auto_download_images is True or False in the settings file.. If it's False it will give user a button to click. Only if a button is clicked, it will download the image and load it into the cell.

The cells are used to have multiple sizes of the same images rendered for different purposes. Like a cell for menu previews. And the cell for big images in the text. And so on. If there would be only one cell. And let's say you loaded the bigger picture first. It would not load it again for another size. It will just render the one already there. Which is not cool.

Help The Documentation

The documentation files are not perfect. And need maintenance.

If you are reading it from the VCStudio build in Documentation:

  • Press to edit locally.
  • Press to commit in our NotABug repository.

(C) J.Y.Amihud 2021. Under GPL v3 or later.