by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jun 24 13:38
    glciampaglia starred human-nature-lab/breadboard
  • Jun 18 15:03
    dependabot[bot] review_requested #222
  • Jun 18 15:03

    dependabot[bot] on npm_and_yarn

    (compare)

  • Jun 18 15:03
    dependabot[bot] closed #203
  • Jun 18 15:03
    dependabot[bot] commented #203
  • Jun 18 15:03
    dependabot[bot] labeled #222
  • Jun 18 15:03
    dependabot[bot] opened #222
  • Jun 18 15:03

    dependabot[bot] on npm_and_yarn

    Bump angular from 1.2.32 to 1.8… (compare)

  • Jun 11 18:14
    disperse labeled #221
  • Jun 11 18:14
    disperse opened #221
  • Jun 08 23:54
  • Jun 06 17:54
    dependabot[bot] labeled #220
  • Jun 06 17:54
    dependabot[bot] opened #220
  • Jun 06 17:54

    dependabot[bot] on npm_and_yarn

    Bump websocket-extensions from … (compare)

  • May 17 02:29
    revagomes starred human-nature-lab/breadboard
  • May 12 06:12
    Protamandua starred human-nature-lab/breadboard
  • May 11 20:21

    dependabot[bot] on npm_and_yarn

    (compare)

  • May 11 20:21
    dependabot[bot] closed #213
  • May 11 20:21
    dependabot[bot] commented #213
  • May 11 20:21
    dependabot[bot] labeled #219
