Solarus-Games English Forum

Solarus => Development => Topic started by: Max on February 27, 2018, 04:23:51 PM

Title: Creating a respawn point on map changed?
Post by: Max on February 27, 2018, 04:23:51 PM
Hi guys!

One thing I dislike about A Link to the Past is that you have to restart at your house or the Pyramid every time you die in the overworld. In the game I'm working on, you spend quite a lot of time in the overworld doing side-quests, and I don't want to set the player back so far if they're killed. I'd like to make it so if you die, you can be taken back whatever map you're currently on.

I know if the player is transported to a new map via a destination, you can save that location for restarting. However, if you use the side of the map scrolling feature, there is no destination to go back to, so one workaround is to design my overworld so there's never any side of the map teletransporters, but I'd like to avoid that if possible.

I also tried dynamically creating a destination using game:on_map_changed() and map:create_destination(), however it seems like the game erases this destination when a gameover happens, because the hero isn't taken back to it. I had this function in my game_manager script. This was my code that doesn't seem to work:

Code (lua) Select

--Set Respawn point whenver map changes
function game:on_map_changed()
  local map = game:get_map()
  local hero = game:get_hero()
  local x, y, layer = hero:get_position()
  map:create_destination({
    name = "respawn",
    x = x, y = y, layer = layer,
    direction = hero:get_direction(),
    save_location = "yes",
    default = true,
  })


But yeah, it seems like that destination is erased whenever a gameover happens, which makes it kind of pointless. Any ideas?
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on February 27, 2018, 07:23:31 PM
This is a bit tricky, but it is doable. What I did in my switching-between-heroes feature was to save the important parameters (position, direction, etc) in some local variables, but it can be saved in savegame variables too if you want the game to automatically save the respawn position even after reseting the game.

The first (and easy) part is to save the coordinates of the position (and direction of the hero) where you entered a map. Put some good code to save the info (as you are already doing) in this event: "game:on_map_changed". You can add some restrictions to this respawning feature if you want it to work only in certain parts of the game (like the overworld) and not in others (like different floors of a dungeon). For that, you can use the world name to define some restrictions (custom map properties in Solarus v1.6 will help too).

Next, you need to respawn the hero position, but only after death. You can easily select the map where you need to respawn and call
Code (Lua) Select
hero:teleport(map_id, [destination_name, [transition_style]])
where you can see that the "destination" is optional, so don't use a destination if there is no one. Instead, change immediately the position of the hero by registering some code in the event "map:on_started" (with the multievents script). This can be used for other purposes like creating falling effects between floors, and more stuff (you can register all the functions you need if you make a clean and flexible code). To register events, use the multievents script to do it for all maps at once (i.e., register the event for the map metatable), and remember that you need to use the syntax defined in the multievents script to avoid overriding functions.
To summarise: I recommend to define a function in some script apart and register it in the event "map_METATABLE:on_started" with the multievents script.

In my second video (very old now) I show how Solarus allows switching between different heroes in different maps, wherever you left them:
https://youtu.be/mFBOuENNbIY
Title: Re: Creating a respawn point on map changed?
Post by: Max on February 28, 2018, 10:02:11 PM
Thanks Diarandor! I've got it basically working. In my game_manager script, I've used the multi events script to register a function for map:on_opening_transition_finished() to set a respawn point. Map:on_started wouldn't work because the hero would be stuck halfway into the map and couldn't move.  My code looks like this for any others interested:

Code (lua) Select

local map_meta = sol.main.get_metatable("map")
map_meta:register_event("on_opening_transition_finished", function()
    local map = game:get_map()
    game:set_value("respawn_map", map:get_id() )
    print(map:get_id().." respawn saved") --this is for testing
    local hero = game:get_hero()
    local x, y, layer = hero:get_position()
    game:set_value("respawn_x", x) game:set_value("respawn_y", y) game:set_value("respawn_layer", layer)
    game:set_value("respawn_direction", hero:get_direction())
end)


