ViZDoom
ViZDoom copied to clipboard
Multiplayer game recording does not work
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
Ok, I managed to fix this for multiplayer games. Here's the recipe that works:
-
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 -
Do not call
new_episode()until demo is saved -
Send the
stopcommand one frame before the episode end to force the game to save the demo to disc
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()