Gamification Design

Stato: Parzialmente implementato — design completo da finalizzare Ultima revisione: Marzo 2026


Filosofia

La gamification di Flow non è fine a sé stessa. Non vogliamo che gli utenti si sentano in un videogioco — vogliamo che le meccaniche di progressione rispecchino la realtà: più esci, più conosci persone, più la piattaforma lo riconosce e ti offre accesso a esperienze migliori.

Principi guida:

  1. Ogni punto XP corrisponde a un’azione reale — partecipare a eventi, costruire relazioni, contribuire alla community
  2. La progressione non è mai bloccante — può aprire accesso prioritario o feature bonus, mai escludere utenti dal core
  3. Il karma è sociale, non individuale — viene calcolato da come gli altri ti percepiscono, non da cosa fai da solo

Sistema XP

Stato attuale

Il calcolo è implementato in gamification_service.dart ma non è visibile nell’UI. Nessuna progress bar, nessun feedback post-azione.

Formula livelli

livello = floor(sqrt(xp / 100)) + 1
XPLivelloXP per prossimo livello
01100
1002156
4003225
9004256
25006

La curva è deliberatamente sub-lineare: i primi livelli si guadagnano in fretta (engagement iniziale), poi la progressione rallenta (sostenibilità a lungo termine).

Azioni che danno XP (proposta)

AzioneXPNote
Primo RSVP a un evento+50Onboarding bonus
RSVP a un evento (Going)+20Base action
Partecipazione confermata (check-in)+40Solo se check-in implementato
Primo evento con una crew+30Bonus crew
Richiesta di amicizia accettata+10Entrambi ricevono
Creazione evento (organizer)+60Incentiva B2B
Recensione post-evento+15Incentiva feedback
Profilo completo (avatar, bio, interessi)+25One-time
Invitare un amico all’app (referral)+50Crescita organica

Non danno XP (anti-abuse):

  • Rimuovere un RSVP
  • Mandare messaggi
  • Guardare profili altrui

Widget XPProgressBar

Esiste già in codebase (xp_progress_bar.dart). Da integrare in:

  • profile_screen.dart — sotto avatar/nome
  • Sheet celebrazione post-RSVP (già presente — aggiungere XP guadagnati al contenuto)
  • Schermata impostazioni/profilo dettagliato

Sistema Karma

Stato attuale

Implementato e funzionante. Raccolta feedback dopo ogni uscita con la crew, calcolo karma, KarmaBadge widget sul profilo.

Come funziona

Dopo un evento, i membri della crew si lasciano feedback reciproco. Il karma è la media pesata dei feedback ricevuti nel tempo, con decay per feedback molto vecchi (incentiva comportamento consistente nel tempo).

Integrazione con livelli di connessione

Il karma dovrebbe influenzare come gli altri ti vedono nei tier di connessione. Un utente con karma alto da “Conoscente” è più credibile di uno con karma basso. Potenziale: mostrare karma accanto al tier nel profilo pubblico.

Karma negativo

Attualmente non gestito. Un utente con sistematicamente feedback negativi dovrebbe vedere il badge degradarsi. Serve una politica esplicita: soglie, appeal, protezione da abuse (un singolo utente non può affondare il karma di qualcuno).


Badge & Achievement

Stato attuale

❌ Non implementati. Nessun modello, nessuna schermata.

Proposta di sistema

I badge sono milestone permanenti che documentano la storia dell’utente su Flow.

Categorie

Explorer — esplorare la città

BadgeCriterio
Prima uscitaPrimo RSVP confermato
Nomade5 quartieri/zone diverse
Notturno10 eventi notturni (dopo mezzanotte)
Mattiniero5 eventi diurni
Weekend warrior20 weekend fuori

Social — costruire connessioni

BadgeCriterio
Primo amicoPrima amicizia accettata
Crew founderCreata prima crew
Gregario3 crew attive simultánee
VeteranoCrew tier 3 con almeno un amico

Organizer — contribuire alla scena

BadgeCriterio
HostPrimo evento creato
Sold outEvento con lista piena
Curator5 eventi con valutazione ≥ 4.5

Karma — riconoscimento sociale

BadgeCriterio
Vibe check10 feedback positivi ricevuti
LeggendaKarma > 4.8 con ≥ 50 feedback

