Git Product home page Git Product logo

Comments (4)

mwydmuch avatar mwydmuch commented on July 17, 2024 1

Hi @sean-mulready, thank you for opening the issue. I believe you wrote an email to me some time ago. I apologize for the lack of response from my side... unfortunately, I lacked time to respond to it, as there was quite a lot of stuff to unpack. I'm sorry :(

When it comes to this question, I believe the @Miffyli is right here. There are a few reasons, that I see and can cause the spikes in the performance, but I don't want to get into that here. While for sure it is possible to make your script a bit faster, I would like to propose to you some other solution that will be much better for your studies in my opinion.

If I understand correctly, you would like to analyze the games of human players, and your scripts log some data while they play. We actually have the functionality in ViZDoom that allows you to "record" the games into very small files that can be used to recreate the games perfectly with completely different settings (different resolutions, additional game variables, etc.), the "recording" files store the sequence of actions that the player took during their game and, based on that, the library is able to recreate what happened. It works both for PLAYER as well as SPECTATOR modes. The usage of this functionality is demonstrated here: https://github.com/Farama-Foundation/ViZDoom/blob/master/examples/python/record_episodes.py

This way, you can create one script that just runs and records the game without any processing (resulting in no problem with performance), and then you can analyze it in another script without worrying about real-time performance. This will also allow you to improve your analysis and repeat it without the need to get people to play the game again. This functionality is battle-tested, as it was used to create all the videos on our YT channel: https://www.youtube.com/@ViZDoom/videos -> we first recorded the games (some played by algorithms, some by people) and created the videos later.

If you would like to ask some more questions, I invite you to our Farama discord server, where you can find me almost every day, I'm definitely much faster to respond to short chat messages: https://discord.com/invite/PfR7a79FpQ

from vizdoom.

Miffyli avatar Miffyli commented on July 17, 2024

I see you are measuring the time difference with Python's time.time. I reckon this will result in bit of variation between steps, as the exact time it takes for vizdoom to simulate a step + handle all Python stuff. It may not exactly reflect how the timing is happening inside the game.

To reduce this variation, I would recommend making the busy loop that interacts with environment and stores information as quick as possible. However it already looks like it is pretty fast.

Another thing for more accurate time measurements, you could use time.perf_counter instead of time.time, which providers more reliable time measurement (but does not help with this case).

Edit: To follow the game (Doom time), use the Tic array instead of Time.

from vizdoom.

sean-mulready avatar sean-mulready commented on July 17, 2024

Hi @Miffyli , hi @mwydmuch ,
thank you both so much for responding so fast (and no worries about any unanswered mails :) ). I'll keep this short:
The suggestion with the two scripts for recording and analyzing got me so excited when I read about last night, that I already spent 3 h today to copy/paste and write these scripts out of the current. And I'm excited as the mean (and median) of my time-diff already got down to 23 ms! And the whole data looks more stable now.
Next thing is to implement the suggested time.perf_counter just out of curiosity :)
I already encountered some minor Problems but I think that'll be subject of short messages on Discord.

Again: Thank both of you!

from vizdoom.

mwydmuch avatar mwydmuch commented on July 17, 2024

@sean-mulready happy to hear that. As @Miffyli said, you don't really need to measure the time by yourself if you need it, you can calculate it based on the state.tic variable, every tic = 1/35 of a second.

Also, if you want your players to have a smooth experience, you should use the ASYNC_SPECTATOR mode, which will progress the game at a normal speed without waiting for the Python controller to respond to every single frame.
Then you can analyze the data in the normal mode at the speed you need to process/extract what you need.

Here I prepare a quick draft of the scripts to demonstrate the idea:

The script for recording the game, it just allows to play specific scenarios and the number of episodes:

import os
import vizdoom as vzd

# Config
scenario = "basic"  # Scenario to play
episodes = 10  # Number of episodes to play
sub_id = "01"  # Test subject


game = vzd.DoomGame()

# Load the scenario config
game.load_config(f"{scenario}.cfg")

# Set some resolution that is pleasant for humans
game.set_screen_resolution(vzd.ScreenResolution.RES_1280X720)
game.set_render_hud(True)

# Use ASYNC_SPECTATOR mode for perfect real-time gaming experience
game.set_mode(vzd.Mode.ASYNC_SPECTATOR)
game.init()

# Recording
print("\nRECORDING EPISODES")
print("************************\n")

# Create a directory for recordings
os.mkdir("recordings")

# Play the specified number of episodes
for i in range(episodes):
    recording_file = f"recordings/{scenario}_sub={sub_id}_epi={i}_rec.lmp"
    game.new_episode(recording_file)

    while not game.is_episode_finished():
        a = game.advance_action()  # Do nothing, just advance action till the end of the episode

    # Report the end of the episode
    print(f"Episode {i} finished. Saved to file {recording_file}")
    print("Total reward:", game.get_total_reward())
    print("************************\n")

game.new_episode()  # This is currently required to ensure the proper stopping and saving of the recording from the last episode (It's a bug I just discovered. I will fix it soon).
game.close()

Now that we have the recordings, we can analyze them this way:

import vizdoom as vzd
from time import sleep

# Config
scenario = "basic"  # Scenario to play
episodes = 10  # Number of episodes to play
sub_id = "01"  # Test subject


game = vzd.DoomGame()

# Use the same config (this is important)
game.load_config(f"{scenario}.cfg")

# New render settings for the replay, since you are not using the screen buffer, set the resolution to smaller to make processing faster
game.set_screen_resolution(vzd.ScreenResolution.RES_320X240)
game.set_render_hud(False)

# Enable additional information that is needed for the analysis

# Enables information about all objects present in the current episode/level.
game.set_objects_info_enabled(True)

# Enables information about all sectors (map layout).
game.set_sectors_info_enabled(True)

#(...) and some other things you need


# The game mode doesn't really matter in this case, so we don't set it and just init the game
game.init()

print("\nREPLAYING THE EPISODES")
print("************************\n")

for i in range(episodes):
    recording_file = f"recordings/{scenario}_sub={sub_id}_epi={i}_rec.lmp"
    game.replay_episode(recording_file)

    while not game.is_episode_finished():
        # Get a state
        s = game.get_state()

        # Proceed to the next state
        game.advance_action()

        # Retrieve the last actions, and the reward
        a = game.get_last_action()  # The example wrongly stated that it's not possible, but we actually implemented it later
        r = game.get_last_reward()

        # Do your analysis here, or dump the date to another format you would like to work with
        print(f"Tic #{s.tic}") 
        # The game will wait for you, so do it as long as you need, you will see that tic count will always increment by 1
        sleep(1) # To simulate a hard work of your script

    print("Episode", i, "finished.")
    print("Total reward:", game.get_total_reward())
    print("************************")

game.close()

from vizdoom.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.