Hoppa till huvudinnehåll

Spelkaraktärer - Repetition 🎮

Ditt uppdrag 🎯

Bygg ett system för att spåra spelkaraktärer och deras matches:

  • Skapa spelkaraktärer
  • Logga matches (vinst/förlust)
  • Se statistik (win rate, total matches, etc.)

Viktigt: Du får INTE titta på lösningar! Detta är en tänk-själv-utmaning.

Varför just spelkaraktärer? 🤔

Detta är din tredje datamodell (forum → market → characters). Varje gång blir det lättare att se mönster och förstå relationer. Plus: Statistik är ett nytt koncept som kommer vara användbart överallt!

Fas 1: Jämför och förstå 🧠

Steg 1: Hitta mönstren

Du har byggt:

  1. Forum → många Messages
  2. Item → många Bids
  3. Nu: Character → många ???

Frågor att fundera på:

  • Vad motsvarar "Messages" för spelkaraktärer?
  • Vad sparar du för varje match?
  • Skiljer sig detta från Messages/Bids på något sätt?

Skriv ner dina svar innan du fortsätter!

Steg 2: Tänk på statistik

I market-appen räknade du kanske "antal bud per item".

För spelkaraktärer behöver du räkna:

  • Totalt antal matcher
  • Antal vinster
  • Antal förluster
  • Win rate (vinster/totalt * 100)

Kritisk fråga: Var sparar du denna data?

Alternativ A: Spara statistik direkt på Character

model Character {
name String
totalGames Int @default(0)
wins Int @default(0)
losses Int @default(0)
}

Alternativ B: Räkna ut statistik från Games

model Character {
name String
games Game[]
}

model Game {
won Boolean // true = vinst, false = förlust
}

Fundera: Vilka är fördelarna och nackdelarna med varje approach?

Fas 2: Designa innan du kodar 📐

Steg 1: Rita dina tabeller

På papper (eller i anteckningar), rita:

  1. Character-tabellen med alla fält du tror du behöver
  2. Game-tabellen med alla fält du tror du behöver
  3. Pilen som visar relationen mellan dem

Tänk på:

  • Vilka fält är required vs optional?
  • Vilka fält behöver vara unique?
  • Vad händer om du tar bort en Character? (Vad händer med Games?)

Steg 2: Planera dina pages

Tänk: Vilka sidor behöver du?

Några förslag:

  • /characters - ?
  • /characters/create - ?
  • /characters/[id] - ?
  • /games - ?
  • /games/create - ?

För varje sida:

  • Vad ska visas?
  • Vilka formulär behövs?
  • Vilken data behöver laddas?

Steg 3: Tänk på utmaningarna

Dessa problem kommer du stöta på. Tänk på lösningar nu:

  1. Dropdown för characters: När du loggar en match, hur väljer användaren vilken character den gäller?

  2. Statistik-beräkning: Om du väljer "Alternativ B" ovan, hur räknar du win rate i din Svelte-komponent?

  3. Data-synkronisering: Om du väljer "Alternativ A", hur uppdaterar du statistiken när en ny match loggas?

Fas 3: Experimentera med datamodellen 🔬

Steg 1: Skapa grundprojekt

npm create svelte@latest character-tracker  
cd character-tracker
npm install
npm install prisma @prisma/client
npx prisma init --datasource-provider sqlite

Steg 2: Din första datamodell-iteration

Baserat på din planering, skapa din schema.prisma.

Börja med det enklaste som fungerar:

model Character {
id String @id @default(uuid())
name String
// Lägg till andra fält du tror du behöver
}

// Ska du ha en Game-modell? Hur ser den ut?

Testa:

npx prisma db push
npx prisma studio

Skapa några characters manuellt. Känns det rätt?

Steg 3: Experimentera med Games

Om du väljer att ha en Game-modell:

  1. Lägg till den i schema
  2. Försök skapa relations
  3. Testa i Prisma Studio

Frågor att testa:

  • Kan du se en Character's games?
  • Kan du se vilket Character ett Game tillhör?
  • Vad händer om du tar bort en Character?

Fas 4: Bygg characters först 👤

Steg 1: Lista characters

Mål: /characters visar alla characters med grundstatistik

Tänk:

  • Hur gjorde du detta för forum/market?
  • Vilken load-funktion behöver du?
  • Om du räknar statistik från games, hur gör du det?

Experimentera först med enkel lista:

