# Thread: [OSRS] Minimap to mainscreen

1. ## [OSRS] Minimap to mainscreen

Hi, I know there exists some code for this already, but I found them to be fairly hardcoded, making them hard to adjust.. So, yesterday when actually just wanting to adjust some bank-handling I started writing this..

However it's probably not correctly adjusted, I've figured out the current values by trial and error. So don't expect pitch to work.. zooming could work.

Maybe someone's able to get them values corrected or verified.. Contributions are welcome.

Source:
https://github.com/SRL/SRL/blob/master/osr/MM2MS.simba

#SRL4osrHAStheCOOLESTshit
Last edited by slacky; 12-08-2017 at 03:30 PM.

2. Nice. Love that it identifies the squares that correspond to minimap dots.
Last edited by KeepBotting; 12-05-2017 at 01:27 AM.

3. My test script for anyone interested (will probably receive changes as I update MM2MS):

Simba Code:
{$DEFINE SMART}{$I SRL/OSR.simba}{$H-}var angle: Double; buffer: TMufasaBitmap;procedure DrawSquare(vec: Vector3; color: Int32);var rect: TRectangle; q: TPoint;begin rect := Minimap.VecToMSRect(vec, angle).Expand(-2); for q in rect.ToTPA.Connect() do if q.InBox(Mainscreen.GetBounds) then Buffer.SetPixel(q.x,q.y, color);end;procedure DrawTile(x,y, color: Int32; ForceColor:Boolean=False);var i,xx,yy: Int32; vec: Vector3;begin vec := Vec3(x,y).RotateXY(angle, MM2MS.MMCX, MM2MS.MMCY); // adjust colors if it's a minimap object if not ForceColor then begin for xx:=Round(vec.x)-1 to Round(vec.x) do for yy:=Round(vec.y)-1 to Round(vec.y) do if (GetColor(xx,yy+2) = 65536) and SimilarColors(60909, GetColor(xx,yy), 50) then begin color :=$FFFF00;          break;        end else if (GetColor(xx,yy+2) = 65536) and SimilarColors(395004, GetColor(xx,yy), 50) then        begin          color := $00FF00; break; end else if (GetColor(xx,yy+2) = 65536) and SimilarColors(15526885, GetColor(xx,yy), 50) then begin color :=$FFFFFF;          break;        end  end;  DrawSquare(vec, color);end;var  x,y: Int32;  V3A: Vector3Array;  pt: TPoint;  vec: Vector3;begin  smart.EnableDrawing := True;  smart.Init;  buffer := GetMufasaBitmap(CreateBitmap(GetClientBounds.Width, GetClientBounds.Height));  AddOnTerminate(@buffer.Free);  while True do  begin    angle := minimap.GetCompassAngle(False);    // iterate over minimap tiles and debug them    for x:=MM2MS.MMCX-52 to MM2MS.MMCX+52 with 4 do      for y:=MM2MS.MMCY-52 to MM2MS.MMCY+52 with 4 do        DrawTile(x,y, HSLToColor((y*100+x)/100, 50,50));    DrawTile(MM2MS.MMCX, MM2MS.MMCY, $111111, True); // debug buffer.DrawBox(chatbox.FLines[8], True,$1);    Smart.Image.DrawBitmap(buffer.GetIndex, Point(0,0));    buffer.Clear();  end;end.
Last edited by slacky; 12-08-2017 at 03:33 PM.

4. Really nice release. Been looking for something like this

5. You have much to be proud of!

6. Slacky: 1 Kasi: 0

7. SRL Junior Member
Join Date
Jul 2015
Posts
80
Mentioned
1 Post(s)
Quoted
22 Post(s)
Oooooh! This is trully amazing. Congrats, will definitely use this. Thank you.

8. Used in accordance with RSWalker you can do some fancy stuff.. Like store the location of some "object" using world coordinate, and recover it on the mainscreen with something like this:
Simba Code:
function WorldToMSTile(me, objLoc: TPoint; z,offx,offy:Double=0): TRectangle;var  angle: Double;begin  objLoc := Point(MM2MS.MMCX, MM2MS.MMCY) + (objLoc - me);  angle  := minimap.GetCompassAngle(False);  objLoc := objLoc.Rotate(angle, Point(MM2MS.MMCX, MM2MS.MMCY));  Result := Minimap.VecToMSRect(Vec3(objLoc.x - offx, objLoc.y - offy, z), angle);end;
z, offx and offy are all alternative params.. offx and offy is used for basic offest since the camera doesn't follow you precisely making MM2MS a tad off at times, but it's predicable.. z is the floor height of the object relative to your height off 0.. So if it's known to be further down than you, then you'd reduce the z value, and vice versa.