Then, when the game over event is called, I first teleport the hero to the saved map, then use map:create_destination() to make a respawn destination using the respawn data I've saved. Then I teleport the hero to this destination, refill her health, and do game:stop_game_over()



So, this basically works. There's a couple problems. The most easily solved is that this won't work for any maps that have map:on_opening_transition_finished() defined already until I go back and fix those to fit with the syntax for the multi events script, but that's easily solved.

More pressingly, this method of sending the hero back to the saved respawn point doesn't reset the map- for example, all enemies you've killed are still dead as if you've never left the map, any blocks you've pushed don't reset, they're still where you've pushed them. I can see this causing serious problems with puzzles, if you partially finish one, then die, you could easily trap yourself since it's basically as if you've never left the room. I haven't tested this much yet, but I'm pretty sure it'll break my game at some point- for example if you die during a boss battle and the room has been closed to trap you in, you'll then be locked outside and won't be able to get back in to fight.

I'm looking around to try to figure out if there's a way to reset the map. I've tried calling game:start(), which I thought would work because I call this after I teleport the hero to a destination that has {save_location = "yes"} as one of it's properties. Since being sent to a destination that saves your location should save your location, I'd assume that after that, calling game:start() would take you back to the saved location, but in my testing, it won't. It'll go back to the last destination that had that property.



For anyone following along and trying to replicate this, I'd definitely recommend just designing your maps so that if you want the respawn point to be saved, you have to transition to the new map using a destination. Doing it this way is complicated and could have been solved by just designing better upfront, haha.
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on February 28, 2018, 10:35:36 PM
Quote from: Max on February 28, 2018, 10:02:11 PM
I'm looking around to try to figure out if there's a way to reset the map. I've tried calling game:start(), which I thought would work because I call this after I teleport the hero to a destination that has {save_location = "yes"} as one of it's properties. Since being sent to a destination that saves your location should save your location, I'd assume that after that, calling game:start() would take you back to the saved location, but in my testing, it won't. It'll go back to the last destination that had that property.
I don't know what would be the best way to do this. But as a hacky workaround you can always use an empty map with a black surface above (so that nothing is shown) and make two immediate teleportations, first to the empty map, and then from there to the original map. You can make a script that makes use of this empty map only when necessary for teleportations that reset the map. Maybe @Christopho has a better and cleaner solution for this.
Title: Re: Creating a respawn point on map changed?
Post by: Max on February 28, 2018, 10:48:58 PM
I actually tried this- still didn't reset the map. Perhaps it's because I used the same script to send the hero there and send her back. The game over function went something like:

Hero:teleport(blank_map)
Hero:teleport(respawn_map, respawn_destination)

Maybe it happens so quick the engine didn't register the change?
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on February 28, 2018, 11:35:31 PM
Quote from: Max on February 28, 2018, 10:48:58 PM
I actually tried this- still didn't reset the map. Perhaps it's because I used the same script to send the hero there and send her back. The game over function went something like:

Hero:teleport(blank_map)
Hero:teleport(respawn_map, respawn_destination)

Maybe it happens so quick the engine didn't register the change?
I am not sure what the engine does with those 2 lines of code, but I think it only calls the second one. You can call "Hero:teleport(blank_map)" in your current map and "Hero:teleport(respawn_map, respawn_destination)" in your blank map. That should work.
Title: Re: Creating a respawn point on map changed?
Post by: llamazing on March 01, 2018, 02:03:47 AM
I think a simple solution to your problem would be to assign a unique world to every map. Then the default behavior would be that the player respawns at the point they entered the map, and you don't have to code anything special. Could be a problem though if you are already using the world property for something else.
Title: Re: Creating a respawn point on map changed?
Post by: Max on March 01, 2018, 03:33:01 AM
It's a nice idea, but that behavior isn't actually default. The default, on restarting the game, teleports you to the last destination entity that saved your location. It might seem like that's the last map that has a different world, but that's actually only the case if you arrive on that world via a destination entity that has "on world changed" as its save location property.

But yeah, if you only change maps via teleports to a destination (ie, not side-of-map transitions), and set a new world for every map, that will work great, and I'd definitely recommend it, haha. I might end up going back and reworking all my maps so there's point-to-destination transition instead of scrolling ones : /
Title: Re: Creating a respawn point on map changed?
Post by: llamazing on March 01, 2018, 04:29:34 AM
Quote from: Max on March 01, 2018, 03:33:01 AM
The default, on restarting the game, teleports you to the last destination entity that saved your location. It might seem like that's the last map that has a different world, but that's actually only the case if you arrive on that world via a destination entity that has "on world changed" as its save location property.

Interesting, I did not know it worked that way. In that case, Diarandor's suggestion should work.
Title: Re: Creating a respawn point on map changed?
Post by: Max on March 02, 2018, 12:25:33 AM
Quote from: Diarandor on February 28, 2018, 11:35:31 PM
I am not sure what the engine does with those 2 lines of code, but I think it only calls the second one. You can call "Hero:teleport(blank_map)" in your current map and "Hero:teleport(respawn_map, respawn_destination)" in your blank map. That should work.

I thought it would work too, but I can't seem to get it to. So, here's what I can do. I can send the hero to the blank map on gameover, then in the blank map's script, send them back to the map that has the respawn location saved. However, I can't seem to get the respawn destination entity to show up and send the hero to it.

Here's the script for the blank map:
Code (lua) Select

function map:on_opening_transition_finished()
  hero:teleport(game:get_value("respawn_map")) --this line doesn't seem to have any issues, it sends the hero to the default destination though. So let's make a destination for respawning with the info we saved earlier.
          map:create_destination({
            name = "respawn_destination",
            layer = game:get_value("respawn_layer"), x = game:get_value("respawn_x"), y = game:get_value("respawn_y"),
            direction = game:get_value("respawn_direction"), save_location = "yes",
          })
  hero:teleport(game:get_value("respawn_map"), "respawn_destination")
end


My best guess why this won't work is that the map:create_distination() method is creating this destination on the blank map. So I tried rewriting that line as:

Code (lua) Select

  hero:teleport(game:get_value("respawn_map"))
  local new_map = game:get_map()
          new_map:create_destination({
            name = "respawn_destination",
            layer = game:get_value("respawn_layer"), x = game:get_value("respawn_x"), y = game:get_value("respawn_y"),
            direction = game:get_value("respawn_direction"), save_location = "yes",
          })
  hero:teleport(game:get_value("respawn_map"), "respawn_destination")


But it still won't work. For all these, I'm getting the No such destination: "respawn_destination" error. So it seems like the map:create_destination() method isn't working as I'm expecting it to. I don't believe there's a function to get the map userdata for the map you aren't currently on, which would make sense as I'm not sure it technically exists when you aren't on it. So I'm not sure exactly how the engine is interpreting this code.

Perhaps for now I'll just leave this, maybe make some map design decisions that make things a little easier for the player, and come back to it when I've learned more.
Title: Re: Creating a respawn point on map changed?
Post by: llamazing on March 02, 2018, 01:46:35 AM
Maps are destroyed when you leave them and regenerated when you enter them again. If you put a print statement as the first line in a map script you can see that it gets called every time you enter the map. This means you can only create a destination on the current map.

What you should do is send the hero to the blank map on game over, then in the blank map script send them to the map with respawn location saved at the default destination, then as the hero enters that map (in map_meta:on_started()) create the respawn destination and redirect the hero there. The blank map would have to override the map_meta behavior.