<!-- Bara namn först -->
{#each characters as character}
<div>{character.name}</div>
{/each}

Sedan lägg till statistik:

<!-- Hur räknar du win rate? -->
{#each characters as character}
<div>
{character.name} - Win rate: {/* din beräkning här */}%
</div>
{/each}

Steg 2: Skapa characters

Mål: Formulär för att skapa ny character

Start enkelt:

<form method="POST">
<input name="name" placeholder="Character name" />
<button>Create</button>
</form>

Expandera sedan:

  • Beskrivning?
  • Bild URL?
  • Spel-typ (t.ex. "Chess", "Starcraft")?

Steg 3: Character-detaljsida

Mål: /characters/[id] visar character med alla games

Utmaning: Hur får du character OCH dess games?

Tips för när du kodar:

// I load function
const character = await prisma.character.findUnique({
where: { id: params.id },
include: { /* vad ska inkluderas? */ }
});

Fas 5: Games och statistik ⚔️

Steg 1: Logga matches

Mål: Formulär för att logga nya matches

Designbeslut: Var ska detta formulär vara?

  • På character-detaljsidan?
  • På en separat /games/create sida?
  • Båda?

Formulär-utmaning:

<form method="POST">
<!-- Hur väljer användaren vilken character? -->
<select name="characterId">
<!-- Vad ska stå här? -->
</select>

<!-- Hur anger användaren vinst/förlust? -->
<!-- Radio buttons? Dropdown? Checkbox? -->

<button>Log Match</button>
</form>

Action-utmaning:

export const actions = {
logMatch: async ({ request }) => {
const data = await request.formData();
const characterId = data.get('characterId');
const won = /* hur får du vinst/förlust från form? */;

// Skapa game
await prisma.game.create({
data: {
won: won,
character: {
connect: { /* vad ska stå här? */ }
}
}
});

// Om du sparar statistik på character - hur uppdaterar du den?
}
}

Steg 2: Visa match-historik

Mål: Lista alla matches för en character

Utmaningar:

  • Sorterad ordning? (Senaste först?)
  • Datum och tid?
  • Färgkodning? (Grönt för vinst, rött för förlust?)

Steg 3: Statistik-beräkningar

Stora utmaningen: Visa korrekt statistik

Om du sparar games separat:

<script>
// Hur räknar du win rate från games-array?
function calculateWinRate(games) {
// Din kod här
}

function calculateStreak(games) {
// Bonusutmaning: Nuvarande win/loss streak
}
</script>

Om du sparar statistik på character:

// I din action efter att ha skapat game
await prisma.character.update({
where: { id: characterId },
data: {
totalGames: { increment: 1 },
wins: won ? { increment: 1 } : undefined,
losses: !won ? { increment: 1 } : undefined
}
});

Fas 6: Avancerade utmaningar 🎯

Experiment att prova själv:

1. Match-detaljer

  • Motståndare
  • Datum/tid för match
  • Kommentarer ("tough game", "easy win")
  • Längd på match

2. Multiple characters per game

  • Lag vs lag
  • Free-for-all med flera spelare
  • Hur ändrar detta din datamodell?

3. Statistik-dashboard

  • Bästa character (högst win rate)
  • Mest aktiva character (flest games)
  • Senaste aktivitet
  • Grafer över tid? (avancerat)

4. Kategorier och filter

  • Olika speltyper
  • Filtrera games efter datum
  • Sök characters

Utmaningar att lösa själv (inga lösningar!) 🧩

Grundnivå:

  1. CRUD för characters
  2. Logga basic matches (bara vinst/förlust) ✓
  3. Visa grundstatistik (win rate, total games) ✓

Mellannivå:

  1. Match-historik med datum och sortering
  2. Formulär-validering (unique names, required fields)
  3. "Ångra senaste match" funktionalitet

Expertnivå:

  1. Prestations-tracking (streak, best period)
  2. Jämförelser mellan characters
  3. Export-funktionalitet (CSV av alla matches)

Reflektion - ställ dig dessa frågor 🤔

Efter varje fas:

Datamodell-reflektion:

  • Vilken approach valde du för statistik? Varför?
  • Vad var svårast med relationer denna gång?
  • Hur skiljer sig detta från market-appen?

Kod-reflektion:

  • Vilka patterns ser du från forum/market som du återanvände?
  • Vad var annorlunda denna gång?
  • Vilka misstag gjorde du som du gjorde förra gången också?

Lärande-reflektion:

  • Känns det lättare än market-appen?
  • Vad förstår du nu som du inte förstod efter forum-appen?
  • Vilka nya koncept lärde du dig?

Skriv ner dina svar! Detta hjälper dig se din utveckling.

Vanliga utmaningar (löses INTE åt dig) ⚠️

"Jag förstår inte statistik-beräkning"

  • Börja med en hårdkodad example
  • Gå igenom steg för steg: Hur räknar DU win rate för hand?
  • Använd console.log() för att se vad som händer
  • Testa först med hårdkodade options
  • Kolla forum-appen: Hur gjorde du för att visa lists?
  • Tänk: Vad behöver option få som value? Vad ska visas för användaren?

"Jag vet inte när jag ska uppdatera statistik"

  • Tänk: När ändras statistiken? (När ett game skapas/raderas)
  • Börja utan automatisk uppdatering
  • Lägg till uppdatering när grundfunktionaliteten fungerar

Success tips 💡

  1. Bygg i denna ordning: Characters → Games → Statistik → Advanced features
  2. Testa varje bit innan du går vidare
  3. Jämför med tidigare appar när du fastnar
  4. Hårdkoda först - använd riktigt data senare
  5. En sak i taget - försök inte bygga allt samtidigt

Nästa steg 🚀

När du har ett fungerande character-tracker system är du redo för den ultimata utmaningen: En komplett parkeringsapp med personer, fordon, parkeringsplatser och komplexa relationer!

Du bygger verklig kompetens! 💪

Med varje app förstår du bättre hur data-relationer fungerar. Detta är grunden för ALL modern webb-utveckling. Du lär dig genom att GÖRA, inte genom att kopiera!