Lua promises

Started by alexgleason, December 03, 2018, 06:24:02 PM

Previous topic - Next topic
I've been working on animating an intro sequence for my game, and running into callback hell with movements. Eg, one movement must happen, then the next movement happens, then a timer happens, then another movement happens, etc.

I found a few Lua promise libraries:


The top one looks very promising. Anyone have experience with this? Also just wanted to share in case others find it interesting.
RIP Aaron Swartz

Not sure if it's really relevant to the topic or not, but you can have multiple movements happen simultaneously if you make each movement its own local function and then call all of them at the same time.

True, you could avoid nesting callbacks by timing the animations correctly, but at the cost of a harder-to-maintain codebase.
RIP Aaron Swartz

Dear Alexgleason,

I was also not satisfied with the look of the code when doing cinematics. And lua is not very famous for the syntax of its promises (the reserved keyword then is iritatingly unavailable). So I saw that lua had a coroutine system. That's why we upgraded solarus to support coroutines and developped an helper that allow to write cutscenes and all kind of asynchronous code without nesting callbacks.

Example :

map:start_coroutine(function()
    local options = {
      entities_ignore_suspend = {dungeon_1_entrance}
    }
    map:set_cinematic_mode(true, options)
    sol.audio.stop_music()
    audio_manager:play_sound("others/chest_open")
    local camera = map:get_camera()
    local camera_x, camera_y = camera:get_position()
    local movement1 = sol.movement.create("straight")
    movement1:set_angle(math.pi / 2)
    movement1:set_max_distance(72)
    movement1:set_speed(75)
    movement1:set_ignore_suspend(true)
    movement(movement1, camera)
    wait(1000)
    local shake_config = {
        count = 32,
        amplitude = 4,
        speed = 90
    }
    wait_for(camera.shake,camera,shake_config)
    camera:start_manual()
    camera:set_position(camera_x, camera_y - 72)
    audio_manager:play_sound("others/secret2")
    animation(dungeon_1_entrance:get_sprite(), "opening")
    map:open_dungeon_1()
    local movement2 = sol.movement.create("straight")
    movement2:set_angle(3 * math.pi / 2)
    movement2:set_max_distance(72)
    movement2:set_speed(75)
    movement2:set_ignore_suspend(true)
    movement(movement2, camera)
    map:set_cinematic_mode(false, options)
    camera:start_tracking(hero)
    game:set_value("main_quest_step", 7)
    map:init_music()
  end)


The functions movement, wait, wait_for , animation and others are injected into the execution environment of your unique callback (it has to start somewhere) which is tranformed into a lua coroutine that execute asynchronously.

I can't remember if you are developping your game on solarus-dev or the 1.5.3. But if your game's release is planned for 2019 or beyond you can develop it on the solarus 1.6 dev branch which is coroutine enabled. And we'll be happy to provide the coroutine_helper script and getting started.

Greg

PS:

I plan to adress your Joystick issue but it will be in 1.7 that will be released only god knows when... sorry.

Hi Greg,

Wow, thank you! This is extremely cool - I'm glad you've already solved it. ;D I'm still on 1.5.3 but will have to check out 1.6.

No worries about 1.7 being far away. If there's anything I really need before launch I can edit the engine myself (hooray open source!) Thanks so much for your work on Solarus.

Alex
RIP Aaron Swartz

Nice, you can take a look at the changelog.txt in the solarus repo if you are interested in the new features of Solarus 1.6. Like shaders, sprite rotations , scale and more.

And customs states, multiple tilesets, more customization for dynamic tiles (frame number and speed), customization for the hero sprites,...
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."