Difference between revisions of "Mapping script"

From Mudlet
Jump to navigation Jump to search
(Fixed syntax highlighting)
(→‎Making your own mapping script: custom speedwalking)
Line 27: Line 27:
 
''speedWalkPath'' is especially useful for making sure you're still on the path. Most Mudlet mapping scripts keep track of how many rooms along the path they have visited so far and check upon arrival into a new room to make sure it's still on the path.
 
''speedWalkPath'' is especially useful for making sure you're still on the path. Most Mudlet mapping scripts keep track of how many rooms along the path they have visited so far and check upon arrival into a new room to make sure it's still on the path.
  
That's it! From here, you'd want to build a walking script that'll send the commands to walk you along the path, along with aliases for the user to use - see the [[Manual:Lua_Functions#Mapper_Functions|Mapper API functions]] and [[Manual:Event_Engine#Mudlet-raised_events|Mudlet mapper events]].
+
That's it! (But see below if you want more.)
 +
 
 +
From here, you'd want to build a walking script that'll send the commands to walk you along the path, along with aliases for the user to use - see the [[Manual:Lua_Functions#Mapper_Functions|Mapper API functions]] and [[Manual:Event_Engine#Mudlet-raised_events|Mudlet mapper events]].
  
 
== Adding rooms ==
 
== Adding rooms ==
Line 92: Line 94:
 
for i = 0, #stubs do print(exitmap[stubs[i]]) end
 
for i = 0, #stubs do print(exitmap[stubs[i]]) end
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
= More complex speedwalking and pathfinding =
 +
 +
The built-in path finder has some limitations you need to be aware of.
 +
 +
* It can't find ways that aren't linked with exits in the map (how do you map rooms with semi-random destinations?)
 +
* It can't take special conditions into account (what if the generated path goes through a cave and you're out of lamp oil? The path to the healer goes over the mountain but your CON is depleted which is why you need the healer in the first place?)
 +
* It only finds a single unique room (what if you need the closest inn?)
 +
* It can't give you a list of the five closest shops, to pick among them.
 +
* Within a single area, it walks "towards" the destination, i.e. it walks 100 paces north to go to the destination instead of five south to the teleport / dragon / flying horse that'd take you there directly. (This limit is not as much of problem when you cross area boundaries.)
 +
* It won't generate a list of "how to go from A to B" commands if you're not in A.
 +
 +
If you want any of this, you need to write your own shortest-path algorithm. Fortunately, as of Mudlet 4.10 this is possible.
 +
 +
* Set ''mudlet.custom_speedwalk = true''.
 +
* Your ''doSpeedwalk'' script will now see different parameters:
 +
 +
<syntaxhighlight lang="lua">
 +
function doSpeedWalk()
 +
  echo("Room we're coming from: " .. speedWalkFrom .. "\n")
 +
  echo("Room you're going to: " .. speedWalkTo .. "\n")
 +
end
 +
</syntaxhighlight>
 +
 +
The forum topic [Wayfinder|https://forums.mudlet.org/viewtopic.php?f=6&t=22930&p=45930#p45930] contains an example script that implements a shortest-path-first algorithm.
  
 
[[Category:Mudlet Manual]]
 
[[Category:Mudlet Manual]]

Revision as of 02:01, 22 October 2020

Mudlet's mapper is split into two parts for the best compatibility on all MUDs - the display and functions in Mudlet, and a per-MUD Lua script that tracks where you are, allows mapping and provides aliases for using the mapper.

Existing mapping scripts

Pre-made mapping scripts are available from Mudlet forums - all topics that have the (mapping script) prefix on them.

Making your own mapping script

If you'd like to code your own mapping script, see the Mapper API and read on for a short tutorial.

To start off, create a new script that'll be included with your mapping script (can even place it into the script folder for your mapping script), and have it do:

mudlet = mudlet or {}; mudlet.mapper_script = true

This'll let Mudlet know that a mapping script is installed, so it won't bother you or whoever else installs your script with a warning that one is necessary.

Next, you want to hook into Mudlet's gotoRoom(id) function and the user clicking on a room in the visual map - for that, define your own doSpeedWalk() function. Mudlet will store the directions / special exits commands your script will need to take in the speedWalkDir table, and the room IDs you'll pass through in the speedWalkPath table:

function doSpeedWalk()
  echo("Path we need to take: " .. table.concat(speedWalkDir, ", ") .. "\n")
  echo("Rooms we'll pass through: " .. table.concat(speedWalkPath, ", ") .. "\n")
end

speedWalkPath is especially useful for making sure you're still on the path. Most Mudlet mapping scripts keep track of how many rooms along the path they have visited so far and check upon arrival into a new room to make sure it's still on the path.

That's it! (But see below if you want more.)

From here, you'd want to build a walking script that'll send the commands to walk you along the path, along with aliases for the user to use - see the Mapper API functions and Mudlet mapper events.

Adding rooms

To make your first room, do the following steps:

  • create an area with setAreaName(areaID, areaname). You can choose any areaID - if you'd like to use the IDs incrementally, see which is the latest from getAreaTable()
  • if you want the Mudlet mapper to generate roomIDs for you, get one with createRoomID(). This is an optional step
  • create your room with addRoom(roomID)
  • give the room coordinates with setRoomCoordinates(roomID, x, y, z). If you're just starting out, put it at 0,0,0 so the room is at the center of the map
  • assign your room to an area with setRoomArea(roomID, areaID)
  • and finally, call centerview(roomID) to make the map view refresh and show your new room!

Working with the mapper API

Whenever working with mapper API, keep in mind of the following things:

  • you'll want to call centerview after you do some modifications, to get to have the map render your new changes

Translating directions

Several functions in the mapper API take and return #'s for directions - and to make it easier to work with them, you can define a table that maps directions to those numbers in a script with the following:

exitmap = {
  n = 1,
  north = 1,
  ne = 2,
  northeast = 2,
  nw = 3,
  northwest = 3,
  e = 4,
  east = 4,
  w = 5,
  west = 5,
  s = 6,
  south = 6,
  se = 7,
  southeast = 7,
  sw = 8,
  southwest = 8,
  u = 9,
  up = 9,
  d = 10,
  down = 10,
  ["in"] = 11,
  out = 12,
  [1] = "north",
  [2] = "northeast",
  [3] = "northwest",
  [4] = "east",
  [5] = "west",
  [6] = "south",
  [7] = "southeast",
  [8] = "southwest",
  [9] = "up",
  [10] = "down",
  [11] = "in",
  [12] = "out",
}

Then, using exitmap[input], you'll get a direction number or a direction name. Here's an example that uses it to work out in which directions are the exit stubs available in room 6:

lua local stubs = getExitStubs(6)
for i = 0, #stubs do print(exitmap[stubs[i]]) end

More complex speedwalking and pathfinding

The built-in path finder has some limitations you need to be aware of.

  • It can't find ways that aren't linked with exits in the map (how do you map rooms with semi-random destinations?)
  • It can't take special conditions into account (what if the generated path goes through a cave and you're out of lamp oil? The path to the healer goes over the mountain but your CON is depleted which is why you need the healer in the first place?)
  • It only finds a single unique room (what if you need the closest inn?)
  • It can't give you a list of the five closest shops, to pick among them.
  • Within a single area, it walks "towards" the destination, i.e. it walks 100 paces north to go to the destination instead of five south to the teleport / dragon / flying horse that'd take you there directly. (This limit is not as much of problem when you cross area boundaries.)
  • It won't generate a list of "how to go from A to B" commands if you're not in A.

If you want any of this, you need to write your own shortest-path algorithm. Fortunately, as of Mudlet 4.10 this is possible.

  • Set mudlet.custom_speedwalk = true.
  • Your doSpeedwalk script will now see different parameters:
function doSpeedWalk()
  echo("Room we're coming from: " .. speedWalkFrom .. "\n")
  echo("Room you're going to: " .. speedWalkTo .. "\n")
end

The forum topic [Wayfinder|https://forums.mudlet.org/viewtopic.php?f=6&t=22930&p=45930#p45930] contains an example script that implements a shortest-path-first algorithm.