From 5f2f171189da856946d73b5d9650e3ff46bff71e Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 00:19:10 +0530 Subject: [PATCH 1/9] feat(squadNumber.ts): Defined a hash from the username to ensure user specific generation --- lib/scoring/squadNumber.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/scoring/squadNumber.ts diff --git a/lib/scoring/squadNumber.ts b/lib/scoring/squadNumber.ts new file mode 100644 index 0000000..aebe2cc --- /dev/null +++ b/lib/scoring/squadNumber.ts @@ -0,0 +1,14 @@ +import type { Position } from "./types"; + +export function generateSquadNumber(login: string, position: Position): number { + //Create a hash from the username + let hash = 0; + for (let i = 0; i < login.length; i++) { + hash = login.charCodeAt(i) + ((hash << 5) - hash); + } + + hash = Math.abs(hash); + + + return hash; +} \ No newline at end of file From e23292dd65b1e3c153fba938eb3035137ef0263a Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 08:48:02 +0530 Subject: [PATCH 2/9] feat(squadNumber.ts): add positional squad numbers configuration --- lib/scoring/squadNumber.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/scoring/squadNumber.ts b/lib/scoring/squadNumber.ts index aebe2cc..23c9752 100644 --- a/lib/scoring/squadNumber.ts +++ b/lib/scoring/squadNumber.ts @@ -9,6 +9,16 @@ export function generateSquadNumber(login: string, position: Position): number { hash = Math.abs(hash); + //Iconic squad numbers grouped by football positions + const posNumbers: Record = { + ST: [7, 9, 10, 11, 19, 22, 18, 20, 14, 45, 99], + RW: [7, 10, 11, 17, 22, 21, 20, 23, 18, 10, 19], + CAM: [10, 8, 11, 20, 22, 18, 23, 42], + CM: [8, 6, 14, 16, 17, 22, 16, 15, 19, 20, 88], + CDM: [6, 4, 15, 16, 14, 28, 23, 8, 18, 25, 5], + CB: [4, 5, 2, 3, 6, 12, 15, 26, 33], + }; + return hash; } \ No newline at end of file From 1fff5eb856152ce1465dae412cba6a48f342b48f Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 08:50:37 +0530 Subject: [PATCH 3/9] feat(squadNumber.ts): Implement hash-based squad number selection with position fallback --- lib/scoring/squadNumber.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/scoring/squadNumber.ts b/lib/scoring/squadNumber.ts index 23c9752..b295cc6 100644 --- a/lib/scoring/squadNumber.ts +++ b/lib/scoring/squadNumber.ts @@ -19,6 +19,8 @@ export function generateSquadNumber(login: string, position: Position): number { CB: [4, 5, 2, 3, 6, 12, 15, 26, 33], }; + const pool = posNumbers[position]||[7, 9, 10, 11]; - return hash; + + return pool[hash % pool.length]; } \ No newline at end of file From 992eb977ea172424ac13f08d9dfa4392f022d3b0 Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 08:55:22 +0530 Subject: [PATCH 4/9] feat(types.ts): add squadNumber property to Card interface --- lib/scoring/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/scoring/types.ts b/lib/scoring/types.ts index 0efb058..4c79df6 100644 --- a/lib/scoring/types.ts +++ b/lib/scoring/types.ts @@ -102,5 +102,6 @@ export interface Card { // Set only for gitfut founders — their bespoke card art/accent + hint metadata. // Optional so every other card (and previously serialized ones) stay valid. founder?: FounderMeta; + squadNumber: number; //Squad nnumber generated from login and position report: Report; } From 3bb5d38b486ab7e71a509beda17294246a961582 Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 09:00:25 +0530 Subject: [PATCH 5/9] feat(engine.ts): integrate squad number generation into buildCard() --- lib/scoring/engine.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/scoring/engine.ts b/lib/scoring/engine.ts index 68ef9c5..50160e3 100644 --- a/lib/scoring/engine.ts +++ b/lib/scoring/engine.ts @@ -3,6 +3,8 @@ import { topLanguageLogo } from "../github/languages"; import { deriveMetrics, deriveSkillMoves, deriveStyle, deriveWeakFoot, deriveWorkRate } from "./attributes"; import { ATTACK_STATS, FINISH_LABELS, FOUNDER_OVERALL, FOUNDERS, K, STATS, WEIGHTS } from "./constants"; import { derivePlaystyles } from "./playstyles"; +import { generateSquadNumber } from "./squadNumber"; + import type { Archetype, Card, @@ -212,6 +214,7 @@ export function buildCard(s: Signals): Card { languageLogo, ...(founder ? { founder } : null), legacy: { L }, + squadNumber: generateSquadNumber(s.login, position), report: { skillMoves: skill.value, weakFoot: weak.value, From d0b263d1ca3b2adeccf87d7fd2a938e6f1e3e8a2 Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 09:06:27 +0530 Subject: [PATCH 6/9] refactor(ScoutReport.tsx): Add export keyword to Section function --- components/ScoutReport.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ScoutReport.tsx b/components/ScoutReport.tsx index a666ce4..f85e9f6 100644 --- a/components/ScoutReport.tsx +++ b/components/ScoutReport.tsx @@ -97,7 +97,7 @@ function AttributeRow({ label, children }: { label: string; children: React.Reac // Editorial section: an accent dash + tracked label, then content — reads as a // scouting-report section rather than a dashboard card. -function Section({ +export function Section({ title, accent, className, From 140f64acaaf0aa7cb55846cd08e1eab396071a40 Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 09:41:43 +0530 Subject: [PATCH 7/9] feat(PlayerNumber.tsx): create PlayerNumber component to display squad numbers --- components/PlayerNumber.tsx | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 components/PlayerNumber.tsx diff --git a/components/PlayerNumber.tsx b/components/PlayerNumber.tsx new file mode 100644 index 0000000..66863fe --- /dev/null +++ b/components/PlayerNumber.tsx @@ -0,0 +1,23 @@ +"use client"; + +import type { Card } from "@/lib/scoring/types"; +import { Section } from "./ScoutReport"; +import { resolveResultTheme } from "./finishTheme"; + +export default function PlayerNumber({ card }: { card: Card }) { + const theme = resolveResultTheme(card); + const accent = theme.ink; + + return ( +
+
+
+ {card.squadNumber} +
+
+
+ ); +} From c881a303611a32c2f31414dd2bcf195009c48ce1 Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 09:43:45 +0530 Subject: [PATCH 8/9] feat(ResultView.tsx):render PlayerNumber in ResultView --- components/ResultView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/ResultView.tsx b/components/ResultView.tsx index 01498fa..c0c90d6 100644 --- a/components/ResultView.tsx +++ b/components/ResultView.tsx @@ -18,6 +18,8 @@ import { AttributesPanel, MetricsPanel, ReportHeader } from "./ScoutReport"; import { confettiPalette, resolveResultTheme } from "./finishTheme"; import { useReveal } from "@/hooks/useReveal"; import { burstConfetti } from "@/lib/confetti"; +import PlayerNumber from "./PlayerNumber"; + const HowItWorksModal = dynamic(() => import("./HowItWorksModal"), { ssr: false }); @@ -183,10 +185,11 @@ export default function ResultView({ - {/* right — scouting metrics */} + {/* right — scouting metrics + squad number */}
+
From 11e91676af02a9176ebcc9d428a16cefcde93e13 Mon Sep 17 00:00:00 2001 From: Gaurav Gaisenn Date: Fri, 10 Jul 2026 09:50:29 +0530 Subject: [PATCH 9/9] feat: add overall rating parameter to the generateSquadNumber() function --- lib/scoring/engine.ts | 2 +- lib/scoring/squadNumber.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/scoring/engine.ts b/lib/scoring/engine.ts index 50160e3..e710199 100644 --- a/lib/scoring/engine.ts +++ b/lib/scoring/engine.ts @@ -214,7 +214,7 @@ export function buildCard(s: Signals): Card { languageLogo, ...(founder ? { founder } : null), legacy: { L }, - squadNumber: generateSquadNumber(s.login, position), + squadNumber: generateSquadNumber(s.login, position, overall), report: { skillMoves: skill.value, weakFoot: weak.value, diff --git a/lib/scoring/squadNumber.ts b/lib/scoring/squadNumber.ts index b295cc6..c160259 100644 --- a/lib/scoring/squadNumber.ts +++ b/lib/scoring/squadNumber.ts @@ -1,6 +1,6 @@ import type { Position } from "./types"; -export function generateSquadNumber(login: string, position: Position): number { +export function generateSquadNumber(login: string, position: Position, overall: number): number { //Create a hash from the username let hash = 0; for (let i = 0; i < login.length; i++) { @@ -21,6 +21,11 @@ export function generateSquadNumber(login: string, position: Position): number { const pool = posNumbers[position]||[7, 9, 10, 11]; - + //Elite players (90+ OVR) always get the classic #1 choice for their position + if(overall >= 90){ + return pool[0]; + } + + //Else use the hash to pick a varied, but consistent number return pool[hash % pool.length]; } \ No newline at end of file