Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Multiplayer game recording does not work #402

Open
alex-petrenko opened this issue Jul 20, 2019 · 2 comments
Open

Multiplayer game recording does not work #402

alex-petrenko opened this issue Jul 20, 2019 · 2 comments
Labels

Comments

@alex-petrenko
Copy link

alex-petrenko commented Jul 20, 2019

Multiplayer recording does not seem to work.
I tried to run the example script record_multiplayer.py, it goes through 1 multiplayer episode successfully, but then the recorded .lmp file is nowhere to be found. I believe Doom does not actually write this file to disk for some reason:

...

Player2 frags: 0.0
Game finished!
Player1 frags: 0.0

REPLAY
************************

Gtk-Message: 18:32:11.653: Failed to load module "canberra-gtk-module"
Traceback (most recent call last):
  File "/home/apetrenk/miniconda3/envs/doom-rl/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/home/apetrenk/miniconda3/envs/doom-rl/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/apetrenk/all/projects/doom/ViZDoom/examples/python/record_multiplayer.py", line 101, in <module>
    replay_as_player2()
  File "/home/apetrenk/all/projects/doom/ViZDoom/examples/python/record_multiplayer.py", line 75, in replay_as_player2
    game.replay_episode("multi_rec.lmp", 2)
vizdoom.vizdoom.FileDoesNotExistException: File "multi_rec.lmp" does not exist.
  • ViZDoom version you are using: 1.1.8 (latest from master)
  • information about your OS: Ubuntu 18.04
@Miffyli Miffyli added the bug label Sep 5, 2019
@alex-petrenko
Copy link
Author

Ok, I managed to fix this for multiplayer games. Here's the recipe that works:

  1. use -record CLI argument, this is the only method that works for multiplayer, e.g. self.game.add_game_args(f'-record {demo_path}')
    Only the very first played episode will be recorded

  2. Do not call new_episode() until demo is saved

  3. Send the stop command one frame before the episode end to force the game to save the demo to disc

@alex-petrenko
Copy link
Author

alex-petrenko commented Feb 26, 2020

Example script:

from __future__ import print_function
import os
import time
from random import choice
from threading import Thread
from vizdoom import *
def demo_name(episode_):
    return f'multi_rec{episode_}.lmp'
def set_timeout(game):
    timeout_minutes = 0.2
    game.set_episode_timeout(int(timeout_minutes * 60 * game.get_ticrate()))
    print('Game timeout:', game.get_episode_timeout())
def player1():
    game = DoomGame()
    game.load_config('/home/alex/all/projects/doom-neurobot/envs/doom/scenarios/ssl2.cfg')
    game.add_game_args(f'-record {demo_name(0)}')
    game.add_game_args("-host 2 -deathmatch +sv_spawnfarthest 1")
    # game.set_mode(Mode.ASYNC_PLAYER)
    game.add_game_args("+name Player1 +colorset 0")
    set_timeout(game)
    # Unfortunately multiplayer game cannot be recorded using new_episode() method, use this command instead.
    game.init()
    actions = [[True, False, False], [False, True, False], [False, False, True]]
    for episode in range(1):
        # game.add_game_args(f'-record {demo_name(episode)}')
        if episode > 0:
            game.new_episode()
        i = 0
        while not game.is_episode_finished():
            i += 1
            if game.is_player_dead():
                game.respawn_player()
            game.make_action(choice(actions))
            if game.get_episode_time() + 1 == game.get_episode_timeout():
                game.send_game_command('stop')
            done = game.is_episode_finished()
            # print(game.get_episode_time(), game.get_episode_timeout(), game.get_ticrate())
    print("Game finished!")
    print("Player1 frags:", game.get_game_variable(GameVariable.FRAGCOUNT))
    game.close()
def player2():
    game = DoomGame()
    game.load_config('/home/alex/all/projects/doom-neurobot/envs/doom/scenarios/ssl2.cfg')
    game.set_window_visible(True)
    game.add_game_args("-join 127.0.0.1")
    game.add_game_args("+name Player2 +colorset 3")
    set_timeout(game)
    game.init()
    actions = [[True, False, False], [False, True, False], [False, False, True]]
    for episode in range(1):
        if episode > 0:
            game.new_episode()
        while not game.is_episode_finished():
            if game.is_player_dead():
                game.respawn_player()
            game.make_action(choice(actions))
    print("Player2 frags:", game.get_game_variable(GameVariable.FRAGCOUNT))
    game.close()
def replay_as_player2():
    game = DoomGame()
    game.load_config('/home/alex/all/projects/doom-neurobot/envs/doom/scenarios/ssl2.cfg')
    # At this moment ViZDoom will crash if there is no starting point - this is workaround for multiplayer map.
    game.add_game_args("-host 1 -deathmatch")
    game.set_mode(Mode.PLAYER)
    game.init()
    # Replays episode recorded by player 1 from perspective of player2.
    game.replay_episode(demo_name(0), 2)
    while not game.is_episode_finished():
        # time.sleep(1)
        game.advance_action()
    print("Game finished!")
    print("Player1 frags:", game.get_game_variable(GameVariable.PLAYER1_FRAGCOUNT))
    print("Player2 frags:", game.get_game_variable(GameVariable.PLAYER2_FRAGCOUNT))
    game.close()
    # Delete multi_rec.lmp
    # os.remove(demo_name(0))
if __name__ == '__main__':
    print("\nRECORDING")
    print("************************\n")
    # if not os.path.exists('multi_rec.lmp'):
    #     os.mknod('multi_rec.lmp')
    p1 = Thread(target=player1)
    p1.start()
    time.sleep(0.1)
    player2()
    print("\nREPLAY")
    time.sleep(1)
    print("************************\n")
    replay_as_player2()

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants