Thursday, March 3, 2016

Lessons learned: Syntax is everything

I may have mentioned this before, but I am not a very good programmer.

Back in high school, I learned the basics of HTML. Straight HTML, mind you. I could make some of the ugliest damned webpages you ever saw, all with the glory of friggin' Notepad. It taught me the basics of program logic, but beyond that I can't say I ever learned any useful programming skills.

That said, I am capable of sort of reading code. So transitioning to Python and learning the rules the hard way (ie: jumping right in with both feet) has been interesting to say the least. *laughs* I've made some real progress.

Ren'Py utilizes Python scripting, but it seems to have its own rules and shortcuts, which make things easier for guys like me who haven't bothered to learn programming via proper channels. What I do is much less programming, and much more like hacking things apart and trying to stitch it together into some sort of Frankenstein's Monster in the hopes that it works (it's aliiiiiiiive!).

Tonight I set some fairly simple goals for myself:

- Set up the class system, and create placeholders for all of the classes

- Ensure that only Attend Class shows up on the appropriate days

- Check to see that the correct class is being executed on a given day and time period

Needless to say, it provided me with a few challenges right off the bat. Chief of all: How do we determine when classes become available?

Because of the structure of the game, it is necessary to differentiate between morning and afternoon classes, as well as to differentiate 'Monday' classes from the rest of the week. This creates ten courses, all of which have their own set skill increases associated with them. Furthermore, if I feel the need to create actual events that take place during these classes, I need to find a way to have them all execute in the correct order.

The first idea that came to mind was to use the day counter that comes packaged into the DSE code. It looked a little something like this;

init python:
    register_stat("Strength", "strength", 10, 100)
    register_stat("Intelligence", "intelligence", 10, 100)
    register_stat("Charisma", "charisma", 50, 100)
        dp_period("Morning", "morning_act")
        if (day == 1 or day == 8):
            dp_choice("Attend Class1", "class01")
        if day == 2:
            dp_choice("Attend Class2", "class03")
        if day == 3:
            dp_choice("Attend Class3", "class05")
        if day == 4:
            dp_choice("Attend Class4", "class07")
        if day == 5:
            dp_choice("Attend Class5", "class09")
        if (day == 6 or day == 7):
            dp_choice("Something Else", "class05")
   
    # This is an example of an event that should only show up under special circumstances
    ###dp_choice("Fly to the Moon", "fly", show="strength >= 100 and intelligence >= 100")
        dp_period("Afternoon", "afternoon_act")
        dp_choice("Study", "study")
        dp_choice("Hang Out", "hang")
        dp_period("Evening", "evening_act")
        dp_choice("Exercise", "exercise")
        dp_choice("Play Games", "play")
   
        dp_period ("Late Eve", "late_act")
        dp_choice ("Twiddle Thumbs", "twiddle")
        dp_choice ("Stare at ceiling", "stare")

It makes perfect sense, except that when you try to run it, it throws an exception: "day not defined".

What gives? Day is clearly defined - it says so right down below in the start code! This was the first major lesson of the day - Day is not defined in the intro block, and you cannot define it in the init code because every time you load the game, it would force the day to become 0 - regardless of what the actual day was. This provides a problem, because you only want the day to become 0 at the start of the game! How do we get around this?

It took some finagling, but I found that placing the day planner code after the day code is initialized gets around this. Now the game properly only provides the correct option depending on what day number it is. Which led to the next problem: While the correct option was showing up, for some reason none of the events were playing out properly! The day progressed, and the correct placeholder for the class was showing up (proving that the correct buttons with the correct commands were being displayed). But for some reason, the execution of the day planner was skipping over my placeholders.

Eventually, I found the source, and it lay in the event planner's code.

    $ event("class01", "act == 'class'", event.only(), priority=200)
    $ event("class02", "act == 'class'", event.only(), priority=200)
    $ event("class03", "act == 'class'", event.only(), priority=200)
The problem lay in the act. The correct event (Class 01 for example) was being called. But instead of executing the correct event, it was attempting to jump to 'Class'. My mistake was in thinking that act meant a classification of an action - instead, that's the part of the code that tells it 'jump to this event name' (or 'when this action is called, jump to this event', I haven't figured out which yet). So essentially, I wound up breaking it completely by accident, but it wound up fixing itself once I corrected the error. So now the correct classes show up on the correct days I tell it, and the correct placeholder activates.

Unfortunately, this has presented a new problem that I didn't anticipate until I sat down to write my progress for the night: While the code works in execution, loading a saved game during the start of the day (when you would decide what to do for the day), everything breaks.

Why does this happen? Because when you load the game fresh and jump right into a save, the start-of-day code has already executed, meaning none of the day planner options have initialized, because they were not defined when the game loaded. Using the "roll back" option to step back to just before the day initializes causes the code to execute properly, but you should not be required to step back the first time you load your game because it hasn't figured out what Morning is.

I haven't found a solution for this yet, but hopefully tomorrow I can figure it out (if I don't manage it tonight before I go to bed).

So while I've hit my goals for the evening, I'm still left with one puzzle that I may leave for tomorrow.

No comments:

Post a Comment