Skip to content
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

level.Options.Ka1 does not give AudioTrack #38

Open
RevolvingMadness opened this issue Jan 11, 2025 · 5 comments
Open

level.Options.Ka1 does not give AudioTrack #38

RevolvingMadness opened this issue Jan 11, 2025 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@RevolvingMadness
Copy link

Describe the bug
When accessing Ka1 on LevelOptions it always returns 0

To Reproduce
Steps to reproduce the behavior:

  1. Use property Ka1 on LevelOptions
  2. 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

@RevolvingMadness RevolvingMadness added the bug Something isn't working label Jan 11, 2025
@Folleach
Copy link
Owner

Folleach commented Jan 12, 2025

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 Track1:

[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.

Footnotes

  1. The code is incomplete, at each stage you need to perform state checks before relying on calling the First methods.

@RevolvingMadness
Copy link
Author

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

@Folleach
Copy link
Owner

Folleach commented Jan 14, 2025

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

@RevolvingMadness
Copy link
Author

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

@Folleach
Copy link
Owner

Folleach commented Jan 15, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants