libGDX Internal Assets List

29th April 2021, 14:00:00

Intro

Tried to loop through files inside an Gdx.files.internal() folder, couldn’t because it returns a empty list? Here’s the solution.

General setup

Tl;dr: It is not possible to list files inside a .jar file, so .list() isn’t going to work on .internal() folders in desktop projects once you create a jar out of it.

To work around that problem, it’s possible to create an assets.txt file which contains a list of all your assets.

Then all you need to do is parse that file and search in it for whatever you need.

Since I’m lazy and I don’t want to edit the file manually, I’ve created a little gradle script for that.

File

All the changes in this page are done inside the main build.gradle file. (projectfolder/build.gradle)

Standard setup app / Liftoff differences

  • Standard setup app uses projectfolder/android/assets or projectfolder/core/assets if you don’t have an android module.
  • Liftoff uses projectfolder/assets for the assets path.

The example code uses projectfolder/assets so you need to edit it accordingly.

Code

Add the following task:

  • Standard setup app: above the allprojects {...} section
  • Liftoff: above the configure(subprojects) {...} section
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
task writeAllAssetsToFile {
doLast {
// projectfolder/assets
def assetsFolder = new File("${project.rootDir}/assets/")
// projectfolder/assets/assets.txt
def assetsFile = new File(assetsFolder, "assets.txt")
// delete that file in case we've already created it
assetsFile.delete()

// iterate through all files inside that folder
// convert it to a relative path
// and append it to assets.txt the file
fileTree(assetsFolder).collect {assetsFolder.relativePath(it) }.each {
assetsFile.append(it + "\n")
}
}
}

That’s pretty much all you need to do.

Running the script

  1. Whenever you add/remove a file, run the task with a terminal:

    • Powershell: .\gradlew.bat writeAllAssetsToFile
    • Cmd: gradlew.bat writeAllAssetsToFile
    • Linux/Mac: gradlew writeAllAssetsToFile
  2. Whenever you add/remove a file, run the task with your IDE. In IntelliJ you can double click the task in the gradle window:

    Gradle menu -> Tasks -> other -> writeAllAssetsToFile

  3. Automatically run the task whenever you compile the project with gradle.

    In my opinion this is the best way. You can tell gradle to always run the task before compiling the project. This ensures that the file is always up to date.

    Just slap the following line either:

    • Standard setup app: inside project("core") { section
    • Liftoff: inside the configure(subprojects) { section
1
compileJava.dependsOn writeAllAssetsToFile

Standard setup app example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
buildscript {
// ...
}

// ...

task writeAllAssetsToFile {
doLast {
def assetsFolder = new File("${project.rootDir}/core/assets/")
def assetsFile = new File(assetsFolder, "assets.txt")
assetsFile.delete()

fileTree(assetsFolder).collect {assetsFolder.relativePath(it) }.each {
assetsFile.append(it + "\n")
}
}
}

allprojects {
// ...
}

project("...") {
// ...
}

// ...

project(":core") {
apply plugin: "java-library"

dependencies {
api "com.badlogicgames.gdx:gdx:$gdxVersion"
// ...
}

compileJava.dependsOn writeAllAssetsToFile
}

// ...

Liftoff example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
buildscript {
// ...
}

// ...

task writeAllAssetsToFile {
doLast {
def assetsFolder = new File("${project.rootDir}/assets/")
def assetsFile = new File(assetsFolder, "assets.txt")
assetsFile.delete()

fileTree(assetsFolder).collect {assetsFolder.relativePath(it) }.each {
assetsFile.append(it + "\n")
}
}
}

configure(subprojects) {
apply plugin: 'java-library'

sourceCompatibility = 8
compileJava {
options.incremental = true
}

// ...

compileJava.dependsOn writeAllAssetsToFile
}

// ...