Need help - bevy 0.16.1 with random select of file not work - what did I wrong?

Hi,

my target is: select random a mp3 file in directory: assets/sounds
and start playing this....
if hardcode one file name the sound is played
but wanna have a random select file

the source code


use std::{fs, process::exit};
use rand::prelude::IndexedRandom;

use bevy::prelude::*;

fn main() {

    getsoundfile();

    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, playsound)
        .run();

}


fn getsoundfile() {
    let mp3_files: Vec<_> = fs::read_dir("assets/sounds")
        .unwrap()
        .filter_map(|entry| entry.ok())
        .collect();
    
    let mut rng = rand::rng();


    if let Some(random_file) = mp3_files.choose(&mut rng) {

        println!("Zufällig ausgewählte MP3-Datei: {}", random_file.path().display());
    } else {
        println!("Keine MP3-Dateien gefunden!");
        exit(99);
    }

}


fn playsound(mut commands: Commands, asset_server: Res<AssetServer>) {
    // MP3-Datei laden (im Ordner "assets/sounds/")
    let randsoundfile: &str = getsoundfile();
    let audio_handle = asset_server.load(randsoundfile.as_str());
//    let audio_handle = asset_server.load(&randsoundfile);
    commands.spawn(AudioPlayer::new(audio_handle));
}

Error:

error[E0308]: mismatched types
  --> src/main.rs:40:31
   |
40 |     let randsoundfile: &str = getsoundfile();
   |                        ----   ^^^^^^^^^^^^^^ expected `&str`, found `()`
   |                        |
   |                        expected due to this

error[E0658]: use of unstable library feature `str_as_str`
  --> src/main.rs:41:56
   |
41 |     let audio_handle = asset_server.load(randsoundfile.as_str());
   |                                                        ^^^^^^
   |
   = note: see issue #130366 <https://github.com/rust-lang/rust/issues/130366> for more information

Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `rand_select` (bin "rand_select") due to 2 previous errors

You never return the file name from getsoundfile. Try returning it:

use std::path::PathBuf;

fn getsoundfile() -> PathBuf {
    let mp3_files: Vec<_> = fs::read_dir("assets/sounds")
        .unwrap()
        .filter_map(|entry| entry.ok())
        .collect();
    
    let mut rng = rand::rng();


    let Some(random_file) = mp3_files.choose(&mut rng) else {
        panic!("Keine MP3-Dateien gefunden!");
    };

    println!("Zufällig ausgewählte MP3-Datei: {}", random_file.path().display());
    random_file.path()
}

fn playsound(mut commands: Commands, asset_server: Res<AssetServer>) {
    // MP3-Datei laden (im Ordner "assets/sounds/")
    let randsoundfile: PathBuf = getsoundfile();
    let audio_handle = asset_server.load(&randsoundfile);
    commands.spawn(AudioPlayer::new(audio_handle));
}
1 Like

@jofas

this works so fine! - I fixed 2 points

Thank you so much - have a nice weekend !

Here is the hole code

use std::{fs};
use rand::prelude::IndexedRandom;
use std::path::PathBuf;

use bevy::prelude::*;

fn main() {

    getsoundfile();

    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, playsound)
        .run();

}


fn getsoundfile() -> PathBuf {
    let mp3_files: Vec<_> = fs::read_dir("assets/sounds")
        .unwrap()
        .filter_map(|entry| entry.ok())
        .collect();
    
    let mut rng = rand::rng();


    let Some(random_file) = mp3_files.choose(&mut rng) else {
        panic!("Keine MP3-Dateien gefunden!");
    };

    println!("Zufällig ausgewählte MP3-Datei: {}", random_file.path().display());
    random_file.path()
}

fn playsound(mut commands: Commands, asset_server: Res<AssetServer>) {
    // MP3-Datei laden (im Ordner "assets/sounds/")
    let randsoundfile: PathBuf = getsoundfile();
    let audio_handle = asset_server.load(&*randsoundfile);
    commands.spawn(AudioPlayer::new(audio_handle));
}

But did not understand why now the path must be: assets/assets/sounds/

because got this error before:

Zufällig ausgewählte MP3-Datei: assets/sounds/sport-rock-248925.mp3
2025-06-27T14:26:10.644716Z ERROR bevy_asset::server: Path not found: /home/developer/rust/rand_select/assets/assets/sounds/sport-rock-248925.mp3

The asset server wants a path relative to the asset directory but you are giving it a path relative to the current directory. See: AssetPath in bevy::asset - Rust

One possible fix would be to do

.filter_map(|entry| entry.ok())
.map(|path| path.strip_prefix("assets"))
.collect()
1 Like

@Bruecki

