Generic Mapping Script

All and any discussion and development of the Mudlet Mapper.
User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Generic Mapping Script

Post by Vadi »

Yeah that's where the hard part of writing a mapper script comes in.

If you get "Table: 08DB9345", try doing display(mytable) then, it'll render the contents of the table for you! Otherwise print(mytable) will just show what you see.

If your MUD supports no wrapping (called screenwidth 0 in some) which would allow Mudlets triggers to run on unwrapped lines and do the linewrapping itself (a godsend), then we could just capture the next line after exits since that'll be the first description. Would that work?

GErswin
Posts: 17
Joined: Fri Jun 09, 2017 6:12 am

Re: Generic Mapping Script

Post by GErswin »

I have these two options, but changing them doesn't seem to do anything.
46H 71V 1499X 0.00% 0C Exits:N> help options columns
Format: OPTIONS COLUMNS <number>

This is one of the two options that allow you to control your display size.
The number listed is the amount of characters sent to you before the line
is wrapped (how "wide" the text is). The default is 80 columns per line.

46H 71V 1499X 0.00% 0C Exits:N> help options lines
Format: OPTIONS LINES <number>

This is one of the two options that allow you to control your display size.
The number listed is the amount of lines that will be sent to you before a
pause for input (how "tall" the text is.) The default is 32 lines.

46H 71V 1499X 0.00% 0C Exits:N> options lines 1000
LINES set to 1000.

46H 71V 1499X 0.00% 0C Exits:N> options columns 1000
COLUMNS set to 512.

46H 71V 1499X 0.00% 0C Exits:N> look
The Reception
This is the reception of the lodge, where you would sign in for a
room. This is also a very popular place where adventurers sit around and
share tales of their journeys. Some stairs in the back lead up to the
quarters.
I also went into Mudlet's settings and changed Main Display -> Word Wrapping to 1000, but nothing visibly changed.

As far as displaying the table, thanks! I did this:
local mytable = getLines(0, 2)
display(mytable)
and it displayed this:
{
"[ OK ] - Lua module rex_pcre loaded.",
"[ OK ] - Lua module zip loaded."
}
Which helped me to understand that I was looking at the very first lines of the entire session, which were apparently invisible to me, but I get what getLines() does now.

I just tried getCurrentLine() and it gives me the room name, but I'm still not sure how to get the description.

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Generic Mapping Script

Post by Jor'Mox »

No offense intended here, but given your skill level, writing a functional mapping script is going to be out of your reach at this point. But, it wouldn't be impossible to make some adjustments to the script here to capture and store room descriptions, and allow you to view/search them.

First though, obviously, you need to capture them via triggers. To do that, basically you want to use an onLine trigger to call a function that stores each line in a table. When a prompt is detected, you clear that table (so you are only ever looking at the text between two prompts). When you see your exits, you know you should have a name and description above them, so then you call another function to go through your table, toss out any leading blank lines (and the prompt at the beginning if it happens to be there), and store your room name and description for you (you probably want to turn the table of description lines into a single string, so it can be stored via setRoomUserData).

Note that actually searching room descriptions will be complicated, because while there is a searchRoomUserData function, it only searches for full, exact matches, which would only help you if you typed the full room description, exactly, with punctuation and capitalization and such. So, a function would have to be made that went through every room sequentially, retrieved its description, and then searched for whatever terms you were searching for. Not hard to do, but quite possibly slow, depending on the size of the map.

If you wanted, you could share the game you are setting this up on, and I could probably login, create the necessary triggers, make some quick adjustments to the script to capture and store a description, and even put in something to let you search your descriptions, and then roll that into a single package that you could install. Then you would just be left with the actual mapping itself to do.

GErswin
Posts: 17
Joined: Fri Jun 09, 2017 6:12 am

Re: Generic Mapping Script

Post by GErswin »

No offense taken. Thanks for all the help, really. The mud is Arctic (mud.arctic.org, port 2700), and it doesn't support GMPC. But you should only do this if you really want to. I believe I'm close to getting over the hump, and then it would just be a few weeks of writing all of the logic. After a few hours last night I've got a script that manually maps a room's name and its exits when I call a function.
Code: [show] | [select all] lua
mudlet = mudlet or {}; mudlet.mapper_script = true

