Where is the debug map editor / how to see map coordinates?

BrainDamage on IRC tells me that it is in ESC->Debug Menu->map editor (on 0.E), but in early march checkout of git master, I see only this:
debug_menu

I haven’t found anything appropriate in --help or in Options.

I want to know where this is:

(gdb) p (('item_location::impl::item_on_map' *) this).cur 
$4 = {<visitable> = {<read_only_visitable> = {_vptr.read_only_visitable = 0x5555575db858 <vtable for map_cursor+16>}, <No data fields>}, pos_ = {static dimension = 3, x = 1847, y = 1826, z = 0}}

You need to assign a key to the debug menu entry in the Keybinding Menu to have full access to the Debug Menu.

Unless that’s not what you’re looking for?

Maybe I can provide better help if you tell me what you want to mod/change?

Thank you. That seems to have done it. Now ESC->Debug menu shows the full menu.

I’m hunting down

item_location lost its target item during a save/load cycle

which leads me to

Thread 1 "cataclysm-tiles" hit Breakpoint 1, item_location::impl::ensure_unpacked (this=0x5555594f3460) at src/item_location.cpp:114                                                                                                           
114                         debugmsg( "item_location lost its target item during a save/load cycle" );                                                                                                                                         
(gdb) bt                                                                                                                                                                                                                                       
#0  item_location::impl::ensure_unpacked (this=0x5555594f3460) at src/item_location.cpp:114                                                                                                                                                    
#1  0x0000555556468dcb in item_location::impl::target (this=0x5555594f3460) at src/item_location.cpp:99                                                                                                                                        
#2  item_location::impl::item_on_map::serialize (this=0x5555594f3460, js=...) at src/item_location.cpp:196                                                                                                                                     
#3  0x0000555556463e6f in item_location::serialize (this=this@entry=0x5555594b1ac0, js=...) at src/item_location.cpp:744                                                                                                                       
#4  0x0000555556e02658 in JsonOut::write<item_location> (v=..., this=0x7fffffffcad0) at src/json.h:700                                                                                                                                         
#5  JsonOut::write_as_array<std::vector<item_location, std::allocator<item_location> > > (container=std::vector of length 1, capacity 1 = {...}, this=0x7fffffffcad0) at src/json.h:773                                                        
#6  JsonOut::write<std::vector<item_location, std::allocator<item_location> >, (void*)0> (container=std::vector of length 1, capacity 1 = {...}, this=0x7fffffffcad0) at src/json.h:784                                                        
#7  JsonOut::member<std::vector<item_location, std::allocator<item_location> > > (value=std::vector of length 1, capacity 1 = {...}, name="targets", this=0x7fffffffcad0) at src/json.h:852                                                    
#8  player_activity::serialize (this=this@entry=0x5555594eddd8, json=...) at src/savegame_json.cpp:292                                                                                                                                         
#9  0x0000555556e07b01 in JsonOut::write<player_activity> (v=..., this=0x7fffffffcad0) at src/json.h:700                                                                                                                                       
#10 JsonOut::member<player_activity> (value=..., name="activity", this=0x7fffffffcad0) at src/json.h:852                                                                                                                                       
#11 Character::store (this=this@entry=0x5555594ed940, json=...) at src/savegame_json.cpp:972                                                                                                                                                   
#12 0x0000555556e2fb95 in player::store (this=this@entry=0x5555594ed940, json=...) at src/savegame_json.cpp:1063                                                                                                                               
#13 0x0000555556e31873 in npc::store (this=this@entry=0x5555594ed940, json=...) at src/savegame_json.cpp:1928                                                                                                                                  
#14 0x0000555556e32e08 in npc::serialize (this=0x5555594ed940, json=...) at src/savegame_json.cpp:1922                                                                                                                                         
#15 0x0000555556ded67a in JsonOut::write<npc> (v=..., this=0x7fffffffcad0) at src/json.h:701                                                                                                                                                   
#16 overmap::serialize (this=0x55555871d480, fout=...) at src/savegame.cpp:1005
#17 0x0000555556b7f6f5 in operator() (stream=..., __closure=<optimized out>) at src/overmap.cpp:4499
#18 std::__invoke_impl<void, overmap::save() const::<lambda(std::ostream&)>&, std::basic_ostream<char, std::char_traits<char> >&> (__f=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/invoke.h:60
#19 std::__invoke_r<void, overmap::save() const::<lambda(std::ostream&)>&, std::basic_ostream<char, std::char_traits<char> >&> (__fn=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/invoke.h:153
#20 std::_Function_handler<void(std::basic_ostream<char, std::char_traits<char> >&), overmap::save() const::<lambda(std::ostream&)> >::_M_invoke(const std::_Any_data &, std::basic_ostream<char, std::char_traits<char> > &) (__functor=..., 
    __args#0=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/std_function.h:291
#21 0x0000555555d3b6e2 in std::function<void (std::ostream&)>::operator()(std::ostream&) const (this=this@entry=0x7fffffffce30, __args#0=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/std_function.h:622
#22 0x0000555555d3a052 in write_to_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void (std::ostream&)> const&) (path="/home/specing/.cataclysm-dda/save/Big Plain/o.0.0", 
    writer=...) at src/ofstream_wrapper.h:36
