M8: progression, items, bankarta och sparfil
All checks were successful
release / build-release (push) Successful in 1m46s

- internal/progress: katalog (skills.json 12 noder, items.json 25 items)
  med validering; XP/nivåer (150·n(n+1)/2) och skillpoäng; skillträd med
  krav och kostnad; items per plats med buffar, genvägar (JR Pass, kartor,
  powerbank) och färgton; banresultat och upplåsning (huvudbanor i ordning,
  sidospår efter föräldern); 33 %-regeln som test
- internal/save: versionerad JSON med kunskap, plånbok, debuffar,
  progression och pågående bana + seed; atomisk skrivning; migrering;
  ~/.config/metro-puzzle-jp/save.json resp. %AppData%
- sim: RunOptions får Extra/FogRadius/Landmarks/FreeGates/RevealAll/
  InfiniteBattery; luck påverkar trängselzonen; Fog.RevealAll och extra
  landmärken
- game: bankarta i spelbrädesstil ersätter menyn (⟳ återupptar med sparad
  seed), skillträd (T), garderob (I), butik i kiosken (B), XP/nivå/items/
  upplåsningar på resultatet, spelaren tonas av skins; autospar vid banstart,
  efter banan och vid köp; flaggor -save/-nosave
- level: kind/order/parent/rewards/shop; ny sidobana 002b Kabukicho som
  belönar skinnet Kimono; 001 belönar Salaryman-skinnet; butikssortiment
  på 002/003
- tools/shots: demo-sparfil (build/, aldrig den riktiga), bilder av karta,
  skills, garderob och butik; alla körningar med -nosave
- docs/README/wiki uppdaterade

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 11:29:30 +02:00
parent d466333f01
commit 915c684dc2
46 changed files with 3058 additions and 316 deletions

432
resources/data/items.json Normal file
View File

@@ -0,0 +1,432 @@
{
"_comment": "Items: kläder, masker, hattar, prylar. slot = head/face/body/feet/bag (ett per plats bärs). price = kontantpris i kiosken (0 = bara belöning). effect som skills + freeGates (spärrar gratis), revealLevel (minikartan avslöjad på en bana), battery (telefonen laddar inte ur). tint = färgton på spelaren när det bärs.",
"items": [
{
"id": "cap_red",
"kind": "hat",
"slot": "head",
"name": {
"sv": "Röd keps",
"en": "Red cap"
},
"price": 800,
"effect": {
"stats": {
"focus": 1.05
}
}
},
{
"id": "sun_hat",
"kind": "hat",
"slot": "head",
"name": {
"sv": "Solhatt",
"en": "Sun hat"
},
"price": 1200,
"effect": {
"stats": {
"thirst": 0.9
}
},
"tint": [
1,
0.95,
0.7
]
},
{
"id": "beanie",
"kind": "hat",
"slot": "head",
"name": {
"sv": "Mössa",
"en": "Beanie"
},
"price": 900,
"effect": {
"stats": {
"toilet": 1.1,
"focus": 1.1
}
}
},
{
"id": "conductor_cap",
"kind": "hat",
"slot": "head",
"name": {
"sv": "Konduktörsmössa",
"en": "Conductor cap"
},
"price": 3000,
"effect": {
"stats": {
"luck": 1.15
}
},
"tint": [
0.8,
0.85,
1
]
},
{
"id": "mask_surgical",
"kind": "mask",
"slot": "face",
"name": {
"sv": "Munskydd",
"en": "Surgical mask"
},
"price": 300,
"effect": {
"stats": {
"toilet": 0.95
}
}
},
{
"id": "mask_fox",
"kind": "mask",
"slot": "face",
"name": {
"sv": "Rävmask",
"en": "Fox mask"
},
"price": 1500,
"effect": {
"stats": {
"luck": 1.1
}
},
"tint": [
1,
0.85,
0.7
]
},
{
"id": "mask_tengu",
"kind": "mask",
"slot": "face",
"name": {
"sv": "Tengumask",
"en": "Tengu mask"
},
"price": 2200,
"effect": {
"stats": {
"focus": 0.9,
"speed": 1.08
}
},
"tint": [
1,
0.7,
0.7
]
},
{
"id": "sunglasses",
"kind": "mask",
"slot": "face",
"name": {
"sv": "Solglasögon",
"en": "Sunglasses"
},
"price": 1100,
"effect": {
"stats": {
"focus": 0.95,
"luck": 1.05
}
}
},
{
"id": "happi",
"kind": "clothes",
"slot": "body",
"name": {
"sv": "Happi-jacka",
"en": "Happi coat"
},
"price": 2500,
"effect": {
"stats": {
"speed": 1.05
}
},
"tint": [
0.7,
0.8,
1
]
},
{
"id": "yukata",
"kind": "clothes",
"slot": "body",
"name": {
"sv": "Yukata",
"en": "Yukata"
},
"price": 4000,
"effect": {
"stats": {
"speed": 0.95,
"focus": 1.15
}
},
"tint": [
0.8,
0.9,
1
]
},
{
"id": "rain_poncho",
"kind": "clothes",
"slot": "body",
"name": {
"sv": "Regnponcho",
"en": "Rain poncho"
},
"price": 700,
"effect": {
"stats": {
"thirst": 1.05,
"toilet": 0.95
}
},
"tint": [
0.8,
1,
0.8
]
},
{
"id": "suit",
"kind": "clothes",
"slot": "body",
"name": {
"sv": "Kostym",
"en": "Suit"
},
"price": 5500,
"effect": {
"stats": {
"luck": 1.2,
"thirst": 1.1
}
},
"tint": [
0.75,
0.75,
0.8
]
},
{
"id": "sneakers",
"kind": "shoes",
"slot": "feet",
"name": {
"sv": "Sneakers",
"en": "Sneakers"
},
"price": 3500,
"effect": {
"stats": {
"speed": 1.1
}
}
},
{
"id": "geta",
"kind": "shoes",
"slot": "feet",
"name": {
"sv": "Geta",
"en": "Geta"
},
"price": 1800,
"effect": {
"stats": {
"speed": 0.9,
"luck": 1.2
}
}
},
{
"id": "hiking_boots",
"kind": "shoes",
"slot": "feet",
"name": {
"sv": "Vandringskängor",
"en": "Hiking boots"
},
"price": 4200,
"effect": {
"stats": {
"speed": 1.05,
"toilet": 0.9
}
}
},
{
"id": "flipflops",
"kind": "shoes",
"slot": "feet",
"name": {
"sv": "Badtofflor",
"en": "Flip-flops"
},
"price": 400,
"effect": {
"stats": {
"speed": 0.92,
"thirst": 0.9
}
}
},
{
"id": "powerbank",
"kind": "gadget",
"slot": "bag",
"name": {
"sv": "Powerbank",
"en": "Power bank"
},
"price": 2000,
"effect": {
"battery": true
}
},
{
"id": "water_bottle",
"kind": "gadget",
"slot": "bag",
"name": {
"sv": "Vattenflaska",
"en": "Water bottle"
},
"price": 600,
"effect": {
"stats": {
"thirst": 0.8
}
}
},
{
"id": "onigiri_box",
"kind": "gadget",
"slot": "bag",
"name": {
"sv": "Onigiri-låda",
"en": "Onigiri box"
},
"price": 900,
"effect": {
"stats": {
"focus": 1.05,
"toilet": 1.05
}
}
},
{
"id": "map_shinjuku",
"kind": "map",
"slot": "bag",
"name": {
"sv": "Karta: Shinjuku",
"en": "Map: Shinjuku"
},
"price": 600,
"effect": {
"revealLevel": "002-shinjuku"
}
},
{
"id": "map_shibuya",
"kind": "map",
"slot": "bag",
"name": {
"sv": "Karta: Shibuya",
"en": "Map: Shibuya"
},
"price": 800,
"effect": {
"revealLevel": "003-shibuya"
}
},
{
"id": "rail_pass",
"kind": "pass",
"slot": "bag",
"name": {
"sv": "JR Pass",
"en": "JR Pass"
},
"price": 8000,
"effect": {
"freeGates": true
}
},
{
"id": "omamori",
"kind": "charm",
"slot": "bag",
"name": {
"sv": "Omamori",
"en": "Omamori"
},
"price": 1300,
"effect": {
"stats": {
"luck": 1.15
}
}
},
{
"id": "skin_kimono",
"kind": "skin",
"slot": "body",
"name": {
"sv": "Kimono (skin)",
"en": "Kimono (skin)"
},
"price": 0,
"effect": {
"stats": {
"luck": 1.05
}
},
"tint": [
1,
0.75,
0.85
]
},
{
"id": "skin_salaryman",
"kind": "skin",
"slot": "body",
"name": {
"sv": "Salaryman (skin)",
"en": "Salaryman (skin)"
},
"price": 0,
"effect": {
"stats": {
"speed": 1.03
}
},
"tint": [
0.7,
0.7,
0.75
]
}
]
}

View File

@@ -1,5 +1,7 @@
{
"id": "001-flygplatsen",
"kind": "main",
"order": 1,
"name": {
"sv": "Flygplatsen",
"en": "The Airport",
@@ -15,6 +17,11 @@
},
"timeLimitSec": 0,
"fareYen": 200,
"rewards": {
"items": [
"skin_salaryman"
]
},
"grid": [
"####################",
"#S.....#.....i.....#",

View File

@@ -1,12 +1,33 @@
{
"id": "002-shinjuku",
"kind": "main",
"order": 2,
"name": {
"en": "Shinjuku Station",
"ja": "新宿駅",
"sv": "Shinjuku station"
},
"difficulty": 2,
"party": 3,
"ticketRequired": true,
"seatSelection": true,
"rideStops": 4,
"destination": {
"en": "Shibuya",
"ja": "渋谷",
"romaji": "Shibuya",
"sv": "Shibuya"
},
"difficulty": 2,
"timeLimitSec": 420,
"maxMissedTrains": 2,
"fareYen": 200,
"shop": [
"cap_red",
"water_bottle",
"mask_surgical",
"map_shinjuku",
"sneakers"
],
"grid": [
"#################################",
"#S#..i..#K#...........#.........#",
@@ -30,47 +51,6 @@
"#pG.#...#.....................#P#",
"#################################"
],
"id": "002-shinjuku",
"maxMissedTrains": 2,
"name": {
"en": "Shinjuku Station",
"ja": "新宿駅",
"sv": "Shinjuku station"
},
"party": 3,
"rideStops": 4,
"seatSelection": true,
"signs": [
{
"text": {
"en": "Shinjuku Station. Track 14 Yamanote Line for Shibuya: far bottom right. Track 8 Chuo Line for Tokyo: far bottom left.",
"ja": "新宿駅 14番線 山手線 渋谷方面 → 南東 8番線 中央線 東京方面 → 南西",
"sv": "Shinjuku station. Spår 14 Yamanote-linjen mot Shibuya: längst ner till höger. Spår 8 Chuo-linjen mot Tokyo: längst ner till vänster."
},
"x": 5,
"y": 1
},
{
"text": {
"en": "\u003c- Track 8 Chuo Line (Tokyo) Track 14 Yamanote Line (Shibuya) -\u003e",
"ja": "← 8番線 中央線 東京方面 14番線 山手線 渋谷方面 →",
"sv": "\u003c- Spår 8 Chuo-linjen (Tokyo) Spår 14 Yamanote-linjen (Shibuya) -\u003e"
},
"x": 11,
"y": 15
},
{
"text": {
"en": "Track 14 Yamanote Line for Shibuya: the gate in the south-east corner.",
"ja": "14番線 山手線 渋谷方面 → 南東口 改札",
"sv": "Spår 14 Yamanote-linjen mot Shibuya: spärren i sydöstra hörnet."
},
"x": 11,
"y": 5
}
],
"ticketRequired": true,
"timeLimitSec": 420,
"trains": [
{
"correct": true,
@@ -113,5 +93,34 @@
},
"track": "8"
}
],
"signs": [
{
"text": {
"en": "Shinjuku Station. Track 14 Yamanote Line for Shibuya: far bottom right. Track 8 Chuo Line for Tokyo: far bottom left.",
"ja": "新宿駅 14番線 山手線 渋谷方面 → 南東 8番線 中央線 東京方面 → 南西",
"sv": "Shinjuku station. Spår 14 Yamanote-linjen mot Shibuya: längst ner till höger. Spår 8 Chuo-linjen mot Tokyo: längst ner till vänster."
},
"x": 5,
"y": 1
},
{
"text": {
"en": "<- Track 8 Chuo Line (Tokyo) Track 14 Yamanote Line (Shibuya) ->",
"ja": "← 8番線 中央線 東京方面 14番線 山手線 渋谷方面 →",
"sv": "<- Spår 8 Chuo-linjen (Tokyo) Spår 14 Yamanote-linjen (Shibuya) ->"
},
"x": 11,
"y": 15
},
{
"text": {
"en": "Track 14 Yamanote Line for Shibuya: the gate in the south-east corner.",
"ja": "14番線 山手線 渋谷方面 → 南東口 改札",
"sv": "Spår 14 Yamanote-linjen mot Shibuya: spärren i sydöstra hörnet."
},
"x": 11,
"y": 5
}
]
}
}