local localRoomID

function MapMe()
	--AddArea()	
	--SetArea()
	AddRoom()
	--centerview(001)
	--echo("MapMe Ran!")
end

function AddArea()
	local tempareaID = addAreaName("MyFifthArea")	
	echo("Area Added! Area ID: " .. tempareaID .. "\n")
end

function SetArea()
	setAreaName(2, "MyFifthArea")
	echo("Area Set! Area Name: " .. "MyFifthArea" .. "\n")
end

function AddRoom()
	localRoomID = createRoomID()
	addRoom(localRoomID)
	echo("Room Added! \n")	
	echo("Room ID: " .. localRoomID .. "\n")
	NameRoom()
	SetRoomArea()
	SetRoomCoordinates()
	--SetRoomExitStubs()
	FindExits()
end

function NameRoom()
	setRoomName(localRoomID, curRoomName)
	echo("Room Name: " .. curRoomName .. "\n")
end

function SetRoomArea()
	setRoomArea(localRoomID, "MyFifthArea")
	echo("Room Area: " .. "MyFifthArea" .. "\n")
end

function SetRoomExitStubs(theExit)
	setExitStub(localRoomID, theExit, true)
	echo("Room Exits Set: " .. theExit .. "\n")
end

function SetRoomCoordinates()
	setRoomCoordinates(localRoomID, 8, 8, 0)
end

function Mapping_SetRoomDescription(roomID, description)
	setRoomUserData(localRoomID, "description", description)
end

