MovieWriter in Godot – Complete Guide

Unlocking Creative Potential with Godot’s MovieWriter

Are you an aspiring game developer or hobbyist looking to harness the power of Godot 4 to create engaging game content that can be shared with the world? Whether it’s for showcasing your game’s highlights or creating trailers for promotional purposes, learning how to use Godot’s MovieWriter class will give you the tools to record high-fidelity video footage directly from your projects.

Recording gameplay or in-engine footage isn’t just about pressing a button and hoping for the best. It’s an art that requires understanding the tools at your disposal. The MovieWriter class in Godot 4 enables developers to capture the essence of their game with perfect frame pacing, independent of their hardware capabilities, ensuring that your captured content is just as you intended it to be.

What is MovieWriter?

MovieWriter is an abstract class in the Godot 4 game engine that facilitates non-real-time video recording. This class helps developers record high-quality videos by forcing a consistent delta in Node._process functions across frames. This functionality is crucial for anyone looking to create videos with consistent pacing, which may not be possible with ordinary real-time screen recording software.

What is it used for?

MovieWriter is versatile and can be used for a variety of purposes:

  • To create promotional content such as trailers or gameplay highlights.
  • To capture footage for video tutorials demonstrating gaming concepts or features.
  • For developers to record and review gameplay sessions with a focus on performance analysis.

Why Learn MovieWriter?

Learning to use the MovieWriter class in Godot 4 offers several advantages:

  • Control Over Quality: You get to set the quality of the video to ensure that it meets the standards required for your project.
  • Flexibility: It supports various formats and can be extended for custom requirements using GDExtension.
  • Perfect Frame Pacing: Ensure your recorded content is free from inconsistencies, regardless of hardware performance constraints.

Besides its built-in features, the potential to create custom movie writers for different formats and needs stands out as a solid reason for game developers to learn and understand the MovieWriter class. You now have the means to produce professional-looking gameplay videos that can captivate an audience and perhaps even play a part in the success of your game!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Setting Up Your Scene for MovieWriter Recording

Before you dive into recording with MovieWriter, you’ll need to set up your scene properly. We’ll start by creating a basic setup to ensure we’re on track. Here’s how you can initiate your scene for recording:

extends Node

var movie_writer

func _ready():
    movie_writer = MovieWriter.new()
    movie_writer.set_format(MovieWriter.FORMAT_WEBM)
    movie_writer.set_video_bitrate(8000000) # 8 Mbps
    movie_writer.set_audio_bitrate(160000) # 160 Kbps
    movie_writer.set_output_path("user://my_movie.webm")

This simple code snippet lays the foundation for our MovieWriter. We’re creating a new instance, configuring the output format, setting video and audio bitrates, and specifying the output path for our recording.

Controlling Recording Sessions

Next, let’s look at how you can start and stop the recording process. This is essential to capture the exact moments you want in your video:

# Start recording
movie_writer.start()

# ... Your game logic goes here ...

# Stop recording
movie_writer.stop()

The start() method begins the recording session, and the stop() method ends it. Place game logic in between these calls to capture your scene’s action.

Ensuring Smooth Frame Capturing

A unique feature of MovieWriter is the ability to ensure each frame is captured consistent with the others, for that professional feel. Here’s how you do that:

var frame_length = 1.0 / 60.0 # 60 FPS

func _process(delta):
    movie_writer.force_next_frame(frame_length)

With this approach, we enforce a consistent frame duration for our video, regardless of the actual rendering time per frame.

Adding Audio to Your Recordings

What’s a video without sound? With MovieWriter, adding game audio is straightforward. Here’s a code snippet on how to include audio in your recordings:

# Assuming you have an AudioStreamPlayer with an id 'game_music'
var game_music = $game_music

func _process(delta):
    if game_writer.is_recording():
        movie_writer.add_audio_frame(game_music.get_audio_frame())

By using the add_audio_frame() method, you can incorporate the current audio frame from your AudioStreamPlayer into the movie. Repeat this for each audio sample you want to include while recording.

Monitoring Recording Progress

You might want to keep track of your recording status. This could be essential for long gameplay sessions or when you are capturing footage that requires precise timing:

