Grimmys / rpg_tactical_fantasy_game

A tactical turn-based game project in pygame, open to support
GNU General Public License v3.0
392 stars 85 forks source link

Game Crash When Loading Level3 #70

Closed JimZhouZZY closed 4 months ago

JimZhouZZY commented 11 months ago

Crash after level loading scene.

pygame 2.5.0 (SDL 2.28.0, Python 3.10.11)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\main.py", line 95, in <module>
    main_loop(scene_manager, main_screen, pygame.time.Clock())
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\main.py", line 33, in main_loop
    quit_game = game_controller.process_game_iteration()
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\src\services\scene_manager.py", line 52, in process_game_iteration
    if self.active_scene.update_state():
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\src\scenes\level_loading_scene.py", line 120, in update_state
    self.level.load_level_content()
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\src\scenes\level_scene.py", line 327, in load_level_content
    self.missions, self.main_mission = tmx_loader.load_missions(
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\src\services\load_from_tmx_manager.py", line 136, in load_missions
    main_mission = _load_mission(tmx_data, True, "main", players)
  File "D:\Py\RPG\repo\origin-master\rpg_tactical_fantasy_game\src\services\load_from_tmx_manager.py", line 104, in _load_mission
    targets = foes_by_mission.pop(mission_id)
KeyError: 'main'

It seems dict foes_by_mission is not loaded properly. It's an empty dictionary.

Grimmys commented 10 months ago

Ok, I think I found the root cause of the issue.

First of all, it's happening only when loading the level from save, not when reaching it "normally" (so initial load is working fine).

The issue is that when loading level from save, data such as foes is loaded from the XML save file, using load_from_xml_manager.py, but missions are loaded from the TMX map file (using load_from_tmx_manager.py), because this kind of data is static: it's never going to change. And it's then looking for the foes related to the mission in its own version of foes_by_mission dict, which is going to be empty.

Suggested solution: move foes_by_mission and its associated method(s) to a common file that would be used by both services, to avoid code duplication and fix the issue of data loaded in one place but fetched in another.

Grimmys commented 10 months ago

foes_by_mission_issue_saves.zip

This archive contains 2 saves to easily reproduce the issue:

If you want to use these saves, don't forget to move them to the saves folder and rename them to a valid slot (i.e save_[0-2].xml).

JimZhouZZY commented 10 months ago

Good to hear that. But unfortunately I dont have the leisure for further investigation. Hope it can be fixed soon.

Best wishes.

Grimmys commented 10 months ago

Sure @JimZhouZZY , I know don't worry!

When I say "you", I mean anybody stumbling on my message and wanting to contribute to the issue.

That's not because you opened the issue that you are responsible of it.

silent-lindsay commented 6 months ago

Ok, I think I found the root cause of the issue.

First of all, it's happening only when loading the level from save, not when reaching it "normally" (so initial load is working fine).

The issue is that when loading level from save, data such as foes is loaded from the XML save file, using load_from_xml_manager.py, but missions are loaded from the TMX map file (using load_from_tmx_manager.py), because this kind of data is static: it's never going to change. And it's then looking for the foes related to the mission in its own version of foes_by_mission dict, which is going to be empty.

Suggested solution: move foes_by_mission and its associated method(s) to a common file that would be used by both services, to avoid code duplication and fix the issue of data loaded in one place but fetched in another.

hello, when I was fixing this bug, something puzzled me that in which condition the file "load_from_xml_manager.py" would be loaded and initialized. I had some attempts to debug in load_from_xml_manager.py but found this file was never steped in.

silent-lindsay commented 6 months ago

foes_by_mission_issue_saves.zip

This archive contains 2 saves to easily reproduce the issue:

  • _save_level2.xml is a save from the previous level, where "Chrisemon" is already next to the altar (mission objective): you just need to select him and "Take" to go the next level, the level should load without issue.
  • _save_level3.xml is a save from the level where the issue can be reproduce, as of now, the game should be crashing because of the explanations given above.

If you want to use these saves, don't forget to move them to the saves folder and rename them to a valid slot (i.e save_[0-2].xml).

Now I think I have fixed this bug well. Following your solution, I moved dict foes_by_mission to a global variable file which was initialized only once and altered only through the new method link_foe_to_mission.

Grimmys commented 4 months ago

Fixed as part of https://github.com/Grimmys/rpg_tactical_fantasy_game/pull/80