thanks may I did it wrong but did not work


    Checking rand_select v0.1.0 (/home/developer/rust/rand_select)
error[E0599]: no method named `strip_prefix` found for struct `DirEntry` in the current scope
  --> src/main.rs:25:28
   |
25 |           .map(|path| path.strip_prefix("assets"))
   |                            ^^^^^^^^^^^^ method not found in `DirEntry`

For more information about this error, try `rustc --explain E0599`.

the Code:

use std::{fs};
use rand::prelude::IndexedRandom;
use std::path::PathBuf;

use bevy::prelude::*;

fn main() {

getsoundfile();

App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(Startup, playsound)
    .run();

}

fn getsoundfile() -> PathBuf {
let mp3_files: Vec<_> = fs::read_dir("assets/sounds")
.unwrap()
// .filter_map(|entry| entry.ok())
// .collect();
.filter_map(|entry| entry.ok())
.map(|path| path.strip_prefix("assets"))
.collect();

let mut rng = rand::rng();


let Some(random_file) = mp3_files.choose(&mut rng) else {
    panic!("Keine MP3-Dateien gefunden!");
};

println!("Zufällig ausgewählte MP3-Datei: {}", random_file.path().display());
random_file.path()

}

fn playsound(mut commands: Commands, asset_server: Res) {
// MP3-Datei laden (im Ordner "assets/saounds/")
let randsoundfile: PathBuf = getsoundfile();
let audio_handle = asset_server.load(&*randsoundfile);
commands.spawn(AudioPlayer::new(audio_handle));
}

I am so sorry !

strip_prefix is defined on Path (and thus PathBuf due to its Deref<Target=Path> implementation), not DirEntry:

use std::{fs};
use rand::prelude::IndexedRandom;
use std::path::PathBuf;

use bevy::prelude::*;

fn main() {

    getsoundfile();

    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, playsound)
        .run();

}


fn getsoundfile() -> PathBuf {
    let mp3_files: Vec<_> = fs::read_dir("assets/sounds")
        .unwrap()
        .filter_map(|entry| entry.ok())
        .collect();
    
    let mut rng = rand::rng();


    let Some(random_file) = mp3_files.choose(&mut rng) else {
        panic!("Keine MP3-Dateien gefunden!");
    };

    println!("Zufällig ausgewählte MP3-Datei: {}", random_file.path().display());
-   random_file.path()
+   random_file.path().strip_prefix("assets/").unwrap().to_owned()
}

fn playsound(mut commands: Commands, asset_server: Res<AssetServer>) {
    // MP3-Datei laden (im Ordner "assets/sounds/")
    let randsoundfile: PathBuf = getsoundfile();
    let audio_handle = asset_server.load(&*randsoundfile);
    commands.spawn(AudioPlayer::new(audio_handle));
}
1 Like

@jofas

Thanks but had this error:

error[E0600]: cannot apply unary operator `-` to type `PathBuf`
    --> src/main.rs:33:1
     |
33   | -   random_file.path()
     | ^^^^^^^^^^^^^^^^^^^^^^ cannot apply unary operator `-`
     |
note: the foreign item type `PathBuf` doesn't implement `Neg`
    --> /home/developer/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/path.rs:1177:1
     |
1177 | pub struct PathBuf {
     | ^^^^^^^^^^^^^^^^^^ not implement `Neg`

For more information about this error, try `rustc --explain E0600`.
error: could not compile `rand_select` (bin "rand_select") due to 1 previous error

The snippet I posted was not meant to be copied as is, but to show the changes I made to your previous snippet in a readable manner. You can copy this:

use std::{fs};
use rand::prelude::IndexedRandom;
use std::path::PathBuf;

use bevy::prelude::*;

fn main() {

    getsoundfile();

    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, playsound)
        .run();

}


fn getsoundfile() -> PathBuf {
    let mp3_files: Vec<_> = fs::read_dir("assets/sounds")
        .unwrap()
        .filter_map(|entry| entry.ok())
        .collect();
    
    let mut rng = rand::rng();


    let Some(random_file) = mp3_files.choose(&mut rng) else {
        panic!("Keine MP3-Dateien gefunden!");
    };

    println!("Zufällig ausgewählte MP3-Datei: {}", random_file.path().display());
    random_file.path().strip_prefix("assets/").unwrap().to_owned()
}

fn playsound(mut commands: Commands, asset_server: Res<AssetServer>) {
    // MP3-Datei laden (im Ordner "assets/sounds/")
    let randsoundfile: PathBuf = getsoundfile();
    let audio_handle = asset_server.load(&*randsoundfile);
    commands.spawn(AudioPlayer::new(audio_handle));
}

I am very sorry !

Thank you so much for your help !

Thanks @ALL

have a nice weekend!