func _process(delta):
    if movie_writer.is_recording():
        print("Currently recording... Frame: %s" % movie_writer.get_frame_count())
    else:
        print("Not recording.")

Using is_recording() helps you determine if a recording session is active, and get_frame_count() provides the total number of frames recorded, giving you a clear sense of your recording progress.

These basics should give you a solid foundation to start capturing your game scenes with Godot’s MovieWriter. Stay tuned for the next part, where we’ll dive into more advanced usage and troubleshooting tips to ensure a smooth recording process.

Advanced MovieWriter Techniques

To get the most out of MovieWriter, let’s explore some advanced techniques to fine-tune your video output.

Customizing Video Settings

First, consider the resolution and frame rate of your video. Higher resolutions and frame rates usually mean better quality but also larger file sizes. You can set these parameters as follows:

movie_writer.set_video_resolution(1920, 1080) # Full HD resolution
movie_writer.set_frame_per_second(60)            # 60 FPS for smooth motion

Managing Recordings Programmatically

Sometimes you might want to handle recordings based on in-game events or actions by the player. Let’s create a toggle function to control the recording process with a button press:

func _input(event):
    if event.is_action_pressed("toggle_recording"):
        if movie_writer.is_recording():
            movie_writer.stop()
        else:
            movie_writer.start()

Now, by mapping “toggle_recording” to a button, you can start and stop the recording during gameplay. This flexibility is ideal for capturing spontaneous or unplanned events.

Using MovieWriter with Scene Transitions

Capturing footage over scene transitions can be a bit tricky, as you want the recording to be seamless. This requires coordination between scenes:

func _on_SceneTree_scene_changed():
    if movie_writer.is_recording():
        movie_writer.force_next_frame(frame_length)

# Connect this callback to the SceneTree's 'scene_changed' signal.
get_tree().connect("scene_changed", self, "_on_SceneTree_scene_changed")

By enforcing the next frame after a scene change, you prevent recording hiccups that could occur during the transition.

Encoding Custom Meta Data

You can encode custom data into your video file. This could come in handy for analytics, debugging, or as an easter egg for players:

movie_writer.set_meta_data("author", "Your Name")
movie_writer.set_meta_data("game_version", "1.0.0")

These meta tags do not impact the visual or audio output but are stored within the file’s properties.

Automated Scene Recording

If you need to record specific scenes automatically (e.g., for a trailer), you can start MovieWriter when the scene loads and stop it after a certain duration or condition:

func _ready():
    movie_writer.start()
    # Start a timer to stop recording after 10 seconds
    var timer = Timer.new()
    timer.wait_time = 10.0
    timer.one_shot = true
    timer.connect("timeout", self, "_on_Timer_timeout")
    add_child(timer)
    timer.start()

func _on_Timer_timeout():
    movie_writer.stop()

With this approach, every aspect of the recording can be scripted and controlled, providing consistency across multiple takes or scenes.

These examples should equip you with a toolkit to effectively leverage MovieWriter in Godot 4 for your video recording needs. Remember to experiment with these functions, and don’t be afraid to delve into the class documentation for even deeper customization.

Stay creative, and enjoy showing off your Godot creations with the power and flexibility of MovieWriter!When creating in-depth tutorials or gameplay videos, customization is key. Let’s explore additional code examples that will give you more control and options when utilizing Godot’s MovieWriter for your game development projects.

Manipulate Recording Speed

Perhaps you want to record a slow-motion video or a time-lapse. You can easily control the speed of the recording like this:

var slow_motion_factor = 0.5  # Half the normal speed
var time_lapse_factor = 4.0   # Four times the normal speed

# Use in the _process function to either slow down or speed up the video recording
func _process(delta):
    if movie_writer.is_recording():
        movie_writer.force_next_frame(frame_length * slow_motion_factor)
        # or for time-lapse
        # movie_writer.force_next_frame(frame_length / time_lapse_factor)

Capture Conditional Gameplay Moments

For more dynamic recordings, you may only want to capture specific moments in gameplay, like a high score achievement or an epic boss fight. Here’s an example of how to handle conditional recording:

