I am trying to learn C++ and have been testing the new modules system with a toy game engine. Unfortunately, this one linking error I keep getting tells me nothing and I don't understand what I'm doing wrong. All I can really figure out is that the main function can't see the implementation of the play function, but I don't know how to fix it. I've cut my project down into the bare minimum so hopefully it's clearer to an experienced C++ programmer. Any input is appreciated, thanks.
main.cxx
import engine;
int main() {
    engine::game<engine::text_ui> my_game("My Game");
    my_game.play();
}
engine.ixx
export module engine;
export import :game;
export import :ui;
game.ixx
export module engine:game;
export import <concepts>;
export import <string>;
export import :ui;
namespace engine {
    export template<typename ui_t>
    requires std::derived_from<ui_t, ui>
    class game {
        std::string name;
        ui_t ui;
    public:
        game(std::string name) : name{name} {};
        void play() const;
    };
}
game.cxx
module engine:game;
import <concepts>;
import :ui;
namespace engine {
    template<typename ui_t>
    requires std::derived_from<ui_t, ui>
    void game<ui_t>::play() const {
        ui.notify(name + " is being played.\n");
    }
}
ui.ixx
export module engine:ui;
export import <string>;
export import <iostream>;
namespace engine {
    export class ui {
    public:
        virtual void notify(std::string text) const = 0;
    };
    export class text_ui : public ui {
        std::istream& in{std::cin};
        std::ostream& out{std::cout};
    public:
        void notify(std::string text) const override { out << text; };
    };
}
error
LNK2019 unresolved external symbol
"public: void __thiscall engine::game<class engine::text_ui>::play(void)const "
(?play@?$game@Vtext_ui@engine@@@engine@@QBEXXZ::<!engine>)
referenced in function _main
 
    