[Solved] Automated game walker for testing purpose

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
Azephir
Newbie
Posts: 8
Joined: Fri Sep 03, 2021 1:05 pm
Projects: The Alchemist - VN bara (azephir.itch.io/the-alchemist)
itch: azephir
Contact:

[Solved] Automated game walker for testing purpose

#1 Post by Azephir »

Hi everyone :D !

I'm making a visual novel on Ren'Py and I start thinking about my testing process.

I use lint script for the testing but i wonder if there are tools to go further.

In detail, my VN is pretty "classic" : no mini-games, no maps, only choices from the "menu" statement of Ren'py.

But I have a lot of different routes with a lot of different conditions.
And I wonder about the equilibrium of my game.
So I would like to have an automated tool that can make random decision when encounter a "menu" statement.
It would be nice to run it like 10 000 times, for example, to see which routes are the more "easy" (more statistically probable), and if there is some route unachievable.
It would be a kind of automated game walker.

Have you ever heard about something like that ?
If not, how do you think I can do it ?

I think of having for each ending a specific number.
And a loop (loop "for") that can execute my game with making random choice each time the game encounter a menu, and return the ending number.
And when the game is over, adding one to an array at the index of the ending number.
And finally, when the global loop is over, print the array.

I don't really know in which language i can do that (lint, python, other ?) and how to execute the game with making random choices.

Thank you for your time !
Cheers :wink:
Azephir
Last edited by Azephir on Mon Sep 13, 2021 6:03 am, edited 1 time in total.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Automated game walker for testing purpose

#2 Post by Remix »

You might be able to setup something using skip/auto and
define config.auto_choice_delay = None

If not None, this variable gives a number of seconds that Ren'Py will pause at an in-game menu before picking a random choice from that menu. We'd expect this variable to always be set to None in released games, but setting it to a number will allow for automated demonstrations of games without much human interaction.

https://renpy.org/doc/html/config.html# ... oice_delay

You would of course have to set up every game end point so it stored some value to persistent and restarted the game to run another random route.
Frameworks & Scriptlets:

Azephir
Newbie
Posts: 8
Joined: Fri Sep 03, 2021 1:05 pm
Projects: The Alchemist - VN bara (azephir.itch.io/the-alchemist)
itch: azephir
Contact:

Re: Automated game walker for testing purpose

#3 Post by Azephir »

Oh ! Nice !

I can even replace my "return" by "$renpy.save_persistent(); $renpy.load("firstsave")" where firstsave is made just after label start but before an "if" statement on an persistant counter.
So the game will execute himself until the counter exeed 10 000 (for exemple) and then execute the conditional statement return.

Really nice !

And maybe I can store more than just the ending in persistent data... Maybe I can store a bunch of different values to know more about the choices made...

I'll think about that.

Thank you !

Azephir
Newbie
Posts: 8
Joined: Fri Sep 03, 2021 1:05 pm
Projects: The Alchemist - VN bara (azephir.itch.io/the-alchemist)
itch: azephir
Contact:

Re: [Solved] Automated game walker for testing purpose

#4 Post by Azephir »

I managed to make it work 8) .
I post here the code to help if someone is in the same case.
Note : you need to erase persistent data first (in renpy launcher), and each time you start (but not each iteration of course !).

in script.rpy

Code: Select all

default test_mode=True #Variable for test mode
default nb_iterations=10 # Number of run
default persistent.loop=True
default nb_run="Problem" #for debug

label start:

    if test_mode:
        "Vous êtes en mode test." #French version of "You are in test mode"
        $config.auto_choice_delay=0.01 #Auto-choice activated
        $config.fast_skipping=True #Fast skipping allowed
        $config.skip_delay=0.01 #For slow skipping
        $persistent.loop=True; #For my small save loop
        "Début de la sauvegarde." #French version of "Start saving"
        $config.skipping="fast"; #Start Fast Skipping

        $preferences.skip_after_choices = True;
        $preferences.skip_unseen = True;
        while(persistent.loop): #loop to have one save by iteration
            $nb_run=persistent.counter+1;
            $string_nb_run=  "%d" % nb_run #change int in string
            $namesave="firstsave"+string_nb_run
            $persistent.loop=False; #get out of the loop
            $renpy.save(namesave); 


        "Run numéro [nb_run]" #for debug "Run number..."
        $config.skipping="fast";
        if nb_run>nb_iterations: #If the iterations are over
            $config.skipping=None; #stop Skipping for debug (not needed)
            "Test nombre de run enclenché" #French version of "If-test of run number passed"
            $a_ecrire=', '.join(map(str, persistent.results)); #stringify the list of list
            "Stockage de la variable" #French version of "Variable save"
            python:
                with open("results.txt","w") as file:
                    file.write(a_ecrire) #write the results in a file in RENPY INSTALLATION FOLDER
                file.closed

            "Fin des itérations" #French version of "End of iterations"
            return
    
 #Resume game.
 
also in script.rpy

Code: Select all

label end_end:
    if test_mode:
        #Choose what result do you want
        $resultats=[["run",nb_run],["var 1",var1],["var 2",var2],["var 3",var3]]; 

        #
        $persistent.results.append(resultats) #put the result of the run on the persistent list
        $persistent.counter=nb_run; #add one on the persistent counter
        $persistent.loop=True; #To be in the loop of the begining
        $renpy.save_persistent(); #Save persistent variables
        $string_nb_run=  "%d" % nb_run  #int to string
        $namesave="lastsave"+string_nb_run  
        $renpy.save(namesave);  	# For debug (not needed)
        $namesave="firstsave"+string_nb_run
        $renpy.load(namesave); #Goes back to the begining

    else:
        return

in options.rpy (but maybe it will also work in script file ?)

Code: Select all

init 1 python :
    ui.interact_renpy=ui.interact #to backup

    def interact3(type='misc', roll_forward=None, **kwargs): # @ReservedAssignment     #Re-write ui.interact because it stop Fast Skipping at menu

        if ui.stack is None: #do not forget stack-->ui.stack
            raise Exception("Interaction not allowed during init phase.")

        if len(ui.stack) != 1: #do not forget stack-->ui.stack
            raise Exception("ui.interact called with non-empty widget/layer stack. Did you forget a ui.close() somewhere?\nStack was " + ('\n'.join([str(item) for item in stack])))

        if ui.at_stack: #do not forget at_stack-->ui.at_stack
            raise Exception("ui.interact called with non-empty at stack.")

        renpy.game.context().info._current_interact_type = type
        rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
        renpy.game.context().info._last_interact_type = type

        if renpy.exports.in_fixed_rollback() and roll_forward is not None:
            return roll_forward
        else:
            return rv

    ui.interact=interact3

Hope it helps :D !
Cheers

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3784
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: [Solved] Automated game walker for testing purpose

#5 Post by Imperf3kt »

The developer menu also lets you jump to labels and set variables, if necessary.
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

Post Reply

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot], Google [Bot]