I'm not sure if first sending the hero to a default location on the respawn map before sending them to the real destination could cause problems (like triggering things in your map script you don't want to trigger yet). From in the quest editor on every map you might have to create a dummy destination that is somewhere you can safely send the hero to initially.
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on March 02, 2018, 08:05:14 AM
As I said in my first post, the destination is OPTIONAL! You don't really need to create a new destination for this, and therefore you shouldn't.
Title: Re: Creating a respawn point on map changed?
Post by: llamazing on March 02, 2018, 02:49:25 PM
Quote from: Diarandor on March 02, 2018, 08:05:14 AM
As I said in my first post, the destination is OPTIONAL! You don't really need to create a new destination for this, and therefore you shouldn't.
It is true that is is not necessary to specify a destination in hero:teleport(), in which case the hero gets sent to the default destination. My point is that you'd have to go though each and every map to verify that sending the hero first to the default destination then moving the hero in map:on_started() to the respawn destination is not going to cause a problem. For example, there may be unintended consequences if the default destination overlaps a sensor that causes things to change on the map.
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on March 02, 2018, 03:47:33 PM
Remark: There is no need of having 1 destination in the map (the hero would teleport to the upper-left corner of the map if there is not a default one, if I remember correctly). I think that sensors and collision tests will not be activated in the process because that can only happen when the map opening transition has finished, and you would do the teleportation in the event "map:on_started" (and not in "map:on_opening_transition_finished").
Title: Re: Creating a respawn point on map changed?
Post by: Max on March 02, 2018, 09:43:22 PM
Can confirm, sensors seem to only start on_map_transition_finished().

Interestingly, I still can't get the map to create a destination based off the saved respawn data and send the hero to it. My last attempt, to summarize, altered the map:on_opening_transition_finished() meta, so that it did two things.

If game:get_value("currently_gameover") was false, it'd save your location in respawn savegame data.
If game:get_value("currently_gameover") was true, it should create a destination from the respawn savegame data and teleport you there.

Then if you die, the engine would set "currently_gameover" true, and send you to a blank map. The blank map's script would send you to the map saved for respawning, and since "currently_gameover" was true, it SHOULD then create the destination from the respawn data and send you there.... but it didn't.



Anyway, I'm starting to feel like this technique is ballooning out. The much simpler, if less elegant, method would just be to place sensors that use game:set_starting_location() to set a manually placed destination as the starting location. It would require something like:

sensor_east:on_activated()
  game:set_starting_location(map:get_id(), "respawn_destination_1")
end

sensor_wast:on_activated()
  game:set_starting_location(map:get_id(), "respawn_destination_2")
end


to be placed on every map that is reached by scrolling, but honestly for my game, that's probably not more than a dozen maps tops, and in the time I've spent trying to figure out an alternate solution, I could have used this less elegant one and gotten it done a while ago, haha.
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on March 02, 2018, 10:24:00 PM
1) Again, don't create a destination just to change the position of the hero, it is unnecessary; just use "hero:set_position(x, y, layer)" after the teleportation.
2) You shouldn't use destinations in your scripts, but instead make your script independent from them. To teleport the hero to another map, you dont need a destination (there may be no destination, and the hero would still be teleported to the upper-left corner of the map). If you force your script to use a default destination and forget to put at least 1 destination in all your maps (which is annoying and easy to forget), your game would have bugs.
3) I can send you my test project (the one with the switching system of the 3 heroes) so that you can study the scripts and take what you need (but I warn you that the code might be a bit unclean and/or complicated). If I can switch from one hero to another in different maps and save their positions and states (which is harder than what you wanna do), then you should be able to respawn wherever you want without problems. You can write me a personal message to give me your mail to send you my testing project.
4) I recommend that you create your game over menu directly in that blank map you are using (in other words, use a special map and its associated script for the game over menu). It's a bit of work, but in that way you will have your map restarted for sure after respawning. (In my test project I use a map for that.)
5) Don't use sensors or other entities. You do not need them, and your maps will get dirty. Do it with elegant code and without using entities, to keep things simple. That is the easiest way (which is not easy in any case).
Title: Re: Creating a respawn point on map changed?
Post by: Max on March 03, 2018, 04:29:43 PM
Quote from: Diarandor on March 02, 2018, 10:24:00 PM
5) Don't use sensors or other entities. You do not need them, and your maps will get dirty. Do it with elegant code and without using entities, to keep things simple. That is the easiest way (which is not easy in any case).

I know and I agree, I'd much rather do it with code- but more than that, I'd rather it worked, haha. I had forgotten about entity:set_position(), that's a useful function and should work exactly as I want! Much better than creating a destination, I just had forgotten about that method. However, I'm still having problems I don't understand.

