// public static async Task<GameScript> LoadAsync( // IEnumerable<ScriptFile> sources, // IScriptCompiler compiler) // { // // TODO Dispose ScriptRunner // using var scriptRunner = compiler.Compile<Game>(sources); // EventQueue eventQueue = new(); // var game = new Game(eventQueue); // await scriptRunner.RunAsync(game); // return new GameScript(game, eventQueue); // } public Task RunAsync(IMediator mediator, GameState?gameState = null) { // Filter event queue while setting up the game. Only ProtagonistChanged // and RoomEntered should be sent to the UI when the game starts. _eventQueue.IgnoreAll(); // Runs the OnGameStart callback in the game script. _game.Start(); // From this point on, allow all events to go to the UI. _eventQueue.AllowAll(); // We do need to make sure that the startup script has at least set // a protagonist and room. if (_game.Protagonist is null) { throw new InvalidOperationException( "Startup script must set a protagonist."); } if (_game.CurrentRoom is null) { throw new InvalidOperationException( "Startup script must enter a room."); } // Save the initial state so we've got something to compare to when // saving the game. _initialState = _game.Save(); if (gameState is not null) { _game.Load(gameState); } _eventQueue.Enqueue(new GameStarted(_game)); _eventQueue.Enqueue(new ProtagonistChanged(_game.Protagonist !)); _eventQueue.Enqueue(new RoomEntered(_game.CurrentRoom !)); return(_eventQueue.FlushAsync(mediator)); }