Hacking League of Legends HUD

Don't care how, just want it done? Latest easy-to-use release with GUI: Download here

Whenever I've joined my friends for an occasional game of League of Legends I've been irritated by the fact that game won't let me customize my HUD so I can play efficiently on my triple screen Eyefinity setup. LOL will happily render on 5760x1080px resolution, however you're stuck with map on the far right and character screen on the far left:

Screenshot from Leauge of Legends on 3 screens before the fix
Screenshot from Leauge of Legends on 3 screens before the fix

One night I've decided it would be a nice challenge to try and fix this. About 6 hours later the first version of a LOL Hudfixer has been born. I've played few games using this hack and have encountered no problems so far. It has been an exciting experience to reverse-engineer some of the logic used in the game, I'll try to outline my findings/approach in this article.

Step one: break it so you can fix it

First I just wanted to impact the HUD in any way I could i.e. break it. Initially I've tried tweaking some .ini files to no avail. It won't be that easy! Game assets are stored in raf files and before we can do anything we need to extract the contents. Luckily modding community has a tool for that - a RAF Manager. With the help of this tool we get access to a large number of resources but how to find the one used by the game to render the HUD? Actually, I have no idea. I've started searching for 'Minimap' and 'HUD' and kept changing random numbers in files I've found until I've noticed HUD breaks. Every time I've made a change I had to re-pack using RAF Manager again, start the game and see if anything breaks. Took me about 3 tries to finally stumble upon correct path:

/DATA/Menu/HUD/Hud2012/Elements/

I've tweaked some numbers in a file named MinimapRight.ini and my map was completely gone! Great Success!

Step two: HUD Rendering in LOL

Here is a small fragment of MinimapRight.ini file that defines size and position of the actual contents of the Minimap:

//////////////////////////////////////////
Type: Icon
Name: MinimapContent
Group: Minimap
Enabled: 0
KeepMaxScale: 1
AlwaysRespond: 1
Draggable: 0
Layer: 1
Anchor: 1,1
Rect: 832.64,576.0 - 1020.16,763.52 / 1024x768
Alpha: 0
Texture: None
UV: 0,0 - 1,1
//////////////////////////////////////////

First item that looks interesting is Rect property. It seems to be giving screen coordinates assuming 1024x768 resolution. However first thing I've tried is a value of 0,0 - 100,100 / 1024x768 however my map didn't move anywhere near top-right corner. Looks like there is more to it. There is another important property we need to look at - Anchor. Here is a visualization of potential Anchor values:

Reverse engineering LOL interface: anchor points
Reverse engineering LOL interface: Anchor Points

So why anchor points are important? LOL allows HUD scaling so if you scale your map it will use the anchor point of 1,1 (as per image above) to align the map to the right-bottom corner. In order to allow that LOL will create an 'invisible canvas', anchor it at given point and then use Rect property to draw it's contents. Here is a visualization:

Reverse engineering LOL interface: anchor points canvas
Reverse engineering LOL interface: Anchor Points

If we scale the HUD using in-game settings, what really happens the M is changed and thus the size is affected but actual position (e.g. map sits in the bottom-right corner) is preserved thanks to the anchorage points, more or less like this:

Reverse engineering LOL interface: scaling canvas
Reverse engineering LOL interface: scaling canvas

The width of the 'magic box' is described above as Mpx (in my code I've actually used constant MAGIC_VALUE). I've discovered that at the default scale in LOL it will be equal to 1440px.

One more complexity is the actual value of Rect, above expressed as 832.64,576.0 - 1020.16,763.52 / 1024x768. First pair of numbers (832.64,576.0) represents cooridnates for the top-left corner of rendered item - in this case top left corner of the minimap contents. Second pair represents the coordinates for the bottom-right corner of the minimap contents position. Third expression (/ 1024x768) defines a divider and while I'm not entirely sure what's its purpose, LOL will divide the coordinates by this value before multiplying it by the M value. So the formula to get pixel value is:

pixelX = x/divider*Mx
pixelY = y/divider*My

where x and y are the coordinates of the point you want to translate to pixels and Mx and My are the magic values (at scale 1.0: Mx = 1440 and My = 1080).

Step 3: Centralize the HUD

Roughly what I was after was this:

Moving the canvas to move the map position - the plan
Moving the canvas to move the map position - the plan

Most likely I could stick a massive negative values for Rect coordinates - however this solution would have 2 major drawbacks:

  1. Adjusting scale just by a tiny factor would produce a massive offset causing HUD elements appearing in all the wrong places
  2. Wouldn't work for wider screens or 5 screen setup

Instead I decided to re-anchor everything centrally and recalculate new Rect coordinates, something along these lines:

Reanchoring the canvas - visualisation
Reanchoring the canvas - visualisation

Side note: I've also tried anchoring using values 0.33 and 0.66 however LOL wouldn't render correctly with these values, my suspicion is these are stored at very low precision.

As you can see from the picture above if canvas is aligned centrally it will spread out equally to sides and if we're to position the minimap touching the right edge we will have to use values > M (similarly to get the left borders we will need negative values). There are hundreds of HUD elements if you count every icon and every possible configuration and moving everything by hand would be very mundane and bug-prone task. That's where my LOL Hudfixer comes handy, just fed it some rafs and it will spit out centrally-aligned files.

Side note: If your screen resolution is lower than the value of M the behavior will most likely be different!

Here is a screenshot from the modded game:

Screenshot from LoL after the mod
Screenshot from LoL after the mod

With a touch of basic reverse engineering I've got HUD rendered the way I wanted. Surely Riot will eventually push a patch that breaks my hack but until then I'll enjoy the game with fixed HUD. And if it breaks - well more hacking for me!

Update Patch 3.11: With LOL recently patched to 3.11 RAF Manager won't be able to pack your data correctly into RAF files rendering all files you've modified unreadable for the game. This means that as of now if you follow the guide above, you will destroy all HUD in lol. Hope you have a backup. I'll update this article if/when this is working again.

Update 4.9.14 (June 2014): Made this work again using my own lame raf archieve manager. If you're on Windows here is a lazy version of the HUD Fixer

Update 5.2.15 (February 2015): Made this work again, with GUI! Download here. Screenshot showing the new map with HUD fixed on 3 screens setup:

Screenshot from LoL after the mod after patch 5.2
Screenshot from LoL after the mod after patch 5.2

Update 5.16 (September 2015): Made this work again, with yet another new GUI! Download here. Screenshot showing the new HUD fixed on 3 screens setup:

Screenshot from LoL after the mod after patch 5.16
Screenshot from LoL after the mod after patch 5.16