Visual Novel Animations – BB – Update 14

close upVisual Novel Animations – BB – Update 14close up

Posted: March 17, 2025

Last Updated: March 17, 2025

Visual Novel Animations – BB – Update 14

Timeframe: February 25, 2025 – March 7, 2025

!!! Jump to Visual Demos !!!

I bring you tidings of bullet hell updates! Like updates 10 & 11, this and the next update will come out in pretty quick succession to one another. Again, this is because I covered 2 pretty distinct things over the past (3-ish?) weeks: visual novel animations and modding (again…).

OVNS ANIMATIONS:

teaser

Animations:

You can now define and invoke simplified, CSS-style animations on your VN’s sprites. Define an animation by sandwiching “keyframes” between <<start_animation>> and <<end_animation>> blocks. Invoke animations with the <<animation>> directive and apply various arguments to change how the animation is invoked.

Keyframe Attributes:

A keyframe represents the state of the sprite/image at a specific timepoint through the animation. Additionally, a keyframe consists of a percentage (the point during the animation when the sprite should achieve that keyframe’s state), and various sprite attributes reflecting the desired image state at that point.

  • width : The width of the sprite. Use dimensions.
  • height : The height of the sprite. Use dimensions.
  • x : The x position of the sprite. Use dimensions.
  • y : The y position of the sprite. Use dimensions.
  • color : The base color of the sprite. Define this as a vector of 4 values between 0 and 1.
// Example animation definitions:

// Stretches and squashes a sprite
// to first be wider and shorter
// and then taller and thinner before
// going back to its original size.
<<start_animation>> stretchnsquash
    0%:     width:100%o height:100%o
    33%:    width:130%o height:70%o
    66%:    width:70%o height:130%o
    100%:   width:100%o height:100%o
<<end_animation>>

// Cycles through different color
// hues on the sprite.
<<start_animation>> hue_cycle
    0%:         color:"1,0,0,1"
    16.67%:     color:"1,1,0,1"
    33.33%:     color:"0,1,0,1"
    50%:        color:"0,1,1,1"
    66.67%:     color:"0,0,1,1"
    83.33%:     color:"1,0,1,1"
    100%:       color:"1,0,0,1"
<<end_animation>>

Animation Invocation:

After defining an animation with keyframes, you need to invoke the animation on a sprite slot to actually use it.

  • key : Required. The name of the animation to play.
  • slot : Required. The sprite slot key to which you want to apply the animation.
  • time : Required. The amount of time the animation lasts per repetition.
  • block : The trigger block type.
    • ‘none‘ : Default. Does not block execution of following directives.
    • ‘auto‘ : Blocks execution of following directives while the animation is playing. Once the animation is over, execution proceeds automatically to the next directive.
    • ‘wait‘ : Blocks execution of following directives while the animation is playing. Once the animation is over, it remains blocked until the user provides input.
  • interrupt : Boolean. If true, then running this animation will auto-finish any animations currently playing on the target sprite slot before beginning. If false, this animation applies on top of any current animations.
  • reset : Boolean. Whether the sprite slot should revert to its pre-animation state at the end of the animation.
  • repeat : An integer describing how many times the animation should repeat. Default is 1.
  • repeatType : How the animation repeats.
    • ‘loop‘ : Default. The animation starts over from the beginning at the start of each repetition.
    • ‘reverse‘ : The animation regresses in the opposite direction once it finishes. This causes the animation to take twice as long for one repetition.
  • ease : Which preset ease function to apply to the animation fraction.
    • ‘linear‘ : Default. The output value follows the form f(input) = input.
    • easeInOutCubic‘ : A function that makes the animation slower at both ends and faster in the middle.
    • easeInOutElastic‘ : Like easeInOutCubic except with some elastic properties.
    • easeInQuint‘ : A function that starts slow and speeds up at the end.
    • easeOutQuint‘ : A function that starts fast and slows down at the end.
  • delay : The amount of time to wait before the animation initially starts.
  • repeatDelay : The amount of time to wait between each repetition of the animation.
// Example setup and invocations:

