Excutable can't find assets

I did the macroquad tutorial project and seems to run like it should when I'm using cargo. But when I built the executable, it seems to have trouble finding the assets. I double checked everything. Even tried the code from the tutorial itself. Still nothing. Any ideas on how I can fix this?I need to figure this out before add macroquad to a few other projects that I have. Here's the code:
use macroquad::audio::{PlaySoundParams, Sound, load_sound, play_sound, play_sound_once};
use macroquad::experimental::animation::{AnimatedSprite, Animation};
use macroquad::experimental::collections::storage;
use macroquad::experimental::coroutines::start_coroutine;
use macroquad::prelude::*;
use macroquad::ui::{Skin, hash, root_ui};
use macroquad_particles::{self as particles, AtlasConfig, Emitter, EmitterConfig};
use std::fs;
use std::path::Path;

const FRAGMENT_SHADER: &str = include_str!("starfield-shader.glsl");

const VERTEX_SHADER: &str = "#version 100
attribute vec3 position;
attribute vec2 texcoord;
attribute vec4 color0;
varying float iTime;

uniform mat4 Model;
uniform mat4 Projection;
uniform vec4 _Time;

void main() {
gl_Position = Projection * Model * vec4(position, 1);
iTime = _Time.x;
}
";
struct Resources {
ship_texture: Texture2D,
bullet_texture: Texture2D,
explosion_texture: Texture2D,
enemy_small_texture: Texture2D,
theme_music: Sound,
sound_explosion: Sound,
sound_laser: Sound,
ui_skin: Skin,
}
impl Resources {
async fn new() -> Result<Resources, macroquad::Error> {
let ship_texture: Texture2D = load_texture("ship.png").await?;
ship_texture.set_filter(FilterMode::Nearest);
let bullet_texture: Texture2D = load_texture("laser-bolts.png").await?;
bullet_texture.set_filter(FilterMode::Nearest);
let explosion_texture: Texture2D = load_texture("explosion.png").await?;
explosion_texture.set_filter(FilterMode::Nearest);
let enemy_small_texture: Texture2D = load_texture("enemy-small.png").await?;
enemy_small_texture.set_filter(FilterMode::Nearest);
build_textures_atlas();

    let theme_music = load_sound("8bit-spaceshooter.ogg").await?;
    let sound_explosion = load_sound("explosion.wav").await?;
    let sound_laser = load_sound("laser.wav").await?;

    let window_background = load_image("window_background.png").await?;
    let button_background = load_image("button_background.png").await?;
    let button_clicked_background = load_image("button_clicked_background.png").await?;
    let font = load_file("atari_games.ttf").await?;
    let window_style = root_ui()
        .style_builder()
        .background(window_background)
        .background_margin(RectOffset::new(32.0, 76.0, 44.0, 20.0))
        .build();
    let button_style = root_ui()
        .style_builder()
        .background(button_background)
        .background_clicked(button_clicked_background)
        .background_margin(RectOffset::new(16.0, 16.0, 16.0, 16.0))
        .margin(RectOffset::new(16.0, 0.0, -8.0, -8.0))
        .font(&font)
        .unwrap()
        .text_color(WHITE)
        .font_size(64)
        .build();
    let label_style = root_ui()
        .style_builder()
        .font(&font)
        .unwrap()
        .text_color(WHITE)
        .font_size(28)
        .build();
    let ui_skin = Skin {
        window_style,
        button_style,
        label_style,
        ..root_ui().default_skin()
    };
    Ok(Resources {
        ship_texture,
        bullet_texture,
        explosion_texture,
        enemy_small_texture,
        theme_music,
        sound_explosion,
        sound_laser,
        ui_skin,
    })
}
async fn load() -> Result<(), macroquad::Error> {
    let resources_loading = start_coroutine(async move {
        let resources = Resources::new().await.unwrap();
        storage::store(resources);
    });
    while !resources_loading.is_done() {
        clear_background(BLACK);
        let text = format!(
            "Loading resources {}",
            ".".repeat(((get_time() * 2.) as usize) % 4)
        );
        draw_text(
            &text,
            screen_width() / 2.0,
            screen_height() / 2.,
            40.,
            WHITE,
        );
        next_frame().await;
    }
    Ok(())
}

}

struct Shape {
size: f32,
speed: f32,
x: f32,
y: f32,
collided: bool,
}
impl Shape {
fn collides_with(&self, other: &Self) -> bool {
self.rect().overlaps(&other.rect())
}

fn rect(&self) -> Rect {
    Rect {
        x: self.x - self.size / 2.0,
        y: self.y - self.size / 2.0,
        w: self.size,
        h: self.size,
    }
}

}

enum GameState {
MainMenu,
Playing,
Paused,
GameOver,
}

fn particle_explosion() -> particles::EmitterConfig {
particles::EmitterConfig {
local_coords: false,
one_shot: true,
emitting: true,
lifetime: 0.6,
lifetime_randomness: 0.3,
explosiveness: 0.65,
initial_direction_spread: 2.0 * std::f32::consts::PI,
initial_velocity: 400.0,
initial_velocity_randomness: 0.8,
size: 16.0,
size_randomness: 0.3,
atlas: Some(AtlasConfig::new(5, 1, 0..)),
..Default::default()
}
}
fn initialize_assets_path() {
// Try multiple possible locations
let possible_paths = [
"assets", // Current directory
"src/assets", // IDE/source directory
"../assets", // One directory up
"./assets", // Explicitly in current dir
];

for path in possible_paths {
    if Path::new(path).exists() {
        set_pc_assets_folder(path);
        println!("Assets loaded from: {}", path);
        return;
    }
}

// If we get here, no path worked
eprintln!("WARNING: Could not find assets directory! Trying default path.");
set_pc_assets_folder("assets"); // Try original as fallback

}
#[macroquad::main("Space Assault")]
async fn main() -> Result<(), macroquad::Error> {
const MOVEMENT_SPEED: f32 = 200.0;

rand::srand(miniquad::date::now() as u64);
let mut squares = vec![];
let mut bullets: Vec<Shape> = vec![];
let mut explosions: Vec<(Emitter, Vec2)> = vec![];
initialize_assets_path(); // Updated path to match the correct location of the assets folder
Resources::load().await?;
let resources = storage::get::<Resources>();
let mut bullet_sprite = AnimatedSprite::new(
    16,
    16,
    &[
        Animation {
            name: "bullet".to_string(),
            row: 0,
            frames: 2,
            fps: 12,
        },
        Animation {
            name: "bolt".to_string(),
            row: 0,
            frames: 2,
            fps: 12,
        },
    ],
    true,
);
bullet_sprite.set_animation(1);
let mut ship_sprite = AnimatedSprite::new(
    16,
    24,
    &[
        Animation {
            name: "idle".to_string(),
            row: 0,
            frames: 2,
            fps: 12,
        },
        Animation {
            name: "left".to_string(),
            row: 2,
            frames: 2,
            fps: 12,
        },
        Animation {
            name: "right".to_string(),
            row: 2,
            frames: 2,
            fps: 12,
        },
    ],
    true,
);
let mut enemy_small_sprite = AnimatedSprite::new(
    17,
    16,
    &[Animation {
        name: "enemy_small".to_string(),
        row: 0,
        frames: 2,
        fps: 12,
    }],
    true,
);
let mut circle = Shape {
    size: 32.0,
    speed: MOVEMENT_SPEED,
    x: screen_width() / 2.0,
    y: screen_height() / 2.0,
    collided: false,
};
let mut score: u32 = 0;
let mut high_score: u32 = fs::read_to_string("highscore.dat")
    .map_or(Ok(0), |i| i.parse::<u32>())
    .unwrap_or(0);
let mut game_state = GameState::MainMenu;

let mut direction_modifier: f32 = 0.0;
let render_target = render_target(320, 150);
render_target.texture.set_filter(FilterMode::Nearest);
let material = load_material(
    ShaderSource::Glsl {
        vertex: VERTEX_SHADER,
        fragment: FRAGMENT_SHADER,
    },
    MaterialParams {
        uniforms: vec![
            UniformDesc::new("iResolution", UniformType::Float2),
            UniformDesc::new("direction_modifier", UniformType::Float1),
        ],
        ..Default::default()
    },
)?;
play_sound(
    &resources.theme_music,
    PlaySoundParams {
        looped: true,
        volume: 1.,
    },
);
root_ui().push_skin(&resources.ui_skin);
let window_size = vec2(370.0, 320.0);
loop {
    clear_background(BLACK);

    material.set_uniform("iResolution", (screen_width(), screen_height()));
    material.set_uniform("direction_modifier", direction_modifier);
    gl_use_material(&material);
    draw_texture_ex(
        &render_target.texture,
        0.,
        0.,
        WHITE,
        DrawTextureParams {
            dest_size: Some(vec2(screen_width(), screen_height())),
            ..Default::default()
        },
    );
    gl_use_default_material();

    match game_state {
        GameState::MainMenu => {
            root_ui().window(
                hash!(),
                vec2(
                    screen_width() / 2.0 - window_size.x / 2.0,
                    screen_height() / 2.0 - window_size.y / 2.0,
                ),
                window_size,
                |ui| {
                    ui.label(vec2(80.0, -34.0), "Main Menu");
                    if ui.button(vec2(65.0, 25.0), "Play") {
                        squares.clear();
                        bullets.clear();
                        explosions.clear();
                        circle.x = screen_width() / 2.0;
                        circle.y = screen_height() / 2.0;
                        score = 0;
                        game_state = GameState::Playing;
                    }
                    if ui.button(vec2(65.0, 125.0), "Quit") {
                        std::process::exit(0);
                    }
                },
            );
        }
        GameState::Playing => {
            let delta_time = get_frame_time();
            if is_key_down(KeyCode::Right) {
                circle.x += MOVEMENT_SPEED * delta_time;
                direction_modifier += 0.05 * delta_time;
                ship_sprite.set_animation(2);
            }
            if is_key_down(KeyCode::Left) {
                circle.x -= MOVEMENT_SPEED * delta_time;
                direction_modifier -= 0.05 * delta_time;
                ship_sprite.set_animation(1);
            }
            if is_key_down(KeyCode::Down) {
                circle.y += MOVEMENT_SPEED * delta_time;
            }
            if is_key_down(KeyCode::Up) {
                circle.y -= MOVEMENT_SPEED * delta_time;
            }
            if is_key_pressed(KeyCode::Space) {
                bullets.push(Shape {
                    x: circle.x,
                    y: circle.y - 24.0,
                    speed: circle.speed * 2.0,
                    size: 32.0,
                    collided: false,
                });
                play_sound_once(&resources.sound_laser);
            }
            if is_key_pressed(KeyCode::Escape) {
                game_state = GameState::Paused;
            }

            // Clamp X and Y to be within the screen
            circle.x = clamp(circle.x, 0.0, screen_width());
            circle.y = clamp(circle.y, 0.0, screen_height());

            // Generate a new square
            if rand::gen_range(0, 99) >= 95 {
                let size = rand::gen_range(16.0, 64.0);
                squares.push(Shape {
                    size,
                    speed: rand::gen_range(50.0, 150.0),
                    x: rand::gen_range(size / 2.0, screen_width() - size / 2.0),
                    y: -size,
                    collided: false,
                });
            }

            // Movement
            for square in &mut squares {
                square.y += square.speed * delta_time;
            }
            for bullet in &mut bullets {
                bullet.y -= bullet.speed * delta_time;
            }
            ship_sprite.update();
            bullet_sprite.update();
            enemy_small_sprite.update();

            // Remove shapes outside of screen
            squares.retain(|square| square.y < screen_height() + square.size);
            bullets.retain(|bullet| bullet.y > 0.0 - bullet.size / 2.0);
            // Remove collided shapes
            squares.retain(|square| !square.collided);
            bullets.retain(|bullet| !bullet.collided);
            explosions.retain(|(explosion, _)| explosion.config.emitting);
            // Check for collisions
            if squares.iter().any(|square| circle.collides_with(square)) {
                if score == high_score {
                    fs::write("highscore.dat", high_score.to_string()).ok();
                }
                game_state = GameState::GameOver;
            }
            for square in squares.iter_mut() {
                for bullet in bullets.iter_mut() {
                    if bullet.collides_with(square) {
                        bullet.collided = true;
                        square.collided = true;
                        score += square.size.round() as u32;
                        high_score = high_score.max(score);
                        explosions.push((
                            Emitter::new(EmitterConfig {
                                amount: square.size.round() as u32 * 4,
                                texture: Some(resources.explosion_texture.clone()),
                                ..particle_explosion()
                            }),
                            vec2(square.x, square.y),
                        ));
                        play_sound_once(&resources.sound_explosion);
                    }
                }
            }
            // Draw everything
            let bullet_frame = bullet_sprite.frame();
            for bullet in &bullets {
                draw_texture_ex(
                    &resources.bullet_texture,
                    bullet.x - bullet.size / 2.0,
                    bullet.y - bullet.size / 2.0,
                    WHITE,
                    DrawTextureParams {
                        dest_size: Some(vec2(bullet.size, bullet.size)),
                        source: Some(bullet_frame.source_rect),
                        ..Default::default()
                    },
                );
            }
            let ship_frame = ship_sprite.frame();
            draw_texture_ex(
                &resources.ship_texture,
                circle.x - ship_frame.dest_size.x,
                circle.y - ship_frame.dest_size.y,
                WHITE,
                DrawTextureParams {
                    dest_size: Some(ship_frame.dest_size * 2.0),
                    source: Some(ship_frame.source_rect),
                    ..Default::default()
                },
            );
            for (explosion, coords) in explosions.iter_mut() {
                explosion.draw(*coords);
            }
            let enemy_frame = enemy_small_sprite.frame();
            for square in &squares {
                draw_texture_ex(
                    &resources.enemy_small_texture,
                    square.x - square.size / 2.0,
                    square.y - square.size / 2.0,
                    WHITE,
                    DrawTextureParams {
                        dest_size: Some(vec2(square.size, square.size)),
                        source: Some(enemy_frame.source_rect),
                        ..Default::default()
                    },
                );
            }
            draw_text(
                format!("Score: {}", score).as_str(),
                10.0,
                35.0,
                25.0,
                WHITE,
            );
            let highscore_text = format!("High score: {}", high_score);
            let text_dimensions = measure_text(highscore_text.as_str(), None, 25, 1.0);
            draw_text(
                highscore_text.as_str(),
                screen_width() - text_dimensions.width - 10.0,
                35.0,
                25.0,
                WHITE,
            );
        }
        GameState::Paused => {
            if is_key_pressed(KeyCode::Space) {
                game_state = GameState::Playing;
            }
            let text = "Paused";
            let text_dimensions = measure_text(text, None, 50, 1.0);
            draw_text(
                text,
                screen_width() / 2.0 - text_dimensions.width / 2.0,
                screen_height() / 2.0,
                50.0,
                WHITE,
            );
        }
        GameState::GameOver => {
            if is_key_pressed(KeyCode::Space) {
                game_state = GameState::MainMenu;
            }
            let text = "GAME OVER!";
            let text_dimensions = measure_text(text, None, 50, 1.0);
            draw_text(
                text,
                screen_width() / 2.0 - text_dimensions.width / 2.0,
                screen_height() / 2.0,
                50.0,
                RED,
            );
        }
    }
    next_frame().await
}

}

The project is uploaded to my github.

Your code is looking for assets relative to the directory you are running your program from.
If I put myself in the target/debug dir and execute "spaceassault" I get an error. If I am in the source directory and execute "/path/to/target/debug/spaceassault" it works fine.

If you add a little print debugging it helps figure out what is happening.

 for path in possible_paths {
        if Path::new(path).exists() {
            set_pc_assets_folder(path);
            println!("Assets loaded from: {}", path);
            return;
        } else {
            println!("No asssets found in : {}", path);
        }
    }

Side Note:
You can embed the assets in your game.

I should add that this issue was on MacOS. I just built the executable on Windows and everything works perfectly. So the issue seems to have something to do with how Macroquad works on MacOS