Monarch Screen Manager for Defold

repository·master·Indexed 42 days ago

https://github.com/britzl/monarch

A screen manager for the Defold game engine that manages a stack of screens with support for popups, transitions, and input focus management. It provides tools for navigating screen hierarchies via monarch.show(), monarch.back(), and monarch.replace(), as well as support for preloading screens and managing collection proxies and factories.

Tokens
5.5K
Snippets
12
Records
22
Agent score
53%

What's inside Monarch

  1. How transitions work in Monarch

    master

    By default, screen navigation in Monarch is instant. You can add optional transitions to make navigation smoother. When a transition is defined for a screen, Monarch will wait for the transition to complete before proceeding with the navigation sequence.

    Transitions are configured using monarch.on_transition(screen_id, fn). The callback function fn must accept (message_id, message, sender) as arguments. The message_id determines which type of transition to start:

    • monarch.TRANSITION_SHOW_IN
    • monarch.TRANSITION_SHOW_OUT
    • monarch.TRANSITION_BACK_IN
    • monarch.TRANSITION_BACK_OUT

    Crucial: Once your transition animation is finished, you must send a monarch.TRANSITION_DONE message back to the sender to notify Monarch that it can continue the navigation.

    monarch.on_transition("my_screen", function(message_id, message, sender)
        -- Start animation based on message_id
        -- ... animation logic ...
        -- When finished:
        sender.send(monarch.TRANSITION_DONE, { transition = message_id })
    end)
  2. How screen nesting works

    master

    Monarch supports nested screens (where a parent screen contains sub-screens/children, such as specific popups).

    Constraint: Nesting is only supported when the parent screen is created via a collection factory. If the parent screen is loaded via a collection proxy, sub-screens will not be able to receive input.

  3. How popups affect the screen stack

    master

    Popups are screens flagged with the Popup property. They change how the stack behaves:

    1. Popup on normal screen: The current top screen remains visible in the background and is not unloaded.
    2. Popup on popup:
      • If the new popup has Popup on Popup set to true, the underlying popup remains visible.
      • If Popup on Popup is false, the underlying popup is closed/removed.
    3. Normal screen on popup: If a non-popup screen is shown on top of one or more popups, all existing popups are removed from the stack.
  4. Use the Monarch Editor Script

    master

    Monarch includes an editor script to automate the creation of screen files.

    • Create a screen: Right-click a .gui, .gui_script, or .collection file in the outline and select the Monarch menu item. This creates the other two file types with the same name and sets up the basic boilerplate (adding the GUI script to the GUI scene, and the GUI scene to the collection).
    • Create from directory: Right-click an empty directory to create all three Monarch files inside it.
    • Custom Templates: You can use your own custom Defold templates by adding their path to your game.project file.
  5. Handle window resizing in transitions

    master

    When using dynamic screen orientation or resizable windows, you must manually notify your transition instance of window size changes so it can adapt its layout/positioning. Use the window_resized(width, height) method on your transition instance.

    local transitions = require "monarch.transitions.gui"
    
    function init(self)
        self.transition = transitions.create(gui.get_node("root"))
    end
    
    function on_message(self, message_id, message, sender)
        if message_id == hash("my_resize_message") then
            self.transition.window_resized(message.width, message.height)
        end
    end
  6. Use predefined GUI transitions

    master

    Monarch provides a monarch.transitions.gui module to easily set up common transitions for GUI nodes. You can create a transition instance and chain methods to define how a screen enters, exits, or returns.

    To apply transitions to a specific screen, use monarch.on_transition(screen_id, transition_instance).

    Predefined transition types:

    • slide_in_right, slide_in_left, slide_in_top, slide_in_bottom
    • slide_out_right, slide_out_left, slide_out_top, slide_out_bottom
    • scale_in, scale_out
    • fade_in (alpha 0.0 -> 1.0)
    • fade_out (alpha 1.0 -> 0.0)

    Common transition sets:

    • transitions.in_right_out_left(node, duration, [delay], [easing])
    • transitions.in_left_out_right(node, duration, [delay], [easing])
    • transitions.in_left_out_left(node, duration, [delay], [easing])
    • transitions.in_right_out_right(node, duration, [delay], [easing])
    • transitions.fade_in_out(node, duration, [delay], [easing])
    local transitions = require "monarch.transitions.gui"
    local monarch = require "monarch.monarch"
    
    function init(self)
        local transition = transitions.create(gui.get_node("root"))
            .show_in(transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
            .show_out(transitions.slide_out_left, gui.EASING_INQUAD, 0.6, 0)
            .back_in(transitions.slide_in_left, gui.EASING_OUTQUAD, 0.6, 0)
            .back_out(transitions.slide_out_right, gui.EASING_INQUAD, 0.6, 0)
    
        monarch.on_transition("foobar", transition)
    end
  7. Install Monarch in Defold

    master

    To use Monarch in your Defold project, add it as a library dependency in your game.project file. Under the dependencies field in the project section, add the following URL:

    https://github.com/britzl/monarch/archive/master.zip

    You can also point to a specific release ZIP file from the Monarch releases page.

  8. Navigate the screen stack

    master

    Manage navigation history and stack state using the following methods:

    • monarch.back([options], [data], [callback]): Goes back to a previous screen. Supports sequential (boolean) in options to wait for the current screen to transition out. Can pass data to the previous screen.
    • monarch.clear([callback]): Clears the entire stack. Visible screens are hidden by navigating back out of them.
    • monarch.top([offset]): Returns the screen_id (string|hash) at the top of the stack. Use a negative offset (e.g., -1) to get the previous screen.
    • monarch.bottom([offset]): Returns the screen_id (string|hash) at the bottom of the stack. Use an offset to get a screen relative to the bottom.
    • monarch.is_top(screen_id): Returns true if the specified screen is at the top of the stack.
    -- Go back to the previous screen
    monarch.back({ sequential = true }, { return_reason = "exit_menu" })
    
    -- Get the current top screen
    local current = monarch.top()
    
    -- Clear everything
    monarch.clear()
  9. Go back to a previous screen with monarch.back()

    master

    To navigate back in the screen hierarchy, you can post a back message to the screen script or call monarch.back(). This removes the topmost screen from the stack.

    Options for monarch.back()

    • callback: An optional function invoked when the transition_back_in transition completes.
    monarch.back()
  10. Preload and unload screens

    master

    To avoid loading delays for heavy content, you can preload screens into memory without making them visible.

    monarch.preload(screen_id, [options], [callback])

    Loads a screen but does not enable it.

    • options: keep_loaded (boolean) - If true, Monarch keeps the screen preloaded even after a hide() or back() event that would normally unload it.
    • callback: Called when preloading is complete.

    monarch.is_preloading(screen_id)

    Returns true if the screen is currently preloading.

    monarch.when_preloaded(screen_id, callback)

    Registers a callback to be invoked once a specific screen has finished preloading.

    monarch.unload(screen_id, [callback])

    Manually unloads a preloaded screen. Preloaded screens are automatically unloaded when hidden, but this allows manual unloading without hiding.

    -- Preload a heavy level screen
    monarch.preload("level_1", { keep_loaded = true }, function()
        print("Level 1 is ready in background")
    end)
    
    -- Wait for preloading to finish
    monarch.when_preloaded("level_1", function()
        monarch.show("level_1")
    end)
  11. Retrieve screen data and state

    master

    Methods for inspecting the current state of the Monarch system:

    • monarch.data(screen_id): Returns the data table associated with a screen (passed during show() or back()).
    • monarch.screen_exists(screen_id): Returns true if the screen exists.
    • monarch.is_visible(screen_id): Returns true if the screen is currently visible.
    • monarch.is_busy(): Returns true if Monarch is currently in the middle of showing or hiding a screen.
    • monarch.is_preloading(screen_id): Returns true if the screen is in a preloading state.