#23 0x0000555556b8124d in overmap::save (this=0x55555871d480) at src/overmap.cpp:4498
#24 0x0000555556c0c0c2 in overmapbuffer::save (this=<optimized out>) at src/overmapbuffer.cpp:200
#25 0x0000555556125d17 in game::save_maps (this=this@entry=0x55555902c910) at src/game.cpp:3136
--Type <RET> for more, q to quit, c to continue without paging--
#26 0x0000555556144230 in game::save (this=this@entry=0x55555902c910) at src/game.cpp:3210
#27 0x0000555556144ad3 in game::quicksave (this=this@entry=0x55555902c910) at src/game.cpp:12203
#28 0x0000555556231c5d in game::handle_action (this=this@entry=0x55555902c910) at src/handle_action.cpp:2353
#29 0x00005555561778b5 in game::do_turn (this=0x55555902c910) at src/game.cpp:1507
#30 0x000055555663621d in main (argc=<optimized out>, argv=<optimized out>) at /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/include/g++-v10/bits/unique_ptr.h:173

and then

p (('item_location::impl::item_on_map' *) this).cur 
$4 = {<visitable> = {<read_only_visitable> = {_vptr.read_only_visitable = 0x5555575db858 <vtable for map_cursor+16>}, <No data fields>}, pos_ = {static dimension = 3, x = 1847, y = 1826, z = 0}}

However, it seems that these coordinates are deeper in an unexplored part of map. Not what I expected. Perhaps my gdb print command was wrong.

EDIT: no, the coordinate center is moving around… The map editor screen is not showing me the true coordinates?

If you mean the values seen in the top left corner of the map editor, these show the relative coordinates of visible, local map (from 0, 0, Z-level to 131, 131, Z-level).

If you want the absolute coordinates, you’re probably better off with Debug Menu[i]nfo...Check [g]ame state (third or forth screen).

If you need help with reading the coordinates of the different map types (overmap, local, etc.), there is a really, really lenghty explanation I’ve come up with.

Using that info, I’ve narrowed the x = 1847, y = 1826, z = 0 to

Overmap:
x = 1847 / 24 = 0’76
y = 1826 / 24 = 0’76
And the tile in that overmap tile (omt?):
x = 1847 % 24 = 23
y = 1826 % 24 = 2

The only item there is the corpse of feral human that my psycho NPCs was ordered to butcher.

The corpse did not disappear after that error. The NPC reports “completed the assigned task.” after the required time, but the corpse stays there and there are no butchery results dropped.

1 Like

I’m back at it:

(gdb) p idx
$2 = -1
(gdb) p i
$3 = (item *) 0x0

Now, how did idx become -1? The only way for that seems to be if item_location::impl::item_on_map object was initialised with a -1 index in the first place, as

(gdb) p needs_unpacking
$4 = true

The only place where that object is initialised is in deserialize() below, which is odd, given that it happens on saving.

1 Like
        "activity": {
            "type": "ACT_BUTCHER_FULL",
            "actor": null,
            "moves_left": 116780,
            "index": 0,
            "position": -2147483648,
            "coords": [],
            "coord_set": [],
            "name": "",
            "targets": [
                {
                    "type": "map",
                    "pos": [
                        -1,
                        -22,
                        0
                    ],
                    "idx": -1
                }
            ],
            "placement": [
                1847,
                1826,
                0
            ],
            "values": [],
            "str_values": [],
            "auto_resume": false,
            "monsters": []
        },
1 Like

I remembered that I’ve made two more snapshots of the save dir before encountering this debugmsg, so I went and looked at what the idx values are in these.

                    "type": "map",
                    "pos": [
                        59,
                        38,
                        0
                    ],
                    "idx": 0

and

                    "type": "map",
                    "pos": [
                        59,
                        38,
                        0
                    ],
                    "idx": 0

So the value evidently somehow became corrupted between the second and third snapshot (there were many more saves in between, naturally). I did not modify this NPC’s task during this, nor did I move the corpse.

On a side note, what do the pos values correspond to? It is not x/y mod 180.

I compared the two pieces of code and found that there was no error of any text type, so it was technically?

Connect:I see. Thank you

These two are first and second and are identical, the third is one post up.

I’ve added

    item_on_map( const map_cursor &cur, int idx ) : impl( idx ), cur( cur ) {
        if (idx == -1)
            debugmsg("Index is -1!");
    }

This produces no debug message. So it should not be corrupted on deserialisation or npc task creation. Since idx is private, it could be that the memory of this element gets overwritten by something or that something funny happens in find_index() or target(). Why does serialize() not write idx directly if idx /= -1? It goes through converting the idx to an item* and then retrieving its idx.

Now, for some reason idx = 0 in item_on_map:

(gdb) print (('item_location::impl::item_on_map' *) this).cur
$5 = {<visitable> = {<read_only_visitable> = {_vptr.read_only_visitable = 0x5555575db858 <vtable for map_cursor+16>}, <No data fields>}, pos_ = {static dimension = 3, x = 1847, y = 1826, z = 0}}
(gdb) print idx
$6 = 0

Both are valid, and the error happens when the NPC goes outside of my reality bubble.

serialize calls target(), which calls ensure_unpacked(), which calls unpack with a valid cursor and index(0). Current theory: map of that area is somehow missing.

It also looks like this is redundant: first the code uses the index to figure out which item it is referring to, then it uses that item to figure out its index.

EDIT: The NPC is ~70 tiles west and ~82 tiles north of me when error is encountered. Saving near the NPC produces no error.

Eliminating that redundancy causes the next save file to be correct, but the butchery is still not done.

At this point I’m not sure how to proceed. Adding another target() call for purpose of single-stepping results in segfault and the workaround above works (as in the “activity” tag in o.0.0 remains correct and unchanged in all but moves_left), but doesen’t (butchery not done).