Modello dati (proposta)

-- Supabase
create table user_badges (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references profiles(id),
  badge_key text not null,          -- es. 'explorer_first_event'
  awarded_at timestamptz default now(),
  context jsonb,                     -- payload opzionale (es. event_id, crew_id)
  unique(user_id, badge_key)
);

Trigger

I badge possono essere assegnati:

  • Lato backend: dopo ogni evento (job post-evento)
  • Lato client: al ritorno da certi flow (post-RSVP, post-crew-creation) — check locale + call API

Leaderboard

Stato attuale

❌ Non implementata.

Considerazioni di design

Una leaderboard globale è rischiosa: crea competizione tossica, favorisce early adopter, demotiva nuovi utenti.

Alternativa consigliata: leaderboard locale/sociale

TipoCosa mostraPerché funziona
Tra amiciXP dei tuoi amiciCompetizione amichevole, scala bassa
Per crewXP combinato della crewIncentiva uscite di gruppo
Per zonaUtenti più attivi nel tuo quartiereDiscovery locale, senso di community
Settimanale (non cumulativo)Reset ogni lunedìEvita monopolio degli early adopter

La leaderboard non dovrebbe mai mostrare XP assoluto — troppo facilmente gamificabile. Meglio rank relativo (“Sei 3° tra i tuoi amici questa settimana”).


Accesso Gated (Karma/Livello)

Stato attuale

Il campo minLevel esiste nel modello Event ma non viene usato per nessun gate reale.

Proposta

Gli organizzatori possono impostare requisiti di accesso come layer di curation, non come paywall:

class EventAccessRequirement {
  final int? minLevel;         // livello minimo XP
  final double? minKarma;      // karma minimo (es. 4.0)
  final bool crewRequired;     // deve venire con una crew
  final int? maxCapacity;      // capacità massima (già nel modello)
}

UX importante: se non hai i requisiti, non vedi un messaggio di errore — vedi una schermata che spiega cosa fare per qualificarti (“Partecipa a 2 eventi per sbloccare”). Questo trasforma il gate in un obiettivo.

Gate lato server: il gate deve essere verificato lato backend al momento della prenotazione, non solo client-side (anti-cheat).


XP Celebration (Sheet post-RSVP)

Stato attuale

✅ Implementato. Sheet celebrazione mostrata dopo RSVP. Mostra animazione e messaggio positivo.

Miglioramenti suggeriti

  1. Mostrare XP guadagnati — “+20 XP” con animazione fly-in
  2. Progress verso prossimo livello — mini-barra animata
  3. Se level up — animazione speciale, confetti, badge temporaneo
  4. Se badge sbloccato — mostrarlo nella stessa sheet

Roadmap implementativa

PrioritàFeatureDipendenzeEffort stimato
AltaXPProgressBar nel profiloNessuna2h
AltaXP feedback in sheet celebrazioneNessuna1h
AltaModello e API badgeBackend1 giorno
MediaBadge schermata (profilo)Modello badge1 giorno
MediaKarma negativo + policyDecisione prodotto2 giorni
MediaLeaderboard amici2 giorni
BassaGate eventi con minLevelBackend1 giorno
BassaLeaderboard zonaGeo data3 giorni

Open Questions

  1. Decay XP? L’XP dovrebbe calare se un utente è inattivo per mesi? Pro: mantiene la leaderboard dinamica. Contro: scoraggia utenti stagionali.
  2. XP visibile ad altri? Il livello XP è pubblico (visibile nel profilo altrui) o privato?
  3. Karmagate: Se un utente ha karma molto basso, dovrebbe essere limitato nell’accedere a eventi premium? Rischio: stigmatizzazione.
  4. Badge falsi positivi: Come evitiamo badge guadagnati per abuso (es. creare e cancellare RSVP ripetutamente per XP)?
  5. Reward tangibili: Ha senso collegare XP a sconti reali con partner (locali, promoter)? Complessità operativa alta, ma incentivo potente.

Riferimenti

  • gamification_service.dart — logica XP attuale
  • xp_progress_bar.dart — widget barra progresso
  • karma_notifier.dart — raccolta e calcolo karma
  • KarmaBadge widget — badge karma sul profilo
  • Feature tracker: project/feature-tracker.md