A Python framework for tasks, games, and experiments

Demo
Documentation
GitHub

About

oTree is an open-source framework that lets you build any kind of interactive task that you want people to take part in, such as:

  • Multiplayer or single-player strategy games
  • Dynamic questionnaires
  • Assessments and tests

It is frequently used for research in economics, psychology, and related fields, and has been used in 600 academic publications.

The best way to understand is by seeing it in action!

Live demos

Why use oTree?

Versatile

Few frameworks are as user-friendly yet versatile as oTree. Build anything from a game of tic-tac-toe to a live auction market.

Easy

oTree limits itself to the most basic programming concepts: if-statements, loops, simple functions, lists, and dicts.

Ideal for learning

oTree is a fun way to learn programming. And it is a great hands-on addition to courses in subjects like economics or psychology.

Ease into programming

Use oTree Studio, a hybrid point-and-click interface that puts oTree on rails.

Walkthrough

Just as Python is a high-level language, oTree is a high-level framework. You don't need to know all the nitty-gritty details of HTTP, SQL, etc. Jump in and start building fun things right away!

Clear code

oTree Studio is a visual layer on top of an easy-to-understand Python code format.

Players will be automatically split into groups of 2, and the game repeats for 10 rounds.

class Constants(BaseConstants):
  players_per_group = 2  
  num_rounds = 10

Here we define the columns of the database table.

class Player(BasePlayer):
  contribution = models.CurrencyField(min=0, max=100)
  opt_out = models.BooleanField()

This page has a time limit of 60 seconds, and is only shown to player 1.

class Contribute(Page):
  timeout_seconds = 60
  form_model = 'player'
  form_fields = ['contribution']

  def is_displayed(player):
    return player.id_in_group == 1

Multiplayer games are super simple. Just add a WaitPage in your game, and it will automatically synchronize players, at which point you can perform calculations.

class WaitForOthers(WaitPage):
  def after_all_players_arrive(group):
    p1, p2 = group.get_players()
    p1.payoff = p1.contribution
    p2.payoff = 100 - p1.contribution

This page gives the user a choice to finish the current section, or skip to one of your other apps (e.g. questionnaire).

class Results(Page):
  form_model = 'player'
  form_fields = ['opt_out']

  def app_after_this_page(player, upcoming_apps):
    if player.opt_out:
      return 'questionnaire'

Chain pages together

page_sequence = [Contribute, WaitForOthers, Results]

Chain apps together

app_sequence = ['trust_game', 'questionnaire']

Dynamic templates

Design your user interface with dynamic tags, HTML, and CSS.

Built-in components like a chat box and automatic form layout.

Please answer the following questions.
{{ formfields }}

You may chat with other users here: 
{{ chat }}

Conditional logic

{{ if player.payoff > 0 }}
  Congrats, you made {{ player.payoff }}
{{ else }}  
  You did not make any money.
{{ endif }}

Features for advanced users

Test your apps with bots, which run in parallel to play multiplayer games against each other. You can program different bot strategies and run multi-agent simulations.

yield Survey, dict(name='Bob', age=20)
yield Auction, dict(bid=random.randint(100, 200))
yield Results

Live pages let players interact within the same page, in real time. Send messages to specific players using their ID, or broadcast to the group using special ID 0.

class Auction(Page):
  def live_method(player, bid):
    group = player.group
    if bid > group.highest_bid:
      group.highest_bid = bid
      return {
        0: dict(msg='New high bid!', bid=bid)
      }    
    else:
      my_id = player.id_in_group
      return {
        my_id: dict(msg='Your bid was too low.')
      }

The above just scratches the surface of what oTree can do. Check out the documentation for more details.



$ pip install otree
$ otree startproject myproject
$ cd myproject
$ otree devserver

FAQ

GitHub