-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add some Honkai: Star Rail wwnames #15
Conversation
Thanks, I think I could clean it up a bit and use words.py to extract some more but if you could re-generate the names using wwiser from latest commits (in case you didn't): wwiser.zip. I've fixed a few bugs recently that were including some unreversable IDs (mainly SFX). I don't have a decent way to handle huge games but probably best would be understanding and trying to mimic how the game handles pcs/bnk, as it would be a hassle for them too unless streamlined somehow, I'm not familiar with the game though. An idea I have in mind is loading .pck directly and read all .bnk inside, not sure if would really help your case. For |
I already used latest Git master version. I created names like this
Can't use shell's expansion because you run out of ARGV space due to so many files. I also tried using Anyway I went down this rabbit hole and looked into how game works. It's Unity game that uses IL2CPP to compile C# into C++. Generally most of these games can be decompiled and reversed pretty easily but Star Rail uses a lot of protections and encrypts a lot of stuff so none of public Unity extractors/decompilers work. But I found that there are some people who have managed to extract game's files - https://github.com/Dimbreath/StarRailData/ . Unfortunately they don't reveal how they did it but my guess would be by loading their DLL at runtime that invokes game's functions to get data back. For now we can just ignore first step and use their already extracted data directly. So if we look there we can find mission files like {
"OnInitSequece": [],
"OnStartSequece": [
{
"TaskList": [
...
{
"$type": "RPG.GameCore.PlayAndWaitSimpleTalk",
"BlackMask": true,
"SimpleTalkList": [
{
"TalkSentenceID": 103060481,
"ProtectTime": 0.3
},
{
"TalkSentenceID": 103060482,
"ProtectTime": 0.3
},
{
"TalkSentenceID": 103060483,
"ProtectTime": 0.3
},
{
"TalkSentenceID": 103060484,
"ProtectTime": 0.3
},
{
"TalkSentenceID": 103060485,
"ProtectTime": 0.3
},
{
"TalkSentenceID": 103060486,
"ProtectTime": 0.3
},
{
"TalkSentenceID": 103060487,
"ProtectTime": 0.3
}
]
},
... Next we can look at {
...
"103060481": {
"TalkSentenceID": 103060481,
"TextmapTalkSentenceName": {
"Hash": 371857150
},
"TalkSentenceText": {
"Hash": 1291295548
}
},
"103060482": {
"TalkSentenceID": 103060482,
"TextmapTalkSentenceName": {
"Hash": 371857150
},
"TalkSentenceText": {
"Hash": 1291295549
}
},
"103060483": {
"TalkSentenceID": 103060483,
"TextmapTalkSentenceName": {
"Hash": 371857150
},
"TalkSentenceText": {
"Hash": 1291295550
}
},
"103060484": {
"TalkSentenceID": 103060484,
"VoiceID": 103060484,
"TextmapTalkSentenceName": {
"Hash": 2092232028
},
"TalkSentenceText": {
"Hash": 1291295543
}
},
"103060485": {
"TalkSentenceID": 103060485,
"VoiceID": 103060485,
"TextmapTalkSentenceName": {
"Hash": 2092232028
},
"TalkSentenceText": {
"Hash": 1291295544
}
},
"103060486": {
"TalkSentenceID": 103060486,
"TextmapTalkSentenceName": {
"Hash": 371857150
},
"TalkSentenceText": {
"Hash": 1291295545
}
},
"103060487": {
"TalkSentenceID": 103060487,
"VoiceID": 103060487,
"TextmapTalkSentenceName": {
"Hash": 2092232028
},
"TalkSentenceText": {
"Hash": 1291295546
}
},
... Now we can use {
...
"103060484": {
"VoiceID": 103060484,
"VoicePath": "chapter3_5_firefly_104"
},
"103060485": {
"VoiceID": 103060485,
"VoicePath": "chapter3_5_firefly_105"
},
... So this allows us to match Unfortunately if we use Also by the way, regarding that {
...
"371857150": "",
"1291295548": "...",
"2092232028": "Firefly",
"1291295543": "In my dream, I saw a scorched earth, and a new sapling emerging from it. It bloomed against the morning sun, and whispered to me.",
"1291295544": "Why do people choose to sleep? I think...",
"1291295546": "...It is because they're afraid to awaken from the dream.",
... So if we want to find corresponding audio file we just need to do this in reverse and start from As for other sounds, in various files can find keys like For example in {
...
"JoinTeamWithSpecialTeamate": "Ev_vo_avatar_addtoteam_to{0}_{1}",
... |
Thanks, added and updated the list with names from
|
Awesome, thanks! It looks really great! And yeah I had read that and tried it a bit but didn't spend much time on that, it's very involved 😄
Indeed it works correctly. I see it did extract |
Really need some better tools when working with such huge games...
Honkai: Star Rail consists of 194
.pck
files taking ~45 GiB. Extracting those we get ~17k.bnk
and ~48k.wem
files.From those looks like
wwiser
gets ~29k IDs. After trying bunch of things maybe I have gotten around ~10k correctly reversed - mainly starting withEv_
andState
.But still there are a lot of wrong mappings and it needs to be cleaned up/fixed more. Also I think it's doable to get even more names.
Anyway I won't be working on this anymore so here it is :)
Sadly what I noticed that
.bnk
files are not created forMusic*
,External*
andStreamed*
folders which means there's huge amount of audio that's essentially undiscoverable because there doesn't seem any way to find/search.I'm mostly interested in voice dialogs which are in
External*
. I tried using whisper speech recognition which transcribes quite well but it's incredibly slow and will take very long time... And even with text it's not clear who exactly said that. Another idea would be try using some speaker recognition model to narrow down searching but haven't tried that.Anyway do you have any ideas how to map those
.wem
inExternal*
to something useful? Really need some metadata because there's hours and hours of audio so not realistic to listen manually to find what you're looking for...