disperse
@disperse
Very strange, I’m not sure what’s going on there. Let me know if you get stuck again
vedhu63w
@vedhu63w
Hi @disperse. Is there a way to save an experiment instance. For example, after the users have finished experiment, is there a way to dump the graph and player choices into some form of output so that I can "replay" the experiment later.
disperse
@disperse
You’ll want to record everything in the data as events:
An event is a label and a timestamp and then one or more data points.
So you could record the graph state as an edgelist at different rounds in an event:
vedhu63w
@vedhu63w
Great Thank you!
disperse
@disperse
a.addEvent(“EdgeList”, [“round”:curRound, “edgeList”:”[[0,1],[1,2],[2,3]]”])
Something like that
vedhu63w
@vedhu63w
And is there a "breadboard" way to dump all of the data into persistent storage that can be loaded easily.
disperse
@disperse
You can write to file and read from file fairly easily with Groovy.
If you just want to persist the state of the graph at the end of each experiment so it can be loaded next run you can do that by writing to and then reading from a file.
new File(‘/home/ec2-user/breadboard/data’, ‘edgelist.csv’).withWriter(‘utf-8’) { writer->
  g.E.each { edge->
    writer.writeLine (edge.inV.id + “,” + edge.outV.id)
  }
}
And you’d read in the edge list when starting the game.
vedhu63w
@vedhu63w
Thank you disperse!
Mollyrollo
@Mollyrollo
Hi, I'm very new to breadboard and im debugging an experiment made by someone else. There's a timer for time until the game starts while the tutorial is shown, but I want the timer to disappear once the game actually starts, whether the timer has actually run out or not. Is there a method for removing a timer that has already been added?
or is there somewhere where I can view all of the timer related methods, because I haven't been able to find any documentation of them
disperse
@disperse
@Mollyrollo It isn’t well documented at this point, take a look in ‘breadboard/groovy/graph.groovy` around line 97 for the code that adds timers.
We use some custom timers in the Coloring Game we published here: https://github.com/human-nature-lab/ColoringGame/blob/master/Steps/GameStartStep.groovy
disperse
@disperse
The short answer for cancelling timers is just to set player.timers = [:] and it will no longer be displayed
Ugur Yildirim
@uguryi
@disperse I want to show my subjects a slider with possible values 0.0 to 1.0 (or, 0 to 100, doesn't really matter). I'm currently using the following code chunk, but this code doesn't show the subjects the values corresponding to specific selections on the bar. Is there a way to add this info? In other words, I want my subjects to be able to see exactly what number their selection corresponds to on the slider.
    a.add(player,
      [name: "Submit",
       custom: """
       <p><strong>TODO</strong></p>
       <div>
         <input type="range" class="param" min="0" max="100" name="range" ng-model="range" required>
       </div>
       <p><hr></p>
       """.toString(),
       result: { params->
         a.addEvent("FractionGive1", ["pid": player.id,
                                      "give1": params['range']])
       }])
Mollyrollo
@Mollyrollo
when I do player.timers = [:] it gives me an error and doesn't get rid of the timer
disperse
@disperse
Oh, sorry, that was an incomplete snippet, it would be:
g.V.each { player->
  player.timers = [:]
}
Mollyrollo
@Mollyrollo
oh it works now thank you!
disperse
@disperse
@uguryi You can add hashmarks and labels on the slider using HTML: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
Alternately, you could display the current value using Javascript.
Ugur Yildirim
@uguryi
@disperse I'm not very familiar with Javascript. Is it easy to display the current value? How do I do it? That's exactly what I'm looking for.
disperse
@disperse
@uguryi It’s pretty easy, you’re looking for something like this:
a.add(player,
      [name: "Submit",
       custom: """
       <p><strong id="rangeValue">Value: 50</strong></p>
       <div>
         <input id="rangeInput" onchange="updateRangeValue" type="range" class="param" min="0" max="100" name="range" ng-model="range" required>
       </div>
       <p><hr></p>

        <script>
        jQuery('#rangeInput').change(function() {
          jQuery('#rangeValue').html('Value: ' + jQuery('#rangeInput').val())
        })
       </script>

       """.toString(),
       result: { params->
         a.addEvent("FractionGive1", ["pid": player.id,
                                      "give1": params['range']])
       }])
Ugur Yildirim
@uguryi
@disperse Thanks!
Ugur Yildirim
@uguryi
For the record, something like the following also works for adding value indicator to a range object:
<div>
         <input type="range" name="inputNameGive1" id="inputIdGive1" value="0.5" min="0" max="1" step="0.01" 
                oninput="outputIdGive1.value = inputIdGive1.value" ng-model="range" class="param" required>
         <output name="outputNameGive1" id="outputIdGive1">0.5</output>
       </div>
@disperse Is there a way to make sure g.pairs() only pairs up active participants? I think it simply pairs up anyone who is in the graph without regard to whether they are dropped or not.
disperse
@disperse
@uguryi You’ll have to create your own pairs method to filter, something like:
def activePlayers = g.V.filter{it.active}.iterator().toList()
    for (int i = 0; i < activePlayers.size(); i += 2) {
      if (activePlayers.size() > (i + 1))
         g.addTrackedEdge(activePlayers.get(i), activePlayers.get(i + 1), "connected")
    }
Ugur Yildirim
@uguryi
Thanks!
Ugur Yildirim
@uguryi

@disperse I'm almost done coding the experiment. Now, I just need to figure out how to let random AI's take over dropped players the right way. I'm currently using the following DropPlayerStep:

a.setDropPlayers(false)
a.setIdleTime(idleTime.intdiv(2))
a.setDropPlayerClosure({ player->
  a.addEvent("DropPlayer", ["pid": (player.id)])
  player.text = c.get("Dropped")
  a.ai.add(player)
})

However, what's happening is that when a player gets dropped, Breadboard first shows the Dropped content for a few seconds together with the Begin button, and then it's back to the earlier content minus the Begin button, and then the game freezes. This will almost certainly be the case with choices other than Begin too, but here's the example code where I'm experiencing this error:

  g.V.each { player->
    if (player.ai == 1) {
      // skip
    } else {
      player.text = c.get("StartPos", player.private.startPos, player.private.startScore) + 
                    "<p><strong>Click 'Begin' to join the game.</strong></p>"
      a.add(player, [name: "Begin", 
                     result: {player.text = c.get("StartPos", player.private.startPos, player.private.startScore) + 
                                            "<p><strong>Thank you, the game will begin in a moment.</strong></p>"}])
    }
  }
disperse
@disperse
Try adding player.dropped = true to the drop player closure. That should hide everything and display a “You have been dropped for being idle” message by default. You can customize the message in the Client HTML tab of the Customize dialog.
Ugur Yildirim
@uguryi
Great, I think that works now. Thanks @disperse !
Ugur Yildirim
@uguryi
@disperse Is it possible to let workers know how many seconds/minutes are remaining until the initStep starts? I feel like sometimes players get bored waiting after reading the tutorial (especially those who join right after the task is posted), and then they visit another page to read the news or something, and by the time they are back, the game has already started and they are dropped for being idle. Is there a way to avoid this?
disperse
@disperse
Yes, if you check the “Start initStep automatically” checkbox then breadboard will set a global startAt variable with the unix timestamp when the game will start. You can use that to add a timer with code in onJoinStep like:
    def curTime = new Date().getTime()
      if (!startAt) {
        startAt = curTime + 1000000
      }
      g.addTimer("player": player, time: ((startAt - curTime)/1000).toInteger(), type: "time", appearance: "info", timerText: "The game will start in:", direction: "down", result: {})
The if (!startAt) block just sets the timer to 1000 seconds in the future if startAt isn’t set (which it won’t be if you haven’t submitted a HIT to AMT).
Ugur Yildirim
@uguryi
@disperse For some reason, the code chunk you gave doesn't work when I try the experiment locally. I try signing in as a subject but never see the tutorials... Any ideas?
disperse
@disperse
Hmm, I’m not sure, are you getting player from playerId in the onJoinStep? Double-check the addTimer method in breadboard/groovy/graph.groovy and make sure the syntax hasn’t changed.
Ugur Yildirim
@uguryi
@disperse the problem has something to do with startAt or curTime. When I manually add a time such as 1000, then it works fine.
disperse
@disperse
You might need to assign startAt as a global variable, put startAt = false outside of the onJoinStep entirely (at the top of the file) and then it will be in global scope.
Ugur Yildirim
@uguryi
Yep, I think I need to do something like that. Will it be overridden by the actual startAt value when I launch the experiment on mTurk? Or, will I need to delete that if statement when running the experiment on mTurk?
disperse
@disperse
Yes, it should be overwritten when you submit the HIT
Ugur Yildirim
@uguryi
Thanks!
Ugur Yildirim
@uguryi

@disperse I'm experiencing a strange problem where choices that are only supposed to be shown to non-AI players are shown to AI's, which slows the experiment down because AI's are not programmed to make those decisions, so I need to wait until they are dropped for the game to move on. When I'm looping over players using g.V.each { player-> ... }, I specifically do something like if (player.ai == 1 || player.dropped == 1) { // skip } else { ... }. However, even when I do this, Breadboard seems to be expecting a choice from dropped AI's... Do you have any ideas about what's going on? I'm guessing this could be related to Breadboard being slow in actually labeling those dropped players as AI since another chunk of code that's supposed to fill in choices for AI's isn't working too... It's as if even after seeing the Dropped screen, those players are still not being treated as AI's...

Update: When I add a random delay using the following, the problem seems to go away... Very strange.

def randomDelay = 1000 + r.nextInt(2000)
  new Timer().runAfter(randomDelay) {
    dictator1To2Step.start()
  }
Brenda
@brenda6268
@disperse I met a problem: in the process of running our game, it was suddenly terminated and reported an error. This situation not always happen, but sometimes it occurs, and we don't know what's wrong with it. This is snapshot: https://drive.google.com/file/d/1nSuX7wS0d-ZycxauCygjp8zLQh5786GS/view?usp=sharing
disperse
@disperse
’No such property: network for class’ makes me think the script is looking for a network global variable or parameter that has not been set.