Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
002d1e83bf | ||
|
|
d56540785f | ||
|
|
73cfd870f6 | ||
|
|
c7558a3947 | ||
|
|
bf4e8de590 | ||
|
|
ab35845572 | ||
|
|
e42f8ceba1 | ||
|
|
faa8b16658 | ||
|
|
53fc17338f | ||
|
|
a9e999b49e | ||
|
|
f676e59008 | ||
|
|
db8aa53d3f | ||
|
|
2a86881108 | ||
|
|
17d4e9cdf3 | ||
|
|
ac40f2176b | ||
|
|
b08a2a3715 | ||
|
|
1ec6590389 |
@@ -1 +1,3 @@
|
|||||||
.vs
|
.vs
|
||||||
|
light_and_dark/light_and_dark/saves/
|
||||||
|
**/__pycache__/
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Project
|
||||||
|
"Light & Dark" — a 2D light/shade platformer prototype (Python 3.10 + pygame).
|
||||||
|
|
||||||
|
- Main game: `light_and_dark/main.py` (single large file, ~9500 lines, no tests)
|
||||||
|
- Level editor: `light_and_dark/level_editor_v43.html` (standalone HTML/JS, no build step)
|
||||||
|
- Levels: `light_and_dark/data/world/rooms/room_0N.json`
|
||||||
|
- Data/config: `light_and_dark/data/config/*.json`, `data/items/*.json`, `data/objects/*.json`, `data/enemies/*.json`
|
||||||
|
|
||||||
|
## Standard session start
|
||||||
|
1. `git status` + `git log --oneline -5` to see uncommitted/untracked work (currently `room_08`/`room_09`/`room_boss_fly_refight` and the `Boss_fly_token.png` sprite are untracked/WIP).
|
||||||
|
2. Read the specific file(s) the request touches before editing; follow existing style.
|
||||||
|
3. After edits, always verify (see below).
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
- `python -m py_compile light_and_dark/main.py` (must pass after any edit)
|
||||||
|
- Validate touched JSON: `python -c "import json; json.load(open('<path>', encoding='utf-8'))"`
|
||||||
|
- To confirm the game boots: run `python light_and_dark/main.py` with a short timeout; no traceback in the first lines = OK (the window blocks, so it will time out).
|
||||||
|
|
||||||
|
## Pitfalls / conventions
|
||||||
|
- **Python booleans are `True`/`False`** — never `true`/`false` in main.py (this once crashed startup). JSON files use lowercase `true`.
|
||||||
|
- Don't add code comments unless asked. Match surrounding style.
|
||||||
|
- Rooms load through `normalize_room_json` + `Room` (main.py) which rewrite JSON into the game format; keep new room JSON keys mirrored there (e.g. trigger/ability-door flags).
|
||||||
|
|
||||||
|
## Key systems (in main.py unless noted)
|
||||||
|
- **Saves**: lantern-only. `save_game` / `apply_save_data`. Quest progress, broken doors, defeated bosses persist ONLY on lantern interaction.
|
||||||
|
- **Trigger walls** (`trigger_wall_blocking`): meta keys `quest`, `quest_complete`, `quest_turned_in`, `lock_when_pass` (appears once walked through), `open_on_miniboss_dead`, `open_on_boss_dead` (released once the room's boss is slain; also hides/inerts moving platforms while the boss lives).
|
||||||
|
- **Exits**: `"requires_boss_dead": true` hides the exit and disables it while the room's boss is alive (used for boss doors and refight rooms). The editor round-trips this flag (checkbox in the Exit properties).
|
||||||
|
- **Bosses** (`BOSS_DEFS_DEFAULT`): `boss_id -> {name, room, refight_room, token_name, token_sprite}`. `boss_01` = Gloom Warden (legacy `room_boss_01`, not in the current build); `boss_02` = **Sky Terror** (flying, `room_08`, refight `room_boss_fly_refight`). A boss drops its token in its world room (not during a refight); tokens feed the Boss Diary (`boss_diary`) and the Combat Master upgrades them for the Hard fight. Token art is per-boss via `boss_token_sprite(boss_id)`.
|
||||||
|
- **Boss aggro**: once the player first enters a boss's `detection_range` in Light form, `Enemy.boss_engaged` latches and the boss chases forever (ignores range and Shade).
|
||||||
|
- **Flying boss** (`behavior: "flyer"`, config `enemy_types.json` → `boss_flyer.flyer`): hovers/bobs, slam-dives (shockwave `poison=False`), summons expiring minions, AOE rings, homing shots. Casts `_flyer_max_casts()` skills per slam-cycle — normal 1 (2 at `phase2_hp_pct`), hard 2 (3 at `hard_phase3_hp_pct`); `self.flyer_hard` is set by `start_refight(..., "hard")`.
|
||||||
|
- **Ability doors** (`AbilityDoor`): `kind` = `"ranged"` (shot open, persists in `broken_doors`) or `"shade"` (solid in light, passable in shade + a `shade_door_grace` window after form switch; ejected to nearest edge after grace).
|
||||||
|
- **Quests** (`QUEST_DEFS_DEFAULT`): objective `"shade": True` counts kills only in shade form. Rewards via `guaranteed_item` (one-time) or `pool` (repeatable). Items by `item_id` (e.g. `necklace_placeholder` = "Plain Necklace").
|
||||||
|
- **Minibosses**: stay defeated per room (`DEFEATED_MINIBOSSES`) until a lantern save in a different room, then respawn.
|
||||||
|
- **Enemies**: insta-die on hazard contact with no drops (`hazard_kill` flag); normal enemies respawn on room re-entry.
|
||||||
|
- **Chests** (`RewardChest`): spawn coin `CoinPickup`s above the chest top (not center, which clips into the platform).
|
||||||
|
- **Shade-kills quest** (`first_kills_shade` in room 6): interactable/prompted only while in shade form (`QuestManager.requires_shade`).
|
||||||
|
|
||||||
|
## Editor (level_editor_v43.html)
|
||||||
|
- Link lines: `drawLinkLinesForCanvas` — exits with a `spawn_id` missing in the target room draw NO line (avoids stale-coordinate artifacts).
|
||||||
|
- Keyboard shortcuts live in the `window keydown` handler: V/P/E/N/O switch tools, F fit, Esc deselect, Ctrl+Z/Y/C/X/V/D.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<Solution>
|
||||||
|
<Project Path="light_and_dark/light_and_dark.pyproj" Type="888888a0-9f3d-457c-b088-3a5042f75d52" Id="e4b51f4c-e0be-4f9e-8a8e-d814a78b30c5">
|
||||||
|
<Build Project="false" />
|
||||||
|
</Project>
|
||||||
|
</Solution>
|
||||||
|
Before Width: | Height: | Size: 702 B After Width: | Height: | Size: 702 B |
|
Before Width: | Height: | Size: 680 B After Width: | Height: | Size: 680 B |
|
Before Width: | Height: | Size: 695 B After Width: | Height: | Size: 695 B |
|
Before Width: | Height: | Size: 879 B After Width: | Height: | Size: 879 B |
@@ -0,0 +1,183 @@
|
|||||||
|
# Light & Dark — Prototype
|
||||||
|
|
||||||
|
A 2D platformer built with **Pygame**. You switch between two forms — **Light** and **Shade** — each with different movement, combat, and ability behavior, all driven by a single shared resource: **Charge (Flow)**.
|
||||||
|
|
||||||
|
> Note: this is a prototype. Some progress (quests, boss tokens, broken walls, defeated bosses) is **in-memory** and resets when you restart — intentional, for fast testing. Saves (via pause menu or lanterns) persist player state, coins, equipment, inventory, and your respawn point.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running the game
|
||||||
|
|
||||||
|
```
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Python 3.10+ and `pygame`. Game data (rooms, items, sets, enemies, drops) lives in `data/`. Rooms are edited with the included browser tool: **`level_editor_v43.html`** — see [Level Editor](#level-editor) below.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Controls
|
||||||
|
|
||||||
|
| Action | Key |
|
||||||
|
|---|---|
|
||||||
|
| Move | A / D |
|
||||||
|
| Jump | W |
|
||||||
|
| Move down / drop | S |
|
||||||
|
| Heal | Space (hold) |
|
||||||
|
| Melee attack | E |
|
||||||
|
| Ranged shot | Q |
|
||||||
|
| Dash | Tab |
|
||||||
|
| Shatterstep | R |
|
||||||
|
| Tether | X |
|
||||||
|
| Reality Break | C |
|
||||||
|
| Fairy Mode (once unlocked) | Z |
|
||||||
|
| Toggle Light/Shade | Left Shift |
|
||||||
|
| Interact / Talk / Save | F |
|
||||||
|
| Use Butterfly Jar | G |
|
||||||
|
| Inventory | I |
|
||||||
|
| Stats overlay | H |
|
||||||
|
| Pause / Settings | Esc |
|
||||||
|
|
||||||
|
**Mouse**: **Left button** = melee attack, **Right button** = ranged shot.
|
||||||
|
|
||||||
|
**Hold-to-recast**: Melee (E / left mouse) and Ranged (Q / right mouse) can be **held** — the attack auto-recasts as soon as its cooldown is ready, and never faster than the cooldown.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The two forms
|
||||||
|
|
||||||
|
**Light** — faster movement, higher jump, and charge **refills** over time. You take contact damage from enemies.
|
||||||
|
|
||||||
|
**Shade** — slower but tanky: **immune to enemy contact damage**, deals double melee damage, and can use shade-specific gear bonuses. But being in Shade **drains Charge** (and Shade is forced off when Charge hits 0). Shade also drains Charge **twice as fast while clipping inside an enemy**.
|
||||||
|
|
||||||
|
**Charge (Flow)** — base max 100, refills at **10/s** in Light (halved to make light sources matter), drains at **40/s** in Shade. Standing near a **butterfly** light source doubles Charge regeneration. Attacks, dash (Light), ranged shots, and healing all cost Charge.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Saving & lanterns
|
||||||
|
|
||||||
|
**Lanterns are save points.** Walk up to a lantern and press **F** to save — a "Press F - Save at lantern" prompt appears when you're in range. Saving **fully restores your health and Charge** (and clears poison), and sets your respawn point to that lantern, so dying (or reloading the save) puts you back at your latest lantern. Saving via a lantern in a *different room* than where you last died also respawns butterfly jars in the world.
|
||||||
|
|
||||||
|
You can also save anytime from the pause menu (**Esc → Save Game**).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Butterfly jars
|
||||||
|
|
||||||
|
Butterfly-in-a-jar pickups are scattered through the rooms (you can hold up to **3**). Press **G** to consume one and instantly refill your Charge bar to max. Collected jars are shown below your coin counters (empty slots are greyed out).
|
||||||
|
|
||||||
|
Jars are lost when you die. They respawn at their pickup points after you save at a lantern in a different room, or after reloading the game.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Death & recovery
|
||||||
|
|
||||||
|
When you die you lose your **butterfly jars for good** and drop your coins. A **faded player model (corpse)** marks the spot — touch it to reclaim all lost coins. Dying again *without* reclaiming keeps only **50%** of the coins in a new corpse at the new death spot (the old corpse vanishes), so the rest is lost. Falling out of the world (void deaths) leaves no recoverable corpse.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Abilities (by form)
|
||||||
|
|
||||||
|
| Ability | Key | Light | Shade |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **Melee** | E | 1 damage, costs 1 Charge | **2 damage**, costs 1 Charge |
|
||||||
|
| **Dash** | Tab | Costs 10 Charge; **stuns** enemies hit | Costs 1 HP; deals **4 damage** to enemies hit |
|
||||||
|
| **Ranged** | Q | Costs 5 Charge, 0.63s cooldown, 0.5 damage; **breaks green ability walls** | Same, but 1.0 damage |
|
||||||
|
| **Shatterstep** | R | Spawns a **platform under your feet** while airborne (extra jumps) | On landing, creates a damaging **shockwave AOE** below you |
|
||||||
|
| **Tether** | X | **Binds** the enemy (3s) and **fears** it (runs away) | **Insta-kills** enemies below a HP threshold (normal ⅓, miniboss 20%, boss 5%); otherwise **slows** them |
|
||||||
|
| **Reality Break** | C | Doubles drop & coin rates and glows enemies | **Instantly kills all enemies** but halves drop & coin rates |
|
||||||
|
| **Heal** | Space | Spend Charge to heal over ~2s (slower while healing) | Unavailable |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Combat notes
|
||||||
|
|
||||||
|
- Enemy contact damage only applies in **Light** form.
|
||||||
|
- The **Gloom Warden's** ground shockwaves **poison** you for 4 seconds (the health bar turns green, −1 HP/s). **Sky Terror's** slam does **not** poison.
|
||||||
|
- Once a boss first spots you in Light form it tracks you permanently — even in Shade form and from any distance.
|
||||||
|
- Attacks and hits use invincibility frames and knockback; your melee hitbox covers ~30% into your body so close/overlapping hits always connect.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Equipment & Armor Sets
|
||||||
|
|
||||||
|
Slots: **helmet, chest, pants, necklace**. Pieces roll stats (move speed, heal, charge, health, etc.).
|
||||||
|
|
||||||
|
**Rarities:** `tempered` (tier 1) → `attuned` (tier 2) → `awakened` (tier 3, unlocks ability slots). The **Upgrader** NPC turns 5 tempered copies of an item into 1 attuned copy.
|
||||||
|
|
||||||
|
**Sets** (3 pieces of the same set, attuned or better):
|
||||||
|
|
||||||
|
| Set | Summary |
|
||||||
|
|---|---|
|
||||||
|
| Dawnrunner | +HP; awakened adds Light move speed |
|
||||||
|
| Gravemark | +max Charge; awakened adds Charge regen |
|
||||||
|
| Vitalweave | +HP; awakened adds +heal |
|
||||||
|
| Duskwarrior | +Shade damage; awakened restores Charge on Shade hits |
|
||||||
|
| Twister | Removes Shade speed penalty; awakened gives move speed after switching forms |
|
||||||
|
| Paladin | Chance to negate incoming damage; awakened adds +HP |
|
||||||
|
| Luminal Growth | +Charge regen while standing still in Light; awakened also negates damage |
|
||||||
|
| Abyss Cleaver | Chance to heal on kill; awakened also gives move speed on kill |
|
||||||
|
| Umbraflow | Reduces Shade Charge drain |
|
||||||
|
| Adaptive Traveller | Move speed after switching forms; awakened restores Charge on switch |
|
||||||
|
|
||||||
|
The shade-focused sets (**Duskwarrior, Umbraflow, Abyss Cleaver, Adaptive Traveller**) are intentionally **excluded** from early boss and town-shop loot, so you can always complete the remaining sets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## NPCs
|
||||||
|
|
||||||
|
> The town room isn't in the current build (removed in the room overhaul); these NPC types still exist and can be placed with the editor.
|
||||||
|
|
||||||
|
- **Vendor** — sells basic armor pieces.
|
||||||
|
- **Necklace Vendor** — sells necklaces.
|
||||||
|
- **Upgrader** — attunes 5× tempered → attuned.
|
||||||
|
- **Combat Master** — upgrades your boss token to unlock the **Hard** boss variant.
|
||||||
|
- **Boss Diary** — an interactable book: view your collected boss tokens in a grid, slot/unslot them, and start refights.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rooms & Progression
|
||||||
|
|
||||||
|
> The room set was overhauled; the old reward/town rooms are gone. Notable rooms:
|
||||||
|
|
||||||
|
- `room_01` — tutorial. Contains a **quest object** (pink): accept the **"First Kills"** quest (kill 4 normal enemies → 5–15 light coins, repeatable).
|
||||||
|
- `room_02` — first enemies.
|
||||||
|
- `room_04` — **miniboss** arena; the walls seal until the miniboss is slain.
|
||||||
|
- `room_05` — **charger boss** arena (seals until slain).
|
||||||
|
- `room_07` — hub, branching to the boss arena and back.
|
||||||
|
- `room_08` — **Sky Terror**, the flying boss. Entering locks you in: the exit back to `room_07` and the right-hand door to `room_09` only appear once he's dead.
|
||||||
|
- `room_09` — the area past Sky Terror's right door.
|
||||||
|
- `room_boss_fly_refight` — Sky Terror **diary refight** arena.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Boss Diary & Tokens
|
||||||
|
|
||||||
|
1. Beat a world boss → collect its **token** (a distinct pickup per boss).
|
||||||
|
2. **Slot** it in the Boss Diary (or keep it in your inventory).
|
||||||
|
3. Slotting unlocks **Fight (Normal)**. Upgrading the token at the **Combat Master** unlocks **Fight (Hard)**.
|
||||||
|
4. Dying in a refight ends it; removing a token from the diary sends it back to your inventory.
|
||||||
|
|
||||||
|
Bosses: **Gloom Warden** (`boss_01`, legacy) and **Sky Terror** (`boss_02`) — Sky Terror lives in `room_08` (51 HP) and refights in `room_boss_fly_refight`; on Hard he opens with **two** skills per attack cycle and escalates to **all three** below 20% HP.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HUD & Stats
|
||||||
|
|
||||||
|
- Top-right: health bar (turns **green while poisoned**), Charge bar, coin counts.
|
||||||
|
- Butterfly-jar slots below the coin counters (shown once you own at least one; remaining slots are greyed out).
|
||||||
|
- Ability icons with cooldown indicators (top-left).
|
||||||
|
- **H** toggles a detailed overlay: exact HP/Charge, move speeds (both forms), heal duration, attack rate, Charge regen, the lantern/light buff, and any stat bonuses from gear.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Level Editor
|
||||||
|
|
||||||
|
Open `level_editor_v43.html` in a browser to edit rooms. Highlights:
|
||||||
|
|
||||||
|
- **Icon toolbar** on the right edge of the canvas (Select, Platform, Enemy, NPC, Player, Entry, Exit, Ability Door, Object). Toggle **grid snap** in the left sidebar.
|
||||||
|
- **Objects catalog** (built-in, always available; `data/objects/objects.json` can override/add): `flow_butterfly` (light source), `lamp` (save point), `flow_butterfly_jar` (collectible), `house`, `diary`, and `player` (a size reference that renders nothing in-game).
|
||||||
|
- **NPC support**: place/select/move NPCs (vendor, upgrader, necklace_vendor, combat_master) and standalone **house props**.
|
||||||
|
- **Layers**: every object (platforms, houses, NPCs, enemies, props, ability doors, exits) has a **layer** number. Lower = further back, higher = further forward; lower is set in the Properties panel. The editor and game both draw back-to-front by `(layer, category)`, and the select tool is layer-aware.
|
||||||
|
- **Link lines**: enable **Draw link lines** (with Compare view) to see dashed lines from a room's exits to the matching doors in the other room.
|
||||||
|
- Load the game's enemy types (`data/enemies/enemy_types.json`) to preview hitboxes and aggro ranges; enemy/miniboss/boss are also built in.
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Light & Dark — Roadmap
|
||||||
|
|
||||||
|
Destination: **polished vertical slice** — Regions 1–2, save system, skill upgrades.
|
||||||
|
Proves the core loop is fun before scaling to the full vision.
|
||||||
|
|
||||||
|
## Design decisions (locked)
|
||||||
|
|
||||||
|
- **Death penalty**: on death, coins drop into a **corpse** (faded player model) at the death spot; touch it to reclaim them. Dying again without reclaiming keeps only 50% (a new corpse appears, the old one vanishes). Butterfly jars are lost for good on death. Void deaths (falling out of the world) leave no corpse.
|
||||||
|
- **Skill upgrades**:
|
||||||
|
- **Vendor** (smith/trainer) gives direct linear power upgrades. Upgrades one selected spell; changing selection costs coins.
|
||||||
|
- **Gems / rings** give alternate behaviors / sidegrades.
|
||||||
|
- **Ranged identity**: keep the bolt, add upgrades (no charge-up / homing rework).
|
||||||
|
- **Bosses**: after the player first enters a boss's detection range (Light form), it tracks them permanently — ignoring range and Shade. The flying boss (**Sky Terror**, `boss_02`) casts a limited number of skills per slam-cycle: normal 1 (2 at ≤33% HP), Hard 2 (all 3 at ≤20% HP). Bosses drop a per-boss token that feeds the Boss Diary.
|
||||||
|
- **Fairy (in slice)**: guide + ambient light source (bonus flow regen near player). Scout mode, teleport, fairy holes deferred to regions 3+.
|
||||||
|
- **Ascended armor**: cut for now. Awakened is good enough at the start; less balancing needed.
|
||||||
|
|
||||||
|
## Milestones
|
||||||
|
|
||||||
|
### M0 — Foundation (the game remembers)
|
||||||
|
| Item | Effort | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| ~~Save/persistence system~~ | L | **DONE (2026-09-28)**: JSON save to `saves/`, save via pause menu. Stores player state, room, coins, equipment, inventory, quests, tokens, boss diary, defeated bosses, broken doors. |
|
||||||
|
| Charge -> Flow rename | S | Code + UI + configs. |
|
||||||
|
| ~~Main menu~~ | M | **DONE (2026-09-28)**: Select Game (greyed with no saves), New Game (name entry), Settings (rebinding), Quit. Wipe-all-saves button (bottom right) with confirmation dialog. |
|
||||||
|
| ~~Lantern save points~~ | M | **DONE (2026-09-29)**: Lanterns are explicit save points — walk up and press F to save; you respawn at your last lantern. Visible radius removed. |
|
||||||
|
|
||||||
|
### M1 — Region 1 complete loop
|
||||||
|
| Item | Effort | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| ~~Death penalty (drop coins, reclaim at death spot; fairy marks it; lose on 2nd death)~~ | M | **DONE (2026-09-29)**: corpse at death spot holds 100% of coins; a repeat death before reclaiming keeps only 50% and the old corpse vanishes. Butterfly jars are lost for good on death. |
|
||||||
|
| ~~Fairy companion (guide + ambient light source -> bonus flow regen)~~ | M | **DONE (2026-09-29)**: fairy follows behind the player's head; flips with facing. |
|
||||||
|
| ~~Flying boss + boss tokens~~ | M | **DONE (2026-10-05)**: **Sky Terror** (`boss_02`) in `room_08` — 51 HP, poison-free slam, skill-cycle phases (2 at ≤33%). Drops a per-boss token feeding the Boss Diary; Hard refight (`room_boss_fly_refight`) starts at 2 skills/cycle and hits all 3 at ≤20% HP. |
|
||||||
|
| More quests (repeatable + one-time; system exists) | S | Just content. |
|
||||||
|
| Lore dialogue for fairy / NPCs | S | Needs written copy. |
|
||||||
|
|
||||||
|
### M2 — Skill upgrades
|
||||||
|
| Item | Effort | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| Vendor (smith/trainer) NPC | M | Reuses NPC + coin systems. |
|
||||||
|
| Vendor upgrades (linear): Dash = lower cooldown, Ranged = more damage, Tether = longer bind/fear | S | Data + UI. |
|
||||||
|
| Ring slot + gems (sidegrades): Dash = speed-stacks / refund-on-kill / afterimage taunt; Ranged = pierce (light) / aoe (shade) / kill-stacks; Tether = boss effects / higher threshold | L | New slot, new item type, build UI. |
|
||||||
|
|
||||||
|
### M3 — Region 2: shade matters
|
||||||
|
| Item | Effort | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| Shade-gated interactions (doors, an NPC, an area) | S-M | Room JSON + existing toggle. |
|
||||||
|
| New enemy behaviors (patrol, dodge-and-leap, burrow-shooter) | M | Enemy system supports it. |
|
||||||
|
| Enemy line-of-sight detection (radius -> raycast) | S-M | Replace/augment the euclidean aggro in `Enemy.update` with a `Rect.clipline` raycast against solid platforms so walls block vision. Per-type `"detection": radius/los` config in `enemy_types.json` + editor toggle. Edge cases: skip the enemy's own support platform, sample player center+feet for tolerance, apply LOS to boss slam `trigger_close/far`. |
|
||||||
|
| ~~Quick recharge pickup~~ | S | **DONE (2026-09-29)**: butterfly jars — collect up to 3, press G to instantly refill Charge. Lost on death; respawn at their points after saving at a lantern in a different room or reloading. |
|
||||||
|
| Ability tweaks: ranged upgrades, ground-slam knockback/iframe, light-step buffs | M | Picks up remaining notes ideas. |
|
||||||
|
| Region-2 boss + ability pacing | M | Re-align pacing (Ranged already exists). |
|
||||||
|
|
||||||
|
### Stretch / core (post-slice, in order)
|
||||||
|
- Map system (current-room minimap -> world graph -> lantern fast travel) — see below
|
||||||
|
- Fast travel (rune stones)
|
||||||
|
- Fairy scout + bond teleport + fairy holes
|
||||||
|
- Regions 3-5 per pacing notes
|
||||||
|
- World-change weapon (stretch-end, decide variant)
|
||||||
|
|
||||||
|
### Cut
|
||||||
|
- Ascended armor (removed).
|
||||||
|
|
||||||
|
## Map system (deferred — brainstorm, not started)
|
||||||
|
|
||||||
|
Feels huge; split into two independent features rather than one.
|
||||||
|
|
||||||
|
1. **Current-room minimap** — cheap and self-contained: scale `room_bounds` + platform rects + a player arrow into a corner/overlay panel. No new data, no persistence. Good first slice.
|
||||||
|
2. **World map / region graph** — nodes = rooms, edges = `exits[]` (derivable automatically from room JSON rather than hand-authored).
|
||||||
|
|
||||||
|
Design notes
|
||||||
|
- **Layout**: add `meta.map_x` / `meta.map_y` (+ optional `meta.region`) per room and place nodes in the editor; fall back to auto-layout from exit topology if absent.
|
||||||
|
- **Discovery**: persist `visited_rooms` and `discovered_links` alongside the existing lantern-only save data. Undiscovered = "?" / fog.
|
||||||
|
- **Theme hook**: map clear in Light, fogged/faded in Shade, or fog dispelled by lanterns — reinforces the light/shade identity (keep it cosmetic).
|
||||||
|
- **Fairy as cartographer**: she fills in rooms and comments on new ones; reuses her room-aware voice lines and mirrors the Boss Diary UI pattern.
|
||||||
|
- **Fast travel**: discovered lanterns become warp nodes; overlaps with the deferred "rune stones" / "fairy bond teleport" items.
|
||||||
|
- **Edge cases**: one-way exits, boss-refight rooms, the missing `room_town_gloomreach.json`, exits with empty `to` (ignore), multiple entry spawns = one node.
|
||||||
|
|
||||||
|
Phasing
|
||||||
|
1. Current-room minimap overlay.
|
||||||
|
2. `visited_rooms` + world map from auto-derived exit links (auto-positioned).
|
||||||
|
3. Manual `map_x/map_y` layout in the editor.
|
||||||
|
4. Lantern fast travel + fairy-bond teleport.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Save is the keystone: death penalty, main menu, and any progress feature hang off it.
|
||||||
|
- Fairy and Flow rename can run in parallel with M0.
|
||||||
@@ -22,7 +22,9 @@
|
|||||||
"miniboss": [170, 40, 210],
|
"miniboss": [170, 40, 210],
|
||||||
"miniboss_hit": [220, 140, 255],
|
"miniboss_hit": [220, 140, 255],
|
||||||
"boss": [240, 220, 80],
|
"boss": [240, 220, 80],
|
||||||
"boss_hit": [255, 245, 160]
|
"boss_hit": [255, 245, 160],
|
||||||
|
"boss_flyer": [150, 90, 220],
|
||||||
|
"boss_flyer_hit": [210, 170, 255]
|
||||||
},
|
},
|
||||||
|
|
||||||
"healing": {
|
"healing": {
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"talk_range": 80,
|
||||||
|
"bubble_duration": 3.5,
|
||||||
|
"idle_interval": 45.0,
|
||||||
|
"idle_lines": ["idle_1", "idle_2", "idle_3"],
|
||||||
|
"dust_lines": ["dust_1", "dust_2", "dust_3"],
|
||||||
|
"attack_lines": ["attack_1", "attack_2", "attack_3"],
|
||||||
|
"auto": {
|
||||||
|
"room_01.json": { "on_enter": "welcome" }
|
||||||
|
},
|
||||||
|
"lines": {
|
||||||
|
"welcome": {
|
||||||
|
"light": "Wake up, sleepyhead! We have a long way to go.",
|
||||||
|
"shade": "Ooh, you found your dark side already?"
|
||||||
|
},
|
||||||
|
"idle_1": {
|
||||||
|
"light": "The butterflies always know the way.",
|
||||||
|
"shade": "Even in the dark, I can still see you."
|
||||||
|
},
|
||||||
|
"idle_2": {
|
||||||
|
"light": "Rest at a lantern and it will remember this place.",
|
||||||
|
"shade": "Careful - the gloom hides sharp things."
|
||||||
|
},
|
||||||
|
"idle_3": {
|
||||||
|
"light": "I will stay close. I always do.",
|
||||||
|
"shade": "You are not alone down here. I am right here."
|
||||||
|
},
|
||||||
|
"spot_greeting": {
|
||||||
|
"light": "Isn't this place pretty?",
|
||||||
|
"shade": "I can barely make you out in here."
|
||||||
|
},
|
||||||
|
"dust_1": {
|
||||||
|
"light": "Fairy dust! I can feel its sparkle.",
|
||||||
|
"shade": "Ooh, shiny. Even the dark likes this."
|
||||||
|
},
|
||||||
|
"dust_2": {
|
||||||
|
"light": "Another pinch of dust - keep going!",
|
||||||
|
"shade": "The dark tastes sweeter with this."
|
||||||
|
},
|
||||||
|
"dust_3": {
|
||||||
|
"light": "This dust hums when I hold it.",
|
||||||
|
"shade": "Keep collecting; I want all of it."
|
||||||
|
},
|
||||||
|
"quest_intro": {
|
||||||
|
"light": "I scattered my fairy dust across these rooms. Bring me 5 and I will fight beside you!",
|
||||||
|
"shade": "Find my 5 fairy dust. I will lend you my sting."
|
||||||
|
},
|
||||||
|
"quest_reward": {
|
||||||
|
"light": "You found them all! Now I can fight - press the Fairy Mode key!",
|
||||||
|
"shade": "All 5! My sting is yours. Press the Fairy Mode key."
|
||||||
|
},
|
||||||
|
"quest_return": {
|
||||||
|
"light": "That's all 5! Return to me at the fairy spot - I have something to show you!",
|
||||||
|
"shade": "All 5 gathered. Come back to my spot - I am ready to change."
|
||||||
|
},
|
||||||
|
"quest_unlock": {
|
||||||
|
"light": "Watch this - hold still!",
|
||||||
|
"shade": "Observe. I am about to change."
|
||||||
|
},
|
||||||
|
"quest_done": {
|
||||||
|
"light": "I am ready whenever you are!",
|
||||||
|
"shade": "Say the word and I strike."
|
||||||
|
},
|
||||||
|
"combat_on": {
|
||||||
|
"light": "To battle! I will pick off the stragglers.",
|
||||||
|
"shade": "Time to hunt. I like this form of yours."
|
||||||
|
},
|
||||||
|
"combat_off": {
|
||||||
|
"light": "Resting my wings now.",
|
||||||
|
"shade": "Fine, back to lurking."
|
||||||
|
},
|
||||||
|
"combat_empty": {
|
||||||
|
"light": "I am out of charge - I need to rest!",
|
||||||
|
"shade": "Empty. Let me recharge."
|
||||||
|
},
|
||||||
|
"attack_1": {
|
||||||
|
"light": "Huah!",
|
||||||
|
"shade": "Huah!"
|
||||||
|
},
|
||||||
|
"attack_2": {
|
||||||
|
"light": "Take this!",
|
||||||
|
"shade": "Take this!"
|
||||||
|
},
|
||||||
|
"attack_3": {
|
||||||
|
"light": "Hyah!",
|
||||||
|
"shade": "Hyah!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
"fps": 60
|
"fps": 60
|
||||||
},
|
},
|
||||||
"colors": {
|
"colors": {
|
||||||
"bg": [30, 30, 30],
|
"bg": [58, 58, 64],
|
||||||
"player_light": [200, 200, 200],
|
"player_light": [200, 200, 200],
|
||||||
"player_dark": [60, 60, 60],
|
"player_dark": [60, 60, 60],
|
||||||
"platform": [80, 80, 80],
|
"platform": [80, 80, 80],
|
||||||
@@ -5,13 +5,16 @@
|
|||||||
"jump_light": -12.0,
|
"jump_light": -12.0,
|
||||||
"jump_shade": -9.0,
|
"jump_shade": -9.0,
|
||||||
"gravity_light": 0.5,
|
"gravity_light": 0.5,
|
||||||
"gravity_shade": 0.4
|
"gravity_shade": 0.4,
|
||||||
|
"jump_release_gravity_mult": 3.0,
|
||||||
|
"shade_door_grace": 0.6
|
||||||
},
|
},
|
||||||
|
|
||||||
"resources": {
|
"resources": {
|
||||||
"base_max_charge": 100.0,
|
"base_max_charge": 100.0,
|
||||||
"charge_drain_rate": 40.0,
|
"charge_drain_rate": 40.0,
|
||||||
"charge_refill_rate": 20.0,
|
"charge_refill_rate": 10.0,
|
||||||
|
"charge_empty_lock": 1.5,
|
||||||
"base_max_health": 10,
|
"base_max_health": 10,
|
||||||
"invincibility_duration": 1.0
|
"invincibility_duration": 1.0
|
||||||
},
|
},
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"charge_cost": 5.0,
|
||||||
|
"damage_mult": 0.5,
|
||||||
|
"cooldown": 0.63,
|
||||||
|
"projectile": {
|
||||||
|
"speed": 650.0,
|
||||||
|
"lifetime": 1.2,
|
||||||
|
"size": [14, 6]
|
||||||
|
},
|
||||||
|
"fairy": {
|
||||||
|
"charge_cost": 5.0,
|
||||||
|
"cooldown": 0.7,
|
||||||
|
"range": 560.0,
|
||||||
|
"voice_every": 3,
|
||||||
|
"damage_mult": 0.5,
|
||||||
|
"speed": 520.0,
|
||||||
|
"lifetime": 1.4,
|
||||||
|
"size": [16, 16],
|
||||||
|
"spread_deg": 6.0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"room_id": "room_05.json",
|
"room_id": "room_reward_01.json",
|
||||||
"chest_pos": [520, 330],
|
"chest_pos": [520, 330],
|
||||||
"ability_pos": [820, 210],
|
"ability_pos": [820, 210],
|
||||||
"chest_coins": [30, 30]
|
"chest_coins": [30, 30]
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
"group_spacing": 90
|
"group_spacing": 90
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"butterfly_jars": {
|
||||||
|
"icon_size": 16,
|
||||||
|
"icon_gap": 4
|
||||||
|
},
|
||||||
|
|
||||||
"inventory_ui": {
|
"inventory_ui": {
|
||||||
"panel": { "x": 20, "y": 20, "w": 560, "h": 545, "pad": 10 },
|
"panel": { "x": 20, "y": 20, "w": 560, "h": 545, "pad": 10 },
|
||||||
"list": { "w": 360, "line_h": 18, "header_h": 40, "pad_y": 6, "pad_right": 14 },
|
"list": { "w": 360, "line_h": 18, "header_h": 40, "pad_y": 6, "pad_right": 14 },
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
{
|
||||||
|
"enemy": {
|
||||||
|
"rect": [40, 60],
|
||||||
|
"health": 3,
|
||||||
|
"speed": 2.2,
|
||||||
|
"air_speed": 2.0,
|
||||||
|
"detection_range": 240,
|
||||||
|
"contact_damage": 1,
|
||||||
|
"drop_profile": "normal"
|
||||||
|
},
|
||||||
|
"miniboss": {
|
||||||
|
"rect": [70, 95],
|
||||||
|
"health": 18,
|
||||||
|
"speed": 1.8,
|
||||||
|
"air_speed": 1.6,
|
||||||
|
"detection_range": 360,
|
||||||
|
"contact_damage": 2,
|
||||||
|
"drop_profile": "miniboss"
|
||||||
|
},
|
||||||
|
|
||||||
|
"boss": {
|
||||||
|
"rect": [110, 120],
|
||||||
|
"health": 10,
|
||||||
|
"speed": 1.6,
|
||||||
|
"air_speed": 1.4,
|
||||||
|
"detection_range": 500,
|
||||||
|
"contact_damage": 3,
|
||||||
|
"drop_profile": "boss",
|
||||||
|
"behavior": "shockwave",
|
||||||
|
"charger": {
|
||||||
|
"retreat_dist": 150,
|
||||||
|
"retreat_jump_vel": -14.0,
|
||||||
|
"retreat_speed_mult": 1.2,
|
||||||
|
"charge_speed_mult": 4.0,
|
||||||
|
"charge_duration": 1.1,
|
||||||
|
"dash_min_dist": 160,
|
||||||
|
"dash_max_dist": 420,
|
||||||
|
"dash_speed_mult": 4.2,
|
||||||
|
"dash_duration": 0.7,
|
||||||
|
"attack_cooldown": 1.8,
|
||||||
|
"above_y": 40
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"boss_flyer": {
|
||||||
|
"rect": [120, 90],
|
||||||
|
"health": 51,
|
||||||
|
"speed": 3.0,
|
||||||
|
"air_speed": 3.0,
|
||||||
|
"detection_range": 620,
|
||||||
|
"contact_damage": 3,
|
||||||
|
"drop_profile": "boss",
|
||||||
|
"behavior": "flyer",
|
||||||
|
"flyer": {
|
||||||
|
"flight_height": 280,
|
||||||
|
"bob_amplitude": 20,
|
||||||
|
"bob_speed": 2.2,
|
||||||
|
"hover_speed": 2.6,
|
||||||
|
"startup_delay": 3.0,
|
||||||
|
"phase2_hp_pct": 0.33,
|
||||||
|
"hard_phase3_hp_pct": 0.20,
|
||||||
|
"slam_cd": 9.0,
|
||||||
|
"slam_dive_vel": 16.0,
|
||||||
|
"ground_time": 2.0,
|
||||||
|
"summon_cd": 8.0,
|
||||||
|
"summon_max": 3,
|
||||||
|
"summon_type": "boss_minion",
|
||||||
|
"summon_life": 6.0,
|
||||||
|
"summon_heal": 4,
|
||||||
|
"summon_damage": 3,
|
||||||
|
"aoe_cd": 9.0,
|
||||||
|
"aoe_radius": 300,
|
||||||
|
"aoe_damage": 1,
|
||||||
|
"aoe_duration": 0.9,
|
||||||
|
"shot_cd": 5.0,
|
||||||
|
"shot_damage": 5,
|
||||||
|
"shot_speed": 300,
|
||||||
|
"shot_lifetime": 2.2,
|
||||||
|
"shot_homing": 1.8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"boss_minion": {
|
||||||
|
"rect": [34, 50],
|
||||||
|
"health": 4,
|
||||||
|
"speed": 2.4,
|
||||||
|
"air_speed": 2.2,
|
||||||
|
"detection_range": 320,
|
||||||
|
"contact_damage": 1,
|
||||||
|
"drop_profile": "normal"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"objects": {
|
||||||
|
"flow_butterfly": {
|
||||||
|
"type": "light_source",
|
||||||
|
"charge_regen_range": 180
|
||||||
|
},
|
||||||
|
"lamp": {
|
||||||
|
"type": "save_point",
|
||||||
|
"charge_regen_range": 90
|
||||||
|
},
|
||||||
|
"flow_butterfly_jar": {
|
||||||
|
"type": "butterfly_jar"
|
||||||
|
},
|
||||||
|
"house": {
|
||||||
|
"type": "house"
|
||||||
|
},
|
||||||
|
"diary": {
|
||||||
|
"type": "diary"
|
||||||
|
},
|
||||||
|
"player": {
|
||||||
|
"type": "player"
|
||||||
|
},
|
||||||
|
"quest_point": {
|
||||||
|
"type": "quest_giver"
|
||||||
|
},
|
||||||
|
"fairy_spot": {
|
||||||
|
"type": "fairy_spot"
|
||||||
|
},
|
||||||
|
"fairy_dust": {
|
||||||
|
"type": "fairy_dust"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 173 B |
|
Before Width: | Height: | Size: 327 B After Width: | Height: | Size: 327 B |
|
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 445 B |
|
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 443 B After Width: | Height: | Size: 443 B |
|
After Width: | Height: | Size: 362 B |
|
After Width: | Height: | Size: 175 B |
|
After Width: | Height: | Size: 320 B |
|
After Width: | Height: | Size: 399 B |
|
After Width: | Height: | Size: 437 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
|
After Width: | Height: | Size: 212 B |
|
After Width: | Height: | Size: 395 B |
|
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 392 B |
|
Before Width: | Height: | Size: 614 B After Width: | Height: | Size: 614 B |
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 306 B |
|
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
|
Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 250 B |
|
Before Width: | Height: | Size: 150 B After Width: | Height: | Size: 150 B |
|
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 135 B |
|
Before Width: | Height: | Size: 136 B After Width: | Height: | Size: 136 B |
@@ -0,0 +1,228 @@
|
|||||||
|
{
|
||||||
|
"name": "room_01",
|
||||||
|
"display_name": "room_01",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_01",
|
||||||
|
"name": "room_01"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
100,
|
||||||
|
180
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room1_right": [
|
||||||
|
1040,
|
||||||
|
680
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 260,
|
||||||
|
"w": 1000,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 20,
|
||||||
|
"h": 780,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 540,
|
||||||
|
"y": 140,
|
||||||
|
"w": 160,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 900,
|
||||||
|
"y": 400,
|
||||||
|
"w": 700,
|
||||||
|
"h": 100,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1580,
|
||||||
|
"y": 20,
|
||||||
|
"w": 20,
|
||||||
|
"h": 380,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1120,
|
||||||
|
"y": 280,
|
||||||
|
"w": 40,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 840,
|
||||||
|
"y": 460,
|
||||||
|
"w": 60,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 600,
|
||||||
|
"y": 400,
|
||||||
|
"w": 140,
|
||||||
|
"h": 100,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 380,
|
||||||
|
"y": 400,
|
||||||
|
"w": 140,
|
||||||
|
"h": 100,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 400,
|
||||||
|
"w": 140,
|
||||||
|
"h": 100,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 620,
|
||||||
|
"w": 760,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 500,
|
||||||
|
"w": 20,
|
||||||
|
"h": 120,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 900,
|
||||||
|
"y": 500,
|
||||||
|
"w": 20,
|
||||||
|
"h": 120,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 800,
|
||||||
|
"y": 520,
|
||||||
|
"w": 60,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 760,
|
||||||
|
"w": 1140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1140,
|
||||||
|
"y": 500,
|
||||||
|
"w": 20,
|
||||||
|
"h": 260,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 760,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
20,
|
||||||
|
760
|
||||||
|
],
|
||||||
|
[
|
||||||
|
20,
|
||||||
|
400
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 1480,
|
||||||
|
"y": 360,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 340,
|
||||||
|
"y": 580,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 700,
|
||||||
|
"y": 760,
|
||||||
|
"type": "butterfly_jar",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "flow_butterfly_jar",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "",
|
||||||
|
"dialogue_id": "",
|
||||||
|
"auto": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 600,
|
||||||
|
"y": 140,
|
||||||
|
"type": "fairy_dust",
|
||||||
|
"radius": 40,
|
||||||
|
"object_id": "fairy_dust",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "",
|
||||||
|
"dialogue_id": "",
|
||||||
|
"auto": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 1060,
|
||||||
|
"y": 660,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_02",
|
||||||
|
"spawn_id": "room2_left",
|
||||||
|
"spawn": [
|
||||||
|
120,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
{
|
||||||
|
"name": "room_02",
|
||||||
|
"display_name": "room_02",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_02",
|
||||||
|
"name": "room_02"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
820,
|
||||||
|
440
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room2_bottom_left": [
|
||||||
|
120,
|
||||||
|
460
|
||||||
|
],
|
||||||
|
"room2_top_left": [
|
||||||
|
120,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"hazard_respawn_1": [
|
||||||
|
840,
|
||||||
|
440
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 320,
|
||||||
|
"w": 1040,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 120,
|
||||||
|
"w": 20,
|
||||||
|
"h": 200,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 420,
|
||||||
|
"y": 220,
|
||||||
|
"w": 220,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1060,
|
||||||
|
"y": 360,
|
||||||
|
"w": 180,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1260,
|
||||||
|
"y": 320,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1500,
|
||||||
|
"y": 100,
|
||||||
|
"w": 20,
|
||||||
|
"h": 540,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 860,
|
||||||
|
"y": 620,
|
||||||
|
"w": 640,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 800,
|
||||||
|
"y": 500,
|
||||||
|
"w": 60,
|
||||||
|
"h": 140,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1400,
|
||||||
|
"y": 500,
|
||||||
|
"w": 100,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1380,
|
||||||
|
"y": 380,
|
||||||
|
"w": 40,
|
||||||
|
"h": 40,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 380,
|
||||||
|
"y": 620,
|
||||||
|
"w": 420,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 260,
|
||||||
|
"y": 580,
|
||||||
|
"w": 120,
|
||||||
|
"h": 60,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 640,
|
||||||
|
"y": 500,
|
||||||
|
"w": 80,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 480,
|
||||||
|
"y": 500,
|
||||||
|
"w": 80,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 540,
|
||||||
|
"w": 220,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 340,
|
||||||
|
"w": 20,
|
||||||
|
"h": 220,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 240,
|
||||||
|
"y": 560,
|
||||||
|
"w": 20,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 380,
|
||||||
|
"y": 600,
|
||||||
|
"w": 420,
|
||||||
|
"h": 20,
|
||||||
|
"group": "hazard",
|
||||||
|
"layer": 0,
|
||||||
|
"respawn": [
|
||||||
|
840,
|
||||||
|
440
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 1160,
|
||||||
|
"y": 320,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1160,
|
||||||
|
"y": 580,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 720,
|
||||||
|
"y": 320,
|
||||||
|
"type": "save_point",
|
||||||
|
"radius": 90,
|
||||||
|
"object_id": "lamp",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 220,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_01",
|
||||||
|
"spawn_id": "room1_right",
|
||||||
|
"spawn": [
|
||||||
|
1040,
|
||||||
|
680
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 440,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_03",
|
||||||
|
"spawn_id": "room3_top_right",
|
||||||
|
"spawn": [
|
||||||
|
1480,
|
||||||
|
220
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,324 @@
|
|||||||
|
{
|
||||||
|
"name": "room_03",
|
||||||
|
"display_name": "room_03",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_03",
|
||||||
|
"name": "room_03"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
1460,
|
||||||
|
220
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room3_top_right": [
|
||||||
|
1480,
|
||||||
|
220
|
||||||
|
],
|
||||||
|
"room3_bottom_left": [
|
||||||
|
140,
|
||||||
|
800
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 1080,
|
||||||
|
"y": 300,
|
||||||
|
"w": 520,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1580,
|
||||||
|
"y": 60,
|
||||||
|
"w": 20,
|
||||||
|
"h": 240,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 40,
|
||||||
|
"w": 1580,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1080,
|
||||||
|
"y": 320,
|
||||||
|
"w": 20,
|
||||||
|
"h": 140,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 620,
|
||||||
|
"w": 1080,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 60,
|
||||||
|
"w": 20,
|
||||||
|
"h": 560,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 620,
|
||||||
|
"y": 520,
|
||||||
|
"w": 80,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
620,
|
||||||
|
520
|
||||||
|
],
|
||||||
|
[
|
||||||
|
620,
|
||||||
|
340
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1080,
|
||||||
|
"y": 460,
|
||||||
|
"w": 20,
|
||||||
|
"h": 160,
|
||||||
|
"group": "trigger",
|
||||||
|
"layer": 0,
|
||||||
|
"quest": "quest_first_kills"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1100,
|
||||||
|
"y": 620,
|
||||||
|
"w": 320,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 800,
|
||||||
|
"y": 320,
|
||||||
|
"w": 160,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1580,
|
||||||
|
"y": 320,
|
||||||
|
"w": 20,
|
||||||
|
"h": 580,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1220,
|
||||||
|
"y": 760,
|
||||||
|
"w": 360,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 880,
|
||||||
|
"w": 1560,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 640,
|
||||||
|
"w": 20,
|
||||||
|
"h": 240,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 640,
|
||||||
|
"w": 20,
|
||||||
|
"h": 240,
|
||||||
|
"group": "trigger",
|
||||||
|
"layer": 0,
|
||||||
|
"name": "first_quest_complete",
|
||||||
|
"quest_turned_in": "quest_first_kills"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 580,
|
||||||
|
"y": 640,
|
||||||
|
"w": 20,
|
||||||
|
"h": 120,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 480,
|
||||||
|
"y": 740,
|
||||||
|
"w": 100,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": 400,
|
||||||
|
"w": 100,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 220,
|
||||||
|
"y": 400,
|
||||||
|
"w": 80,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
220,
|
||||||
|
400
|
||||||
|
],
|
||||||
|
[
|
||||||
|
220,
|
||||||
|
260
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 40,
|
||||||
|
"y": 220,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1520,
|
||||||
|
"y": 640,
|
||||||
|
"w": 60,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 600,
|
||||||
|
"y": 840,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 960,
|
||||||
|
"y": 840,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 200,
|
||||||
|
"y": 580,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 520,
|
||||||
|
"y": 700,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1520,
|
||||||
|
"y": 840,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 960,
|
||||||
|
"y": 580,
|
||||||
|
"type": "quest_giver",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "quest_point",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "quest_first_kills"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 90,
|
||||||
|
"y": 194,
|
||||||
|
"type": "reward_chest",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": null,
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "",
|
||||||
|
"coins": [
|
||||||
|
10,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 880,
|
||||||
|
"y": 320,
|
||||||
|
"type": "light_source",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "flow_butterfly",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 440,
|
||||||
|
"y": 400,
|
||||||
|
"type": "fairy_dust",
|
||||||
|
"radius": 40,
|
||||||
|
"object_id": "fairy_dust",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 1500,
|
||||||
|
"y": 200,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_02",
|
||||||
|
"spawn_id": "room2_bottom_left",
|
||||||
|
"spawn": [
|
||||||
|
120,
|
||||||
|
460
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 40,
|
||||||
|
"y": 780,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_04",
|
||||||
|
"spawn_id": "room4_top_right",
|
||||||
|
"spawn": [
|
||||||
|
1480,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900
|
||||||
|
}
|
||||||
@@ -0,0 +1,353 @@
|
|||||||
|
{
|
||||||
|
"name": "room_04",
|
||||||
|
"display_name": "room_04",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_04",
|
||||||
|
"name": "room_04"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
1440,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room4_top_right": [
|
||||||
|
1480,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"hazard_respawn": [
|
||||||
|
1080,
|
||||||
|
180
|
||||||
|
],
|
||||||
|
"room4_bottom_left": [
|
||||||
|
120,
|
||||||
|
620
|
||||||
|
],
|
||||||
|
"room4_bottom_right": [
|
||||||
|
1480,
|
||||||
|
640
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 1340,
|
||||||
|
"y": 160,
|
||||||
|
"w": 260,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 0,
|
||||||
|
"w": 1440,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1580,
|
||||||
|
"y": 20,
|
||||||
|
"w": 20,
|
||||||
|
"h": 140,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1340,
|
||||||
|
"y": 180,
|
||||||
|
"w": 20,
|
||||||
|
"h": 60,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1020,
|
||||||
|
"y": 240,
|
||||||
|
"w": 340,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 920,
|
||||||
|
"y": 240,
|
||||||
|
"w": 100,
|
||||||
|
"h": 20,
|
||||||
|
"group": "hazard",
|
||||||
|
"layer": 0,
|
||||||
|
"respawn": [
|
||||||
|
1080,
|
||||||
|
180
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 460,
|
||||||
|
"y": 240,
|
||||||
|
"w": 460,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 900,
|
||||||
|
"y": 260,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 20,
|
||||||
|
"w": 20,
|
||||||
|
"h": 520,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 700,
|
||||||
|
"w": 1580,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 520,
|
||||||
|
"w": 160,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 540,
|
||||||
|
"w": 20,
|
||||||
|
"h": 180,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 240,
|
||||||
|
"y": 280,
|
||||||
|
"w": 160,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
240,
|
||||||
|
280
|
||||||
|
],
|
||||||
|
[
|
||||||
|
240,
|
||||||
|
640
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 460,
|
||||||
|
"y": 260,
|
||||||
|
"w": 20,
|
||||||
|
"h": 280,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 480,
|
||||||
|
"y": 300,
|
||||||
|
"w": 880,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1340,
|
||||||
|
"y": 320,
|
||||||
|
"w": 20,
|
||||||
|
"h": 220,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 460,
|
||||||
|
"y": 540,
|
||||||
|
"w": 20,
|
||||||
|
"h": 160,
|
||||||
|
"group": "trigger",
|
||||||
|
"layer": 0,
|
||||||
|
"name": "close_when_pass",
|
||||||
|
"lock_when_pass": true,
|
||||||
|
"open_on_miniboss_dead": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1340,
|
||||||
|
"y": 540,
|
||||||
|
"w": 20,
|
||||||
|
"h": 160,
|
||||||
|
"group": "trigger",
|
||||||
|
"layer": 0,
|
||||||
|
"name": "open_miniboss_dead",
|
||||||
|
"open_on_miniboss_dead": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1360,
|
||||||
|
"y": 520,
|
||||||
|
"w": 240,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1580,
|
||||||
|
"y": 540,
|
||||||
|
"w": 20,
|
||||||
|
"h": 160,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 720,
|
||||||
|
"y": 620,
|
||||||
|
"w": 60,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
720,
|
||||||
|
620
|
||||||
|
],
|
||||||
|
[
|
||||||
|
720,
|
||||||
|
540
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 820,
|
||||||
|
"y": 540,
|
||||||
|
"w": 60,
|
||||||
|
"h": 20,
|
||||||
|
"group": "dissolve",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
820,
|
||||||
|
540
|
||||||
|
],
|
||||||
|
[
|
||||||
|
820,
|
||||||
|
600
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"stand_time": 2,
|
||||||
|
"dissolve_time": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1040,
|
||||||
|
"y": 580,
|
||||||
|
"w": 100,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
1040,
|
||||||
|
580
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1040,
|
||||||
|
480
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 760,
|
||||||
|
"y": 200,
|
||||||
|
"type": "enemy",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 880,
|
||||||
|
"y": 640,
|
||||||
|
"type": "miniboss",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 560,
|
||||||
|
"y": 240,
|
||||||
|
"type": "save_point",
|
||||||
|
"radius": 90,
|
||||||
|
"object_id": "lamp",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 1500,
|
||||||
|
"y": 60,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_03",
|
||||||
|
"spawn_id": "room3_bottom_left",
|
||||||
|
"spawn": [
|
||||||
|
140,
|
||||||
|
800
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 600,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_06",
|
||||||
|
"spawn_id": "room6_top_right",
|
||||||
|
"spawn": [
|
||||||
|
520,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1500,
|
||||||
|
"y": 600,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_05",
|
||||||
|
"spawn_id": "room5_top_left",
|
||||||
|
"spawn": [
|
||||||
|
120,
|
||||||
|
120
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [
|
||||||
|
{
|
||||||
|
"x": 160,
|
||||||
|
"y": 540,
|
||||||
|
"w": 20,
|
||||||
|
"h": 160,
|
||||||
|
"layer": 0,
|
||||||
|
"kind": "shade"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
{
|
||||||
|
"name": "room_05",
|
||||||
|
"display_name": "room_05",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_05",
|
||||||
|
"name": "room_05"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
140,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room5_top_left": [
|
||||||
|
120,
|
||||||
|
120
|
||||||
|
],
|
||||||
|
"room5_bottom_right": [
|
||||||
|
1420,
|
||||||
|
780
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 180,
|
||||||
|
"w": 220,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 20,
|
||||||
|
"h": 840,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 340,
|
||||||
|
"y": 180,
|
||||||
|
"w": 240,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 700,
|
||||||
|
"y": 180,
|
||||||
|
"w": 200,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 840,
|
||||||
|
"w": 1520,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1520,
|
||||||
|
"y": 680,
|
||||||
|
"w": 20,
|
||||||
|
"h": 180,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1380,
|
||||||
|
"y": 700,
|
||||||
|
"w": 20,
|
||||||
|
"h": 140,
|
||||||
|
"group": "trigger",
|
||||||
|
"layer": 0,
|
||||||
|
"name": "open_when_boss_slain",
|
||||||
|
"open_on_boss_dead": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1380,
|
||||||
|
"y": 680,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "trigger",
|
||||||
|
"layer": 0,
|
||||||
|
"name": "open_when_boss_slain",
|
||||||
|
"open_on_boss_dead": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1380,
|
||||||
|
"y": 0,
|
||||||
|
"w": 20,
|
||||||
|
"h": 680,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1040,
|
||||||
|
"y": 740,
|
||||||
|
"w": 160,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
1040,
|
||||||
|
740
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1040,
|
||||||
|
200
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"open_on_boss_dead": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 620,
|
||||||
|
"y": 720,
|
||||||
|
"type": "boss",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": "shockwave"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 860,
|
||||||
|
"y": 180,
|
||||||
|
"type": "save_point",
|
||||||
|
"radius": 90,
|
||||||
|
"object_id": "lamp",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 740,
|
||||||
|
"y": 180,
|
||||||
|
"type": "fairy_dust",
|
||||||
|
"radius": 40,
|
||||||
|
"object_id": "fairy_dust",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 80,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_04",
|
||||||
|
"spawn_id": "room4_bottom_right",
|
||||||
|
"spawn": [
|
||||||
|
1480,
|
||||||
|
640
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1440,
|
||||||
|
"y": 740,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_07",
|
||||||
|
"spawn_id": "room7_top_left",
|
||||||
|
"spawn": [
|
||||||
|
180,
|
||||||
|
460
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
{
|
||||||
|
"name": "room_06",
|
||||||
|
"display_name": "room_06",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_06",
|
||||||
|
"name": "room_06"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
480,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room6_top_right": [
|
||||||
|
520,
|
||||||
|
240
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 300,
|
||||||
|
"w": 660,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 420,
|
||||||
|
"y": 180,
|
||||||
|
"w": 240,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 640,
|
||||||
|
"y": 200,
|
||||||
|
"w": 20,
|
||||||
|
"h": 100,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 420,
|
||||||
|
"y": 0,
|
||||||
|
"w": 20,
|
||||||
|
"h": 180,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 420,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 20,
|
||||||
|
"w": 20,
|
||||||
|
"h": 280,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 140,
|
||||||
|
"y": 260,
|
||||||
|
"type": "quest_giver",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "quest_point",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "first_kills_shade"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 560,
|
||||||
|
"y": 200,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_04",
|
||||||
|
"spawn_id": "room4_bottom_left",
|
||||||
|
"spawn": [
|
||||||
|
120,
|
||||||
|
620
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
{
|
||||||
|
"name": "room_07",
|
||||||
|
"display_name": "room_07",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_07",
|
||||||
|
"name": "room_07"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
220,
|
||||||
|
440
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room7_top_left": [
|
||||||
|
180,
|
||||||
|
460
|
||||||
|
],
|
||||||
|
"room7_bottom_right": [
|
||||||
|
1040,
|
||||||
|
460
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 60,
|
||||||
|
"y": 200,
|
||||||
|
"w": 20,
|
||||||
|
"h": 340,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 80,
|
||||||
|
"y": 520,
|
||||||
|
"w": 1080,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1160,
|
||||||
|
"y": 320,
|
||||||
|
"w": 20,
|
||||||
|
"h": 220,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 440,
|
||||||
|
"y": 494,
|
||||||
|
"type": "reward_chest",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": null,
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "",
|
||||||
|
"coins": [
|
||||||
|
30,
|
||||||
|
10
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 820,
|
||||||
|
"y": 500,
|
||||||
|
"type": "ability_pickup",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": null,
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 640,
|
||||||
|
"y": 520,
|
||||||
|
"type": "save_point",
|
||||||
|
"radius": 90,
|
||||||
|
"object_id": "lamp",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1100,
|
||||||
|
"y": 520,
|
||||||
|
"type": "fairy_dust",
|
||||||
|
"radius": 40,
|
||||||
|
"object_id": "fairy_dust",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 80,
|
||||||
|
"y": 420,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_05",
|
||||||
|
"spawn_id": "room5_bottom_right",
|
||||||
|
"spawn": [
|
||||||
|
1420,
|
||||||
|
780
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1080,
|
||||||
|
"y": 420,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_08",
|
||||||
|
"spawn_id": "room8_bottom_left",
|
||||||
|
"spawn": [
|
||||||
|
300,
|
||||||
|
400
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
{
|
||||||
|
"name": "room_08",
|
||||||
|
"display_name": "room_08",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_08",
|
||||||
|
"name": "room_08"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
340,
|
||||||
|
300
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room8_bottom_left": [
|
||||||
|
300,
|
||||||
|
400
|
||||||
|
],
|
||||||
|
"room8_bottom_right": [
|
||||||
|
1400,
|
||||||
|
400
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 200,
|
||||||
|
"y": 460,
|
||||||
|
"w": 1340,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 180,
|
||||||
|
"y": 120,
|
||||||
|
"w": 20,
|
||||||
|
"h": 360,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1520,
|
||||||
|
"y": 100,
|
||||||
|
"w": 20,
|
||||||
|
"h": 360,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 820,
|
||||||
|
"y": 220,
|
||||||
|
"type": "boss_flyer",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": "flyer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 200,
|
||||||
|
"y": 360,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_07",
|
||||||
|
"spawn_id": "room7_bottom_right",
|
||||||
|
"spawn": [
|
||||||
|
1040,
|
||||||
|
460
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1440,
|
||||||
|
"y": 360,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_09",
|
||||||
|
"spawn_id": "room9_top_left",
|
||||||
|
"spawn": [
|
||||||
|
220,
|
||||||
|
300
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
{
|
||||||
|
"name": "room_09",
|
||||||
|
"display_name": "room_09",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_09",
|
||||||
|
"name": "room_09"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
220,
|
||||||
|
260
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room9_top_left": [
|
||||||
|
220,
|
||||||
|
300
|
||||||
|
],
|
||||||
|
"room9_top_right": [
|
||||||
|
2660,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"room9_bottom_right": [
|
||||||
|
2660,
|
||||||
|
600
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 100,
|
||||||
|
"y": 360,
|
||||||
|
"w": 300,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 80,
|
||||||
|
"y": 220,
|
||||||
|
"w": 20,
|
||||||
|
"h": 440,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 460,
|
||||||
|
"y": 440,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 620,
|
||||||
|
"y": 500,
|
||||||
|
"w": 120,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 800,
|
||||||
|
"y": 560,
|
||||||
|
"w": 80,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 80,
|
||||||
|
"y": 660,
|
||||||
|
"w": 2699,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1580,
|
||||||
|
"y": 540,
|
||||||
|
"w": 240,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1980,
|
||||||
|
"y": 540,
|
||||||
|
"w": 100,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2260,
|
||||||
|
"y": 660,
|
||||||
|
"w": 140,
|
||||||
|
"h": 20,
|
||||||
|
"group": "moving",
|
||||||
|
"layer": 0,
|
||||||
|
"path": [
|
||||||
|
[
|
||||||
|
2260,
|
||||||
|
660
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2260,
|
||||||
|
340
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2460,
|
||||||
|
"y": 300,
|
||||||
|
"w": 320,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2780,
|
||||||
|
"y": 120,
|
||||||
|
"w": 20,
|
||||||
|
"h": 200,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2780,
|
||||||
|
"y": 480,
|
||||||
|
"w": 20,
|
||||||
|
"h": 200,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [],
|
||||||
|
"npcs": [
|
||||||
|
{
|
||||||
|
"x": 1296,
|
||||||
|
"y": 606,
|
||||||
|
"type": "necklace_vendor",
|
||||||
|
"layer": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2012,
|
||||||
|
"y": 486,
|
||||||
|
"type": "combat_master",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 1240,
|
||||||
|
"y": 660,
|
||||||
|
"type": "house",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "house",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "",
|
||||||
|
"dialogue_id": "",
|
||||||
|
"auto": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1660,
|
||||||
|
"y": 540,
|
||||||
|
"type": "house",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "house",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": "",
|
||||||
|
"dialogue_id": "",
|
||||||
|
"auto": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1754,
|
||||||
|
"y": 490,
|
||||||
|
"type": "diary",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "diary",
|
||||||
|
"layer": 1,
|
||||||
|
"quest_id": "",
|
||||||
|
"dialogue_id": "",
|
||||||
|
"auto": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1460,
|
||||||
|
"y": 660,
|
||||||
|
"type": "save_point",
|
||||||
|
"radius": 90,
|
||||||
|
"object_id": "lamp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 840,
|
||||||
|
"y": 560,
|
||||||
|
"type": "fairy_dust",
|
||||||
|
"radius": 40,
|
||||||
|
"object_id": "fairy_dust",
|
||||||
|
"layer": 0,
|
||||||
|
"quest_id": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 100,
|
||||||
|
"y": 260,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_08",
|
||||||
|
"spawn_id": "room8_bottom_right",
|
||||||
|
"spawn": [
|
||||||
|
1400,
|
||||||
|
400
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2700,
|
||||||
|
"y": 560,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "",
|
||||||
|
"spawn_id": "",
|
||||||
|
"spawn": [
|
||||||
|
2700,
|
||||||
|
560
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 2700,
|
||||||
|
"y": 200,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_10",
|
||||||
|
"spawn_id": "room10_top_left",
|
||||||
|
"spawn": [
|
||||||
|
140,
|
||||||
|
280
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
"name": "room_10",
|
||||||
|
"display_name": "room_10",
|
||||||
|
"meta": {
|
||||||
|
"id": "room_10",
|
||||||
|
"name": "room_10"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
160,
|
||||||
|
260
|
||||||
|
],
|
||||||
|
"entry_spawns": {
|
||||||
|
"room10_top_left": [
|
||||||
|
140,
|
||||||
|
280
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 340,
|
||||||
|
"w": 440,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 120,
|
||||||
|
"w": 20,
|
||||||
|
"h": 220,
|
||||||
|
"group": "ground",
|
||||||
|
"layer": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"x": 340,
|
||||||
|
"y": 300,
|
||||||
|
"type": "fairy_spot",
|
||||||
|
"radius": 180,
|
||||||
|
"object_id": "fairy_spot",
|
||||||
|
"dialogue_id": "spot_greeting",
|
||||||
|
"quest_id": "quest_fairy_dust"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 40,
|
||||||
|
"y": 240,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_09",
|
||||||
|
"spawn_id": "room9_top_right",
|
||||||
|
"spawn": [
|
||||||
|
2660,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"hint": "",
|
||||||
|
"layer": 0,
|
||||||
|
"requires_boss_dead": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"name": "boss_fly_refight",
|
||||||
|
"display_name": "boss_fly_refight",
|
||||||
|
"meta": {
|
||||||
|
"id": "boss_fly_refight",
|
||||||
|
"name": "boss_fly_refight"
|
||||||
|
},
|
||||||
|
"bounds": {},
|
||||||
|
"player_spawn": [
|
||||||
|
280,
|
||||||
|
400
|
||||||
|
],
|
||||||
|
"entry_spawns": {},
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"x": 200,
|
||||||
|
"y": 460,
|
||||||
|
"w": 1340,
|
||||||
|
"h": 20,
|
||||||
|
"group": "ground"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 180,
|
||||||
|
"y": 120,
|
||||||
|
"w": 20,
|
||||||
|
"h": 360,
|
||||||
|
"group": "ground"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1540,
|
||||||
|
"y": 120,
|
||||||
|
"w": 20,
|
||||||
|
"h": 360,
|
||||||
|
"group": "ground"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"enemies": [
|
||||||
|
{
|
||||||
|
"x": 820,
|
||||||
|
"y": 220,
|
||||||
|
"type": "boss_flyer",
|
||||||
|
"layer": 0,
|
||||||
|
"behavior": "flyer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"npcs": [],
|
||||||
|
"props": [],
|
||||||
|
"exits": [
|
||||||
|
{
|
||||||
|
"x": 1460,
|
||||||
|
"y": 360,
|
||||||
|
"w": 80,
|
||||||
|
"h": 100,
|
||||||
|
"to": "room_09.json",
|
||||||
|
"spawn_id": "",
|
||||||
|
"spawn": [
|
||||||
|
1754,
|
||||||
|
540
|
||||||
|
],
|
||||||
|
"requires_boss_dead": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ability_doors": [],
|
||||||
|
"room_w": 1600,
|
||||||
|
"room_h": 900,
|
||||||
|
"mist": false
|
||||||
|
}
|
||||||
@@ -4,13 +4,13 @@
|
|||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>e4b51f4c-e0be-4f9e-8a8e-d814a78b30c5</ProjectGuid>
|
<ProjectGuid>e4b51f4c-e0be-4f9e-8a8e-d814a78b30c5</ProjectGuid>
|
||||||
<ProjectHome>.</ProjectHome>
|
<ProjectHome>.</ProjectHome>
|
||||||
<StartupFile>pygame_test.py</StartupFile>
|
<StartupFile>main.py</StartupFile>
|
||||||
<SearchPath>
|
<SearchPath>
|
||||||
</SearchPath>
|
</SearchPath>
|
||||||
<WorkingDirectory>.</WorkingDirectory>
|
<WorkingDirectory>.</WorkingDirectory>
|
||||||
<OutputPath>.</OutputPath>
|
<OutputPath>.</OutputPath>
|
||||||
<Name>pygame test</Name>
|
<Name>light_and_dark</Name>
|
||||||
<RootNamespace>pygame test</RootNamespace>
|
<RootNamespace>light_and_dark</RootNamespace>
|
||||||
<TestFramework>unittest</TestFramework>
|
<TestFramework>unittest</TestFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="pygame_test.py" />
|
<Compile Include="main.py" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" />
|
||||||
<!-- Uncomment the CoreCompile target to enable the Build command in
|
<!-- Uncomment the CoreCompile target to enable the Build command in
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
New skills
|
||||||
|
Tether
|
||||||
|
- hit an enemy, inflict a visual bind for a few seconds, end effect depends on which form the player is in when it ends
|
||||||
|
- light form: blind enemy (make them walk the other direction)
|
||||||
|
- shade form: instakill after a certain enemy HP threshold, slow otherwise
|
||||||
|
|
||||||
|
Reality Break
|
||||||
|
- light form: make all enemies double their drop rates
|
||||||
|
- shade form: instantly kill all enemies, halves drop rates
|
||||||
|
|
||||||
|
Shatterstep
|
||||||
|
- light form: for X seconds, create a platform below your feet when jumping, allowing for multiple jumps in the air
|
||||||
|
- shade form: when jumping, create aoe below you upon landing
|
||||||
|
|
||||||
|
|
||||||
|
Skill upgrades
|
||||||
|
Dash
|
||||||
|
- Refund cost upon successful stun/kill
|
||||||
|
- lower cooldown
|
||||||
|
- more range
|
||||||
|
- build up movement speed stacks with every dash, lose stacks upon getting hit
|
||||||
|
- more damage against targets that are stunned (inflict mark?)
|
||||||
|
- leave behind afterimage (enemy taunt)
|
||||||
|
|
||||||
|
Ranged Attack
|
||||||
|
- hold to charge, release for stronger attack (more damage and stun)
|
||||||
|
- faster speed, higher charge cost
|
||||||
|
- slower speed but more damage
|
||||||
|
- upgrade light form: pierce and slow
|
||||||
|
- upgrade shade form: aoe
|
||||||
|
- for every enemy kill collect stacks that increase damage, lose stacks upon not finishing enemies
|
||||||
|
|
||||||
|
Tether
|
||||||
|
- light form: higher hp threshold for kill; if used against boss: slower attacks
|
||||||
|
- shade form: longer fear; if used against boss: slower movement speed
|
||||||
|
|
||||||
|
|
||||||
|
How to obtain skill upgrades
|
||||||
|
- vendor (smith? trainer?) that can upgrade one spell (selection can be changed but requires paying for it every time)
|
||||||
|
- item (gem?) that can be slotted into armor to unlock a skill upgrade
|
||||||
|
- ring to go with necklaces (no synergy to not force those even more like armor already does)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Ascended armor
|
||||||
|
- select one awakened armor piece as the main piece and one as the sacrifice
|
||||||
|
- select X number of traits from the sacrifice to merge onto the main piece
|
||||||
|
- sacrifice gets destroyed in the process, creating an Ascended armor piece
|
||||||
|
- cost: many coins/rare resource?
|
||||||
|
|
||||||
|
|
||||||
|
Further ideas
|
||||||
|
|
||||||
|
Quests:
|
||||||
|
Repeatable
|
||||||
|
- usually has a loot pool of items but the player also gains resources to buy stuff from this loot pool (as some sort of pity system)
|
||||||
|
One-time
|
||||||
|
- fixed reward
|
||||||
|
- essential or useful for progression
|
||||||
|
|
||||||
|
Boss Tokens
|
||||||
|
- bosses drop an item (unique per boss) that can be "collected" (diary) to fight them again
|
||||||
|
- token can be brought to a specific NPC to upgrade it to fight harder bosses
|
||||||
|
|
||||||
|
Rework for Charge -> Flow, butterflies (for lore) instead of Lanterns
|
||||||
|
|
||||||
|
Regions
|
||||||
|
1st region: Shade mode is a thing, but not widely used. Player gets used to FLOW. First easy quest.
|
||||||
|
2nd region: Shade mode is needed for a handful of interactions, but not really for combat. First boss fight. First ability. Town 1.
|
||||||
|
3rd region: Shade mode is required to access areas or NPCs. New boss which unlocks region 4, but is optional for now.
|
||||||
|
4th region: Access through third area boss. Shade mode is required to traverse (unique environmental effects). Boss fight that has special targeting projectiles
|
||||||
|
if the player isn't in shade mode. New ability. Fast travel to 5th region/Town 2?
|
||||||
|
5th region: Alternate to 4th region in terms of progress. Light area. Town 2. Quest board/NPCs/player housing (for accessing the diary)
|
||||||
|
|
||||||
|
Ability changes (ideas)
|
||||||
|
Ranged:
|
||||||
|
- pierce
|
||||||
|
- less dmg for less flow cost
|
||||||
|
- faster/ramp up traveling speed/scale damage with speed
|
||||||
|
- more damage to specific enemies
|
||||||
|
- bigger but slower
|
||||||
|
- other directions (up/diagonal?)
|
||||||
|
- hold button to charge/release, first enemy hit will be marked for ? seconds, further shots will home in on marked enemy
|
||||||
|
|
||||||
|
Ground slam shade:
|
||||||
|
- knockback
|
||||||
|
- dmg immunity when hitting 1+ enemies
|
||||||
|
|
||||||
|
Light step:
|
||||||
|
- dmg up for ? seconds after/when touching platform
|
||||||
|
- speed increase after/when touching platform
|
||||||
|
|
||||||
|
Companion (fairy)
|
||||||
|
- interaction/guide
|
||||||
|
- ability: fairy bond teleport?
|
||||||
|
|
||||||
|
Fairy bond
|
||||||
|
- reinforce bond with fairy companion: allow fairy scout mode (fly and look but no interactions) and later on teleport to companion if it flies
|
||||||
|
ahead in this mode
|
||||||
|
- access to this bond mode takes a few seconds (channel) to not make the light step ability unneccessary
|
||||||
|
- fairy can make light at the expense of the player's flow
|
||||||
|
- fairy holes (environmental features/shortcuts) where player can teleport through with bond teleport
|
||||||
|
|
||||||
|
Fast travel
|
||||||
|
- items found all over the map (rune stones) which can be slotted into special devices to link those together as fast travel points
|
||||||
|
|
||||||
|
Enemies
|
||||||
|
design/behavior?
|
||||||
|
- slow patrol, move/jump in player direction
|
||||||
|
- slow patrol, doge backwards and leap at player
|
||||||
|
- stationary, shoot at player, burrow to somewhere else nearby
|
||||||
|
|
||||||
|
Quick recharge
|
||||||
|
- player can collect something in advance to refill charge mid-battle with a quick press of a button
|
||||||
|
|
||||||
|
Death
|
||||||
|
- what does the player lose?
|
||||||
|
- upgrades to lose less?
|
||||||
|
|
||||||
|
Lore
|
||||||
|
- player character is a being of light and dark, created by a forbidden love between a light and dark being
|
||||||
|
- gods? -> forbidden child <- banished and sleeping -> woken up long later by fairy companion (this is where the game starts)?
|
||||||
|
- parents of player character sent companion to support and guide the player back to their parents
|
||||||
|
- flow/charge is not inheritently dark or light, it is simply a resource that exists in the player character and a few other things in the world
|
||||||
|
|
||||||
|
World change
|
||||||
|
- mid game progress: unique weapon that the player can choose to take
|
||||||
|
- world changes if weapon is taken
|
||||||
|
- if weapon is not taken, player can still explore and return later to take the weapon unless they trigger a different event which would also change the world
|
||||||
|
(but differently compared to when they'd take the weapon) -> do they still get that weapon but in a different variant?
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<Solution>
|
|
||||||
<Project Path="pygame test/pygame test.pyproj" Type="888888a0-9f3d-457c-b088-3a5042f75d52" Id="e4b51f4c-e0be-4f9e-8a8e-d814a78b30c5">
|
|
||||||
<Build Project="false" />
|
|
||||||
</Project>
|
|
||||||
</Solution>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"charge_cost": 5.0,
|
|
||||||
"damage_mult": 0.5,
|
|
||||||
"cooldown": 0.45,
|
|
||||||
"projectile": {
|
|
||||||
"speed": 650.0,
|
|
||||||
"lifetime": 1.2,
|
|
||||||
"size": [14, 6]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"enemy": {
|
|
||||||
"rect": [40, 60],
|
|
||||||
"health": 3,
|
|
||||||
"speed": 2.2,
|
|
||||||
"air_speed": 2.0,
|
|
||||||
"detection_range": 240,
|
|
||||||
"contact_damage": 1,
|
|
||||||
"drop_profile": "normal"
|
|
||||||
},
|
|
||||||
"miniboss": {
|
|
||||||
"rect": [70, 95],
|
|
||||||
"health": 18,
|
|
||||||
"speed": 1.8,
|
|
||||||
"air_speed": 1.6,
|
|
||||||
"detection_range": 360,
|
|
||||||
"contact_damage": 2,
|
|
||||||
"drop_profile": "miniboss"
|
|
||||||
},
|
|
||||||
|
|
||||||
"boss": {
|
|
||||||
"rect": [110, 120],
|
|
||||||
"health": 10,
|
|
||||||
"speed": 1.6,
|
|
||||||
"air_speed": 1.4,
|
|
||||||
"detection_range": 500,
|
|
||||||
"contact_damage": 3,
|
|
||||||
"drop_profile": "boss"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"objects": {
|
|
||||||
"lamp": {
|
|
||||||
"type": "light_source",
|
|
||||||
"charge_regen_range": 180
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
{
|
|
||||||
"meta": {
|
|
||||||
"id": "room_01",
|
|
||||||
"name": "Room 01 - Tutorial Steps"
|
|
||||||
},
|
|
||||||
"player_spawn": [
|
|
||||||
-260,
|
|
||||||
500
|
|
||||||
],
|
|
||||||
"bounds": {
|
|
||||||
"kill_y": 2000
|
|
||||||
},
|
|
||||||
"platforms": {
|
|
||||||
"ground": [
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
640,
|
|
||||||
2060,
|
|
||||||
460
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
560,
|
|
||||||
520,
|
|
||||||
80
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1560,
|
|
||||||
220,
|
|
||||||
120,
|
|
||||||
880
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-1100,
|
|
||||||
-520,
|
|
||||||
600,
|
|
||||||
1620
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1680,
|
|
||||||
-100,
|
|
||||||
920,
|
|
||||||
1200
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
-520,
|
|
||||||
940,
|
|
||||||
840
|
|
||||||
],
|
|
||||||
[
|
|
||||||
440,
|
|
||||||
-520,
|
|
||||||
2160,
|
|
||||||
420
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"floating": [
|
|
||||||
[
|
|
||||||
800,
|
|
||||||
220,
|
|
||||||
320,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
880,
|
|
||||||
520,
|
|
||||||
240,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
500,
|
|
||||||
400,
|
|
||||||
320,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
440,
|
|
||||||
280,
|
|
||||||
200,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1220,
|
|
||||||
220,
|
|
||||||
340,
|
|
||||||
40
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enemies": [],
|
|
||||||
"exits": [
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
-420,
|
|
||||||
480,
|
|
||||||
90,
|
|
||||||
80
|
|
||||||
],
|
|
||||||
"to": "room_reward_01",
|
|
||||||
"spawn": [
|
|
||||||
120,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"hint": "Reward"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
1560,
|
|
||||||
100,
|
|
||||||
120,
|
|
||||||
120
|
|
||||||
],
|
|
||||||
"to": "room_02",
|
|
||||||
"spawn": [
|
|
||||||
-420,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"hint": "",
|
|
||||||
"spawn_id": "entry_1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability_doors": [],
|
|
||||||
"entry_spawns": {},
|
|
||||||
"props": [
|
|
||||||
{
|
|
||||||
"type": "light_source",
|
|
||||||
"pos": [
|
|
||||||
0,
|
|
||||||
560
|
|
||||||
],
|
|
||||||
"radius": 180
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
{
|
|
||||||
"meta": {
|
|
||||||
"id": "room_02",
|
|
||||||
"name": "Room 02 - First Enemies"
|
|
||||||
},
|
|
||||||
"player_spawn": [
|
|
||||||
-320,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"bounds": {
|
|
||||||
"kill_y": 2000
|
|
||||||
},
|
|
||||||
"platforms": {
|
|
||||||
"ground": [
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
360,
|
|
||||||
2440,
|
|
||||||
660
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-760,
|
|
||||||
-580,
|
|
||||||
260,
|
|
||||||
1600
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1940,
|
|
||||||
-580,
|
|
||||||
240,
|
|
||||||
1600
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-760,
|
|
||||||
-820,
|
|
||||||
2940,
|
|
||||||
240
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"floating": [
|
|
||||||
[
|
|
||||||
260,
|
|
||||||
260,
|
|
||||||
140,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
520,
|
|
||||||
220,
|
|
||||||
140,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
760,
|
|
||||||
180,
|
|
||||||
140,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
940,
|
|
||||||
120,
|
|
||||||
170,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1200,
|
|
||||||
160,
|
|
||||||
170,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1460,
|
|
||||||
100,
|
|
||||||
170,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1200,
|
|
||||||
-20,
|
|
||||||
280,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
40,
|
|
||||||
-140,
|
|
||||||
1100,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
-140,
|
|
||||||
460,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
-260,
|
|
||||||
260,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
-380,
|
|
||||||
160,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
-320,
|
|
||||||
-500,
|
|
||||||
1380,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1140,
|
|
||||||
-440,
|
|
||||||
340,
|
|
||||||
40
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1560,
|
|
||||||
-380,
|
|
||||||
380,
|
|
||||||
40
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enemies": [
|
|
||||||
{
|
|
||||||
"type": "enemy",
|
|
||||||
"pos": [
|
|
||||||
240,
|
|
||||||
-200
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "enemy",
|
|
||||||
"pos": [
|
|
||||||
620,
|
|
||||||
140
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "enemy",
|
|
||||||
"pos": [
|
|
||||||
860,
|
|
||||||
-200
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "enemy",
|
|
||||||
"pos": [
|
|
||||||
480,
|
|
||||||
-580
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "enemy",
|
|
||||||
"pos": [
|
|
||||||
1740,
|
|
||||||
280
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"exits": [
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
-500,
|
|
||||||
300,
|
|
||||||
80,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
"to": "room_01",
|
|
||||||
"spawn": [
|
|
||||||
1560,
|
|
||||||
140
|
|
||||||
],
|
|
||||||
"hint": "Back"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
1860,
|
|
||||||
-500,
|
|
||||||
80,
|
|
||||||
120
|
|
||||||
],
|
|
||||||
"to": "room_07",
|
|
||||||
"spawn": [
|
|
||||||
180,
|
|
||||||
240
|
|
||||||
],
|
|
||||||
"hint": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability_doors": [],
|
|
||||||
"entry_spawns": {
|
|
||||||
"entry_1": [
|
|
||||||
-420,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"entry_3": [
|
|
||||||
1840,
|
|
||||||
-440
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,426 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "room_07",
|
|
||||||
"display_name": "room_07",
|
|
||||||
"meta": {
|
|
||||||
"id": "room_07",
|
|
||||||
"name": "room_07"
|
|
||||||
},
|
|
||||||
"bounds": {
|
|
||||||
"kill_y": 3200
|
|
||||||
},
|
|
||||||
"player_spawn": [
|
|
||||||
200,
|
|
||||||
220
|
|
||||||
],
|
|
||||||
"entry_spawns": {
|
|
||||||
"entry_1": [
|
|
||||||
180,
|
|
||||||
240
|
|
||||||
],
|
|
||||||
"entry_2": [
|
|
||||||
4200,
|
|
||||||
2720
|
|
||||||
],
|
|
||||||
"entry_3": [
|
|
||||||
-320,
|
|
||||||
2720
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"platforms": [
|
|
||||||
{
|
|
||||||
"x": 60,
|
|
||||||
"y": 320,
|
|
||||||
"w": 1460,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": -1160,
|
|
||||||
"y": 2780,
|
|
||||||
"w": 5500,
|
|
||||||
"h": 120,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": -1160,
|
|
||||||
"y": -300,
|
|
||||||
"w": 1220,
|
|
||||||
"h": 2480,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": -1280,
|
|
||||||
"y": -300,
|
|
||||||
"w": 120,
|
|
||||||
"h": 3200,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2300,
|
|
||||||
"y": 1860,
|
|
||||||
"w": 2040,
|
|
||||||
"h": 320,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 4340,
|
|
||||||
"y": -300,
|
|
||||||
"w": 100,
|
|
||||||
"h": 3200,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 60,
|
|
||||||
"y": -300,
|
|
||||||
"w": 4280,
|
|
||||||
"h": 80,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 60,
|
|
||||||
"y": 1860,
|
|
||||||
"w": 1600,
|
|
||||||
"h": 320,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1600,
|
|
||||||
"y": 440,
|
|
||||||
"w": 1060,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2780,
|
|
||||||
"y": 320,
|
|
||||||
"w": 580,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 3280,
|
|
||||||
"y": 800,
|
|
||||||
"w": 1060,
|
|
||||||
"h": 60,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1660,
|
|
||||||
"y": 1920,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1940,
|
|
||||||
"y": 2040,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1660,
|
|
||||||
"y": 2160,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1940,
|
|
||||||
"y": 2280,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1660,
|
|
||||||
"y": 2400,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1940,
|
|
||||||
"y": 2520,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1660,
|
|
||||||
"y": 2640,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1940,
|
|
||||||
"y": 2720,
|
|
||||||
"w": 360,
|
|
||||||
"h": 20,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2660,
|
|
||||||
"y": 880,
|
|
||||||
"w": 520,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2140,
|
|
||||||
"y": 880,
|
|
||||||
"w": 380,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1940,
|
|
||||||
"y": 880,
|
|
||||||
"w": 120,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1680,
|
|
||||||
"y": 880,
|
|
||||||
"w": 100,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1440,
|
|
||||||
"y": 880,
|
|
||||||
"w": 80,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1220,
|
|
||||||
"y": 880,
|
|
||||||
"w": 80,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 940,
|
|
||||||
"y": 880,
|
|
||||||
"w": 180,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 660,
|
|
||||||
"y": 820,
|
|
||||||
"w": 180,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 300,
|
|
||||||
"y": 740,
|
|
||||||
"w": 260,
|
|
||||||
"h": 60,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 260,
|
|
||||||
"y": 640,
|
|
||||||
"w": 40,
|
|
||||||
"h": 1100,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 300,
|
|
||||||
"y": 1260,
|
|
||||||
"w": 4040,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 3240,
|
|
||||||
"y": 980,
|
|
||||||
"w": 60,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 3100,
|
|
||||||
"y": 1060,
|
|
||||||
"w": 60,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 3240,
|
|
||||||
"y": 1140,
|
|
||||||
"w": 60,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 3380,
|
|
||||||
"y": 440,
|
|
||||||
"w": 300,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 3700,
|
|
||||||
"y": 560,
|
|
||||||
"w": 300,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 4020,
|
|
||||||
"y": 680,
|
|
||||||
"w": 320,
|
|
||||||
"h": 40,
|
|
||||||
"group": "ground"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"enemies": [
|
|
||||||
{
|
|
||||||
"x": 2080,
|
|
||||||
"y": 360,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 280,
|
|
||||||
"y": 2680,
|
|
||||||
"type": "miniboss"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 520,
|
|
||||||
"y": 2700,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 680,
|
|
||||||
"y": 2700,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 980,
|
|
||||||
"y": 2700,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 840,
|
|
||||||
"y": 2700,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 820,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1040,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1340,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 1700,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2140,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2480,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2700,
|
|
||||||
"y": 1160,
|
|
||||||
"type": "enemy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 2740,
|
|
||||||
"y": 1720,
|
|
||||||
"type": "miniboss"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"props": [],
|
|
||||||
"exits": [
|
|
||||||
{
|
|
||||||
"x": -1160,
|
|
||||||
"y": 2640,
|
|
||||||
"w": 100,
|
|
||||||
"h": 140,
|
|
||||||
"to": "room_town_gloomreach",
|
|
||||||
"spawn_id": "",
|
|
||||||
"spawn": [
|
|
||||||
120,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"hint": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": -420,
|
|
||||||
"y": 2720,
|
|
||||||
"w": 80,
|
|
||||||
"h": 60,
|
|
||||||
"to": "room_boss_01",
|
|
||||||
"spawn_id": "entry_2",
|
|
||||||
"spawn": [
|
|
||||||
-360,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"hint": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 4240,
|
|
||||||
"y": 2700,
|
|
||||||
"w": 100,
|
|
||||||
"h": 80,
|
|
||||||
"to": "room_reward_01",
|
|
||||||
"spawn_id": "",
|
|
||||||
"spawn": [
|
|
||||||
1760,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"hint": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 60,
|
|
||||||
"y": 180,
|
|
||||||
"w": 100,
|
|
||||||
"h": 140,
|
|
||||||
"to": "room_02",
|
|
||||||
"spawn_id": "",
|
|
||||||
"spawn": [
|
|
||||||
1840,
|
|
||||||
-440
|
|
||||||
],
|
|
||||||
"hint": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability_doors": [
|
|
||||||
{
|
|
||||||
"x": -980,
|
|
||||||
"y": 2180,
|
|
||||||
"w": 80,
|
|
||||||
"h": 600
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 4100,
|
|
||||||
"y": 2180,
|
|
||||||
"w": 40,
|
|
||||||
"h": 600
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"room_w": 1600,
|
|
||||||
"room_h": 900
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
{
|
|
||||||
"meta": {
|
|
||||||
"id": "room_boss_01",
|
|
||||||
"name": "room_boss_01"
|
|
||||||
},
|
|
||||||
"player_spawn": [
|
|
||||||
-240,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"bounds": {
|
|
||||||
"kill_y": 1400
|
|
||||||
},
|
|
||||||
"platforms": {
|
|
||||||
"ground": [
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
360,
|
|
||||||
1500,
|
|
||||||
240
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enemies": [
|
|
||||||
{
|
|
||||||
"type": "boss",
|
|
||||||
"pos": [
|
|
||||||
280,
|
|
||||||
200
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"exits": [
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
-460,
|
|
||||||
300,
|
|
||||||
80,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
"to": "room_07",
|
|
||||||
"spawn": [
|
|
||||||
-320,
|
|
||||||
2720
|
|
||||||
],
|
|
||||||
"hint": "Retreat",
|
|
||||||
"spawn_id": "entry_3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
880,
|
|
||||||
260,
|
|
||||||
120,
|
|
||||||
100
|
|
||||||
],
|
|
||||||
"to": "room_reward_01",
|
|
||||||
"spawn": [
|
|
||||||
100,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"hint": "Reward",
|
|
||||||
"spawn_id": "entry_2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability_doors": [],
|
|
||||||
"entry_spawns": {
|
|
||||||
"entry_2": [
|
|
||||||
-360,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
{
|
|
||||||
"meta": {
|
|
||||||
"id": "room_reward_01",
|
|
||||||
"name": "room_reward_01"
|
|
||||||
},
|
|
||||||
"player_spawn": [
|
|
||||||
140,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"bounds": {
|
|
||||||
"kill_y": 2000
|
|
||||||
},
|
|
||||||
"platforms": {
|
|
||||||
"ground": [
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
360,
|
|
||||||
2400,
|
|
||||||
240
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"floating": [
|
|
||||||
[
|
|
||||||
650,
|
|
||||||
260,
|
|
||||||
220,
|
|
||||||
18
|
|
||||||
],
|
|
||||||
[
|
|
||||||
1100,
|
|
||||||
260,
|
|
||||||
220,
|
|
||||||
18
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enemies": [],
|
|
||||||
"exits": [
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
0,
|
|
||||||
300,
|
|
||||||
80,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
"to": "room_boss_01",
|
|
||||||
"spawn_id": "entry_2",
|
|
||||||
"spawn": [
|
|
||||||
110,
|
|
||||||
260
|
|
||||||
],
|
|
||||||
"hint": "Back"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
1840,
|
|
||||||
300,
|
|
||||||
60,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
"to": "room_07",
|
|
||||||
"spawn_id": "entry_2",
|
|
||||||
"spawn": [
|
|
||||||
4200,
|
|
||||||
2720
|
|
||||||
],
|
|
||||||
"hint": "Forward"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability_doors": [
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
1700,
|
|
||||||
60,
|
|
||||||
60,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
1580,
|
|
||||||
60,
|
|
||||||
40,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"entry_spawns": {
|
|
||||||
"entry_2": [
|
|
||||||
100,
|
|
||||||
300
|
|
||||||
],
|
|
||||||
"entry_1": [
|
|
||||||
1800,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"props": [
|
|
||||||
{
|
|
||||||
"type": "reward_chest",
|
|
||||||
"pos": [
|
|
||||||
520,
|
|
||||||
330
|
|
||||||
],
|
|
||||||
"radius": 180
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "ability_pickup",
|
|
||||||
"pos": [
|
|
||||||
820,
|
|
||||||
210
|
|
||||||
],
|
|
||||||
"radius": 180
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
{
|
|
||||||
"meta": {
|
|
||||||
"id": "room_town_gloomreach",
|
|
||||||
"name": "room_town_gloomreach"
|
|
||||||
},
|
|
||||||
"player_spawn": [
|
|
||||||
80,
|
|
||||||
260
|
|
||||||
],
|
|
||||||
"bounds": {
|
|
||||||
"kill_y": 2000
|
|
||||||
},
|
|
||||||
"platforms": {
|
|
||||||
"ground": [
|
|
||||||
[
|
|
||||||
-500,
|
|
||||||
360,
|
|
||||||
2400,
|
|
||||||
240
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enemies": [],
|
|
||||||
"exits": [
|
|
||||||
{
|
|
||||||
"rect": [
|
|
||||||
10,
|
|
||||||
300,
|
|
||||||
80,
|
|
||||||
60
|
|
||||||
],
|
|
||||||
"to": "room_reward_01",
|
|
||||||
"spawn": [
|
|
||||||
1700,
|
|
||||||
260
|
|
||||||
],
|
|
||||||
"hint": "Back"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability_doors": [],
|
|
||||||
"entry_spawns": {
|
|
||||||
"entry_1": [
|
|
||||||
120,
|
|
||||||
300
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"npcs": [
|
|
||||||
{
|
|
||||||
"type": "vendor",
|
|
||||||
"pos": [
|
|
||||||
700,
|
|
||||||
306
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "upgrader",
|
|
||||||
"pos": [
|
|
||||||
860,
|
|
||||||
306
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "necklace_vendor",
|
|
||||||
"pos": [
|
|
||||||
1020,
|
|
||||||
306
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
New skills
|
|
||||||
Tether
|
|
||||||
- hit an enemy, inflict a visual bind for a few seconds, end effect depends on which form the player is in when it ends
|
|
||||||
- light form: blind enemy (make them walk the other direction)
|
|
||||||
- shade form: instakill after a certain enemy HP threshold, slow otherwise
|
|
||||||
|
|
||||||
Reality Break
|
|
||||||
- light form: make all enemies double their drop rates
|
|
||||||
- shade form: instantly kill all enemies, halves drop rates
|
|
||||||
|
|
||||||
Shatterstep
|
|
||||||
- light form: for X seconds, create a platform below your feet when jumping, allowing for multiple jumps in the air
|
|
||||||
- shade form: when jumping, create aoe below you upon landing
|
|
||||||
|
|
||||||
|
|
||||||
Skill upgrades
|
|
||||||
Dash
|
|
||||||
- Refund cost upon successful stun/kill
|
|
||||||
- lower cooldown
|
|
||||||
- more range
|
|
||||||
- build up movement speed stacks with every dash, lose stacks upon getting hit
|
|
||||||
- more damage against targets that are stunned (inflict mark?)
|
|
||||||
- leave behind afterimage (enemy taunt)
|
|
||||||
|
|
||||||
Ranged Attack
|
|
||||||
- hold to charge, release for stronger attack (more damage and stun)
|
|
||||||
- faster speed, higher charge cost
|
|
||||||
- slower speed but more damage
|
|
||||||
- upgrade light form: pierce and slow
|
|
||||||
- upgrade shade form: aoe
|
|
||||||
- for every enemy kill collect stacks that increase damage, lose stacks upon not finishing enemies
|
|
||||||
|
|
||||||
Tether
|
|
||||||
- light form: higher hp threshold for kill; if used against boss: slower attacks
|
|
||||||
- shade form: longer fear; if used against boss: slower movement speed
|
|
||||||
|
|
||||||
|
|
||||||
How to obtain skill upgrades
|
|
||||||
- vendor (smith? trainer?) that can upgrade one spell (selection can be changed but requires paying for it every time)
|
|
||||||
- item (gem?) that can be slotted into armor to unlock a skill upgrade
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ascended armor
|
|
||||||
- select one awakened armor piece as the main piece and one as the sacrifice
|
|
||||||
- select X number of traits from the sacrifice to merge onto the main piece
|
|
||||||
- sacrifice gets destroyed in the process, creating an Ascended armor piece
|
|
||||||
- cost: many coins/rare resource?
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pygame>=2.6
|
||||||