def reset(self):
        """
        Clear and generate the whole scene
        """
        # reset logger
        reset_logger()
        step_infos = {}

        # initialize
        self._episode_start_time = time.time()
        self.episode_step = 0
        if self.global_config["debug_physics_world"]:
            self.addTask(self.report_body_nums, "report_num")

        # Update record replay
        self.replay_episode = True if self.global_config["replay_episode"] is not None else False
        self.record_episode = self.global_config["record_episode"]
        self.only_reset_when_replay = self.global_config["only_reset_when_replay"]

        _debug_memory_usage = False

        if _debug_memory_usage:

            def process_memory():
                import psutil
                import os
                process = psutil.Process(os.getpid())
                mem_info = process.memory_info()
                return mem_info.rss

            cm = process_memory()

        # reset manager
        for manager_name, manager in self._managers.items():
            # clean all manager
            new_step_infos = manager.before_reset()
            step_infos = concat_step_infos([step_infos, new_step_infos])
            if _debug_memory_usage:
                lm = process_memory()
                if lm - cm != 0:
                    print("{}: Before Reset! Mem Change {:.3f}MB".format(manager_name, (lm - cm) / 1e6))
                cm = lm
        self.terrain.before_reset()
        self._object_clean_check()

        for manager_name, manager in self.managers.items():
            if self.replay_episode and self.only_reset_when_replay and manager is not self.replay_manager:
                # The scene will be generated from replay manager in only reset replay mode
                continue
            new_step_infos = manager.reset()
            step_infos = concat_step_infos([step_infos, new_step_infos])

            if _debug_memory_usage:
                lm = process_memory()
                if lm - cm != 0:
                    print("{}: Reset! Mem Change {:.3f}MB".format(manager_name, (lm - cm) / 1e6))
                cm = lm

        for manager_name, manager in self.managers.items():
            new_step_infos = manager.after_reset()
            step_infos = concat_step_infos([step_infos, new_step_infos])

            if _debug_memory_usage:
                lm = process_memory()
                if lm - cm != 0:
                    print("{}: After Reset! Mem Change {:.3f}MB".format(manager_name, (lm - cm) / 1e6))
                cm = lm

        # reset terrain
        # center_p = self.current_map.get_center_point() if isinstance(self.current_map, PGMap) else [0, 0]
        center_p = [0, 0]
        self.terrain.reset(center_p)

        # move skybox
        if self.sky_box is not None:
            self.sky_box.set_position(center_p)

        # refresh graphics to support multi-thread rendering, avoiding bugs like shadow disappearance at first frame
        for _ in range(5):
            self.graphicsEngine.renderFrame()

        # reset colors
        BaseEngine.COLORS_FREE = set(COLOR_SPACE)
        BaseEngine.COLORS_OCCUPIED = set()
        new_i2c = {}
        new_c2i = {}
        # print("rest objects", len(self.get_objects()))
        for object in self.get_objects().values():
            if object.id in self.id_c.keys():
                id = object.id
                color = self.id_c[object.id]
                BaseEngine.COLORS_OCCUPIED.add(color)
                BaseEngine.COLORS_FREE.remove(color)
                new_i2c[id] = color
                new_c2i[color] = id
        # print(len(BaseEngine.COLORS_FREE), len(BaseEngine.COLORS_OCCUPIED))
        self.c_id = new_c2i
        self.id_c = new_i2c
        return step_infos

        Clear and generate the whole scene
        
metadrive/engine/base_engine.py