function FindExits()
--Look through the captured Exit string for each exit
--This mud only has NSEWUD exits (plus secret exits but I'll deal with those later)
--This is a horrible way to do this but it works for now

	-- Look for N exit	
	local matchN = string.findPattern(curExits, "N")	
	if matchN then
   	echo("I did find: " .. matchN .. "\n")
		SetRoomExitStubs(exitmap.n)
	else	
		echo("I did NOT find N" .. "\n")
	end

	-- Look for S exit	
	local matchS = string.findPattern(curExits, "S")	
	if matchS then
   	echo("I did find: " .. matchS .. "\n")
		SetRoomExitStubs(exitmap.s)
	else	
		echo("I did NOT find S" .. "\n")
	end

	-- Look for E exit	
	local matchE = string.findPattern(curExits, "E")	
	if matchE then
   	echo("I did find: " .. matchE .. "\n")
		SetRoomExitStubs(exitmap.e)
	else	
		echo("I did NOT find E" .. "\n")
	end

	-- Look for W exit	
	local matchW = string.findPattern(curExits, "W")	
	if matchW then
   	echo("I did find: " .. matchW .. "\n")
		SetRoomExitStubs(exitmap.w)
	else	
		echo("I did NOT find W" .. "\n")
	end

	echo("Done searching exits" .. "\n")

end
That said, if you were going to do anything, I'd prefer solving a different problem than the room description search - I've always wanted to be able to map while following, rather than just moving on my own. That format looks like this:
362H 101V 9450795X 211C Mem:1 Exits:D>
Ghibka flies down.
You follow Ghibka down.
Sorcerer's Lounge
This lounge area looks almost like a library. Bookshelves line all
four walls of this room. Many young mages spend their breaks here studying.
A set of creaky wooden steps lead up into a large classroom.
But I'm prepared to spend a few weeks figuring it all out. It's been fun so far.

Again, thanks for all of the help so far. You've already done more than enough through explanations.

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Generic Mapping Script

Post by Jor'Mox »

My script actually already has a mechanism in place for capturing what I call "forced movement", i.e. where you move without entering a command. Basically you would just need to have a trigger to capture the line saying you follow whoever in whichever direction, and raise the relevant event with the direction captured by your trigger, and it would go from there. So, knowing that, and being already passingly familiar with Arctic Mud, I'm pretty sure I can help, and even include that with what I do, since it should be fairly simple.

Just so you know, working through all the logic is actually quite difficult, and it took months to put together what you see in the script I created. There end up being a lot of abnormal cases that you have to account for. Though a very basic mapper that just takes the direction you went and either moves you to the appropriate room if one is there from where you are currently, or creates a new room as needed, is not very challenging. It is making it smarter and more capable than that that is the real challenge.

GErswin
Posts: 17
Joined: Fri Jun 09, 2017 6:12 am

Re: Generic Mapping Script

Post by GErswin »

Sounds like I'm underestimating the amount of work. I'll take any help you have time to give!

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Generic Mapping Script

Post by Jor'Mox »

Looks like the game is down for the week. Will have to pick this up when it is back online.

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Generic Mapping Script

Post by Jor'Mox »

Okay, so I managed to get some triggers setup that allowed me to map Solace without any issues, though they rely on a few things that I don't know for sure are absolutes, so I'll spell everything out here so you can tell me if there are exceptions that need to be handled.

First, I created a trigger to capture the prompt, and with it the room exits. I used this as the regex pattern: ^.* Exits:(.*)>
I used this as the code:
Code: [show] | [select all] lua
local short = matches[2]
local long = {N = "north", S = "south", W = "west", E = "east", U = "up", D = "down"}
local exits = ""
for w in string.gmatch(short,"%a") do
	exits = exits .. long[w] .. " "
end
map.prompt.exits = exits
raiseEvent("onPrompt")
Note that I only ran into the cardinal directions, which you see listed in the code there, nothing like "northwest" or whatever. If there are such exits, then it needs to be parsed differently so that the end result getting stored in map.prompts.exits is just a list of each direction, written out in full, separated by a space.

Second, I created a trigger to capture the room name, and which is also used to identify that a room has been viewed. This trigger is somewhat more complicated. First, it uses a color trigger to match the color that room names are displayed in, dark cyan. The color trigger is followed by a regex trigger with this pattern: ^\s+\w+. It has "multiline / AND Trigger" checked, and has the line delta set to 1. As a consequence, it is looking for dark cyan text followed by a line of text that is indented, which matches what I see when I look at a room, with the room name flush against the left side, and the first line of the room description indented. The indent condition was used to avoid matching random dark cyan text, such as a shout I saw someone use. Two potential problem areas here would be other cases that look like the above, but aren't a room name and description, or room names coming in a different color. If these never happen, or if there are a limited number of relatively easily distinguishable cases (maybe some rooms have dark green room names, for example), then we should be good to go with at most minor alterations. The trigger has the following code:
Code: [show] | [select all] lua
map.prompt.room = multimatches[1][1]
raiseEvent("onNewRoom")
Third, I created a beginning of line substring trigger with the pattern: Alas, you cannot go that way...
It has the code:
Code: [show] | [select all] lua
raiseEvent("onMoveFail")
If there are additional messages you can get when you try to move a given direction but can't, just add them in as extra patterns in this trigger.

GErswin
Posts: 17
Joined: Fri Jun 09, 2017 6:12 am

Re: Generic Mapping Script

Post by GErswin »

Wow, amazing! Thanks so much!
  • The exits in the game are north, south, east, west, up, down, and special case exits like "crawl gap" which don't correspond to a direction. There are no cardinal combos like "northwest."
  • Room names are always the same color, but there may be a time when an indent appears after a shout or due to random circumstances. It's probably super rare, though. I'll keep an eye out.
  • There are some additional "alas, you cannot go that way..." lines (e.g. "The door is locked." "Something seems to be blocking your way."), so I'll add them in .
I'll give it a good run tonight with these new commands, and report back. Again, thanks a lot. I really appreciate it.

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Generic Mapping Script

Post by Jor'Mox »

GErswin wrote:That said, if you were going to do anything, I'd prefer solving a different problem than the room description search - I've always wanted to be able to map while following, rather than just moving on my own. That format looks like this:
362H 101V 9450795X 211C Mem:1 Exits:D>
Ghibka flies down.
You follow Ghibka down.
Sorcerer's Lounge
This lounge area looks almost like a library. Bookshelves line all
four walls of this room. Many young mages spend their breaks here studying.
A set of creaky wooden steps lead up into a large classroom.
So, I forgot to add this in, but it should be pretty easy. Add a trigger with this as the pattern: ^You follow .+ (\w+).$
And have it use this as the code: raiseEvent("onForcedMove",matches[2])

Post Reply