View File

@@ -0,0 +1,122 @@
{
"destination": {
"en": "Shinjuku",
"ja": "新宿",
"romaji": "Shinjuku",
"sv": "Shinjuku"
},
"difficulty": 2,
"fareYen": 200,
"grid": [
"#################################",
"#S....#....K#.....#.............#",
"#.###.#.#####.###.#.#.#########.#",
"#...#.#.........#.#.#.....#.....#",
"#.###.###########.#.#####.#######",
"#...#.#.....#...#.#.....#.#.....#",
"#.#.#.#.###.#.#.#.#.#####.#.###.#",
"#.#...#.#T....#.#.#.#...#.....#.#",
"#.#.###.#######.#.#.#.#.#####.#.#",
"#.#....i......#.#...#.#.....#.#.#",
"#.#####.#####.#.#####.#####.#.#.#",
"#.....#....W#.#.....#.#...#.#.#.#",
"#####.###.###.#####.#.#.#.#.###.#",
"#...#.#...#...#...#.#.#.#...#...#",
"#.#.#.###.#.###.#.#.#.#.#####.###",
"#.#.#...#.#.#.....#.#.#...#.....#",
"#.#.###.#.#.#.#####.#.###.#.#.#.#",
"#.#i..#.#.#.#.#...#...#...#...#.#",
"#G#.#.#.###.#.#.#.#####.#######G#",
"#pG.#.......#...#......i......GP#",
"#################################"
],
"id": "002b-kabukicho",
"kind": "side",
"name": {
"en": "Kabukicho exit",
"ja": "歌舞伎町",
"sv": "Kabukicho-utgången"
},
"order": 2,
"parent": "002-shinjuku",
"party": 2,
"rewards": {
"items": [
"skin_kimono"
],
"skillPoints": 1
},
"rideStops": 3,
"signs": [
{
"text": {
"en": "Side trip: Kabukicho. Back to Shinjuku on the Yamanote Line, track 1 south-east. The Chuo Line goes the wrong way.",
"ja": "歌舞伎町 1番線 山手線 新宿方面 → 南東 3番線 中央線 東京方面",
"sv": "Sidospår: Kabukicho. Tillbaka till Shinjuku med Yamanote-linjen, spår 1 i sydost. Chuo-linjen går åt fel håll."
},
"x": 7,
"y": 9
},
{
"text": {
"en": "\u003c- Track 3 Chuo Line (Tokyo) Track 1 Yamanote Line (Shinjuku) -\u003e",
"ja": "← 3番線 中央線 東京方面 1番線 山手線 新宿方面 →",
"sv": "\u003c- Spår 3 Chuo-linjen (Tokyo) Spår 1 Yamanote-linjen (Shinjuku) -\u003e"
},
"x": 3,
"y": 17
},
{
"text": {
"en": "Track 1 Yamanote Line: the gate in the south-east corner.",
"ja": "1番線 山手線 新宿方面 → 南東口 改札",
"sv": "Spår 1 Yamanote-linjen: spärren i sydöstra hörnet."
},
"x": 23,
"y": 19
}
],
"timeLimitSec": 240,
"trains": [
{
"correct": true,
"destination": {
"en": "Shinjuku",
"ja": "新宿",
"romaji": "Shinjuku"
},
"line": {
"en": "Yamanote Line",
"ja": "山手線",
"romaji": "Yamanote-sen"
},
"platform": "P",
"schedule": {
"dwellSec": 7,
"intervalSec": 22,
"offsetSec": 4
},
"track": "1"
},
{
"correct": false,
"destination": {
"en": "Tokyo",
"ja": "東京",
"romaji": "Tokyo"
},
"line": {
"en": "Chuo Line",
"ja": "中央線",
"romaji": "Chuo-sen"
},
"platform": "p",
"schedule": {
"dwellSec": 7,
"intervalSec": 26,
"offsetSec": 9
},
"track": "3"
}
]
}

View File

