GeometryDashAPI
GeometryDashAPI copied to clipboard
level.Options.Ka1 does not give AudioTrack
Describe the bug
When accessing Ka1 on LevelOptions it always returns 0
To Reproduce Steps to reproduce the behavior:
- Use property
Ka1onLevelOptions - See that it always gives
0
Expected behavior
It should return the AudioTrack instead of 0
https://wyliemaster.github.io/gddocs/#/resources/client/level-components/level-start
I've tried to reproduce the example on the v0.2.29 And this looks fine
[TestFixture]
public class LevelTests
{
[Test]
public void AudioTrack()
{
var level = new Level();
level.Options.Ka1 = 10;
var result = level.SaveAsString(compress: false);
result.Should().Contain("kA1,10");
level = new Level(result.Replace("kA1,10", "kA1,111"), compressed: false);
level.Options.Ka1.Should().Be(111);
}
}
So I want to ask a couple of questions.
Which framework are you using? .NET Framework or .NET (Core) How can I reproduce this behavior through the game?
The reason I'm asking the last question is because kA1 looks obsolete.
There are an alternative ways to get Audio Track[^1]:
[TestFixture]
public class LevelTests
{
[Test]
public async Task AudioTrack()
{
// for online levels
var client = new GameClient();
var response = await client.SearchLevelsAsync(new Server.Queries.GetLevelsQuery(Server.Enums.SearchType.Featured));
var page = response.GetResultOrDefault();
var levelInfo = page.Levels.FirstOrDefault();
if (levelInfo.MusicId > 0)
{
// retrieve additional info of custom track
var track = page.Musics.FirstOrDefault(x => x.MusicId == levelInfo.MusicId);
}
else
{
var officialAudioTrack = levelInfo.OfficialSong;
}
// for "my levels" page
var local = await LocalLevels.LoadFileAsync();
var localLevel = local.First();
var musicId = localLevel.MusicId;
var customMusic = localLevel.CustomMusic; // indicates that official or custom
}
}
In addition, these methods allow you to get an audio track without loading the entire level into memory. Some levels may take up more than 100 MB of RAM. RobTop also forbids loading online levels too often.
[^1]: The code is incomplete, at each stage you need to perform state checks before relying on calling the First methods.
The way you showed me using MusicId works but I was calling .LoadLevel() and accessing .Options.Ka1
My .NET version is 7.0.410 and I'm pretty sure I'm using .NET core
I created a level and made it use the song id 123. I used the code:
var localLevels = await LocalLevels.LoadFileAsync();
var level = localLevels.GetLevel("<level name>");
var loadedLevel = level.LoadLevel();
var songID = loadedLevel.Options.Ka1;
Console.WriteLine(songID); // Is 0, not 123
Looks like the game doesn't use Ka1 now. Because when I was developing the library, I couldn't make Ka1 non-0.
Might the second example from the comment above be suitable for you?
var localLevels = await LocalLevels.LoadFileAsync();
var level = localLevels.GetLevel("<level name>");
var songID = level.MusicId;
Console.WriteLine(songID); // should be 123
You can check for yourself whether the game set Ka1 if you reach this line in debug mode.
data variable will contain the full string representation of the level
I am downloading a level from the servers and saving it into a text file (not encrypted) and later in my program I want to read the level from the text file and get the song id. I could use MusicId but that is only present on LevelCreatorModel, not Level
I think in that case you can save metadata about level. This will allow you to find out song id, author, name of the level, likes and etc later, because this information is not present in the content of level. For example you can use json format, like this cli utility for Geometry Dash: https://github.com/Folleach/GeometryDash.Console?tab=readme-ov-file#featured