Here's my code for my blank map. This code seems pretty straightforward, but all that's being called is hero:teleport(). Everything after that isn't called.

Code (lua) Select

function map:on_started()
  hero:teleport(game:get_value("respawn_map"))
  hero:set_position(game:get_value("respawn_x"), game:get_value("respawn_y"), game:get_value("respawn_layer"))
  print(game:get_value("respawn_x")) --for testing
  sol.audio.play_sound("secret") --for testing
  hero:set_direction(game:get_value("respawn_direction"))
end


I also tried writing this in a separate script and just having the script for the blank map requiring it. I'm at a loss here.
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on March 03, 2018, 04:40:06 PM
If you teleport the hero to a different map, the remaining code will not be called in the next map but in the current map (or maybe it is not even called). Use the "magical" multievents script and some map event to change the position in the respawning map.
Title: Re: Creating a respawn point on map changed?
Post by: llamazing on March 03, 2018, 08:15:09 PM
Something like the following should work
Code (lua) Select

--game_manager.lua
local map_meta = sol.main.get_metatable("map")
map_meta:register_event("on_started", function()
  local hero = game:get_hero()
  if game:get_value("currently_gameover") then
    hero:set_position( --move to respawn location
      game:get_value("respawn_x"),
      game:get_value("respawn_y"),
      game:get_value("respawn_layer")
    )
    hero:set_direction(game:get_value("respawn_direction"))
  else
    --save location in respawn savegame data
    local x, y, layer = hero:get_position()
    game:set_value("respawn_x", x) game:set_value("respawn_y", y) game:set_value("respawn_layer", layer)
    game:set_value("respawn_direction", hero:get_direction())
    game:set_value("respawn_map", self:get_id() )
  end
end)

-----

--blank map script
function map:on_started() --overrides the map_meta:on_started function, which is what you want
  hero:teleport(game:get_value("respawn_map"))
end
Title: Re: Creating a respawn point on map changed?
Post by: Max on March 04, 2018, 08:57:45 PM
ALRIGHT GUYS!
It works. There's a little bit of hacky stuff I had to do, which I will explain as I post what my code is. So the basic idea is this, for anyone who wants to join the conversation at the conclusion to implement a system like this:

STEP 1. Each time the player enters a map, the game will do one of two things. If the player has entered the map during normal gameplay, the game_manager script will put the player's location (x, y, layer, and map) and facing direction into savegame values. If, however, you enter the map during the respawning process, you will be moved to the saved location using hero:change_position(). It is of note that this has to be the map:on_opening_transition_finished() event, NOT map:on_started(). Part of the opening transition is moving the player actually onto the map, if you do map:on_started, the respawn location that gets saved is halfway onto the map from the edge if you entered by the side of the map. The player will be frozen halfway onto the map, although they can leave the map to reset, but anyway. You've gotta store the location data from on_opening_transition_finished.

STEP 2. Upon a gameover state, the game_manager script sets the hero's life to whatever you want (I'm using 80% full, most Zelda games do 3-4 hearts), then teleports the player to a blank map used only for respawning. Game:start() is never called, notably, because that would reset the player to the last saved DESTINATION, and often the player enters a map without using a destination, which was the whole point of this system.

