Homunculus Devlog 2018-06-09

By Max Woerner Chase

In this post:


Okay everyone, let's crack open part 10 of the roguelike tutorial and see if I wrote myself into any corners with my extensive rewrites.

I left off around "Now let's change our main loop. It'll display the main menu, and depending on the player's choice, it will either start a new game, load an existing one, or exit the program."

The main functions start off the same, but the tutorial is still setting up individual variables instead of initializing an object. I'll add in these show_* variables and see where it goes with this. And the background image. I'll try to splice in the rest of the logic after my "game = None" line; I sense things could get a little dicier now. So, the rest of the tutorial main function is in a loop. I'm going to make it "while True" until I work out how I want to apportion the responsibility for checking on the windows. I notice that some of the names collide with stuff I've defined, so I'm going to prefix the tutorial variables with underscores for now.

Actually, I probably didn't need to do that. Anyway, I got all the way to the end of the chapter, fired up the runner, and—

... Well, it didn't throw any exceptions, so technically it all works, right?

Right? Yes, um, I should figure out why it didn't seem to enter the loop. I have some ideas.

Okay, it turns out I left off a "not" when I was copying a conditional, which is a pretty big deal! That doesn't explain why the input handling is flaky. I'll check again and see what I find.

"AttributeError: 'NoneType' object has no attribute 'play'" Yeah, this is my fault somehow. Found the issue. I'd been messing around with the logic, attempting "clever" stuff, and I clevered myself out of actually keeping the game loaded.

... Eh. Something's still wrong with the logic. I want to get that fixed, then call it a week.

Time to stick print statements in places. Okay, it's reading the load-game branch. So the logic must be faulty.

Got it. I'd glazed over one of the bits where "show_main_menu" gets set to False. I would like to reiterate that this tutorial has no tests.

Here's where the main function stands now:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# To test: ... augh

import os

from tcod import image_load
import tdl

from . import RESOURCES_DIR
from . import constants
from .input_handlers import handle_main_menu
from .menus import main_menu, message_box
from .new_game import new_game
from .save_load import load_game


def main():

    tdl.set_font(
        os.path.join(RESOURCES_DIR, 'arial10x10.png'),
        greyscale=True,
        altLayout=True)

    root_console = tdl.init(
        constants.SCREEN_WIDTH,
        constants.SCREEN_HEIGHT,
        title=constants.WINDOW_TITLE)
    con = tdl.Console(constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT)
    panel = tdl.Console(constants.SCREEN_WIDTH, constants.PANEL_HEIGHT)

    show_main_menu = True
    show_load_error_message = False

    main_menu_background_image = image_load(
        os.path.join(RESOURCES_DIR, 'menu_background.png'))

    game = None

    while not tdl.event.is_window_closed():
        user_input = None

        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
                user_input = event
                break

        if show_main_menu:
            main_menu(
                root_console,
                main_menu_background_image,
                constants.SCREEN_WIDTH,
                constants.SCREEN_HEIGHT,
                constants.COLORS)

            if show_load_error_message:
                message_box(
                    root_console,
                    'No save game to load',
                    50,
                    constants.SCREEN_WIDTH,
                    constants.SCREEN_HEIGHT)

            tdl.flush()

            action = handle_main_menu(user_input)

            if show_load_error_message and action:
                show_load_error_message = False
            elif action.get('new_game'):
                game = new_game()
            elif action.get('load_saved_game'):
                try:
                    with open(constants.SAVE_FILE) as save_data:
                        data = save_data.read()
                        if data:
                            game = load_game(data)
                except FileNotFoundError:
                    pass
                show_load_error_message = not game
            elif action.get('exit_game'):
                break
            show_main_menu = not game
        else:
            root_console.clear()
            con.clear()
            panel.clear()
            game.play(root_console, con, panel)
            game = None

            show_main_menu = True

Next week, new functionality on several levels! Also, I think I want to redo the component system.