Call and Return

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Eiliya
Regular
Posts: 148
Joined: Tue Dec 04, 2012 6:21 am
Contact:

Call and Return

#1 Post by Eiliya »

I've been working on making a combat system of my own (since Jake's thing is too complex for my tiny brain) and I've run into an issue.

My system generates a random encounter which then calls the combat system. Stats are used to decide which combatant goes first and then a call is made to the proper combatant. That combatants label then starts by generating the CUI, followed by checking for death. If hp is less than one the script jumps to the game over label, if not the player (or AI for the enemy) continues until they are done, at which point the script calls the other combatant. This is then repeated until either the player is defeated or the enemy is vanquished. When the monster is vanquished, I tried using return to simply have the script backtrack until it reaches the place where the random encounter was first called from, and then just continue from there. According to my theory, it should work.

But it doesn't, which is why I am here typing. When the player gets defeated, the script jumps to the label death, which in turn jumps to the label game_over, which simply drops the script off at the bottom of the file. In my previous experience, this caused the game to revert back to the main menu, but for some reason, it just sends me back to the place in the player combat script where the death label was jumped to. I also tried to add a return at the bottom of the game over label, but it made no difference.

Here's my code, if anyone can figure out what I'm doing wrong, please let me know.

Code: Select all

label start:
    "-Snip-"
    call random_encounter
    "-Snip2-"

label random_encounter:
    #Remember to add a random generator here. For now, it just gives a single encounter, a swarm of bats.
    $ enemy = 1
    call combat_setup
    return

label combat_setup:
    #This contains lots of python code that sets the stats for the two combatants based on the values of $ player and $ enemy.
    #I didn't include it because it works as intended and is really, really long.
    call combat_ui
    if p_spd > e_spd:
        call p_turn
    else:
        call e_turn
    return

label combat_ui:
    #Lots of code that sets the health bar for the player and enemy based on current hp values.
    return

label p_turn:
    call combat_ui
    if p_hp < 1:
        jump death
    else:
        pass
    if p_act < 1:
        #Code to return enemy stats to proper states.
        call e_turn
    else:
        menu:
            "Attack":
                #Code to calculate the attack and it's consequenses.
                $ p_act -= 1
                call p_turn
            "Special":
                #Code for special abilities and magic. p_act modifications vary depending on action, and is included here.
                call p_turn
            "Brace":
                #Code adding the effects of bracing.
                $ p_act -= 1
                call p_turn
    return

label e_turn:
    call combat_ui
    if e_hp < 1:
        "The enemy is dead."
        return
    else:
        if e_act < 1:
            #Code to return player stats to proper states.
            call p_turn
        else:
            $ e_act -= 1
            if e_hp < 8 and e_mp > 0:
                #Code for special attack.
                call e_turn
            else:
                #Code for regular attack.
                call e_turn
    return

label death:
    "You have died."
    jump game_over

label game_over:
    "Thank you for playing, I hope you had a good time."

#### And this is the end of the file ####
Of course, I have clipped out the insanely long python stuff about how the combat works, stats and ui and similar things. If this code provided up above actually works properly for you people, I will reply with the unaltered version. As for what is actually happening for me when I try the game, the code seems to create an infinite loop.

Edit: As a note, this code actually does NOT work for me (in the way that it creates the infinite loop) which seems to indicate (at least to me) that the fault is somewhere in the code I typed up above. Hence why I typed "if the code works for you people."

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Call and Return

#2 Post by trooper6 »

I'm very suspicious of your call combat_ui label and how often you call it. I have a suspicion that you are using lots of ui code--which is the older style that is not as preferred as the newer screen language. If you had a screen (or a couple of screens) with all of your hud elements, then you could just show the screen at the beginning of combat and then hide it at the end of combat. It would cut down on some of your over complicated branching.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

Eiliya
Regular
Posts: 148
Joined: Tue Dec 04, 2012 6:21 am
Contact:

Re: Call and Return

#3 Post by Eiliya »

Yeah, I do use a lot of code for the UI, and it's called every time a combatants turn begins, so that it's able to properly display the current health of both combatants. I would very much like to replace it with something better, but I have no idea at all of how to do that. I looked at the various tutorials and information (such as the renpy documentation) regarding it, and it made absolutely no sense what-so-ever for me, so I decided to go with this, which is a form I at least understand how it works.

My UI code is very simple at this stage. When the label is called, it simply checks the player hp and the enemy hp and then assigns an image based on the value it gets. Like this:

Code: Select all

label combat_ui:
    if p_hp == 14:
        show player_014
    elif p_hp == 1:
        show player_001
    #These very simple if statements go from 0 hp to 150 hp for both the player and the enemy and then ends with a return function.
    return
Of course, I know there's a bar function that could probably fill this specific funtion is a much less complicated way, but I don't understand how to use it. Sure, I know how to make a bar, but how to I alter it's apperance based on what it shows, how do I assign values telling where in the sceen I want it, and how do I create multiple bars? What if I want it shown as a collumn instead of a bar? Or a circle, as is the case for the player health bar in my game?

Here's an exaple of what my enemy health bar looks like (http://i.imgur.com/y9Mxs6B.gifv). It's composed of a multitude of .png files (one for each value of health) and then simply displays the correct one based on the current enemy health. How do I implement this graphic into the screen bar function to make it work as I want it to?

......I just realized that this was an off-topic question, so I will repost it in a separate topic and ask for help there. Even after I removed the combat_ui call from my code, I still get an error. This time, when the player dies and the game jumps to the death/game_over labels, it just continues from the previous point as if the jump to death never happened. Here's an example:

The player makes it into the first dungeon (call dungeon_01). As soon as the exploration begins, the game causes a random encounter (call combat_setup). The player acts first (call p_turn), and once they are done, the game swaps to the enemy (call e_turn). The enemy then attacks the player, resulting in death (jump death) and then game over (jump game_over). The game_over label then drops off of the end of the script, which should return the game to the main menu from my knowledge.

However, instead it returns to the last call (call e_turn) and continues from beyond it. This makes the script hit a return, which in turn sends it back even further, backtracking to the call dungeon_01 function, from which the game then moves on as if nothing had happened. This topic is for me to figure out why this happens and how I go about making it so that the death through combat actually causes the player to properly die. Any clues on that?

philat
Eileen-Class Veteran
Posts: 1909
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Call and Return

#4 Post by philat »

Well, you're still in the call stack when you jump to the death label so once you hit a return after the jump, you return to the point of the call. Just build the whole thing using jumps if you're not confident designing call logic.

Eiliya
Regular
Posts: 148
Joined: Tue Dec 04, 2012 6:21 am
Contact:

Re: Call and Return

#5 Post by Eiliya »

Yeah, I was actually considdering that, making it all into jumps rather than calls. The problem I have is that I don't understand why falling off the end of a file results in a return function. I was also considdering making the "if hp less than 1" simply cause a return label (thus sending the script back to the call for dungeon) and then make the jump to death after all the returns were completed.

I'm actually going to give both of those a try and see if I can get either of them to work as intended.

Post Reply

Who is online

Users browsing this forum: No registered users