STEP 3. This blank map has overriding behavior for map:on_opening_transition_finished(), because we don't want this location to be saved as a respawn point or the engine to try and move the hero to the restart position. The script for the respawn map creates a black surface (I made a menu called black screen for this) to hide what's about to happen. Then it teleports the hero to the map saved back in step one.
-HOWEVER, since we didn't specify a destination, you'll be taken to some destination on the map that's the default one, or else put at 0,0, either way, this is undesirable. So once you've been teleported there, the game_manager script will kick back in. This time, instead of saving your location (since we're in the respawning process), the game will use hero:change_position() to move the hero to the position we saved. The black screen hiding what's going on is for this purpose. Otherwise, we'd see the hero end up at some other location then be immediately moved to the saved one.
-Seeing the hero moved first to a wrong position, then the right one, could be avoided by having the hero:change_position() be called from a map:on_started() meta event instead of map:on_opening_transition_finished(). However, I just didn't want to go back and change all the syntax of everything I'd coded that already used that event, so I used the hacky method of just throwing up a black surface to hide everything. Then I take the surface away once everything is in place.




So all in all, the ingredients you'll need to recreate a system like this are:
1. game_manager script
2. a blank room
3. a menu that's a black surface to hide the untidy parts.


Game manager script:
Code (lua) Select

--Set Respawn point whenver map changes

local map_meta = sol.main.get_metatable("map")
map_meta:register_event("on_opening_transition_finished", function()

  if game:get_value("gameovering") == true then --if we're in the respawning process, move the hero to the saved position
    game:set_value("gameovering", false)
    local hero = game:get_hero()
    hero:set_position(game:get_value("respawn_x"), game:get_value("respawn_y"), game:get_value("respawn_layer"))
    hero:set_direction(game:get_value("respawn_direction"))
    require("scripts/menus/respawn_screen")
    sol.menu.stop(respawn_screen) --take away the black curtain that hides the messiness.

  else --if it's normal gameplay, not the respawning process.
    local map = game:get_map()
    game:set_value("respawn_map", map:get_id() ) --savegame value "respawn map" is this new map's ID
--    print(map:get_id().." respawn saved")
    local hero = game:get_hero()
    local x, y, layer = hero:get_position()
    game:set_value("respawn_x", x) game:set_value("respawn_y", y) game:set_value("respawn_layer", layer)
    game:set_value("respawn_direction", hero:get_direction())

  end
end)




--Game Over

function game:on_game_over_started()
  local hero = game:get_hero()
  hero:set_animation("dead")
  sol.audio.play_sound("hero_dying")
  sol.timer.start(game, 1500, game_over_stuff)
end


local function game_over_stuff()
    -- some of this is just because my game has elixers, which function like the potions from Zelda gameboy games. They'll heal you
    --when you die if you have them in your inventory.

    local elixer = game:get_item("elixer")
    local amount_elixer = elixer:get_amount()
    local hero = game:get_hero()

    if amount_elixer > 0 then --you can ignore this case if you don't have a magic potion thing system
      game:set_life(game:get_value("elixer_restoration_level"))
      hero:set_animation("walking")
      elixer:remove_amount(1)
      game:stop_game_over()
    else
      game:start_dialog("_game.game_over", function(answer)
        --save and continue
        if answer == 2 then
          game:save()
        --contine without saving
        elseif answer == 3 then
        --quit
        elseif answer == 4 then
          sol.main.exit()
        end

    game:set_value("gameovering", true) --because we're in the respawning process
    game:set_life(game:get_max_life() * .8) --this can be set to whatever you want, but you can't leave the player with no health!
    hero:set_invincible(true, 1500) --this is just a few frames of invincibility for when you're respawned.
    hero:teleport("respawn_map") --this teleports the hero to our blank map
    game:stop_game_over()

      end) --end gameover dialog choice
    end --end "if elixers" condition
end --end gameover stuff function


Script for the blank room:
Code (lua) Select

local map = ...
local game = map:get_game()
require("scripts/menus/respawn_screen")

-- Event called at initialization time, as soon as this map becomes is loaded.
function map:on_started()
    sol.menu.start(game, respawn_screen)
    hero:teleport(game:get_value("respawn_map"))
end

--This empty function is here to override the map:on_opening_transition_finished() metatable multievent.
--It keeps the game_manager script from saving a respawn location here, or trying to send the hero to the respawn location when
--the player arrives here.
function map:on_opening_transition_finished()
end



Then I've got a little menu to hide the messiness of sending the player to a map, THEN moving them to their starting location.
Code (lua) Select

respawn_screen = {}

local black_screen = sol.surface.create()
black_screen:fill_color({0,0,0})

function respawn_screen:on_draw(dst_surface)
  black_screen:draw(dst_surface)

end




So, that works! Thanks for all the help, Diarandor and llamazing!


EDIT: For anyone wishing to replicate this- spiral staircase teleports don't play nicely with this! If you're respawned back to a map you entered via spiral staircase teleport, the engine actually starts you in a wall with these and shows the animation of the hero coming up the stairs. If you're respawned using this script, you'll be started in the wall, but the engine won't know you haven't arrived there by staircase, and you'll just be stuck in the wall. Watch out!
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on March 04, 2018, 09:07:49 PM
Nice work! When will you release a demo? :P
Title: Re: Creating a respawn point on map changed?
Post by: Max on March 04, 2018, 09:35:14 PM
I'm hoping to get it out this week. You guys have been super helpful with some of the major things I've been wanting to get done first- this respawn system and a quest log. I've got maybe half a dozen little things (like, you can't read this paper on the desk in this house, this puzzle is slightly too hard) that I can fix in an hour, then there's a tavern in one town I need to finish, then it's one last playtest and last-minute balancing before I send it out.

