Settings(
    /// Default music volume.
    music_volume:        0.5,
    /// Music volume when ingame state is paused.
    music_volume_paused: 0.1,

    /// Y level, at which to kill entities, when they dip below it.
    death_floor: -200.0,

    camera: (
        /// Camera size multiplier;
        /// is multiplied by the window size, to figure out the camera's size (zoom level).
        size_mult:       (0.65625, 0.65625),
        /// Rectangle in the center of the window, where the camera smoothly scrolls to player;
        /// Outside of this rectangle, the camera instantly snaps to where player is back inside.
        /// Basically, the player can never be outside of this inner rectangle.
        /// Is also multiplied by the window size.
        inner_size_mult: (0.328125, 0.328125),
        /// Camera's smooth scroll speed multiplier.
        base_speed:      (250.0, 250.0),
        /// Pixel padding, in which camera will stop scrolling to player.
        /// The camera will always center within +- these amounts of pixels, (accuracy kinda).
        deadzone:        (16.0, 16.0),
        /// Extra padding beyond the camera's size, in which entities are loaded.
        loader_padding:  (32.0, 32.0),
    ),

    player: (
        /// This is not used currently. Size is read from map.json, so it is defined with Tiled.
        size:                       (16.0, 32.0),
        /// Player velocity acceleration.
        acceleration:               (1000.0, 0.0),
        /// Jump velocity boost.
        jump_strength:              400.0,
        /// Wall jump velocity boost (x, y).
        wall_jump_strength:         (500.0, 500.0),
        /// Amount of velocity to kill when releasing the jump button.
        decr_jump_strength:         200.0,
        /// The minimum amount of y velocity, after killing the jump.
        min_jump_velocity:          50.0,
        /// Max velocity.
        max_velocity:               (Some(200.0), None),
        /// Decrease velocity by this amount, every frame.
        /// x value has no effect when moving, y value has no effect when falling/jumping.
        decr_velocity:              (2000.0, 1000.0),
        /// Gravitational pull when _not jumping_.
        gravity:                    (0.0, -800.0),
        /// Gravitational pull _when jumping_.
        jump_gravity:               (0.0, -350.0),
        /// Velocity when sliding on / clinging to a `Solid` & `Collision` entity.
        slide_strength:             75.0,
        /// Behavior when turning around. Possible values:
        /// - `0` (_will hopefully be `No` in the future_)
        ///   Don't do anything to velocity when turning around. Example:
        ///   When player is moving _left_ and then turns around to move _right_,
        ///   the velocity of running _left_ (negative) must first increase and pass 0 (positive),
        ///   before the player starts running to the _right_.
        ///   _(left: negative, right: positive)_
        /// - `1` (_will hopefully be `ResetVelocity` in the future_)
        ///   When turning around, reset velocity to 0.
        ///   This means, the previous direction's velocity does _not_ need to drain first.
        /// - `2` (_will hopefully be `InvertVelocity` in the future_)
        ///   When turning around, the velocity's sign is instantly inverted (`velocity.x * -1.0`),
        ///   which means, that no speed is lost when turning around.
        quick_turnaround:           0,
        /// Turning around behavior when in mid air.
        air_quick_turnaround:       0,
        /// If the x velocity should be decreased when in air.
        decrease_x_velocity_in_air: true,
        /// Player starting health
        health:                     6,
        /// Player max health
        max_health:                 30,
        /// Player damage
        damage:                     1,
    ),

    loading_text: (
        text:      "Loading...",
        font_file: "fonts/undefined-medium.ttf",
        font_size: 64.0,
    ),

    level_manager: (
        /// LevelManager settings for normal campaign
        normal: (
            levels_dir: "levels/normal",
            level_names: (
                "overworld_1.json", "overworld_2.json", "overworld_3.json",
                "graveyard_1.json", "graveyard_2.json", "graveyard_3.json",
                "graveyard_4.json", "graveyard_5.json", "graveyard_6.json", "graveyard_7.json",
            ),
            song_names: (
                "level_1.ogg", "level_1.ogg", "level_1.ogg",
                "level_2.ogg", "level_3.ogg", "level_3.ogg",
                "level_6.ogg", "level_6.ogg", "level_4.ogg", "level_4.ogg",
            ),
            tile_size: (32.0, 32.0),
            /// Relative path to the save file
            savefile_path: "savefile",
            /// Health to replenish on death
            health_increase_on_death: 2,
            /// Settings for the _level_ speedrun timer UI
            level_timer_ui: (
                text_prefix: "Level time: ",
                font_file:   "fonts/undefined-medium.ttf",
                font_size:   24.0,
                font_color:  [1.0, 1.0, 1.0, 0.5],
                offset:      (8.0, -8.0),
                highscore: (
                    text_prefix: "Level time PB: ",
                    font_file:   "fonts/undefined-medium.ttf",
                    font_size:   12.0,
                    font_color:  [0.8, 0.8, 0.8, 0.5],
                    offset:      (0.0, -24.0), // Relative to parent timer UI
                ),
            ),
            /// Settings for the _global_ speedrun timer UI
            global_timer_ui: (
                text_prefix: "Game time: ",
                font_file:   "fonts/undefined-medium.ttf",
                font_size:   16.0,
                font_color:  [1.0, 1.0, 1.0, 0.5],
                offset:      (8.0, -48.0),
                highscore: (
                    text_prefix: "Game time PB: ",
                    font_file:   "fonts/undefined-medium.ttf",
                    font_size:   12.0,
                    font_color:  [0.8, 0.8, 0.8, 0.5],
                    offset:      (0.0, -16.0), // Relative to parent timer UI
                ),
            ),
        ),

        /// LevelManager settings for bonus_a campaign
        bonus_a: (
            levels_dir: "levels/bonus_a",
            level_names: (
                "bonus_a_1.json", "bonus_a_2.json", "bonus_a_3.json",
            ),
            song_names: (
                "level_7.ogg", "level_7.ogg", "level_7.ogg",
            ),
            tile_size: (32.0, 32.0),
            /// Relative path to the save file
            savefile_path: "savefile_bonus_a",
            /// Health to replenish on death
            health_increase_on_death: 2,
            /// Settings for the _level_ speedrun timer UI
            level_timer_ui: (
                text_prefix: "Level time: ",
                font_file:   "fonts/undefined-medium.ttf",
                font_size:   24.0,
                font_color:  [1.0, 1.0, 1.0, 0.5],
                offset:      (8.0, -8.0),
                highscore: (
                    text_prefix: "Level time PB: ",
                    font_file:   "fonts/undefined-medium.ttf",
                    font_size:   12.0,
                    font_color:  [0.8, 0.8, 0.8, 0.5],
                    offset:      (0.0, -24.0), // Relative to parent timer UI
                ),
            ),
            /// Settings for the _global_ speedrun timer UI
            global_timer_ui: (
                text_prefix: "Game time: ",
                font_file:   "fonts/undefined-medium.ttf",
                font_size:   16.0,
                font_color:  [1.0, 1.0, 1.0, 0.5],
                offset:      (8.0, -48.0),
                highscore: (
                    text_prefix: "Game time PB: ",
                    font_file:   "fonts/undefined-medium.ttf",
                    font_size:   12.0,
                    font_color:  [0.8, 0.8, 0.8, 0.5],
                    offset:      (0.0, -16.0), // Relative to parent timer UI
                ),
            ),
            /// If the time of both timers should be printed to the console, in regular intervals
            timers_print_to_stdout: false,
        ),

        /// LevelManager settings for bonus_b campaign
        bonus_b: (
            levels_dir: "levels/bonus_b",
            level_names: (
                "bonus_b_1.json", "bonus_b_2.json", "bonus_b_3.json",
            ),
            song_names: (
                "level_8.ogg", "level_8.ogg", "level_8.ogg",
            ),
            tile_size: (32.0, 32.0),
            /// Relative path to the save file
            savefile_path: "savefile_bonus_b",
            /// Health to replenish on death
            health_increase_on_death: 2,
            /// Settings for the _level_ speedrun timer UI
            level_timer_ui: (
                text_prefix: "Level time: ",
                font_file:   "fonts/undefined-medium.ttf",
                font_size:   24.0,
                font_color:  [1.0, 1.0, 1.0, 0.5],
                offset:      (8.0, -8.0),
                highscore: (
                    text_prefix: "Level time PB: ",
                    font_file:   "fonts/undefined-medium.ttf",
                    font_size:   12.0,
                    font_color:  [0.8, 0.8, 0.8, 0.5],
                    offset:      (0.0, -24.0), // Relative to parent timer UI
                ),
            ),
            /// Settings for the _global_ speedrun timer UI
            global_timer_ui: (
                text_prefix: "Game time: ",
                font_file:   "fonts/undefined-medium.ttf",
                font_size:   16.0,
                font_color:  [1.0, 1.0, 1.0, 0.5],
                offset:      (8.0, -48.0),
                highscore: (
                    text_prefix: "Game time PB: ",
                    font_file:   "fonts/undefined-medium.ttf",
                    font_size:   12.0,
                    font_color:  [0.8, 0.8, 0.8, 0.5],
                    offset:      (0.0, -16.0), // Relative to parent timer UI
                ),
            ),
            /// If the time of both timers should be printed to the console, in regular intervals
            timers_print_to_stdout: false,
        ),
    ),

    enemies: (
        gravity: (0.0, -500.0),
        normal:  (
            health:                4,
            damage:                2,
            reward:                4,
            knockback:             (600.0, 200.0),
            trigger_distance:      (192.0, 128.0),
            acceleration:          (200.0, 0.0),
            max_velocity:          (Some(50.0), Some(500.0)),
            decr_velocity:         (1000.0, 1000.0),
            affected_by_knockback: true,
        ),
        charger: (
            health:                2,
            damage:                2,
            reward:                1,
            knockback:             (700.0, 200.0),
            trigger_distance:      (256.0, 32.0),
            acceleration:          (500.0, 0.0),
            max_velocity:          (Some(200.0), Some(500.0)),
            decr_velocity:         (300.0, 1000.0),
            affected_by_knockback: true,
        ),
        flying:  (
            health:                3,
            damage:                4,
            reward:                2,
            knockback:             (400.0, 150.0),
            trigger_distance:      (256.0, 192.0),
            acceleration:          (500.0, 100.0),
            max_velocity:          (Some(25.0), Some(25.0)),
            decr_velocity:         (300.0, 300.0),
            affected_by_knockback: true,
        ),
        reaper:  (
            health:                6,
            damage:                2,
            reward:                6,
            knockback:             (1000.0, 400.0),
            trigger_distance:      (192.0, 128.0),
            acceleration:          (256,0, 0.0),
            max_velocity:          (Some(100.0), Some(500.0)),
            decr_velocity:         (1000.0, 1000.0),
            affected_by_knockback: true,
        ),
        turret:  (
            health:                0,
            damage:                4,
            reward:                0,
            knockback:             (0.0, 0.0),
            trigger_distance:      (1536.0, 256.0),
            acceleration:          (0.0, 0.0),
            max_velocity:          (None, None),
            decr_velocity:         (0.0, 0.0),
            affected_by_knockback: false,
        ),
        turret_data: (
          shot_interval_ms:   4500,
          bullet_velocity:    (200.0, 0.0),
          bullet_size:        (16.0, 16.0),
          bullet_lifetime_ms: 20_000,
        )
    ),

    items: (
        extra_jump: (
            cost: 12,
        ),
        wall_jump: (
            cost: 6,
        ),
        knockback: (
            cost: 6,
        ),
        bullet_shoot: (
            cost: 14,
        ),
        dash: (
            cost: 12,
        ),
        bullet_deflect: (
            cost: 10,
        ),
        thrust: (
            cost: 10,
        ),
        speed_up: (
            cost: 6,
        ),
        jump_up: (
            cost: 8,
        ),
        damage_up: (
            cost: 12,
        ),

        settings: (
            knockback_strength:           (150.0, 75.0),
            bullet_shoot_damage:          1,
            bullet_shoot_velocity:        (500.0, 0.0),
            bullet_shoot_size:            (16.0, 16.0),
            bullet_shoot_lifetime_ms:     2_500,
            dash_duration_ms:             150,
            dash_velocity:                (550.0, 250.0),
            dash_input_delay_ms:          250,
            dash_double_tap:              false,
            dash_only_in_air:             true,
            bullet_deflect_damage:        1,
            bullet_deflect_velocity_mult: (-1.0, 1.0),
            bullet_deflect_lifetime_ms:   2_500,
            thrust_strength:              (400.0, 200.0),
            speed_up_max_velocity_up:     50.0,
            speed_up_acceleration_up:     300.0,
            jump_up:                      50.0,
            damage_up:                    1,
        )
    ),

    /// Settings for harmful tiles (spikes).
    harmful: (
      knockback_strength: (600.0, 600.0),
    ),

    /// Settings for the entity loader system.
    entity_loader: (
        /// Anything beyond this distance to the player will be unloaded,
        /// anything within this distance to the player will be loaded.
        // TODO: Unused! Loading distance is now the camera.
        load_distance:                  (256.0, 256.0),
        /// The `load_distance` minus the `enemy_load_distance_difference`,
        /// is the load_distance for enemies.
        /// We load enemies from less far away, because if they are loaded
        /// and moving into unloaded solid tiles, then they will get stuck
        /// once the tiles become loaded.
        enemy_load_distance_difference: (72.0, 72.0),
        /// Bullets can also load entities.
        /// Entities who are within this distance to each bullet are loaded.
        bullet_load_distance:           (64.0, 64.0),
    ),

    /// If the time of both timers should be printed to the console, in regular intervals
    timers_print_to_stdout: false,

    /// Noclip settings; only in development mode.
    noclip: (
        acceleration: (800.0, 800.0),
        max_velocity: (Some(2000.0), Some(2000.0)),
    )
)
