Issue with how objects update online

URL of experiment: Pavlovia

Description of the experiment:

Hi everyone,
Any help would be really appreciated; I’m really lost on this one!
In my experiment, the participants see two present boxes. There’s a wait period and then a response cue (’?’) is shown. Participants then have to choose one of the two boxes. After their choice is made, there’s a wait period. The correct box that they should have chosen is then shown onscreen and a star is animated to fly from the centre of the screen upwards. Participants have 4s to respond from the response cue (’?) onset. If they don’t respond, a warning message is shown, ‘Please choose a present box’.



The issues:

This works locally. However, online I get the following issues:

  • On the first trial, the correct box that they should have chosen isn’t visible.
  • On subsequent trials, when the correct box is visible, the correct box from the last trial is shown briefly. As if the box is updating in real-time. The same is true for the number value under the box.
  • The star animation appears to be shown briefly in it’s finished position before restarting its animated flight up the screen
  • The warning message is shown after each trial. Even when a response is made.

This is a video of the experiment behaving as intended locally:



This is a video of the experiment behaving inappropriately online:


I slowed down the online video and saw that what was happening was the correct box and final star position from the last trial was briefly being shown on each trial before it resets/updates to the correct box for the current trial.

See the slowed video here:



And here is a screenshot of the moment that the star/present box from the last trial briefly flash onscreen:



The code:

This is the code from the main code component in the practice trials. The main trials code is largely the same.

This is a more detailed look at the Each Frame tab on the JS side:

let buttons = mouse.getPressed(); // read mouse state
const xys = mouse.getPos(); // get mouse coordinates
mouse.x.push(xys[0]); // add mouse coordinates to x/y list, in principle for data storage, but not implemented right now
mouse.y.push(xys[1]);
mouse.leftButton.push(buttons[0]); // store buttons in button list, likewise for storage
mouse.midButton.push(buttons[1]);
mouse.rightButton.push(buttons[2]);

if ((PRACTresponded === 0)) {
    if (!buttons.every( (e,i,) => (e == prevButtonState[i]) )) { // button state changed?
      prevButtonState = buttons; 
        if ((((PRACTRespCue.status === PsychoJS.Status.STARTED) && (buttons.reduce( (e, acc) => (e+acc) ) > 0)) && (PRACTblue.contains(mouse)))) {
            PRACTresponded = 1;
            if ((corrAns === "blue")) {
                PRACToutcome = 1;
                PRACToutcomeMsg = "Correct! The star was in the blue box!";
                PRACTcorrectImage = "images/blue.png";
                if ((mouse.getPos()[0] < 0)) {
                    PRACTcorrectRew = PRACTreward1;
                    PRACTtotalScore = (PRACTtotalScore + PRACTreward1);
                } else {
                    if ((mouse.getPos()[0] > 0)) {
                        PRACTcorrectRew = PRACTreward2;
                        PRACTtotalScore = (PRACTtotalScore + PRACTreward2);
                    }
                }
            } else {
                PRACToutcome = 0;
                PRACToutcomeMsg = "Bad luck! The star was in the red box.";
                PRACTcorrectImage = "images/red.png";
                if ((mouse.getPos()[0] < 0)) {
                    PRACTcorrectRew = PRACTreward2;
                } else {
                    if ((mouse.getPos()[0] > 0)) {
                        PRACTcorrectRew = PRACTreward1;
                    }
                }
            }
            PRACTMsg = ("Total score = " + PRACTtotalScore.toString());
        } else {
            if ((((PRACTRespCue.status === PsychoJS.Status.STARTED) && (buttons.reduce( (e, acc) => (e+acc) ) > 0)) && (PRACTred.contains(mouse)))) {
                PRACTresponded = 1;
                if ((corrAns === "red")) {
                    PRACToutcome = 1;
                    PRACToutcomeMsg = "Correct! The star was in the red box!";
                    PRACTcorrectImage = "images/red.png";
                    if ((mouse.getPos()[0] < 0)) {
                        PRACTcorrectRew = PRACTreward1;
                        PRACTtotalScore = (PRACTtotalScore + PRACTreward1);
                    } else {
                        if ((mouse.getPos()[0] > 0)) {
                            PRACTcorrectRew = PRACTreward2;
                            PRACTtotalScore = (PRACTtotalScore + PRACTreward2);
                        }
                    }
                } else {
                    PRACToutcome = 0;
                    PRACTcorrectImage = "images/blue.png";
                    PRACToutcomeMsg = "Bad luck! The star was in the blue box.";
                    if ((mouse.getPos()[0] < 0)) {
                        PRACTcorrectRew = PRACTreward2;
                    } else {
                        if ((mouse.getPos()[0] > 0)) {
                            PRACTcorrectRew = PRACTreward1;
                        }
                    }
                }
                PRACTMsg = ("Total score = " + PRACTtotalScore.toString());
            }
        }
    }
}

if ((PRACTcross3.status === PsychoJS.Status.FINISHED)) {
    continueRoutine = false;
    }

if ((PRACTcorrectImg.status === PsychoJS.Status.STARTED)) {
    if ((PRACTstarPos[1] < 0.3)) {
        PRACTstarPos[1] = (PRACTstarPos[1] + 0.05);
        }
    }

