Reset the entire map?

Hello! I'm having a bit of an issue with quest, at least the desktop version, and I was hoping y'all could help. I've hit an error where when moving between maps using the TeleportTo function to save the prior map sometimes it just freezes up the map and it stops working altogether. I've been using the TeleportTo code for saving areas to leave and return to for AGES without any issue and haven't made any changes to it or anything related and it doesn't happen on the online version, only the desktop version, so I think it might just be an issue with Quest's memory or how it is with Windows 11 since I didn't have this problem on 10 rather than the code itself and this is happening with entrances I haven't touched in ages and were perfectly fine before so this isn't something I changed. Now, I love the map, it's one of my favorite things about Quest.

So I was wondering, is there a quick way to just wipe and reset the map? I was thinking of just giving the player an item they can use if the map goes hinky so they can just reset it, even if it clears the prior mapped out data, better that than just having it be broken altogether. (Or if you have any idea what's causing that/how to fix the error itself please let me know!)


Sorry I hope it's alright to bump this.


Does running Grid_Redraw again not fix it?

In that case, off the top of my head I'd suggest something like this as a way to clear the map:

game.pov.grid_coordinates = NewDictionary()
dictionary add (game.pov.grid_coordinates, game.pov.parent.name, QuickParams ("x", 0.0, "y", 0.0, "z", 0.0))
JS.Grid_ClearAllLayers ()
Grid_Redraw
Grid_DrawPlayerInRoom (game.pov.parent)

This clears out the coordinate dictionary, sets the coordinates of the current room to zero, and then redraws the map based on that.

But… how does it interact with the teleport system?

If the map is also messed up the next time you teleport to a new location, it may be necessary to clear all other coordinate systems too. To do this, you would do something like:

foreach (attr, GetAttributeNames (game.pov, false)) {
  if (StartsWith (attr, "saved_map_for_")) {
    set (game.pov, attr, null)
  }
}

If teleporting again actually fixes the map, it may be beneficial to try resetting the map to its last-saved-state rather than clearing it. In which case you could do this to try fixing a messed up map:

game.pov.grid_coordinates = NewDictionary()
dictionary add (game.pov.grid_coordinates, game.pov.parent.name, QuickParams ("x", 0.0, "y", 0.0, "z", 0.0))
foreach (attr, GetAttributeNames (game.pov, false)) {
  if (StartsWith (attr, "saved_map_for_")) {
    coords = GetAttribute (game.pov, attr)
    if (DictionaryContains (coords, game.pov.parent.name)) {
      game.pov.grid_coordinates = coords
    }
  }
}
JS.Grid_ClearAllLayers ()
Grid_Redraw
Grid_DrawPlayerInRoom (game.pov.parent)

It basically restores the map to a backup of the state it was in the last time this room was part of the map data saved when teleporting; or clears it if that doesn't help.


Other thoughts: Saving the map between teleporting might be a good idea, but it may also be adding unnecessary complexity. For many games, it would be simpler just to manually set coordinates. For example, you could put something like this in your start script instead of clearing the map every time you teleport:

zonex = 0
zoney = 0
coords = NewDictionary()

// list of rooms that you can teleport to
zones = Split("starting room;wizard's tower;banana plantation;dungeons;planet araraaargh")
zonesize = sqrt(ListCount(zones) + 1)/2
for (zonex, -zonesize, zonesize) {
  for (zoney, -zonesize, zonesize) {
    if (ListCount (zones) > 0) {
      zone = ListItem (zones, 0)
      list remove (zones, zone)
      dictionary add (coords, zone, QuickParams ("x", zonex * 250.0, "y", zoney * 250.0, "z", 0.0))
    }
  }
}
player.grid_coordinates = coords

(using a list of the room names for the places you can teleport to)
This basically puts the separate locations the player can teleport to in a grid on the map, 250 standard-room-widths apart. Most games never get anywhere close to this size with an exploreable map; so it means there's no need to save and reload different parts of the map: the other areas are on the same map, they're just so far away that the player never sees them.

If you only have one teleport destination in each area (which seems to be a prerequisite for the TeleportTo function), you could do this instead; and teleporting is as simple as moving the player to a new area.


Hello mrangel! Thank you for your help! I tried the first options to redraw the map and unfortunately none of them seem to work. They do redraw it but after attempting to move it just stays frozen, but that last option you presented very much intrigues me and I think might be a better solution. My apologies though, where exactly do I put that script? And, to make sure, this is exactly what it would look like correct? Each of the places listed in the zones would be the separate starting room for each building or area the player would otherwise TeleportTo, right?

zonex = 0
zoney = 0
coords = NewDictionary()

// list of rooms that you can teleport to
zones = Split("Intro;Your room;Treehollow_Cir;University_Gates;Math_Entrance;Science_Entrance;Art_Entrance;English_And_Social_Entrance;Administrative_Building_Entrance;Gym_Entrance;Dorms_Entrance;OGGraveyard1;SecondGraveyard1")
zonesize = sqrt(ListCount(zones) + 1)/2
for (zonex, -zonesize, zonesize) {
  for (zoney, -zonesize, zonesize) {
    if (ListCount (zones) > 0) {
      zone = ListItem (zones, 0)
      list remove (zones, zone)
      dictionary add (coords, zone, QuickParams (zonex * 250.0, zoney * 250.0, 0.0))
    }
  }
}
player.grid_coordinates = coords

Edit: So I found the Start Script tab under Game, sorry about that. However, it doesn't quite seem to have the desired effect. The areas seem to be layered almost right on top of each other. For example Intro and Your Room are only a few squares away from each other on the map and are completely visible from each other, same with the University_Gates, completely visible. Did I do something wrong?


Ooops, sorry. My bad. I missed out the keys.

Should work better:

zonex = 0
zoney = 0
coords = NewDictionary()

// list of rooms that you can teleport to
zones = Split("Intro;Your room;Treehollow_Cir;University_Gates;Math_Entrance;Science_Entrance;Art_Entrance;English_And_Social_Entrance;Administrative_Building_Entrance;Gym_Entrance;Dorms_Entrance;OGGraveyard1;SecondGraveyard1")
zonesize = 1
while (ListCount(zones) > (2*zonesize+1)^2) zonesize = zonesize + 1
for (zonex, -zonesize, zonesize) {
  for (zoney, -zonesize, zonesize) {
    if (ListCount (zones) > 0) {
      zone = ListItem (zones, 0)
      list remove (zones, zone)
      dictionary add (coords, zone, QuickParams ("x", zonex * 250.0, "y", zoney * 250.0, "z", 0.0))
    }
  }
}
player.grid_coordinates = coords

No problem! It still doesn't seem to be working though :( I copied it in exactly from your post and the areas are still showing up directly next to each other. It also gives me six instances of the error "Error running script: Error evaluating expression 'DictionaryItem(coordinates, coordinate)': The given key was not present in the dictionary." Strangely enough too, I find that the map is drawing the University Gates area specifically over the Intro area. I cannot figure out why. To explain the first part of the map: The intro goes In to "Your room", which goes Down to the rest of the house, after exploring the house, the front door goes North to Treehollow_Cir. After exploring the neighborhood one of the streets goes North to University Gates, so University Gates should be on the layer below Your Room. So weirdly the map is drawing both the Intro and the University Gates on the same upper layer as the Your Room and in the same square. I'm really at a loss.

Clarifying question though. When moving the player to one of those key locations, what script would I be using? So from the exit that would lead to University Gates, would I still be using the TeleportTo script or would I be just using the MoveObject script? I switched to just moving the player, is that why it wasn't working? I tried moving between one area that still had the TeleportTo still in place on the map and it still caused the map to freeze. Also, is there anything in particular I need to do with the Exits? Do I need to make sure the exits of the areas don't connect to anything? As it stands right now , the street and University Gates don't connect to each other but they do connect to the same dummy room to get the TeleportTo to work with the exit. Could that be causing it?


Clarifying question though. When moving the player to one of those key locations, what script would I be using? So from the exit that would lead to University Gates, would I still be using the TeleportTo script or would I be just using the MoveObject script?

You would just use MoveObject

Also, is there anything in particular I need to do with the Exits?

Like the original teleport script, this one should work so long as the player never enters a room which contains an exit leading to a different zone (because entering a room causes its exits and the rooms they lead to to be placed on the map).

I'll see if I can figure out what the problem is. I'll have to make a test game to try it out, so I'll probably wait until I've got a stable net connection. Sorry I'm not being too useful right now.


It's no problem at all, you are a massive help! It might have to do with the way the exits are set up on my end. I will try to fiddle with those exits and see if that could be part of the issue.


Okay… I tried making a test game to try it on, and got errors right away. In this case,a type error - you can't pass a double to for.

I tried using the rounding functions, which according to the documentation take a double and return an int… but they seem to actually return doubles. So instead I changed
zonesize = sqrt(ListCount(zones) + 1)/2
to

zonesize = 1
while (ListCount(zones) > (2*zonesize+1)^2) zonesize = zonesize + 1

(really you could just set it randomly; but I wanted to reduce manual stuff when you add more rooms).

In any case… it seems to work now. Except that it doesn't draw the room you just teleported into, which I can't figure out… I ended up modifying my teleport command to do it manually, which is weird, because I'm just calling the same functions that are called by OnEnterRoom.


Hmm okay so all I would need to do then to get it to work is set the teleport command to draw the room you're moved into? How would I do that? And where is the zonesize = sqrt(ListCount(zones) + 1)/2 to replace? I don't see that in the code you gave me, the more recent one already appears to have the other one set in it?


Also slight update! So I actually figured out part of why the Reset The Map function wasn't working, I was misunderstanding part of the code, but it doesn't work entirely and I think I can better explain what's happening.

So before I was using

player.parent = room
JS.Grid_ClearAllLayers ()
Grid_Redraw
Grid_DrawPlayerInRoom (game.pov.parent)

Because I didn't understand that "room" was actually supposed to be the name of a room not just the word, my bad, but that doesn't work to reset the room anywhere like I need. I tried removing just that line so I had

JS.Grid_ClearAllLayers ()
Grid_Redraw
Grid_DrawPlayerInRoom (game.pov.parent)

and it confirmed something of what I was suspecting about the error. It does reset the map correctly, but whatever is causing the error in the TeleportTo script is de-linking the player with the yellow dot, so when I hit one of the directions to move, like North, it draws the North room on the map and the player is technically moved, the correct text displays etc, however the dot on the map and the map itself does not change position, it stays as if the player had not moved, so it's drawing the map around the room instead, the player's location on the map is just frozen but it's still drawing as they move. And that's what it was doing before the reset, it's de-linking the view with the dot and drawing around it, I just couldn't see it as well. So I just need to figure out how to re-link the player on the map with the actual player's movements and that should be enough to fix it, or at least fix it after resetting it. Does that maybe help at all?

Edit: There's a line missing and the forum won't let me post it for some reason. It just says "Sorry you can't post that here" I'm going to try to break it up if I can "player. grid _coordinates = null" This would be the first line in the two above.


Sorry to bump this again but I'm still really struggling with this issue :( If I knew the function to force the map to draw the new area when the player is moved into it when using mrangel's script above I could try it out a bit further but I'm stuck on that at the moment before I can test it further. Ultimately if there was a way to re-link the player with the map that would fix everything though. Would anyone have any advice on how I can proceed?


What is TeleportTo function?
Is it from a link, or did you write out a code?
Show us the link or your code.

Why don't you just use

MoveObject (player, room3)

What are the benefits of your TeleportTo function over MoveObject?


What are the benefits of your TeleportTo function over MoveObject?

If the map is turned on, moving the player to a room which isn't connected to their current location by exits will cause odd errors, because Quest doesn't know where to put it on the map. The TeleportTo function in the documentation is an example of how to get around this problem, although it isn't perfect.

This is in a big list of projects that I need to get around to (just above fixing operator precedence for QuestScript 5.7.7's expression parser). But I've not had as much time to work on stuff lately, and it gets hard to focus with little kids running around the house screaming, so the only coding time I get is usually answering questions from my phone – not idea for larger, more complex bits of code.


Okay, so

If the map is turned on, moving the player to a room which isn't connected to their current location by exits will cause odd errors.

What I would be recommending would be something like this:

MoveObject (player, room1)
MoveObject (player, room2)
MoveObject (player, room3)

Literally spam the moveobject all the way from the player's position to the next room to thee next room until you reach that target teleport location.
I know this is terrible coding but since I cant find the TeleportTo function code and that you say the code is not pefect, this is my low-efficient workaround.

Also, make sure your rooms have exits to each other.


Found the teleport code https://docs.textadventures.co.uk/quest/showing_a_map.html
Apparently the forum search and the documentation search gives different results, so finding teleport code at forum and google leads to nothing.


Yep, that is the TeleportTo function that I am using that is causing the map to break, that is correct, daeun. The TeleportTo function is, as mrangel said, to reach areas that are not connected by exits. But unfortunately it recently causing the error where the player and map are coming unlinked with each other as I described above.

Mrangel, you mentioned that you modified your move object command to draw the room manually upon moving the player there using your new map script, how did you do that? It's of course not the end of the world if it doesn't but it is a lot better looking and more professional looking if it draws the room they're in when they're moved in rather than making them move in and out so I'd really like to do that as well so I can test out further.


The teleport command I was using for my test was simply:

game.pov.parent = object
Grid_CalculateMapCoordinates (object, game.pov)
Grid_DrawPlayerInRoom (object)

(obviously, if you were using a teleport function instead of a command, you'd probably give the parameter a more sensible name than object)

(First line moves the player; second calculates the coordinates of all the rooms adjacent to the one they're teleporting to, so that the exits can be drawn correctly; third actually draws it and moves the player dot on the map)

This shouldn't be necessary… Grid_CalculateMapCoordinates and Grid_DrawPlayerInRoom should both be called by changedparent and OnEnterRoom. I've gone through the code in my head several times, and I'm sure it should draw the room automatically, but it doesn't seem to do it.


Hi mrangel, sorry for the long delay in getting back to you, things have been chaotic. I've been working attempting things with the script and things are working a little bit better. I'm having a few issues with the initial move though for some reason. So when I use

MoveObject (player, Treehollow_Cir)
game.pov.parent = object
Grid_CalculateMapCoordinates (object, game.pov)
Grid_DrawPlayerInRoom (object)

The game gives me an error saying "Error running script: Error compiling expression 'object': Unknown object or variable 'object'" and doesn't draw the map properly. I've noticed this error happens any time I've tried to use a script that uses "game.pov.parent = object" as a part of it. Oddly enough sometimes the consecutive movements, seem to be okay and it draws the area correctly after that as long as I just use the MoveObject line and not the following three so I have no idea why. Am I doing something wrong? I feel like it's so close to being fixed there's just something I'm missing. I still need to go through and finish adjusting the exits for every single other area but the first few are promising I just don't know why some work and some don't.


That's because I was testing it with a teleport command, which introduces the variable object.
For your example, I assume it would be:

game.pov.parent = Treehollow_Cir
Grid_CalculateMapCoordinates (Treehollow_Cir, game.pov)
Grid_DrawPlayerInRoom (Treehollow_Cir)

Oh I see! I'm sorry, my lack of understanding with this sort of thing is showing! I tried that so

MoveObject (player, Treehollow_Cir)
game.pov.parent = Treehollow_Cir
Grid_CalculateMapCoordinates (Treehollow_Cir, game.pov)
Grid_DrawPlayerInRoom (Treehollow_Cir)

and it still didn't draw the new area upon moving the player there.

Also just out of curiosity to test I went ahead with this version with your game start script in place separating the areas on the same map I attempted to use the TeleportTo function and it still broke the map. I also have tried using the TeleportTo script and the last part you gave me so

TeleportTo (Treehollow_Cir)
game.pov.parent = Treehollow_Cir
Grid_CalculateMapCoordinates (Treehollow_Cir, game.pov)
Grid_DrawPlayerInRoom (Treehollow_Cir)

just to see if that might help but it still didn't.

I just want to make sure. I've got the TeleportTo script as copied out of that article, I even copied it fresh just to make sure I hadn't accidentally bumped a key or something and there were 0 changes, but do you see any errors in it?

from = player.parent
set (player, "saved_map_for_" + from.name, player.grid_coordinates)
if (HasAttribute(player, "saved_map_for_" + to.name)) {
  player.grid_coordinates = GetAttribute(player, "saved_map_for_" + to.name)
}
else {
  player.grid_coordinates = null
}
player.parent = to
JS.Grid_ClearAllLayers ()
Grid_Redraw
Grid_DrawPlayerInRoom (game.pov.parent)

I feel just so defeated, every time I think it's working for a minute it turns out to just be a momentary reprieve before it breaks again.


Sorry if I am bothering you with the following code, I am just trying to help and english is not my main language.
This tp function tps you to target location, and clears all map, is it what you are trying to do?

<!--Saved by Quest 5.8.6836.13983-->
<asl version="580">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="test">
    <gameid>57336ed3-787b-4dca-a8c8-d6811b9fd1f8</gameid>
    <version>1.0</version>
    <firstpublished>2024</firstpublished>
    <gridmap />
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <isroom />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <exit alias="east" to="room1">
      <inherit name="eastdirection" />
    </exit>
    <object name="tp">
      <inherit name="editor_object" />
      <tp type="script">
        TeleportTo (room4)
      </tp>
    </object>
  </object>
  <object name="room1">
    <inherit name="editor_room" />
    <exit alias="west" to="room">
      <inherit name="westdirection" />
    </exit>
    <exit alias="north" to="room2">
      <inherit name="northdirection" />
    </exit>
  </object>
  <object name="room2">
    <inherit name="editor_room" />
    <exit alias="south" to="room1">
      <inherit name="southdirection" />
    </exit>
    <exit alias="east" to="room3">
      <inherit name="eastdirection" />
    </exit>
  </object>
  <object name="room3">
    <inherit name="editor_room" />
    <exit alias="west" to="room2">
      <inherit name="westdirection" />
    </exit>
    <exit alias="northwest" to="room4">
      <inherit name="northwestdirection" />
    </exit>
  </object>
  <object name="room4">
    <inherit name="editor_room" />
    <exit alias="southeast" to="room3">
      <inherit name="southeastdirection" />
    </exit>
  </object>
  <verb>
    <property>tp</property>
    <pattern>tp</pattern>
    <defaultexpression>"You can't tp " + object.article + "."</defaultexpression>
  </verb>
  <function name="TeleportTo" parameters="to">
    from = player.parent
    set (player, "saved_map_for_" + from.name, player.grid_coordinates)
    if (HasAttribute(player, "saved_map_for_" + to.name)) {
      player.grid_coordinates = GetAttribute(player, "saved_map_for_" + to.name)
    }
    else {
      player.grid_coordinates = null
    }
    player.parent = to
    JS.Grid_ClearAllLayers ()
    Grid_Redraw
    Grid_DrawPlayerInRoom (game.pov.parent)
  </function>
</asl>

So, a bit more unfortunate news, mrangel. I think I figured out a solution and in the end... I think Quest just can't take it. What I did to get around the rooms not loading was I created false rooms that are the same dimensions on top of the intended entrance rooms. So a Treehollow_Cir2 The script moves the player there THEN moves the player In into Treehollow_Cir. With the alias set to " " and no visible exits in Treehollow_Cir2, no text displays so it's not noticeable to the player, just a split second longer load as they pop into Treehollow_Cir. So basically it fails to draw Treehollow_Cir2 but is corrected by being moved into Treehollow_Cir. It was a little messy and I didn't love it but it worked, so I tried it and it was working but I experimented, moved around, and unfortunately after moving between a few different areas Quest just crashes. I just don't think it can handle a map that big. Once or twice between areas it's fine with but once you're going back and forth more than that the program starts to really chug and then it just whitescreened not only the map but the whole program. So either there's something inherently broken in my map that it can't load or it just can't handle the size of the map. I've seen some pretty large maps in Quest before so I'm a bit surprised it can't handle mine. It's fairly big but not excessively complicated. I counted them and it's at about roughly around 190 rooms currently.


Hey daeun no worries, I very much appreciate your help, it's no bother! To try to clarify: I don't want to clear the map when my players teleport. I want the map to be saved so when they return (for example when they go inside a building and then back outside the building) they don't have to fill the entire map back out again which is what the TeleportTo function is supposed to do. So if that function you provided wipes the map every time they teleport but doesn't restore it, then that wouldn't be what I'm looking for.

The problem is with the TeleportTo function when they return to an area sometimes the map breaks and I'm looking for a way to either fix that issue or as an emergency fix give them the ability to reset the map altogether in that scenario, but that would only be a fix if it breaks.


Perhaps you could copy a small part of your game into a code file, to demonstrate the errors you are having so that mrangel can try multiple solutions to test on it.
But judging by your big game, I do think it is possible for quest to glitch out and that the glitch might not appear in a smaller demonstration.
Just giving my two cents, this error is beyond me :)


To be honest I wouldn't even begin to know where to start to try to create a test file. There's just so much of it and I'd have to take out such a substantial chunk of my game for a few reasons before trying to share it it'd take me hours to prepare most likely. I've been working on this game for about two years now. I certainly appreciate you though!


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums