This is my 2nd attempt at this game, I took advice and tips on the last one from here.

I took tips on how to not let memory stack overflow and to write a bit better story. Do suggest on how I can improve my code in general ? Thank you.

import time #added to enable pause

#A text based vampire survival game

y = ['yes', 'Yes', 'y', 'Y']
n = ['no', 'No', 'n', 'N']

#story begins here
def intro():
print('You wake up in front of a castle, you have no idea where you are or why you are here.'
'You suddenly see a colony of bats fly away.' 'You turn back and see a vampire figure appear out of nowhere. You will:')
B. Run inside the castle.
C. Run to the cave.''')
choice = input('>>>  ')
print('\n Well you dont ask vampires for directions. \n\nRip')
return "Gameover"
return "castle"
return "cave"
else:
print("Invalid input")
time.sleep(1)
intro()

def option_castle():
print('You ran inside the castle and see a glass front cubbord with garlic inside.You hear the Vampire coming,''You will: ')
print('''    A. Take the garllic to scare the vampire.
B. Hide
C. Escape from backdoor.''')
choice = input('>>>  ')
print("The garlic did stopped the vampire but it did not stopped it's blood thirsty bats.\n\n RIP")
return "Gameover"
print("This is not hide n'seek \n\n RIP" )
return "Gameover"
return "village"
else:
print('Invalid input')
time.sleep(1)
option_castle()

def option_cave():
print('You ran inside a dark cave, you were not sure if its a good idea or not but in there you see a shiny silver dagger.' 'Hurry bats are coming: ')
print('''    A. You pick up the dagger and fight.
B. You pick up the dagger and hide.
C. You run.''')
choice = input('>>>  ')
print('You picked the silver dagger and stood there like a fearsome warrior. The vampire attacked you but you were cunning and avoiding its attack stabbed the vampire right in its heart. Well done vampire slayer, you may live.')
return "Gameover"
print("Cowards don't get to fight and live. \n\n RIP")
return "Gameover"
return "village"
else:
print("Invalid input")
time.sleep(1)
option_cave()

def option_abdvilllage():
print('You ran towards an abandoned village in the open. The bats are coming faster than before, you will: ')
print('''    A. Hide
B. Pick a wood to stab the vampire
C. Enter the cave''')
choice = input('>>>  ')
print('You hid in a hut and well it worked, you were lucky and the sun rose killing the vampire. You were a coward but a lucky one.')
return "Gameover"
print("You were ready to stab the vampire with the wood but neither you were fast enough nor the wood was pointed enough. \n\n RIP")
return "Gameover"
return "cave"
else:
print('Invalid Input')
time.sleep(1)
option_abdvilllage()

def main_loop():
state = "intro"

while state != "end":
if state == "intro":
state = intro()
elif state == "castle":
state = option_castle()
elif state == "village":
state = option_abdvilllage()
elif state == "cave":
state = option_cave()
elif state == "Gameover":
again = input("\nDo you want to play again? (Y or n)").lower()
if again in y:
state = "intro"
else:
print('\nvery well')
break

def play():
start = input('Do you want to play? Y or N  ')
if start in y:
main_loop()
elif start in n:
print('very well')
else:
print('wrong input')
time.sleep(1)
play()

play()

• Hello, I added a link to the original question and I slightly changed the title of your question. – dariosicily Aug 1 at 10:37
• "I took advice and tips on the last one from here." It may be confusing but the stack overflow error comes from recursion. You'd need to remove; intro() from intro, option_cave() from  option_cave, ..., to fix this. (You can use a while loop) – Peilonrayz Aug 2 at 5:13

Note: those are my personal opinions, whenever I write that you should do something, treat it as 'I think you should'. Although I usually don't do that, I will not give you solutions to the 'issues' that I am going to point out, it seems like you are good at figuring things by yourself. However, if you don't know how to - ask away.

Positives

1. I really like the idea of the variables like answer_A.
2. Functions are named as I would expect them, when I read the name - I know what is happening.
3. Same goes for variable names, most of the variables are properly named
4. Your code is very readable, I didn't even have to have any explanation to understand what it is doing - keep it up!

Extract more functions

1. The following can be generalised to a separate function and hence you can have the same logic for other main functions.

if choice in answer_A:
print("The garlic did stopped the vampire but it did not stopped it's blood thirsty bats.\n\n RIP")
return "Gameover"
print("This is not hide n'seek \n\n RIP" )
return "Gameover"
return "village"
else:
print('Invalid input')
time.sleep(1)
option_castle()

2. Printing options can be generalized as well - not only to make the code easier but so you can easily expand your number of options - read about args.

print('''    A. Take the garllic to scare the vampire.
B. Hide
C. Escape from backdoor.''')


Variables
"Gameover","intro", "cave" etc should be extracted to variables so you can easily translate/refactor it later.

Generalizations

You might want to extract reading user input and writing the output to a separate class/function (class is preferable). This will give you opportunity to port your game to UI other than console.

nits

1. Usually, it is a good practice to use  if __name__ == "__main__" (see here) when you want to run script directly (play())
2. Variables y and x could be better named to indicate what they contain
3. Extract 1 in time.sleep(1) to a variable. You might want to change it later and if you would have more functions, it would be annoying.