@@ -1,12 +1,35 @@
{
"id": "003-shibuya",
"kind": "main",
"order": 3,
"name": {
"en": "Shibuya Station",
"ja": "渋谷駅",
"sv": "Shibuya station"
},
"difficulty": 3,
"party": 4,
"ticketRequired": true,
"seatSelection": true,
"individualCards": true,
"rideStops": 5,
"destination": {
"en": "Ikebukuro",
"ja": "池袋",
"romaji": "Ikebukuro",
"sv": "Ikebukuro"
},
"difficulty": 3,
"timeLimitSec": 360,
"maxMissedTrains": 1,
"fareYen": 200,
"shop": [
"sun_hat",
"happi",
"geta",
"map_shibuya",
"powerbank",
"rail_pass"
],
"grid": [
"#################################",
"#S.........W#....i........#.....#",
@@ -30,48 +53,6 @@
"#pG...............#.......#...GP#",
"#################################"
],
"id": "003-shibuya",
"individualCards": true,
"maxMissedTrains": 1,
"name": {
"en": "Shibuya Station",
"ja": "渋谷駅",
"sv": "Shibuya station"
},
"party": 4,
"rideStops": 5,
"seatSelection": true,
"signs": [
{
"text": {
"en": "Shibuya Station. Track 2 Yamanote Line for Ikebukuro: south-east. Track 4 Tokyu Toyoko Line for Yokohama: south-west. Tickets at the machine.",
"ja": "渋谷駅 2番線 山手線 池袋方面 → 南東 4番線 東急東横線 横浜方面 → 南西 切符 自動券売機",
"sv": "Shibuya station. Spår 2 Yamanote-linjen mot Ikebukuro: sydöst. Spår 4 Tokyu Toyoko-linjen mot Yokohama: sydväst. Biljetter i automaten."
},
"x": 17,
"y": 1
},
{
"text": {
"en": "\u003c- Track 4 Tokyu Toyoko Line (Yokohama) Track 2 Yamanote Line (Ikebukuro) -\u003e",
"ja": "← 4番線 東急東横線 横浜方面 2番線 山手線 池袋方面 →",
"sv": "\u003c- Spår 4 Tokyu Toyoko-linjen (Yokohama) Spår 2 Yamanote-linjen (Ikebukuro) -\u003e"
},
"x": 23,
"y": 5
},
{
"text": {
"en": "Track 2 Yamanote Line for Ikebukuro: the gate in the south-east corner. Everyone needs a ticket and card balance.",
"ja": "2番線 山手線 池袋方面 → 南東口 改札",
"sv": "Spår 2 Yamanote-linjen mot Ikebukuro: spärren i sydöstra hörnet. Alla behöver biljett och saldo på kortet."
},
"x": 29,
"y": 13
}
],
"ticketRequired": true,
"timeLimitSec": 360,
"trains": [
{
"correct": true,
@@ -114,5 +95,34 @@
},
"track": "4"
}
],
"signs": [
{
"text": {
"en": "Shibuya Station. Track 2 Yamanote Line for Ikebukuro: south-east. Track 4 Tokyu Toyoko Line for Yokohama: south-west. Tickets at the machine.",
"ja": "渋谷駅 2番線 山手線 池袋方面 → 南東 4番線 東急東横線 横浜方面 → 南西 切符 自動券売機",
"sv": "Shibuya station. Spår 2 Yamanote-linjen mot Ikebukuro: sydöst. Spår 4 Tokyu Toyoko-linjen mot Yokohama: sydväst. Biljetter i automaten."
},
"x": 17,
"y": 1
},
{
"text": {
"en": "<- Track 4 Tokyu Toyoko Line (Yokohama) Track 2 Yamanote Line (Ikebukuro) ->",
"ja": "← 4番線 東急東横線 横浜方面 2番線 山手線 池袋方面 →",
"sv": "<- Spår 4 Tokyu Toyoko-linjen (Yokohama) Spår 2 Yamanote-linjen (Ikebukuro) ->"
},
"x": 23,
"y": 5
},
{
"text": {
"en": "Track 2 Yamanote Line for Ikebukuro: the gate in the south-east corner. Everyone needs a ticket and card balance.",
"ja": "2番線 山手線 池袋方面 → 南東口 改札",
"sv": "Spår 2 Yamanote-linjen mot Ikebukuro: spärren i sydöstra hörnet. Alla behöver biljett och saldo på kortet."
},
"x": 29,
"y": 13
}
]
}
}

239
resources/data/skills.json Normal file
View File

