Here's the guide and repo to set everything up! I apologize in advance but I used AI to write up this guide to make sure it covers every single detail, so that even the less knowledgeable can set it up.
Repo: https://github.com/i-Ac1D-i/heroic-chant
This guide assumes zero experience with any of this. If you already know your way around adb, skip to section 5 and just read the README.
What actually works right now
- Login, lobby, the full 138-hero roster
- Story stages: turn-based combat, rewards, star flags, unlocking the next stage
- Progress that survives closing the game
- Hero rarity (A / S / SS / SSS)
- Level up, star-up with shards and memory stones, the awakening skill tree
- Equipment: equip, auto-equip, upgrade, sell, runes
- City Search (the idle farm) with a working claim button
- Summoning at the real drop rates, pulled from the game's own tables
- Guilds: founding, donations, buffs, the exchange shop
What doesn't: PvP, arena, raids, guild wars — basically anything that needs other players. The Store screen only renders its Costume tab. The gacha grants your hero correctly but the result screen doesn't close itself, so you back out and reopen and the hero's sitting there.
58 of the 401 packets the client can send have handlers written. The rest get decoded and logged but don't do anything yet. That's the todo list if anyone wants to pitch in.
1. What you need before you start
A Windows PC. The server is plain Python so it runs anywhere, but every command below is written for Windows because that's what I have. Linux and Mac people, you'll be fine, just swap the path separators.
An Android emulator that can do ARM. This is important and it's where most people are going to get stuck.
The APK ships arm64-v8a and armeabi-v7a only. There is no x86 build. That means a normal Android Studio emulator will not run this. You need one that does ARM translation:
- MuMu Player 12 — https://www.mumuplayer.com/ (what I used, this is the one I'd recommend)
- LDPlayer 9 — https://www.ldplayer.net/
A real Android phone works too, but it also needs root.
Root. Non-negotiable, sorry. The game's 2 GB of assets have to sit inside /data/data/com.ngelgames.herocantare/, which is a protected folder. A fresh install can't download them because the CDN is dead, so we're copying them in by hand, and that needs root. Both emulators above have a root toggle in their settings.
Around 8 GB of free disk once everything's unzipped.
Emulator settings: Android 9 or 11, root ON, 4 GB RAM.
2. Downloads
The game files
- APK (138 MB): https://drive.google.com/file/d/1hayI4L–WCQbv4QEMLVLbg07Pkr-Sx8a/view?usp=sharing
- herocantare.db (47 MB): https://drive.google.com/file/d/1U3LYz0VUOmfTQcFQe3v7jqJliBxMJ6ci/view?usp=sharing
- files.zip (~1.8 GB):
https://drive.google.com/file/d/1K-_zXE0j7W3zQ39cx2OML4iIa_h31jEd/view?usp=sharing - server-research.zip (4 MB): https://drive.google.com/file/d/1_pwe4MEQVo3WdFAGHMD0gVJhZhYPWhhT/view?usp=sharing
The tools
- Python — https://www.python.org/downloads/Get 3.10 or newer. When you run the installer, tick the "Add python.exe to PATH" checkbox on the very first screen. It's at the bottom and it's easy to miss. If you skip it, nothing below will work and you'll have to reinstall.
- Git — https://git-scm.com/download/winClick through accepting every default.
- Android platform-tools (this is adb) — https://dl.google.com/android/repository/platform-tools-latest-windows.zipThat's the direct download straight from Google. Official page if you'd rather go through it: https://developer.android.com/studio/releases/platform-tools
3. Setting up adb
adb is the tool your PC uses to talk to the emulator. You want it on your PATH so you can type adb from any folder instead of the full path every single time.
Unzip it somewhere permanent. I use C:\platform-tools. Not Downloads, not Desktop — somewhere you won't clean out later. When you unzip you should end up with C:\platform-tools\adb.exe sitting right there. If you've got C:\platform-tools\platform-tools\adb.exe you nested it one folder too deep, move everything up a level.
Add it to PATH:
- Hit Start, type
environment, click "Edit the system environment variables" - Click the Environment Variables… button at the bottom
- In the top box (the one labelled "User variables"), find the row called Path and click it
- Click Edit…
- Click New
- Type
C:\platform-tools - OK on all three windows to close them
Now close every terminal window you have open. PATH changes only apply to new ones. This catches everybody.
Open a fresh PowerShell (Start, type powershell, Enter) and check:
adb version
If you get "Android Debug Bridge version 1.0.41" or similar, you're set. If you get "not recognized", the PATH didn't take — check the folder path is right and that you actually opened a new window.
While you're there, check Python too:
python --version
Should say 3.10 or higher.
4. Turn on ADB in your emulator
MuMu Player 12: Settings (the gear icon) → Other → turn on ADB debugging. Note the port it shows you, it's usually 16384.
LDPlayer 9: Settings → Other settings → ADB debugging: Open local connection.
Turn on root while you're in there. In MuMu it's under Other as "Root permission". Restart the emulator after changing it.
Now check your PC can see it:
adb devices
You want a line like 127.0.0.1:16384 device. If the list comes back empty, connect by hand:
adb connect 127.0.0.1:16384
Use 7555 for older MuMu, 5555 for LDPlayer.
If it says unauthorized, look at the emulator screen — there's a popup asking you to allow USB debugging. Tick "always allow" and hit OK.
5. Building the folder tree
Pay attention to this bit. The tools find things by relative path, so if the folders aren't laid out exactly like this, nothing works.
Make a folder somewhere. I'll call it HeroCantare but the name genuinely doesn't matter. Inside it you're aiming for exactly this:
HeroCantare\ ├── com.ngelgames.herocantare_1.2.389.apk ├── files\ │ └── ngelgames\ │ ├── AssetBundle\ │ ├── dnsinfo.json │ ├── real_serverinfo.json │ └── ... (lots more) ├── table\ │ └── herocantare.db ├── server-research\ │ ├── dump.cs │ └── protocol.json └── server\ <- the repo, we clone this in a second
So:
- Put the APK in the root folder. Rename it to exactly
com.ngelgames.herocantare_1.2.389.apk— Google Drive likes adding junk to filenames. - Make a folder called
tableand dropherocantare.dbin it. - Unzip
additional-files.zipinto the root. It gives youfiles\andserver-research\. Double-check afterwards that you've gotHeroCantare\files\ngelgames\AssetBundleand notHeroCantare\additional-files\files\ngelgames\AssetBundle— if you got the extra layer, move the folders up one.
Now open PowerShell in that folder. Easiest way: open the folder in File Explorer, click the address bar at the top, type powershell, hit Enter.
Clone the server:
git clone https://github.com/i-Ac1D-i/heroic-chant.git server
The server on the end matters — it names the folder server, which is what the tools are expecting.
Then go into it:
cd server
Every command from here on runs from inside that server folder.
6. Building the game data
The repo deliberately ships with no game data in it at all. Not one asset, not one table, no packet definitions. That's on purpose, I'm not redistributing someone else's game. So we build all of it locally from the files you just downloaded.
Install the libraries the build tools need:
pip install -r requirements-dev.txt
That pulls in UnityPy (reads Unity asset bundles), capstone (an ARM disassembler), and cryptography. Takes a minute or two.
Now build the packet definitions:
python tools/gen_protocol.py --apk ../com.ngelgames.herocantare_1.2.389.apk
This yanks libil2cpp.so out of the APK and disassembles every marshalling function in it to work out the exact byte layout of all 859 packets. Takes a couple of minutes and prints a wall of text. You want it to finish saying 859/859 verified.
Then extract the data tables:
python tools/extract_assets.py
That reads the Unity bundles and dumps 252 JSON tables into server\data\. Another minute or so.
Now test it before you go anywhere near the emulator:
python tools/selftest.py
This runs the actual server against a fake client — handshake, login, clearing a stage, checking the rewards landed, levelling a hero. You want to see:
ALL CHECKS PASSED
If that passes, the server side is completely done and anything that goes wrong from here is a device problem, which narrows things down a lot. If it fails, fix it now, don't carry on.
7. Installing the game
Install the APK:
adb install ../com.ngelgames.herocantare_1.2.389.apk
Launch it once from the emulator's app drawer, let it sit a few seconds, then close it. It'll fail to load, that's expected — we just need Android to create its data folder.
Now push the game assets in. This is the slow part, it's 2 GB:
adb push ../files/ngelgames /sdcard/ngelgames
Go make a coffee.
Then copy it into the app's private folder and fix the permissions. Three commands:
adb shell su -c "cp -a /sdcard/ngelgames /data/data/com.ngelgames.herocantare/files/" adb shell su -c 'chown -R $(stat -c %U:%G /data/data/com.ngelgames.herocantare) /data/data/com.ngelgames.herocantare/files' adb shell su -c "restorecon -R /data/data/com.ngelgames.herocantare/files"
Note the single quotes on that middle one — that's deliberate. PowerShell would try to run the $(stat ...) bit on your PC if you used double quotes, and stat isn't a Windows command. Single quotes send it through untouched so it runs on the device, which is where it needs to run.
Do not skip that last one. restorecon fixes the SELinux labels. Get it wrong and the app silently can't read its own files, shows you no error at all, and you'll burn an hour wondering why it crashes.
If su gives you "permission denied", root isn't actually on. Back to your emulator settings, turn it on, restart the emulator.
You can delete the staging copy afterwards to claw back 2 GB:
adb shell rm -rf /sdcard/ngelgames
8. Pointing the client at your PC
The client has a config baked into it full of dead server addresses. We rewrite them to point at you.
We're going to use the loopback route via adb reverse, which tunnels ports over the ADB connection. Much easier than going over your LAN — no admin rights, no firewall rules, no touching your router. As far as the emulator is concerned your PC is just 127.0.0.1.
Patch the config files:
python tools/patch_client_config.py ../files/ngelgames --host 127.0.0.1
That rewrites dnsinfo.json (39 hostnames), real_serverinfo.json, and all 37 real_patchinfo*.json files, keeping a .bak of each one. Add --restore later if you ever want the originals back.
Push the patched files back:
adb push ../files/ngelgames /sdcard/ngelgames adb shell su -c "cp -a /sdcard/ngelgames /data/data/com.ngelgames.herocantare/files/" adb shell su -c "restorecon -R /data/data/com.ngelgames.herocantare/files"
Now redirect the one hostname that isn't in that config. Before the client opens a socket it fetches two JSON files over plain HTTP from dlhc.ngelgames.net. That hostname is baked into the binary and it's not in dnsinfo.json, so it goes through the normal system resolver and we have to catch it in the hosts file:
adb shell su -c "mount -o rw,remount /system" adb shell su -c "echo '127.0.0.1 dlhc.ngelgames.net' >> /system/etc/hosts"
Check it stuck:
adb shell su -c "cat /system/etc/hosts"
Your new line should be at the bottom. If the mount command failed, try /etc/hosts instead of /system/etc/hosts — some emulator builds symlink it differently.
9. Run it
One command does everything:
python tools/resume.py
It connects to the emulator, sets up the port forwards, starts both servers, and launches the game for you.
What it's doing under the hood:
adb reverse tcp:80 tcp:8080— the device's port 80 now lands on your PC's 8080adb reverse tcp:21010 tcp:21010— same deal for the game server port- starts the boot shim, which answers those two HTTP requests the client makes
- starts the game server
- force-stops and relaunches the game
You should see:
device: 127.0.0.1:16384 reverse: reverse tcp:80 tcp:8080 | reverse tcp:21010 tcp:21010 bootserver : http://127.0.0.1:8080 (log: logs/boot.log) game server: 127.0.0.1:21010 (log: logs/game.log) launched com.ngelgames.herocantare
Logs land in server\logs\. Ctrl+C stops both servers.
A healthy boot looks like this in logs\game.log:
hc.net connected ('127.0.0.1', 41xxx) hc.net handshake complete with (...) (hostID 1) hc.net C2S CenterServerC2S.GetServerGroupInfoReq hc.center new account 1001 for device <id> hc.net C2S CenterServerC2S.GetConnectGameServerInfoReq hc.net connected (...) hc.net C2S GameServerC2S.LogInReq hc.login login: account 1001 (Player1001) client 1.2.389, 138 units
That last line means you're in. Go play.
One thing to know: the adb reverse forwards die whenever the emulator restarts or your PC reboots. That is the number one reason this "randomly stops working". Just run python tools/resume.py again, it puts them back.
10. When it doesn't work
| What you're seeing | What's wrong |
|---|---|
| Stuck on the loading / patch screen forever | It never reached the boot shim. Check logsboot.log — if it's empty, either the hosts redirect or the adb reverse isn't there |
| Crashes at the splash screen | Either your emulator isn't doing ARM translation, or the files copy didn't land properly. Redo the chown and restorecon |
logsgame.log says connected then immediately disconnected |
Client didn't like the handshake. Run with --log-level DEBUG and look for a decode error |
| Both logs completely empty | DNS isn't redirected. Run adb shell ping dlhc.ngelgames.net — it has to come back as 127.0.0.1 |
| Black screen after login | Client's waiting on a packet nobody handles yet. logsgame.log will have a no handler line naming it |
adb: no devices/emulators found |
Emulator isn't running, ADB isn't enabled in its settings, or you need adb connect 127.0.0.1:16384 |
adb not found -- add platform-tools to PATH |
Section 3, and make sure you opened a fresh terminal after |
su: permission denied |
Root isn't enabled in the emulator. Turn it on, restart the emulator |
herocantare.db not found |
It's in the wrong place. It goes in HeroCantaretableherocantare.db, not inside server |
If you're stuck, run the server on its own with debug logging so you can watch every packet going both directions:
python -m hc.main --public-host 127.0.0.1 --log-level DEBUG
11. Messing with your save
Accounts are plain JSON sitting at server\accounts\1001.json. Open it in any text editor, change your gold or your gems or whatever you feel like, restart the client. Nothing is validated, because it's your own server on your own machine.
To wipe and start fresh: delete that file and remove your device's entry from accounts\index.json.
12. If you want to help out
There's a CONTRIBUTING.md in the repo that walks through adding a packet handler start to finish with a real worked example. It's honestly not hard — the difficult part (working out the wire format) is already done, so most handlers come out around ten lines.
The way to find something to do: run the server, play, and watch for lines like
C2S GameServerC2S.SomeThingReq -- no handler (24 body bytes)
That's a packet the game sent that nobody's implemented. There are 343 of them, and the ones the game hits first are the ones worth doing first.
Bigger stuff that needs actual design work: arena and PvP (the game shipped with AI bot teams sitting in its data, so it's doable without other players), guild raids and wars, and working out why the Store screen only draws its Costume tab.
Legal, quickly
The server code is mine and you can do whatever you want with it. The game isn't mine.
No game assets, data tables, packet definitions or APK are in the repo and they shouldn't be added — everything gets rebuilt from your own copy. The Drive links up top are there so people who already played this game can play it again. It's been dead for two years, there's no way to buy it and no way to play it.
Don't repackage this into an APK and hand it around as "the game". Share the server and let people point their own client at it.
That's the lot. If you get stuck, post what logs\game.log and logs\boot.log say — that's usually enough to spot the problem straight away.
Source: r/Herocantare · by /u/haikottero