func _on_BossDefeated():  # A signal emitted when a boss is defeated
    movie_writer.start()
    yield(get_tree().create_timer(5.0), "timeout")  # Record for the next 5 seconds
    movie_writer.stop()

Adding Visual Effects During Recording

Create more engaging videos by adding visual effects or transitions right before recording a frame. The following snippet demonstrates how to fade in from black at the start of a recording:

# Assume there's a ColorRect node covering the entire screen with a black color
var fade_in = $ColorRect

func _ready():
    fade_in.material.set_shader_param("alpha", 1.0)
    fade_in.animate_property("material:shader_param/alpha", 1.0, 0.0, 1.0, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
    movie_writer.start()

# Adjust your _process function to cover the fade-in duration
func _process(delta):
    if movie_writer.is_recording():
        # Record the frame after the fade-in effect has completed
        if not fade_in.is_visible():
            movie_writer.force_next_frame(frame_length)

Handling GUI Elements in Recordings

There might be moments where you’d prefer not to record the GUI or only specific elements of it. Here’s how you can toggle the visibility of GUI layers during recording:

func _toggle_GUI_visibility():
    var gui_layer = get_node("GUI")
    gui_layer.visible = not gui_layer.visible

# Call this function based on user input or game events, so the GUI is hidden before recording
_toggle_GUI_visibility()
movie_writer.start()
# ... Your game event
movie_writer.stop()
_toggle_GUI_visibility()

Stitching Multiple Recordings Together

If you’re creating a montage or a highlight reel, you might end up with several video fragments that you want to stitch together. We handle this programmatically by setting up a queue of recordings:

var recording_queue = []
var current_recording = 0

func _start_next_recording():
    if current_recording < recording_queue.size():
        movie_writer.set_output_path(recording_queue[current_recording]["path"])
        yield(get_tree().create_timer(recording_queue[current_recording]["duration"]), "timeout")
        current_recording += 1
        _start_next_recording()
    else:
        print("All recordings completed")

# Add the recordings to the queue
recording_queue.append({"path": "user://recording1.webm", "duration": 5.0})
recording_queue.append({"path": "user://recording2.webm", "duration": 10.0})

# Begin the recording sequence
_start_next_recording()

These advanced techniques should further your ability to create dynamic, high-quality videos for showcasing your Godot projects. Remember to test different configurations and parameters to find the best setup for your specific needs. With Godot’s MovieWriter, your options for game development and presentation are as limitless as your creativity!

Continue Your Game Development Journey with Zenva

Now that you’ve got a taste of what Godot’s MovieWriter can do to enhance your game development skill set, remember that this is just the beginning. To take your knowledge to the next level and explore the vast opportunities within game development, our Godot Game Development Mini-Degree is the perfect next step.

Dive into a comprehensive curriculum that covers all things Godot, from the basics of using 2D and 3D assets, to scripting with GDScript, and mastering gameplay mechanics for a variety of game types. Our collection of self-paced online courses, complete with flexible learning materials, will guide you through creating your own cross-platform games. Whether you’re beginning your journey or looking to sharpen your existing skills, there’s something for everyone.

Expand your horizons even further with our broader range of Godot courses. At Zenva, we provide over 250 courses to support your aspirations—from becoming an indie game developer to breaking into the professional gaming industry, we’re here to help you every step of the way. Remember, learning is a continuous adventure, and with Zenva, you’re well on your path from beginner to professional. Keep creating, keep learning, and let your passion for game development flourish!

Conclusion

Embarking on the path of game development is an adventure filled with creative challenges and the joy of bringing your visions to life. The powerful capabilities of Godot’s MovieWriter demonstrate just how far you can push the boundaries of game development, enabling you to capture and showcase your work in the best light possible. Remember, each new tool you learn not only enhances your current project but also equips you with the skills to build the games of tomorrow.

At Zenva, we’re committed to helping you become the game developer you aspire to be. You’ve already taken the leap by exploring the possibilities of MovieWriter—why stop there? Continue to level up your skills with our Godot Game Development Mini-Degree and join a community of like-minded individuals who share your passion for game creation. Let’s turn those game development dreams into reality, one frame at a time!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.