Yes, $user_id isn’t available inside of your function. You need to pass the author’s id to the function as a parameter. Try this code. It also checks if the Discourse username has been set. If it’s not set, the default author link will be returned.
add_filter( 'author_link', 'wpdc_modify_author_link', 10, 2 );
function wpdc_modify_author_link( $link, $author_id ) {
$discourse_username = get_user_meta( $author_id, 'discourse_username', true );
if ( ! empty( $discourse_username ) ) {
return "https://community.naturephotographers.network/u/$discourse_username";
}
return $link;
}