This is the README from the GitHub repository. For the full source code, please visit the project on GitHub.

About this project


As the GitHub README above already reveals, this is a mod for the video game 'Hades' by Supergiant Games. I started playing the game about 2 years ago and really enjoyed it, so it felt nice to give something back in the form of a nice QOL mod.

The mod itself is quite simple, it just adds a little text popup to show the player the secrets of a room after they have completed it. Originally, there was a version of this mod that just covered the fishing points, as these were the secrets I tended to miss the most, but I later rewrote the mod to cover all the secrets.

The Hades Modding Discord was a great place to get support in the creation of this mod. Navigating a game's codebase for the first time can be a bit intimidating, so their help was greatly appreciated.

Technical details


This project was quite interesting on a technical level, because writing a mod for a game is quite different than just creating a project for yourself.

Luckily, the way the game is written made this process significantly easier than for most other games. The game's engine is written in C and entirely hidden from the user, as expected. However, most of the games logic is written in Lua, which is a language I had not heard about until I looked into this game.

All of the Lua scripts are neatly organized and completely available for anyone to modify, which means that no advanced reverse-engineering is required. The scripts are compiled at startup by the engine, so there is no need to worry about compiling them manually. This will also immediately show the modder if there were any errors with the scripts.

The only other thing required to create a mod for Hades is are the community-created tools 'ModUtil' and 'ModImporter', which insure that multiple mods can be installed at the same time without conflict.

Now the only thing left to do was write the actual code. I needed to find the place in the scripts where a room is checked as 'done', so I have a 'hook' to insert my text-popup. Once I found this function, which after a long search I found is called DoUnlockRoomsExist, I could check for all the secrets.

The mod script then boils down to this:

1.Overwrite the base function:

Lua
local baseDoUnlockRoomsExist = DoUnlockRoomsExist
function DoUnlockRoomsExist( run, room )
    baseDoUnlockRoomsExist( run, room )
    thread ( CheckRoomSecrets )
end

2.Check each secret:

Lua
function CheckRoomSecrets()
    
    if config.showInfernalTrove then
        if currentRoom.challengeSwitch ~= nil then
            local secretName = "Infernal Trove"
            ...
            finalMessage = ConcatToFinalMessage( finalMessage, secretName )
        end
    end
    
    if config.showWellShop then
        if currentRoom.WellShop ~= nil then
            finalMessage = ConcatToFinalMessage( finalMessage, "Well of Charon" )
        end
    end
    
    ... // Do for all secrets
    
    ShowIndicatorText( finalMessage )
    
end

3. Concat the secret names to the final message:

Lua
function ConcatToFinalMessage( currentMessage, secretName )
    if currentMessage ~= nil then
        return currentMessage .. "," .. secretName
    else
        return secretName
    end
end

4. Show the text!

Lua
function ShowIndicatorText( text )
    
    ...
    
    // Create blank obstacle that we can turn into a TextBox
    local customTextIndicatorId = CreateScreenObstacle({ Name = "BlankObstacle", ... })
    CreateTextBox({ Id = customTextIndicatorId, Text = text, ... })
    
    ...
    
end