I'm eager to get it out because I don't have it backed up anywhere currently and it's making me nervous. Anyone have advice on a best place to host a file? My google drive is pretty full of music/video production stuff, and it seems like github is most people around here's choice. Is that free?
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on March 04, 2018, 10:48:26 PM
Advice: make several videos on youtube before releasing it with your art. You can keep them hidden if you want. Those could be a partial (but nice) proof of your autorship. In any case, I am not a lawyer, but it is unlikely that someone would steal your art (one can use my own art instead, which is free and hence legal for commercial use). When you publish it, put the licenses of each file somewhere in the data folder (it is usually done in a file "license.txt").

EDIT: github is free (as in free beer, but not as in freedom, I think) and a nice place to put the data of your demo. You can use your email and other devices for backup copies, just in case your computer breaks.
Title: Re: Creating a respawn point on map changed?
Post by: llamazing on March 05, 2018, 12:58:59 AM
GitHub works well for when you want to collaborate with others on a project or track changes. It is free for public repositories (that anyone can access).
Title: Re: Creating a respawn point on map changed?
Post by: Max on May 03, 2018, 09:17:48 PM
Hey! So I thought this script was working out all great and fine, but I've encountered an issue. If you use any of the "spiral staircase" modifiers to your teleports, you can get stuck in a wall if you respawn.

The problem is this- the spiral staircase things work like this I think: they change the behavior of your teleport, so that instead of going right to the destination, the put you 16px to the right or left of your destination (in a wall), then the engine automatically moves the hero into the destination then down 16px while playing an animation to simulate the staircase thing.

The problem comes if you die in the room you entered by staircase. Since that's your respawn map, this script will send you back to wherever you entered the map. However, if you entered via spiral staircase, you technically entered the map 16px to the right or left of where the stairs (and your destination entity) are. So you'll respawn trapped in the wall, since the respawn script doesn't know if you came into the room via staircase.


So I'm wondering, is there any way to let the script know that you entered the map via spiral staircase?
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on May 03, 2018, 10:59:30 PM
It should be possible. Spiral staircase teleporters should notify to your respawn script immediately after the teleportation, and the respawn script should compute the correct respawn position: +16 pixels in the direction of the stairs.
Title: Re: Creating a respawn point on map changed?
Post by: Max on May 03, 2018, 11:10:06 PM
Okay, that makes sense. Do you know how I can get the staircase teleporters to notify my script? The only way I can think of it map:get_entities by type, getting spiral staircase types, and comparing all their coordinates to the hero's coordinate, and if any are the same, having a conditional branch that set the respawn x-value to +-16.

But that seems like an inordinately difficult way to do it, but is that the only way?
Title: Re: Creating a respawn point on map changed?
Post by: Diarandor on May 03, 2018, 11:43:16 PM
I got a new idea: use the state of the hero "stairs" together with some event: on_state_changed or on_map_changed. I'm not sure if that state is used for both types of stairs, but if so, you may need to detect the good case somehow. Maybe using the direction of the hero instead of the direction of the stairs could work too.