@@ -0,0 +1,239 @@
{
"_comment": "Språkträdet/skill tree. cost = skillpoäng (1 per level-up). requires = id:n som måste vara upplåsta. effect: stats (multiplikatorer: speed/thirst/focus/toilet/luck), kana, fogRadius (+rutor), landmarks (toaletter/kiosker/automater syns alltid på minikartan).",
"skills": [
{
"id": "kana",
"branch": "språk",
"name": {
"sv": "Kana",
"en": "Kana"
},
"desc": {
"sv": "Du kan läsa hiragana och katakana – alla kana-ord visas som romaji.",
"en": "You can read hiragana and katakana – kana words show as romaji."
},
"cost": 2,
"requires": [],
"effect": {
"kana": true
}
},
{
"id": "focus1",
"branch": "språk",
"name": {
"sv": "Skarp blick",
"en": "Sharp eye"
},
"desc": {
"sv": "+25 % chans att lära ord av skyltar, snabbare hjälp.",
"en": "+25% chance to learn words from signs, faster help."
},
"cost": 1,
"requires": [],
"effect": {
"stats": {
"focus": 1.25
}
}
},
{
"id": "focus2",
"branch": "språk",
"name": {
"sv": "Fotografiskt minne",
"en": "Photographic memory"
},
"desc": {
"sv": "Ytterligare +25 % fokus.",
"en": "Another +25% focus."
},
"cost": 2,
"requires": [
"focus1"
],
"effect": {
"stats": {
"focus": 1.25
}
}
},
{
"id": "polite",
"branch": "språk",
"name": {
"sv": "Sumimasen!",
"en": "Sumimasen!"
},
"desc": {
"sv": "Folk hjälper dig gärna: hjälpen går dubbelt så fort.",
"en": "People like helping you: help takes half the time."
},
"cost": 1,
"requires": [
"focus1"
],
"effect": {
"stats": {
"focus": 1.5
}
}
},
{
"id": "legs1",
"branch": "kropp",
"name": {
"sv": "Snabba fötter",
"en": "Quick feet"
},
"desc": {
"sv": "+10 % gångfart.",
"en": "+10% walking speed."
},
"cost": 1,
"requires": [],
"effect": {
"stats": {
"speed": 1.1
}
}
},
{
"id": "legs2",
"branch": "kropp",
"name": {
"sv": "Pendlarsteg",
"en": "Commuter stride"
},
"desc": {
"sv": "Ytterligare +10 % gångfart.",
"en": "Another +10% speed."
},
"cost": 2,
"requires": [
"legs1"
],
"effect": {
"stats": {
"speed": 1.1
}
}
},
{
"id": "camel",
"branch": "kropp",
"name": {
"sv": "Kamel",
"en": "Camel"
},
"desc": {
"sv": "Törsten kommer 25 % långsammare.",
"en": "Thirst builds 25% slower."
},
"cost": 1,
"requires": [],
"effect": {
"stats": {
"thirst": 0.75
}
}
},
{
"id": "bladder",
"branch": "kropp",
"name": {
"sv": "Stålblåsa",
"en": "Steel bladder"
},
"desc": {
"sv": "Toamätaren sjunker 25 % långsammare.",
"en": "Toilet meter drops 25% slower."
},
"cost": 1,
"requires": [
"camel"
],
"effect": {
"stats": {
"toilet": 0.75
}
}
},
{
"id": "lucky",
"branch": "resenär",
"name": {
"sv": "Omikuji",
"en": "Omikuji"
},
"desc": {
"sv": "+30 % tur: färre omskanningar, lättare att få plats, färre matförgiftningar.",
"en": "+30% luck: fewer rescans, easier to squeeze in, fewer food poisonings."
},
"cost": 1,
"requires": [],
"effect": {
"stats": {
"luck": 1.3
}
}
},
{
"id": "commuter",
"branch": "resenär",
"name": {
"sv": "Rusningsvan",
"en": "Rush-hour pro"
},
"desc": {
"sv": "Ytterligare +30 % tur.",
"en": "Another +30% luck."
},
"cost": 2,
"requires": [
"lucky"
],
"effect": {
"stats": {
"luck": 1.3
}
}
},
{
"id": "scout",
"branch": "utforskare",
"name": {
"sv": "Spanare",
"en": "Scout"
},
"desc": {
"sv": "Du ser ett steg längre i gångarna.",
"en": "You see one step further down the corridors."
},
"cost": 1,
"requires": [],
"effect": {
"fogRadius": 1
}
},
{
"id": "local",
"branch": "utforskare",
"name": {
"sv": "Lokalkännedom",
"en": "Local knowledge"
},
"desc": {
"sv": "Toaletter, kiosker och automater syns alltid på minikartan.",
"en": "Toilets, kiosks and machines always show on the minimap."
},
"cost": 2,
"requires": [
"scout"
],
"effect": {
"landmarks": true
}
}
]
}