TypeError: core.wait is not a function

Description of the problem: I use the code below to show the correct location of the object. When I run the experiment on Pavlovia I get the error “TypeError: core.wait is not a function”. How can i solve this problem?

if mouse.isPressedIn(colourfulcircle):
    corrCount=corrCount+1
else:
    whitecircle.draw()
    colourfulcircle.setPos(corrLocation)
    colourfulcircle.setColor(corrColor)
    colourfulcircle.draw()
    retrocue.draw()
    win.flip()
    core.wait(7)
    test.finished=True
    trials.started=True
if (corrCount == 24):
        test.finished=True
        trials.finished=True
if not mouse.isPressedIn(colourfulcircle):
    corrCount=0
1 Like

core.wait() is a PsychoPy function that doesn’t exist in PsychoJS. Having said that, core.wait() should never be used in a Builder experiment, only in Python scripts that are crafted by hand. Builder scripts are structured around a drawing and event loop that assumes that any code that runs can be completed within one screen refresh (typically at 60 Hz this is 16.666 ms), because Builder is actively drawing to the screen on every refresh, checking for responses and so on, even if stimuli don’t appear to be changing. core.wait() breaks this active drawing cycle and can completely muck up Builder’s internal timing. You should restructure your experiment to avoid core.wait(). The translation to PsychoJS should then hopefully be straightforward.

1 Like

Thanks Michael! What should I use instead of core.wait?

I’m not entirely sure of the intended logic here, but a simple workaround here might be to end the routine:

if mouse.isPressedIn(colourfulcircle):
    corrCount=corrCount+1
    continueRoutine = False
else:
    corrCount=0

if corrCount == 24:
    test.finished=True
    trials.finished=True

and then have the next routine be one where you show the stimuli you want for a set duration of 7 seconds. The lines where you end the enclosing loops won’t take effect until that all routines within the loop have completed, so it doesn’t matter which routine you put trials.finished=True on.

I show a cue for the colorful circle and I want participants to remember the specific location. I get responses for the locations. If participant give an inaccurate response, I want PsychoPy to show the accurate response by showing the colorful circle in the accurate location. So I think I can’t put stimuli on the next routine. Isn’t there an alternative function that I can use instead of core.wait?
Thanks in advance

Why not? You’re already doing it at the moment in your code – there is no reason why that can’t be implemented in the next routine instead. Just do exactly the same thing in the next routine. e.g. Add a Builder Polygon stimulus component with 100 vertices to be your circle stimulus, with a fixed duration of 7 s, a location of corrLocation and a color of corrColor, and so on.

No – any equivalent function would do the same thing, and break Builder’s active drawing and response loop. For example, a participant couldn’t push the escape key to exit the experiment during that period, because Builder would be blocked from checking the keyboard. The method above achieves what you want, and will easily translate to run online.

1 Like

Thank you very much for your help. But I just want to show the correct location when they answer incorrectly. When I add a new routine it will be shown also when they do it right, am I wrong?

Sorry, lost track of this topic. You can make routines contingent on some condition. e.g. in the “begin routine” tab on the feedback routine, do something like this:

if corrCount > 0:
    continue_routine = False
1 Like

I’m not sure that continueRoutine =False works in Begin Routine online yet so if not, put it in Each Frame

1 Like

Came across this problem recently and thought I would share my simple solution to replacing core.wait in the builder without having to copy a routine in your experiment.

  1. Initialise a flag (e.g. start_variable = False) in the “Begin Routine” section of a code component.
  2. Where you would call core.wait, instead set the flag start_variable to True.
  3. Create a variable component (e.g. end_routine) and set its start condition to be $start_variable==True.
  4. Set the variable component’s duration to the amount of time you wish to wait.
  5. Add to your code component in the “Each Frame” section:
if end_routine.finished == True:
    continueRoutine = False
1 Like