if ((PRACTrespCueTime === 0)) {
    if ((PRACTRespCue.status === PsychoJS.Status.STARTED)) {
        PRACTrespCueTime = 1;
        PRACTcueStart = PRACTtimer.getTime();
    }
}
if ((PRACTrespCueTime === 1)) {
    if (((PRACTresponded === 0) && ((PRACTtimer.getTime() - PRACTcueStart) > 3.99))) {
        PRACTwarningGo = 1;
        continueRoutine = false;
    }
}

And on the python side:

if PRACTresponded==0:
    if PRACTRespCue.status==STARTED and mouse.getPressed()[0]==1 and mouse.isPressedIn(PRACTblue): #if blue clicked
        PRACTresponded=1
        if corrAns=='blue': #and blue correct
            PRACToutcome = 1
            PRACToutcomeMsg = 'Correct! The star was in the blue box!'
            PRACTcorrectImage = 'images/blue.png'
            if mouse.getPos()[0] <0: #if clicked left
                PRACTcorrectRew = PRACTreward1 #correct reward is on left
                PRACTtotalScore = PRACTtotalScore + PRACTreward1
            elif mouse.getPos()[0] >0: #if clicked right
                PRACTcorrectRew = PRACTreward2 #correct reward is on right
                PRACTtotalScore = PRACTtotalScore + PRACTreward2
        else:
            PRACToutcome = 0
            PRACToutcomeMsg = 'Bad luck! The star was in the red box.'
            PRACTcorrectImage = 'images/red.png'
            if mouse.getPos()[0] <0: #if clicked left
                PRACTcorrectRew = PRACTreward2 #correct reward is on right
            elif mouse.getPos()[0] >0: #if clicked right
                PRACTcorrectRew = PRACTreward1 #correct reward is on left
            
        PRACTMsg = 'Total score = ' + str(PRACTtotalScore)
           
    elif PRACTRespCue.status==STARTED and mouse.getPressed()[0]==1 and mouse.isPressedIn(PRACTred): #if red clicked
        PRACTresponded=1
        if corrAns=='red': #and red correct
            PRACToutcome = 1
            PRACToutcomeMsg = 'Correct! The star was in the red box!'
            PRACTcorrectImage = 'images/red.png'
            if mouse.getPos()[0] <0: #if clicked left
                PRACTcorrectRew = PRACTreward1 #correct reward is on left
                PRACTtotalScore = PRACTtotalScore + PRACTreward1
            elif mouse.getPos()[0] >0: #if clicked right
                PRACTcorrectRew = PRACTreward2 #correct reward is on right
                PRACTtotalScore = PRACTtotalScore + PRACTreward2
        else:
            PRACToutcome = 0
            PRACTcorrectImage = 'images/blue.png'
            PRACToutcomeMsg = 'Bad luck! The star was in the blue box.'
            if mouse.getPos()[0] <0: #if clicked left
                PRACTcorrectRew = PRACTreward2 #correct reward is on right
            elif mouse.getPos()[0] >0: #if clicked right
                PRACTcorrectRew = PRACTreward1 #correct reward is on left
               
        PRACTMsg = 'Total score = ' + str(PRACTtotalScore)
        
if PRACTcross3.status==FINISHED:
    continueRoutine = False
    
if PRACTcorrectImg.status==STARTED:
    if PRACTstarPos[1]<0.3:
        PRACTstarPos[1] = PRACTstarPos[1]+0.05

if PRACTrespCueTime==0:
    if PRACTRespCue.status==STARTED:
        PRACTrespCueTime=1
        PRACTcueStart = PRACTtimer.getTime()
        
if PRACTrespCueTime==1:
    if PRACTresponded==0 and PRACTtimer.getTime()-PRACTcueStart >3.99:
        PRACTwarningGo = 1
        continueRoutine = False
    

Any help at all would be amazing! Thank you!
Hannah

An update (some issues I’ve solved)

The original issues and their solutions:

  • On the first trial, the correct box that they should have chosen isn’t visible.
    SOLUTION: I moved the code that set the correct box to the begin routine tab. This seems to have only worked for the practice trials though, not the main experimental trials which is really odd.

  • On subsequent trials, when the correct box is visible, the correct box from the last trial is shown briefly. As if the box is updating in real-time. The same is true for the number value under the box.
    SOLUTION: This now seems to only happen on some of the trials. Unsure why it only happens for some and not all. The practice trials seem to work fine. It seems to be more the main trials that are affected.

  • The star animation appears to be shown briefly in it’s finished position before restarting its animated flight up the screen
    SOLUTION: Same as above. Seems to only happen on some of the trials.

  • The warning message is shown after each trial. Even when a response is made.
    SOLUTION: I needed to move the continueRoutine=False code on my warning message routine to the Each Frame tab.


The remaining issue

My main issue at the minute is that the correct box image doesn’t show up on the first trial of the experimental trials. It does show up on all subsequent trials. What is odd is that the correct box image does show up on the first trial of the practice trials. The practice trials and the experimental trials have almost identical code components. It is really weird.

The animation of the star is also a little clunky but I’m more concerned about the correct box image not showing up.

Thank you for reading and for any advice you can give!

Solved remaining issue!

I made the rookie mistake of forgetting to change the correctImg component’s image field to update every repeat rather than every frame after I moved the code that set the image file to the ‘begin routine’ tab. Whoops!

The star animation is a bit faster and less smooth online but this is something that I could either choose to live with or play around with/see if I could slow it down a bit by editing the parameters.

Thank you for reading! :slight_smile:

1 Like