Struktury Danych — Zadania
Zadanie (Task)
Każde zadanie ma wspólne pola bazowe + pole content zależne od typu.
Quiz — pytania wielokrotnego wyboru
json
{
"id": "task_001",
"type": "quiz",
"title": "Tabliczka mnożenia do 5",
"description": "Sprawdź czy znasz tabliczkę mnożenia!",
"thumbnail": "tasks/math_quiz.png",
"age_groups": ["4-8", "8-13"],
"duration_minutes": 5,
"xp_reward": 25,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_001",
"type": "multiple_choice",
"text": "Ile to 3 × 4?",
"options": ["10", "12", "14", "16"],
"correct": 1
},
{
"id": "q_002",
"type": "multiple_choice",
"text": "Ile to 5 × 5?",
"options": ["20", "25", "30", "35"],
"correct": 1
}
],
"pass_threshold": 0.7,
"shuffle_questions": true,
"shuffle_options": true
},
"location_id": "loc_library_01",
"world_id": "world_poland",
"created_by": "system"
}Quiz — prawda/fałsz
json
{
"id": "task_010",
"type": "quiz",
"title": "Prawda czy fałsz — Zwierzęta",
"description": "Czy wiesz ciekawostki o zwierzętach?",
"thumbnail": "tasks/animals_tf.png",
"age_groups": ["4-8", "8-13"],
"duration_minutes": 3,
"xp_reward": 15,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_010",
"type": "true_false",
"text": "Pingwiny potrafią latać.",
"correct": false
},
{
"id": "q_011",
"type": "true_false",
"text": "Delfiny to ssaki.",
"correct": true
},
{
"id": "q_012",
"type": "true_false",
"text": "Pająk ma 6 nóg.",
"correct": false
}
],
"pass_threshold": 0.7,
"shuffle_questions": true,
"shuffle_options": false
},
"location_id": "loc_library_01",
"world_id": "world_poland",
"created_by": "system"
}Quiz — dopasowywanie (matching)
json
{
"id": "task_011",
"type": "quiz",
"title": "Dopasuj stolice do krajów",
"description": "Połącz kraj z jego stolicą",
"thumbnail": "tasks/capitals.png",
"age_groups": ["8-13"],
"duration_minutes": 5,
"xp_reward": 30,
"difficulty": "medium",
"badge_id": null,
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_020",
"type": "matching",
"text": "Dopasuj kraj do stolicy",
"pairs": [
{ "left": "Polska", "right": "Warszawa" },
{ "left": "Francja", "right": "Paryż" },
{ "left": "Niemcy", "right": "Berlin" },
{ "left": "Hiszpania", "right": "Madryt" }
]
}
],
"pass_threshold": 0.75,
"shuffle_questions": false,
"shuffle_options": true
},
"location_id": "loc_office_01",
"world_id": "world_poland",
"created_by": "system"
}Quiz — uzupełnianie luk (fill-in)
json
{
"id": "task_012",
"type": "quiz",
"title": "Uzupełnij zdania — Historia Polski",
"description": "Wpisz brakujące słowo",
"thumbnail": "tasks/history_fill.png",
"age_groups": ["8-13"],
"duration_minutes": 7,
"xp_reward": 35,
"difficulty": "hard",
"badge_id": null,
"requires_task_id": "task_011",
"content": {
"questions": [
{
"id": "q_030",
"type": "fill_in",
"text": "Pierwszą stolicą Polski był ___.",
"correct_answers": ["Gniezno"],
"case_sensitive": false
},
{
"id": "q_031",
"type": "fill_in",
"text": "Bitwa pod Grunwaldem odbyła się w roku ___.",
"correct_answers": ["1410"],
"case_sensitive": false
}
],
"pass_threshold": 0.5,
"shuffle_questions": false,
"shuffle_options": false
},
"location_id": "loc_office_01",
"world_id": "world_poland",
"created_by": "system"
}Quiz — pytanie otwarte (open)
json
{
"id": "task_013",
"type": "quiz",
"title": "Opowiedz o swoim ulubionym zwierzątku",
"description": "Odpowiedz na pytania własnymi słowami",
"thumbnail": "tasks/open_animals.png",
"age_groups": ["4-8"],
"duration_minutes": 5,
"xp_reward": 20,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_040",
"type": "open",
"text": "Jakie jest Twoje ulubione zwierzę i dlaczego?",
"min_length": 10,
"max_length": 500
},
{
"id": "q_041",
"type": "open",
"text": "Opisz jak wygląda to zwierzę.",
"min_length": 10,
"max_length": 500
}
],
"pass_threshold": null,
"shuffle_questions": false,
"shuffle_options": false
},
"location_id": "loc_library_01",
"world_id": "world_poland",
"created_by": "system"
}Video — film z quizem
json
{
"id": "task_002",
"type": "video",
"title": "Dinozaury — skąd się wzięły?",
"description": "Film o dinozaurach z quizem na końcu",
"thumbnail": "tasks/dino.png",
"age_groups": ["4-8", "8-13"],
"duration_minutes": 8,
"xp_reward": 30,
"difficulty": "medium",
"badge_id": "badge_cinema_5",
"requires_task_id": null,
"content": {
"video_url": "https://cdn.lumosislands.com/videos/dino.mp4",
"video_duration_seconds": 420,
"subtitles_url": "https://cdn.lumosislands.com/subs/dino_pl.vtt",
"quiz_after": {
"questions": [
{
"id": "q_050",
"type": "multiple_choice",
"text": "Kiedy wyginęły dinozaury?",
"options": ["100 lat temu", "1000 lat temu", "65 milionów lat temu"],
"correct": 2
},
{
"id": "q_051",
"type": "true_false",
"text": "Tyranozaur był roślinożercą.",
"correct": false
}
],
"pass_threshold": 0.5
}
},
"location_id": "loc_cinema_01",
"world_id": "world_poland",
"created_by": "system"
}Video — film bez quizu
json
{
"id": "task_020",
"type": "video",
"title": "Jak działa wulkan?",
"description": "Animacja pokazująca erupcję wulkanu",
"thumbnail": "tasks/volcano.png",
"age_groups": ["8-13"],
"duration_minutes": 6,
"xp_reward": 20,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"video_url": "https://cdn.lumosislands.com/videos/volcano.mp4",
"video_duration_seconds": 340,
"subtitles_url": "https://cdn.lumosislands.com/subs/volcano_pl.vtt",
"quiz_after": null
},
"location_id": "loc_observatory_01",
"world_id": "world_poland",
"created_by": "system"
}Audio — podcast z quizem
json
{
"id": "task_030",
"type": "audio",
"title": "Historia Polski — podcast dla dzieci",
"description": "Posłuchaj krótkiego podcastu o historii Polski",
"thumbnail": "tasks/historia_podcast.png",
"age_groups": ["8-13"],
"duration_minutes": 12,
"xp_reward": 25,
"difficulty": "medium",
"badge_id": null,
"requires_task_id": null,
"content": {
"audio_url": "https://cdn.lumosislands.com/audio/historia_pl.mp3",
"audio_duration_seconds": 680,
"transcript_url": "https://cdn.lumosislands.com/transcripts/historia_pl.txt",
"cover_image": "tasks/historia_cover.png",
"quiz_after": {
"questions": [
{
"id": "q_060",
"type": "multiple_choice",
"text": "Kto był pierwszym królem Polski?",
"options": ["Bolesław Chrobry", "Mieszko I", "Kazimierz Wielki", "Władysław Jagiełło"],
"correct": 0
}
],
"pass_threshold": 0.5
}
},
"location_id": "loc_library_01",
"world_id": "world_poland",
"created_by": "system"
}Audio — bajka na słuchanie (bez quizu)
json
{
"id": "task_031",
"type": "audio",
"title": "Bajka na dobranoc — Kotek Mruczek",
"description": "Posłuchaj bajki o przygodach kotka",
"thumbnail": "tasks/kotek.png",
"age_groups": ["2-4"],
"duration_minutes": 5,
"xp_reward": 10,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"audio_url": "https://cdn.lumosislands.com/audio/kotek_mruczek.mp3",
"audio_duration_seconds": 280,
"transcript_url": null,
"cover_image": "tasks/kotek_cover.png",
"quiz_after": null
},
"location_id": "loc_library_01",
"world_id": "world_poland",
"created_by": "system"
}Game — minigra edukacyjna
json
{
"id": "task_040",
"type": "game",
"title": "Sortuj kształty — Geometria",
"description": "Przeciągnij kształty do odpowiednich kategorii",
"thumbnail": "tasks/shapes.png",
"age_groups": ["2-4", "4-8"],
"duration_minutes": 5,
"xp_reward": 20,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"game_type": "sorting",
"instructions": "Przeciągnij każdy kształt do odpowiedniego pudełka",
"items": [
{ "id": "item_1", "label": "Kwadrat", "image": "shapes/square.png", "category": "4 boki" },
{ "id": "item_2", "label": "Trójkąt", "image": "shapes/triangle.png", "category": "3 boki" },
{ "id": "item_3", "label": "Prostokąt", "image": "shapes/rectangle.png", "category": "4 boki" },
{ "id": "item_4", "label": "Pięciokąt", "image": "shapes/pentagon.png", "category": "5 boków" }
],
"categories": ["3 boki", "4 boki", "5 boków"],
"time_limit_seconds": null
},
"location_id": "loc_factory_01",
"world_id": "world_poland",
"created_by": "system"
}Game — memory (dopasowywanie par)
json
{
"id": "task_041",
"type": "game",
"title": "Memory — Zwierzęta i ich dźwięki",
"description": "Znajdź pary: zwierzę i jego dźwięk",
"thumbnail": "tasks/memory_animals.png",
"age_groups": ["2-4", "4-8"],
"duration_minutes": 5,
"xp_reward": 15,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"game_type": "memory",
"instructions": "Odkrywaj karty i łącz zwierzę z jego dźwiękiem",
"pairs": [
{ "card_a": { "type": "image", "value": "animals/cow.png" }, "card_b": { "type": "text", "value": "Muuu" } },
{ "card_a": { "type": "image", "value": "animals/cat.png" }, "card_b": { "type": "text", "value": "Miau" } },
{ "card_a": { "type": "image", "value": "animals/dog.png" }, "card_b": { "type": "text", "value": "Hau hau" } },
{ "card_a": { "type": "image", "value": "animals/duck.png" }, "card_b": { "type": "text", "value": "Kwa kwa" } }
],
"time_limit_seconds": 120
},
"location_id": "loc_field_01",
"world_id": "world_poland",
"created_by": "system"
}Game — puzzle (układanka)
json
{
"id": "task_042",
"type": "game",
"title": "Puzzle — Mapa Polski",
"description": "Ułóż puzzle z mapą Polski",
"thumbnail": "tasks/puzzle_poland.png",
"age_groups": ["4-8", "8-13"],
"duration_minutes": 10,
"xp_reward": 30,
"difficulty": "medium",
"badge_id": "badge_puzzle_master",
"requires_task_id": null,
"content": {
"game_type": "puzzle",
"instructions": "Przeciągnij kawałki na swoje miejsca",
"image_url": "tasks/puzzle_poland_full.png",
"grid_size": { "cols": 4, "rows": 3 },
"time_limit_seconds": 300
},
"location_id": "loc_office_01",
"world_id": "world_poland",
"created_by": "system"
}Creative — zadanie kreatywne
json
{
"id": "task_050",
"type": "creative",
"title": "Narysuj swoje ulubione zwierzę",
"description": "Użyj narzędzi rysowania, aby narysować zwierzę",
"thumbnail": "tasks/draw_animal.png",
"age_groups": ["2-4", "4-8"],
"duration_minutes": 10,
"xp_reward": 20,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"creative_type": "drawing",
"instructions": "Narysuj swoje ulubione zwierzę. Możesz użyć dowolnych kolorów!",
"tools": ["pen", "brush", "fill", "eraser", "stickers"],
"canvas_size": { "width": 800, "height": 600 },
"background_image": null,
"sticker_packs": ["animals", "nature"]
},
"location_id": "loc_music_studio_01",
"world_id": "world_poland",
"created_by": "system"
}Creative — nagranie audio
json
{
"id": "task_051",
"type": "creative",
"title": "Nagraj wiersz",
"description": "Przeczytaj wiersz na głos i nagraj swoją wersję",
"thumbnail": "tasks/record_poem.png",
"age_groups": ["4-8"],
"duration_minutes": 5,
"xp_reward": 20,
"difficulty": "easy",
"badge_id": null,
"requires_task_id": null,
"content": {
"creative_type": "audio_recording",
"instructions": "Przeczytaj wiersz na głos i nagraj swoją wersję. Możesz nagrać kilka razy!",
"reference_text": "Wlazł kotek na płotek\ni mruga,\nładna to piosenka\nniedługa.",
"max_duration_seconds": 60,
"max_attempts": 3
},
"location_id": "loc_music_studio_01",
"world_id": "world_poland",
"created_by": "system"
}Zadanie dla dorosłych (14+) — test na prawo jazdy
json
{
"id": "task_driving_001",
"type": "quiz",
"title": "Test na prawo jazdy — Znaki drogowe",
"description": "Sprawdź swoją wiedzę o znakach drogowych",
"thumbnail": "tasks/driving_signs.png",
"age_groups": ["14+"],
"duration_minutes": 15,
"xp_reward": 50,
"difficulty": "hard",
"badge_id": "badge_driving_signs",
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_d001",
"type": "multiple_choice",
"text": "Co oznacza ten znak?",
"image": "signs/stop.png",
"options": ["Zakaz wjazdu", "Stop — zatrzymaj się", "Koniec drogi", "Ustąp pierwszeństwa"],
"correct": 1
},
{
"id": "q_d002",
"type": "multiple_choice",
"text": "Jaka jest maksymalna prędkość w terenie zabudowanym (5:00-23:00)?",
"options": ["40 km/h", "50 km/h", "60 km/h", "70 km/h"],
"correct": 1
},
{
"id": "q_d003",
"type": "true_false",
"text": "Na skrzyżowaniu równorzędnym pierwszeństwo ma pojazd nadjeżdżający z prawej strony.",
"correct": true
}
],
"pass_threshold": 0.8,
"shuffle_questions": true,
"shuffle_options": false
},
"location_id": "loc_office_driving",
"world_id": "world_poland",
"created_by": "system"
}Zadanie dla dorosłych (14+) — egzamin studencki
json
{
"id": "task_uni_001",
"type": "quiz",
"title": "Wprowadzenie do programowania — Python",
"description": "Test z podstaw Pythona na egzamin",
"thumbnail": "tasks/python_basics.png",
"age_groups": ["14+"],
"duration_minutes": 20,
"xp_reward": 60,
"difficulty": "hard",
"badge_id": null,
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_u001",
"type": "multiple_choice",
"text": "Co wypisze: print(type(3.14))?",
"options": ["<class 'int'>", "<class 'float'>", "<class 'str'>", "<class 'double'>"],
"correct": 1
},
{
"id": "q_u002",
"type": "fill_in",
"text": "Aby zdefiniować funkcję w Pythonie, używamy słowa kluczowego ___.",
"correct_answers": ["def"],
"case_sensitive": true
},
{
"id": "q_u003",
"type": "multiple_choice",
"text": "Która struktura danych jest niezmiennicza (immutable)?",
"options": ["list", "dict", "set", "tuple"],
"correct": 3
}
],
"pass_threshold": 0.6,
"shuffle_questions": true,
"shuffle_options": true
},
"location_id": "loc_observatory_uni",
"world_id": "world_open_python",
"created_by": "org_university_001"
}Zadanie z contentu rodzica
json
{
"id": "task_parent_001",
"type": "quiz",
"title": "Powtórka — Tabliczka mnożenia do 10",
"description": "Quiz stworzony przez mamę",
"thumbnail": null,
"age_groups": ["4-8", "8-13"],
"duration_minutes": 10,
"xp_reward": 20,
"difficulty": "medium",
"badge_id": null,
"requires_task_id": null,
"content": {
"questions": [
{
"id": "q_p001",
"type": "multiple_choice",
"text": "Ile to 7 × 8?",
"options": ["54", "56", "58", "64"],
"correct": 1
},
{
"id": "q_p002",
"type": "fill_in",
"text": "9 × 9 = ___",
"correct_answers": ["81"],
"case_sensitive": false
}
],
"pass_threshold": 0.7,
"shuffle_questions": true,
"shuffle_options": true
},
"location_id": "loc_factory_custom_01",
"world_id": "world_custom_parent_001",
"created_by": "parent_001"
}Pola wspólne (wszystkie typy)
| Pole | Typ | Opis |
|---|---|---|
id | string | Unikalny identyfikator |
type | string | "quiz", "video", "audio", "game", "creative" |
title | string | Tytuł na kafelku Netflix-style |
description | string | Krótki opis |
thumbnail | string? | Obrazek na kafelku (null = placeholder) |
age_groups | string[] | Grupy wiekowe — tablica, np. ["4-8", "8-13"]. Dostępne wartości: "2-4", "4-8", "8-13", "14+" |
duration_minutes | number | Szacowany czas wykonania |
xp_reward | number | XP za ukończenie |
badge_id | string? | Opcjonalna odznaka za ukończenie |
requires_task_id | string? | ID zadania wymaganego wcześniej |
content | object | Treść zadania (zależy od typu — patrz niżej) |
location_id | string | ID lokacji |
world_id | string | ID świata |
difficulty | string | Poziom trudności: "easy", "medium", "hard". Ustawiany ręcznie w content manager. |
created_by | string | "system", "parent_XXX", "school_XXX", "org_XXX" |
Content — typy pytań (Quiz)
| Typ pytania | Pola |
|---|---|
multiple_choice | text, image?, options[], correct (index) |
true_false | text, correct (boolean) |
matching | text, pairs[] ({left, right}) |
fill_in | text, correct_answers[], case_sensitive |
open | text, min_length, max_length |
Pola quizu
| Pole | Typ | Opis |
|---|---|---|
questions | array | Lista pytań |
pass_threshold | number? | Wymagany % poprawnych (null = brak wymagania, np. pytania otwarte) |
shuffle_questions | boolean | Czy mieszać kolejność pytań |
shuffle_options | boolean | Czy mieszać odpowiedzi (multiple_choice) |
Content — Video
| Pole | Typ | Opis |
|---|---|---|
video_url | string | URL do pliku wideo |
video_duration_seconds | number | Długość wideo w sekundach |
subtitles_url | string? | URL do napisów (WebVTT) |
quiz_after | object? | Opcjonalny quiz po filmie (ta sama struktura co quiz content) |
Content — Audio
| Pole | Typ | Opis |
|---|---|---|
audio_url | string | URL do pliku audio |
audio_duration_seconds | number | Długość audio w sekundach |
transcript_url | string? | URL do transkrypcji |
cover_image | string? | Obrazek wyświetlany podczas odtwarzania |
quiz_after | object? | Opcjonalny quiz po odsłuchaniu |
Content — Game
| Pole | Typ | Opis |
|---|---|---|
game_type | string | "sorting", "memory", "puzzle", "sequence", "coloring" |
instructions | string | Instrukcje dla gracza |
time_limit_seconds | number? | Opcjonalny limit czasu |
Pola zależne od game_type
| game_type | Dodatkowe pola |
|---|---|
sorting | items[] ({id, label, image, category}), categories[] |
memory | pairs[] ({card_a, card_b}) — karta: {type, value} (type: "image" lub "text") |
puzzle | image_url, grid_size ({cols, rows}) |
sequence | items[] ({id, label, image, position}) — ułóż w kolejności |
coloring | outline_image, color_palette[] |
Content — Creative
| Pole | Typ | Opis |
|---|---|---|
creative_type | string | "drawing", "audio_recording", "photo", "text_writing" |
instructions | string | Instrukcje |
Pola zależne od creative_type
| creative_type | Dodatkowe pola |
|---|---|
drawing | tools[], canvas_size, background_image?, sticker_packs[] |
audio_recording | reference_text?, max_duration_seconds, max_attempts |
photo | prompt, example_image?, max_photos |
text_writing | prompt, min_length, max_length, template? |
Wymagania zadań
Zadania mogą mieć wymagania:
- Grupy wiekowe (
age_groups) — zadanie widoczne dla użytkowników, których grupa wiekowa pokrywa się z co najmniej jedną grupą z tablicy - Wcześniejsze zadanie (
requires_task_id) — zadanie zablokowane do momentu ukończenia wskazanego zadania - Lokacje są zawsze dostępne — wymagania dotyczą tylko zadań