// Set up the sprites
<<sprite>> slot:custom_slot1 key:gregg_casual flip:autox color:1,1,1,1 size:60%v,60%v pos:10%h,0
<<sprite>> slot:custom_slot2 key:gregg_blank flip:autox color:1,1,1,1 size:60%v,60%v pos:90%h,0
<<sprite>> slot:custom_slot3 key:gregg_casual flip:autox color:1,1,1,1 size:60%v,60%v pos:40%h,0
<<sprite>> slot:custom_slot4 key:gregg_blank flip:autox color:1,1,1,1 size:60%v,60%v pos:60%h,0
<<sprite>> slot:custom_slot5 key:gregg_casual flip:auto color:1,1,1,1 size:60%v,60%v pos:25%h,100%v
<<sprite>> slot:custom_slot6 key:gregg_blank flip:auto color:1,1,1,1 size:60%v,60%v pos:75%h,100%v

// Call a color-cycling animation on 2 of them.
<<animation>> key:hue_cycle slot:custom_slot1 time:2 repeat:1000 delay:3 interrupt:true repeatType:loop block:none
<<animation>> key:hue_cycle slot:custom_slot2 time:2 repeat:1000 delay:3 interrupt:true repeatType:loop block:none
// Call a stretch & squash animation on another 2.
<<animation>> key:stretchnsquash slot:custom_slot3 time:0.8 repeat:1000 delay:3 interrupt:true repeatType:loop block:none ease:easeInOutCubic
<<animation>> key:stretchnsquash slot:custom_slot4 time:0.8 repeat:1000 delay:3.4 interrupt:true repeatType:loop block:none ease:easeInOutCubic
// Call both animations on the last 2.
<<animation>> key:hue_cycle slot:custom_slot5 time:2 repeat:1000 delay:3 interrupt:true repeatType:loop block:none
<<animation>> key:hue_cycle slot:custom_slot6 time:2 repeat:1000 delay:3 interrupt:true repeatType:loop block:none
<<animation>> key:stretchnsquash slot:custom_slot5 time:0.8 repeat:1000 delay:3.4 interrupt:false repeatType:loop block:none ease:easeInOutCubic
<<animation>> key:stretchnsquash slot:custom_slot6 time:0.8 repeat:1000 delay:3 interrupt:false repeatType:loop block:none ease:easeInOutCubic

New Directives:

  • <<reset_slots>>: You now pass in slot keys which you want to reset.
  • <<reset_all_slots>>: Now resets all slots and deletes all custom sprite slots.
  • <<stop_animations>>: Pass in slots for which you wish to stop all running animations.
  • <<start_animation>>: Start parsing animation keyframes.
  • <<end_animation>>: End parsing animation keyframes.
  • <<animation>>: Invokes a named animation on a sprite slot along with other invocation arguments.

Dimensions:

A minor but important change was the addition of Dimensions. These just provide a better way to define position and size on the screen with options that allow for scaling based on screen dimensions and other relative size options. Read more in the documentation here.

OVNS Builder Animation Blocks:

While I was at it, I added the relevant animation blocks to the OVNS builder. I made two new blocks:

  • Define Animation Block: Provides an editor that allows the user to add/remove keyframes and edit the sprite attributes at each keyframe.
  • Invoke Animation Block: Provides an editor for invoking an animation on a sprite slot similar to the settings block.
keyframe_editor
invocation

Miscellaneous:

  • Changing a sprite in a builder now registers as an undo-able action.
  • Changed the kill system order so that things are still visible on the frame they are killed.
  • Upgraded my VN trigger system a little bit:
    • IRunningTrigger: A new interface that represents arbitrary blocking triggers. Check if a trigger is done with internal logic, force trigger completion, or reset trigger state.
    • AnimationRunningTrigger: An IRunningTrigger to interface between TriggerControl and SpriteSlots. Animations call AnimationRunningTrigger.Complete() to indicate that the animations are no longer blocking.
    • TriggerControl: Updated to check the blocking trigger for its ‘done’ status and has options for continued blocking based on user input.
  • OVNS Builder now allows a few more keyboard controls (ESC) to make things nicer to use. “New-on-output” hotkey pulls up block search and autoconnects new block to the last selected block.
  • RepositionInsideScreen bugfix fixes tooltips and block search panel.
  • Asset selection button on some settings. When you need to select an asset (sprite, font, audio clip,…), you previously needed to know the key for that asset and manually type it in. Now, you can click the asset selector and browse for an asset, and it should return the valid key (if the file is already registered in an asset map) or just the path to the file.

Video Demos

I’ve been putting images throughout my recent posts rather than having a specific demo section. I think it’s nice for breaking up big text walls. Let me know what you think about it.