from otree.api import * import random doc = """ Payment app: selects one random paying round (common to all participants) based on per-round payoffs stored in participant.vars['payoffs']. """ class C(BaseConstants): NAME_IN_URL = 'payment_info' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): def creating_session(self): # Only choose once per session if 'paying_round' not in self.session.vars: num_rounds = None # Find any participant who has stored per-round payoffs for participant in self.session.get_participants(): payoffs = participant.vars.get('payoffs') if isinstance(payoffs, (list, tuple)) and len(payoffs) > 0: num_rounds = len(payoffs) break if num_rounds is None: # Fallback if nothing found: default to round 1 num_rounds = 1 # Choose one common paying round for ALL participants self.session.vars['paying_round'] = random.randint(1, num_rounds) class Group(BaseGroup): pass class Player(BasePlayer): # payoff from the randomly selected paying round bonus = models.CurrencyField(default=0) class Payment(Page): @staticmethod def vars_for_template(player: Player): participant = player.participant session = player.session # The paying round was set in creating_session paying_round = session.vars.get('paying_round', 1) # Retrieve per-round payoffs payoffs = participant.vars.get('payoffs', []) if isinstance(payoffs, (list, tuple)) and len(payoffs) >= paying_round: selected_payoff = payoffs[paying_round - 1] else: selected_payoff = cu(0) # Store for record (optional) player.bonus = selected_payoff # Make sure your SESSION_CONFIG has 'participation_fee' participation_fee = session.config.get('participation_fee', cu(0)) # Final payment = payoff from random round + participation fee total_payment = selected_payoff + participation_fee return { "final_payoff": selected_payoff, "bonus": selected_payoff, "participation_fee": participation_fee, "total_payment": total_payment, "paying_round": paying_round, } page_sequence = [Payment]