me is just the result of a call to RSW.GetMyPos()
objLoc is the position on the world map of the object.

I used the above without any colorfinding to write a very simple iron-miner. I did use FindColors to verify that the rocks contained ores tho.
What I am talking about can be seen here: https://github.com/slackydev/Simba-M...imba#L157-L170

But it relies heavily on that RSW is accurate wherever you are.. and that depends on a number of other factors.. So it may or may not work for you.
Last edited by slacky; 12-14-2017 at 03:46 PM.

9. @slacky, have you talked to @Joopi about using memory editing to replace the picture of the map with an image which encodes position in the pixels? It seems like it would remove most of the error that is left, although there is some static error due to the blur caused when the map texture is rotated.

10. Originally Posted by R0b0t1
@slacky, have you talked to @Joopi about using memory editing to replace the picture of the map with an image which encodes position in the pixels? It seems like it would remove most of the error that is left, although there is some static error due to the blur caused when the map texture is rotated.
Yes, I was there when that talk was ongoing, contributed with a variant that reduced the image quality instead of just throwing away the current minimap image as well.
• Can be seen here https://prnt.sc/hm7ke2
However that the proposed encoding of coords to localmap buffer will only increase accuracy for the first step: minimap->local, but the localmap will still have to be cross-correlated with the given world map to get a set of coordinates that makes sense (that doesn't relate to where you spawned when you logged in or teleported).

However, there is a much better solution that can be done which I have suggested earlier to those interested: Get the localx, and localy tiles which are stored in plain form in memory (no multipliers needed), the only thing needed is to write a decent "signature" search function to locate those, one that last throughout every update - Should not be too much of an issue, I just haven't given a fuck about that.
This is something I've told several people about, time again throughout the past almost 3 years when they have shown interest. Some even say to have a working implementation.

The reason why I haven't done any thing extra related to memory scanning is simple: Memory scanning was only implemented to alternatively give users a way to speed up RSWalker, but doing so without changing how your location is determined, cross correlation is still how we determine position, either memscan is enabled or not.
Going to the point where I write specialized solutions solely based on memory scanning is outside what I want RSW to be, I wish to keep it "color". The memscan stuff that I have now was pushing my boundaries.
Last edited by slacky; 05-28-2018 at 06:09 PM.

11. Originally Posted by slacky
Yes, I was there when that talk was ongoing, contributed with a variant that reduced the image quality instead of just throwing away the current minimap image as well.
• Can be seen here https://prnt.sc/hm7ke2
When @Joopi presented it in IRC previous to the discussion you participated in everyone present came up with more or less the same thing.

Originally Posted by slacky
However that the proposed encoding of coords to localmap buffer will only increase accuracy for the first step: minimap->local, but the localmap will still have to be cross-correlated with the given world map to get a set of coordinates that makes sense (that doesn't relate to where you spawned when you logged in or teleported).
Right, but isn't this a solved problem?

Originally Posted by slacky
However, there is a much better solution that can be done which I have suggested earlier to those interested: Get the localx, and localy tiles which are stored in plain form in memory (no multipliers needed), the only thing needed is to write a decent "signature" search function to locate those, one that last throughout every update - Should not be an issue, I just haven't given a fuck about that.
This is something I've told several people about, time again throughout the past almost 3 years when they have shown interest. Some even say to have a working implementation.
I considered it as well, but when doing memory scanning in the past (Cheat Engine) for single values it is almost always necessary to do scanning involving ranges and changed values. This can be automated but it would require some testing at the beginning of a script each time RS is launched, or fairly invasive reverse engineering.

Originally Posted by slacky
Going to the point where I write specialized solutions solely based on memory scanning is outside what I want RSW to be, I wish to keep it "color". The memscan stuff that I have now was pushing my boundaries.
Okay. Most of my interest is that if there is a "perfect" method it then becomes possible to train machine learning systems or to verify some other system is working properly.
Last edited by R0b0t1; 12-12-2017 at 01:11 AM.

12. Originally Posted by R0b0t1
*useless remarks* *bs statements*
Either you basically overlook what I say, or you otherwise just claim it's wrong, and you top that off with BS statements, I am not even gonna bother with attempting to feed this to you, there does not exist a small enough spoon to teach you. So, just fuck off, I am not interested in this. Don't bother responding, you have my answers, and have already gone enough off topic.

Noob

Your first claim takes minimal effort, so I am gonna bring forth some essential part of the chatlog from that day:
Chatlog showing they did NOT do what I a little later that night suggested, instead they just threw the coordinates in there with some maths and as a result got a color gradiant:
Code:
...
Nov 19 23:38:18 <BenLand100>	possibly i was asuming 512x512
Nov 19 23:38:22 <BenLand100>	so 0 to 511
Nov 19 23:38:38 <BenLand100>	should look like https://benland.us/files/7avtz64N.png
Nov 19 23:46:41 <BenLand100>	(that's what rs walker does)
Nov 19 23:47:52 <BenLand100>	Joopi: if you use {s Floor[x/n], s Floor[y/n], s (Mod[x, n] + n*Mod[y, n])} with n=8 and s=4 you get https://benland.us/files/qHfSyU77.png which makes maximal use of the color space while still having encoded position https://benland.us/files/qHfSyU77.png
Nov 19 23:48:55 <BenLand100>	with n=2 s=1 you get https://benland.us/files/Hg7H8BEU.png which has the property that cts1 tolerance is the same as linear distance
Nov 19 23:52:15 <Joopi>	https://imgur.com/a/r5H5H
Nov 19 23:52:45 <Joopi>	I got this by doing X := Floor((t mod 2048)/4);
Nov 19 23:52:59 <Joopi>	2048 since it's 4 indexes per pixel
Nov 19 23:55:14 <Joopi>	t = index

// --------------------------------------
// ... some time later:

Nov 20 03:47:15 <slacky>	joopi: http://prntscr.com/hco8eu
Nov 20 03:47:22 <slacky>	I encoded the location into the colors :P
Nov 20 03:48:04 <slacky>	http://prntscr.com/hco8nd **
Nov 20 03:48:13 <slacky>	that one has the coordinate output as well :P
...
Nov 20 03:52:39 <slacky>	I reduced the colors to 16 colors per channel.. so that I had some bits overhead to work with. And as the world map in memory is stored with an alpha channel witch I _assume_ is unused, I also used that.
Nov 20 03:53:12 <BenLand100>	but you won't be able to get the alpha channel off the screen
Nov 20 03:53:27 <slacky>	oh right.
Nov 20 03:53:31 <BenLand100>	reducing colorspace is clever tho
Nov 20 03:53:52 <BenLand100>	so what 512 need 9 bits
Nov 20 03:54:00 <BenLand100>	18 total of 24
Nov 20 03:54:05 <BenLand100>	that's p  reduced
Nov 20 03:54:46 <BenLand100>	two states of each color
Nov 20 03:54:59 <BenLand100>	so you can do black and primary colors then encode position :)
...
Nov 20 04:21:30 <slacky>	http://prntscr.com/hcogn7
Nov 20 04:21:33 <slacky>	not as pretty tho :P
Nov 20 04:22:03 <BenLand100>	but anyway this has the positions encoded in the low 6 bits of each color https://benland.us/files/qu1oNs4z.png
Nov 20 04:22:33 <ianh>		can I see some code for that?
Nov 20 04:22:43 <slacky>	http://prntscr.com/hcoh83
Nov 20 04:22:48 <slacky>	that one looks kinda cool
Nov 20 04:23:02 <BenLand100>	https://benland.us/files/pLVoGWJr.png
Nov 20 04:23:04 <slacky>	but my original idea was to try ot make it more or less invisible
Nov 20 04:24:11 <slacky>	mine looks cooler than yours BenLand100 :P
Nov 20 04:24:14 <BenLand100>	psh
Nov 20 04:24:28 <BenLand100>	i am trying to pack the bits so that it's smooth
Nov 20 04:25:51 <BenLand100>	https://benland.us/files/gsNPQjWU.png
Nov 20 04:26:23 <BenLand100>	hmm no that's worse
Nov 20 04:26:27 <ianh>		that's perfect
Nov 20 04:28:41 <BenLand100>	dis p good https://benland.us/files/NT2PTL9G.png
Nov 20 04:28:55 <slacky>	indeed

.. and so it goes on for some time
The rest of your horseshit.. I am just not willing to respond to. You are not worth anymore effort.

Welcome to my universal ignorelist.
Last edited by slacky; 12-12-2017 at 04:38 PM.

13. Originally Posted by slacky
Either you basically overlook what I say, or you otherwise just claim it's wrong, and you top that off with BS statements, I am not even gonna bother with attempting to feed this to you, there does not exist a small enough spoon to teach you. So, just fuck off, I am not interested in this. Don't bother responding, you have my answers, and have already gone enough off topic.
Please sir, I did not mean to make you angry. It is just the case I am not very smart. Joopi was talking about memory scanning for a few days prior, and I think it had come up then. Please read my signature.

I did ask some questions I had hoped you would respond to.
Last edited by R0b0t1; 12-15-2017 at 01:23 AM.

14. Really neat work indeed! It's been a while since anyone's dove into this area; in fact I've not seen accurate MM>MS conversion since ReadySteadyGo's tile projection or zmon's 3D engine, which was remarkable. Based off your description, I'm guessing the SRL-OSR include Olly and yourself are working on is intended to operate at the furthest camera zoom setting?

Originally Posted by slacky
Either you basically overlook what I say, or you otherwise just claim it's wrong, and you top that off with BS statements, I am not even gonna bother with attempting to feed this to you, there does not exist a small enough spoon to teach you. So, just fuck off, I am not interested in this. Don't bother responding, you have my answers, and have already gone enough off topic.

Welcome to my universal ignorelist.
Take it easy, as far as I can tell R0b0t1 was only asking questions to understand. That's a large basis for this community in general; we aim to teach and, even ourselves, learn.

15. Originally Posted by Flight
Really neat work indeed! It's been a while since anyone's dove into this area; in fact I've not seen accurate MM>MS conversion since ReadySteadyGo's tile projection or zmon's 3D engine, which was remarkable. Based off your description, I'm guessing the SRL-OSR include Olly and yourself are working on is intended to operate at the furthest camera zoom setting?
Many reflection / injection client developers use these algorithms WorldToMM, WorldToMS, TileToMS etc. Many of them have 100% accurate conversions since they use the exact same algorithms in the client as well as accurate zoom and pitch variables. Which are impossible to get reliably in colour. It'd probably be difficult to justify an entire include based off this, as you can't reliably get the pitch in any sense as OP already mentioned. The pitch changes depending on where you are in-game, so hard coding a value isn't gonna cut it.

16. Originally Posted by Flight
Based off your description, I'm guessing the SRL-OSR include Olly and yourself are working on is intended to operate at the furthest camera zoom setting?
Yes. There's a simple variable you can modify if you wanna try it out for some different zoom setting: https://github.com/SRL/SRL/blob/mast...M2MS.simba#L21 - it think that will work.

17. Hey this is really cool! I can't believe how accurate you have got it.

I have very fond memories working on something similar.

I wonder if it may be possible to work out the pitch using the both the main screen and the minimap.

Hey this is really cool! I can't believe how accurate you have got it.

I have very fond memories working on something similar.

I wonder if it may be possible to work out the pitch using the both the main screen and the minimap.
Thank you.

I have no idea how one would do that without having something static to go off.
Probably be doable if one had 2 distant stationary objects on the mainscreen, but that would still at only be doable in special scenarios.

Edit, I guess it can be bruteforced, by projection-transforming (at various pitches low to high) the whole minimap and correlate it with the mainscreen, then return the pitch that yield the best match. It might work, but will fail when there's a lot of dots, and the tile-height is uneven, etc. Example: https://i.imgur.com/Cou22lV.png - Shading also makes it less reliable, but should not be the main concern.
Don't think pitch is really worth the effort tho.

@Flight MM2MS.SCALE := 1.375 seems to be the default zoom if that's what aerolib uses:
Last edited by slacky; 12-15-2017 at 04:23 AM.

19. Originally Posted by slacky
Yes. There's a simple variable you can modify if you wanna try it out for some different zoom setting: https://github.com/SRL/SRL/blob/mast...M2MS.simba#L21 - it think that will work.
That's great, and probably a wise option to revolve the include around furthest camera zoom, considering how much more of the game screen is visible. I'd probably try it out eventually but I wouldn't want to borrow more of your hard work than what I already have (RSText, RSWalker and so on...).

On a similar note; have you and Olly considered publicizing your include a bit? Perhaps creating & releasing some scripts to draw some attention?

Originally Posted by Kasi
Many reflection / injection client developers use these algorithms WorldToMM, WorldToMS, TileToMS etc. Many of them have 100% accurate conversions since they use the exact same algorithms in the client as well as accurate zoom and pitch variables. Which are impossible to get reliably in colour. It'd probably be difficult to justify an entire include based off this, as you can't reliably get the pitch in any sense as OP already mentioned. The pitch changes depending on where you are in-game, so hard coding a value isn't gonna cut it.
'Tis true, I remember it as far back as Aryan. It's possible to determine a rough pitch via color as well, it'll just take some imagination. I've done it before very accurately via TEntities in the past as part of some R&D in that area. Perhaps I can dust it off and make a quick demonstration video. But the concept is simple: define a TEntity and examine its height value while adjusting your pitch in-game.

20. Originally Posted by Flight
'Tis true, I remember it as far back as Aryan. It's possible to determine a rough pitch via color as well, it'll just take some imagination. I've done it before very accurately via TEntities in the past as part of some R&D in that area. Perhaps I can dust it off and make a quick demonstration video. But the concept is simple: define a TEntity and examine its height value while adjusting your pitch in-game.
I'd be quite interested to see your method work accurately in different places around runescape - quite hesitant to believe it.

There's also a very similar method, which doesn't involve adjusting in-game pitch. Due to the nature of the runescape camera (it's always looking down on the player, the focal point), You can somewhat calculate a pitch based on how much of the player is taking up the screen. However, it could still be inaccurate. Due to stuff like player hairstyles and armours / helms, tile heights would also play a part in this, a couple pixels could mean a lot of variance in terms of pitch.
Last edited by Kasi; 12-15-2017 at 12:52 PM.

21. Originally Posted by Flight
On a similar note; have you and @ considered publicizing your include a bit? Perhaps creating & releasing some scripts to draw some attention?
I am a shitty script-writer. I overcomplicate some parts, while oversimplyfing most other parts. And very rarely have it in me to maintain the scripts I write. I would likely do it if I just had it in me, but I am usually better suited at helping with hard parts others face, so that Idon't have to think about the "whole script" logic.
Nor am I really up to date on what fancy bots people like these days, idk much of runescape, just the basic f2p stuff.
Last edited by slacky; 12-15-2017 at 04:30 PM.

22. Originally Posted by Kasi
I'd be quite interested to see your method work accurately in different places around runescape - quite hesitant to believe it.

There's also a very similar method, which doesn't involve adjusting in-game pitch. Due to the nature of the runescape camera (it's always looking down on the player, the focal point), You can somewhat calculate a pitch based on how much of the player is taking up the screen. However, it could still be inaccurate. Due to stuff like player hairstyles and armours / helms, tile heights would also play a part in this, a couple pixels could mean a lot of variance in terms of pitch.
That's how I determined pitch before was based off the size of my player's TEntity. I've seen suggestions on finding facing direction and such based off certain pieces of equipment, so I suppose it's the same concept, just the TEntity is a more complete image of the player.

Originally Posted by slacky
I am a shitty script-writer. I overcomplicate some parts, while oversimplyfing most other parts. And very rarely have it in me to maintain the scripts I write. I would likely do it if I just had it in me, but I am usually better suited at helping with hard parts others face, so that Idon't have to think about the "whole script" logic.
Nor am I really up to date on what fancy bots people like these days, idk much of runescape, just the basic f2p stuff.
I understand 100%... When it comes to going off other bots, IMO that should never be a factor. We're unique for a reason and we've been here far longer than anyone else also for a reason. They can classify our scripts as basic but at the end of the day, we'll still be here running strong, update after update while they're constantly playing catch-up. They also aim for the bells & whistles to attract customers vs us for the challenge and teaching aspect.

That being said, I'd really, really like to see a script made by you, and utilizing yours and Olly's include. I believe many would. Sorry for keeping this so far off topic, I'll stop now haha.

23. Just a slight update on this, I added better support for zooming, taking a value between 0 and 100, where 100 is fully zoomed in. Works well with SRL's options.GetZoom.

If you just run your script at a different zoom you just need to set the mm2ms zoom (once):
> MM2MS.SetZoom(options.GetZoom);
Now that will be applied to functions like:
> Minimap.PointToMsRect(...);

While at it, even tho SRL itself isn't designed for it, I added support for resizable. But it does rely on SRL's GetCompassAngle, which however does not support resizable.
But for resizable it's just a matter of initializing MM2MS yourself like so:
> MM2MS.Init(True); //MM2MS.Init(Resizable: Boolean)

At least it's future proofed a bit more with that added. If you currently wanna use it, you at least have to write your own GetCompassAngle, unless you are north only.

Also tweaked the mm2ms projection slightly, it was tiny bit off before.
Last edited by slacky; 03-05-2018 at 07:18 AM.

24. Hey slacky!

love this. using zoom for other things as well.