Skip to content
New issue

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

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

Already on GitHub? Sign in 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()

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

No branches or pull requests

2 participants