Skip to content

7 - Polish

Some things I am doing as i am wrapping up this tutorial and the Dynamic Story module to ship with the next 0.30 release.

This part is going to be a bit more scattered as i am doing it on the fly as I finish the implementation.

I don't think you need to do all (or even any) of these, but it's going to be beneficial to review the process and understand the concepts.

  1. Status indication
  2. Comments
  3. Error Handling
  4. Generate story intention
  5. Defaulting to the scene_loop_init event

7.1 - Status Indication

We want to show some status indication wile the Dynamic Premise node is working.

Open the generate-premise module

Generate Premise

Looking at the stages we have Input processing at stage -1 and then Theme Generation at stage 1.

This makes stage 0 an ideal place to handle status indication.

Create a new group called Init - Stage 0 and color it yellow.

Add the following nodes to the group:

  • Emit Status
  • Stage

Emit Status

  • message: Generating a new story line...
  • status: busy
  • as_scene_message: true

Stage

  • stage: 0

Connect the nodes as follows:

  • <Emit Status>.emitted <Stage>.state

I am also dragging the existing Module Style node into this group as well, just to make it more tidy.

Init - Stage 0

Save!

Save the module.

Start the scene loop to test.

Scene loop showing status indication

7.2 - Comments

I am not going to go through all the comments i am adding, but i want to point out that you CAN in fact add comments to your modules.

Right click anywhere on the canvas and select Comment.

Then double click the comment to edit it.

Comments

7.3 - Error Handling

Right now if something goes wrong in the Generate Premise node, the status emission will stick around.

Lets fix that.

Open the generate-premise module

Generate Premise

Add a new group called Error Handling and color it red.

Add the following nodes to the group:

  • Emit Status (Conditional) x2 - Will be used to send a new status message
  • Argument - Error handlers are function definitions, we need an argument to pass the exception to
  • Unpack Exception - Unpacks the exception into a name and message
  • core/Case - Used to select which message to emit based on the exception name
  • Coallesce - Coallesce into single return value
  • Return - Return value for the error handler function (needs to be True to indicate error was caught)
  • Define Function - Defines the error handler function
  • Get Function - Retrieves the error handler function
  • Error Handler

Argument

  • name: exc

Shift + click the node title to auto-title it to exc.


Case

  • case_a: GenerationCancelled

Emit Status (Conditional) - Generation Cancelled

  • message: Generation cancelled
  • status: warning
  • as_scene_message: true

Emit Status (Conditional) - Generation Failed

  • message: Something went wrong.
  • status: error
  • as_scene_message: true

Define Function

  • name: error_handler

Shift + click the node title to auto-title it to DEF error_handler.


Get Function

  • name: error_handler

Shift + click the node title to auto-title it to FN error_handler.


Then connect the nodes as follows:

  • <exc>.value <Unpack Exception>.exc
  • <Unpack Exception>.name <Case>.value
  • <Case>.a <Emit Status (Conditional) - Generation Cancelled>.state
  • <Case>.none <Emit Status (Conditional) - Generation Failed>.state
  • <Emit Status (Conditional) - Generation Cancelled>.state <Coallesce>.a
  • <Emit Status (Conditional) - Generation Failed>.state <Coallesce>.b
  • <Coallesce>.value <Return>.value
  • <Return>.value <DEF error_handler>.nodes

  • <FN error_handler>.fn <Error Handler>.fn

Error Handling

Save!

Save the module.

Learn more about functions and error handling

Learn more about functions and error handling in the Functions and Error Handling sections of the documentation.

7.4 - Generate Story Intention

Story intention is a feature that was also added with 0.30. Its main purpose at this point is to aid the new auto-direction feature.

However since it is included in most contex, we can also use it to ensure the initial theme selection and proposed story line isn't lost past the introductory text. There is only so much information the intro text can hold.

I am doing this as the 4th stage in the Generate Premise module.

It's revisiting already learned concepts, so i won't go through the entire process. Hopefully at this point you can look at the image below and understand what is going on.

I will note that i am adding another Set State node to Stage 3 to store the template variables we generate there, just so i don't have to repeat the same nodes in Stage 4.

New set state node in stage 3

Stage 4 to generate story intention

7.5 - Defaulting to the scene_loop_init event

The user shouldn't have to manually set the scene_loop_init event for the Dynamic Premise module to work.

Good thing we can set a default.

Open the dynamic-premise module

Dynamic Premise

Find the Properties panel in the upper left corner of the node editor and expand it.

Enter scene_loop_init in the Event to listen for field.

Set default event

Save!

Save the module.

I am also noting that there are 3 unlabled inputs in that panel from the Module Property nodes we have added.

To fix this, simply set the description of each of the Module Property nodes.

Set descriptions

Save!

Save the module.

Reload the module.

Properties panel inputs now properly labeled

If we add a new Dynamic Premise node to a scene loop, we can see that the event_name property is now set to scene_loop_init by default.

Scene loop showing default event

7.6 - Final thoughts

A missing stage and some reorganization

After testing the module for a bit, i am noting that story intention should be generated before the introduction.

There could also be a benefit of adding another stage after analysis that picks and expands on one of the story line suggestions put forth by the analysis.

I will likely do this, but since none of this introduces any new concepts it will not be part of the tutorial.

You can always open up the final generate-storyline module and see how it is put together in the end.