function p.new_game()
    --Setting camera mode.
    game_body.set_default_fly_mode()

    --Maybe need to procedurally create the starting position.
    local game_desc = ga_get_sys_s("game.package.config_desc")
    if( game_desc == "Genesis" or
        game_desc == "Classic" )
    then
        ga_set_s("xar.create_start_pos.state", "not_started")
    end

    --Only adding extra builtin waypoints
    --if using "Cheater Hub" configuration.
    if( ga_get_sys_s("game.package.config_desc") == "Cheater Hub" ) then
        game_cheater_waypoints.add()
    end

    --Setting curve mode on by default.
    --The reason it is not set this way in globals.txt
    --is because I don't want to modify legacy saved games.
    ga_set_b("xar.difficulty.curve.enabled", true)

    --Initializing package vars, if they have not been already.
    game_package_init.init()
end

function p.load_game()
    -- ga_print("top.load_game begin")

    --Setting dependent variables.
    game_var_helpers.set_dep_vars()

    --Adding windows to the hud.
    --Lower numbers are rendered first.
    ga_hud_window_add("win_hud_user_below", 50)
    ga_hud_window_add("win_hud", 100) --Do not change.
    ga_hud_window_add("win_hud_user_above", 150)

    --more?

    -- ga_print("top.load_game end")
end

function p.reboot_game()
    ga_print("Here in top.reboot_game")

    --Clearing certain env vars.
    ga_set_f("xar.emp_end_time", 0.0)

    local countdown = 10000 --10 thousand.
    while true do
        if ga_reboot_dyn_itr_at_end() then
            --Done the rebooting process.
            return true
        end

        countdown = countdown - 1
        if( countdown <= 0 ) then
            --Too many vars to do now,
            --must do them later.
            return false
        end

        local var = ga_reboot_dyn_itr_get()

        --Only saving the var called
        --"dyn.test.my_favorite_book".
        if var == "dyn.test.my_favorite_book" then
            ga_reboot_dyn_itr_save()
        end

        ga_reboot_dyn_itr_next()
    end

    --Will never reach here.
    return true
end

--Called during a regular (non discrete) update.
--This is called once per frame.
function p.update()
    game_update.update()
end

--Gets called when the game is paused,
--such as when in a menu.
function p.update_passive()
    game_update.update_passive()
end

--Gets called first during a (discrete) update cycle.
--The the engine performs its own discrete update.
--Then the update_discrete_post function gets called
--There are 25 discrete updates per second.
function p.update_discrete_pre()
    game_update.update_discrete_pre()
end

function p.update_discrete_post()
    game_update.update_discrete_post()
end

--Note: sometimes this function will crash by either calling
--ga_get_viewer_chunk_id or ga_get_viewer_level!!!
--This is because the mtree is sometimes loading locked!!!
function p.game_input(str)
    -- ga_print("top.game_input: " .. str)
    
    if not ga_get_sys_b("game.player.alive") then return "" end

    if (str == "help2") then
        ga_console_print("Strings that can be passed to game_input:")
        ga_console_print("\n")
        ga_console_print("which_equipped")
        ga_console_print("use_equipped (primary | secondary) (start | stop)")
        ga_console_print("equip_from_screen_inv_wheel")
        ga_console_print("equip_from_screen_inv NUM")
        ga_console_print("open_window hud_1")
        ga_console_print("open_window hud_2")
        ga_console_print("open_window hud_3")
        ga_console_print("open_window hud_4")
        ga_console_print("open_window hud_5")
        ga_console_print("open_window hud_6")
        ga_console_print("open_window hud_7")
        ga_console_print("marker (start | stop)")
        ga_console_print("^xff00ffCheat codes:")
        ga_console_print("takeall")
        ga_console_print("giveall")
        ga_console_print("givegold")
        ga_console_print("giveupgrades0")
        ga_console_print("giveupgrades")
        ga_console_print("giveupgrades2")
        ga_console_print("giveweaponmodes")
        ga_console_print("freemarkers")
        ga_console_print("topofworld")
        ga_console_print("inf2")
        ga_console_print("pink")
        ga_console_print("blue")
        ga_console_print("wep_script_start")
        ga_console_print("wep_script_stop")
        return ""
    end

    if( str == "__game_saved__" ) then
        if( ga_get_b("xar.hud.msg.show_saved_game_msg") ) then
            game_msg.add("Game saved")
        end
        return ""
    end

    if( str:find("^__spiral_of_death__") ~= nil ) then
        if( ga_get_b("xar.hud.msg.show_spiral_of_death_msg") ) then
            --num = string.gsub(str, "^__spiral_of_death__ ", "")
            --game_msg.add("*** Danger: spiral of death: " .. num)
            --game_msg.add("SOD: " .. num) --Put this back in!
        end
        return ""
    end

    if( str == "__screenshot__" ) then
        game_msg.add("Screenshot saved")
        return ""
    end

    if( str == "__screenshot_failed__" ) then
        game_msg.add("*** Error: the Inner Core is too shy to have a screenshot taken")
        return ""
    end

    if( str:find("^__cmd__") ~= nil ) then
        local stripped = string.sub(str, 9)
        local mod = "Command: " .. stripped
        game_msg.add(mod)
        return ""
    end

    if( str:find("^move") ~= nil ) then
        --str starts with "move".
        game_movement.input(str)
        return ""
    end

    for i = 0,9 do
        if (str == "equip_from_screen_inv " .. tostring(i)) then
            if game_change_wep.can_use_wep(i) then
                ga_set_i("xar.player.cur_wep", i)
                game_inv_exec.end_use()
            end
            return ""
        end
    end

    if (str == "equip_from_screen_inv_wheel" ) then
        local total = ga_get_sys_i("game.input.mouse.wheel_value")
        if (total ~= 0) then
            local cur_wep = ga_get_i("xar.player.cur_wep")
            local next_wep = cur_wep
            if( total > 0 ) then
                for i = 1,total do
                    next_wep = game_change_wep.next_useable_wep(next_wep)
                end
            end
            if( total < 0 ) then
                for i = 1,(-total) do
                    next_wep = game_change_wep.prev_useable_wep(next_wep)
                end
            end
            ga_set_i("xar.player.cur_wep", next_wep)
            game_inv_exec.end_use()
        end
    elseif( str == "equiv_from_screen_inv_right" ) then
        local cur_wep = ga_get_i("xar.player.cur_wep")
        local next_wep = cur_wep
        local next_wep = game_change_wep.next_useable_wep(next_wep)
        ga_set_i("xar.player.cur_wep", next_wep)
        return ""
    elseif( str == "equiv_from_screen_inv_left" ) then
        local cur_wep = ga_get_i("xar.player.cur_wep")
        local next_wep = cur_wep
        local next_wep = game_change_wep.prev_useable_wep(next_wep)
        ga_set_i("xar.player.cur_wep", next_wep)
        return ""
    elseif( str == "which_equipped" ) then
        local cur_wep = ga_get_i("xar.player.cur_wep")
        return tostring(cur_wep)
    elseif (str == "use_equipped primary start") then
        if( ga_get_b("xar.input.use_primary_uses_object") and
            ga_use_object_exists() )
        then
            ga_command("use")
            return ""
        else
            local gun = ga_get_i("xar.player.cur_wep")
            game_inv_exec.start_use(gun, true)
        end
        return ""
    elseif (str == "use_equipped primary stop") then
        game_inv_exec.end_use()
        return ""
    elseif (str == "use_equipped secondary start") then
        if( ga_get_b("xar.input.use_secondary_uses_object") and
            ga_use_object_exists() )
        then
            ga_command("use2")
            return ""
        end
        local gun = ga_get_i("xar.player.cur_wep")
        game_inv_exec.start_use(gun, false)
        return ""
    elseif (str == "use_equipped secondary stop") then
        game_inv_exec.end_use()
        return ""
    elseif (str == "open_window hud_1") then
        ga_command("set menu.in_package true")
        return ""
    elseif (str == "open_window hud_2") then
        if( not ga_genesis() ) then
            ga_window_push("win_stats2")
        end
        return ""
    elseif (str == "open_window hud_3") then
        if( not ga_genesis() ) then
            ga_window_push("win_stats3")
        end
        return ""
    elseif (str == "open_window hud_4") then
        if( not ga_genesis() ) then
            ga_window_push("win_stats4")
        end
        return ""
    elseif( str == "open_window hud_5" ) then
        ga_window_push("win_stats5")
        return ""
    elseif( str == "open_window hud_6" ) then
        ga_window_push("win_stats6")
        return ""
    elseif( str == "open_window hud_7" ) then
        ga_window_push("win_stats7")
        return ""
    elseif (str == "marker start") then
        if( not ga_get_b("xar.input.holding_drop_marker") ) then
            ga_set_f("xar.input.holding_drop_marker_start",
                ga_get_sys_f("game.time.total"))
        end
        ga_set_b("xar.input.holding_drop_marker", true)
        return ""
    elseif (str == "marker stop") then
        if ga_get_b("xar.input.holding_drop_marker") then
            game_drop_markers.drop_marker_short()
            ga_set_b("xar.input.holding_drop_marker", false)
        end
        return ""
    elseif (str == "telekinesis" ) then
        game_telekinesis.payload()
        return ""
    elseif( str:find("^wep_script_start") ~= nil ) then
        local wep_to_use = -1
        local mode = ""
        --Matching anything but a space.
        local i = 1
        for word in string.gmatch(str, "[^ ]+") do
            if i == 2 then
                wep_to_use = tonumber(word)
            end
            if i == 3 then
                mode = word
            end
            i = i + 1
        end
        --
        ga_set_b("xar.inv_exec.wep_script_in", true)
        local cur_wep = ga_get_i("xar.player.cur_wep")
        ga_set_i("xar.inv_exec.wep_script_last_wep", cur_wep)
        p.game_input("equip_from_screen_inv " .. tostring(wep_to_use))
        if mode == "primary" then p.game_input("use_equipped primary start") end
        if mode == "secondary" then p.game_input("use_equipped secondary start") end
        return ""
    elseif( str == "wep_script_stop" ) then
        if( ga_get_b("xar.inv_exec.wep_script_in") ) then
            local last_wep = ga_get_i("xar.inv_exec.wep_script_last_wep")
            -- ga_print("last_wep = " .. tostring(last_wep))
            -- ga_exit()
            if( last_wep >= 0 ) then
                p.game_input("equip_from_screen_inv " .. tostring(last_wep))
                ga_set_i("xar.inv_exec.wep_script_last_wep", -1)
            end
        end
        return ""
    elseif( str == "takeall") then
        game_cheats.takeall()
        return ""
    elseif (str == "giveall") then
        game_cheats.giveall()
        return ""
    elseif (str == "givegold" ) then
        game_cheats.givegold()
        return ""
    elseif (str == "giveupgrades0") then
        game_cheats.giveupgrades0()
        return ""
    elseif (str == "giveupgrades") then
        game_cheats.giveupgrades()
        return ""
    elseif (str == "giveupgrades2") then
        game_cheats.giveupgrades2()
        return ""
    elseif (str == "giveweaponmodes" ) then
        game_cheats.get_all_weapon_modes()
        return ""
    -- elseif (str == "givetrophies" ) then
        -- game_trophy.give_all_trophies()
        -- return ""
    elseif (str == "freemarkers") then
        game_cheats.freemarkers()
        return ""
    elseif (str == "topofworld") then
        game_cheats.topofworld()
        return ""
    elseif (str == "inf2" ) then
        local enabled = ga_get_b("xar.cheat.inf2.enabled")
        if( enabled ) then
            game_inf2.disable()
            ga_set_b("xar.cheat.inf2.enabled", false)
        else
            local worked = game_inf2.enable()
            if( worked ) then
                ga_set_b("xar.cheat.inf2.enabled", true)
                ga_console_print("^xff00ffLong live the game Infinifrag 2!")
            end
        end
        return ""
    elseif (str == "pink") then
        game_cheats.pink_tele()
        return ""
    elseif (str == "blue") then
        game_cheats.blue_tele()
        return ""
    elseif (str == "debug1" ) then
        ga_debug1()
        return ""
    end

    -- ga_console_print("^1Error: unknown string passed to game_input: ")
    -- ga_console_print(str)
    return "error"
end

function p.screen_inv_selected()
    return ga_get_i("xar.player.cur_wep")
end

function p.killed_player()
    ga_print("here in top.killed_player")
    ga_play_sound_menu("player_death")
end

function p.respawn_player(param)
    local keep_ammo = false
    if( param == "keepammo" ) then keep_ammo = true end

    ga_print("top.respawn_player begin")
    --

    if( ga_get_b("xar.difficulty.hardcore") ) then
        ga_set_sys_b("game.player.alive", false)
        return
    end

    ga_hud_window_remove("win_death")

    game_damage.clear_damage()

    local fixed_cost = 30

    if( keep_ammo ) then
        local respawn_cost = math.min(
            fixed_cost,
            game_respawn.get_keepammo_cost())
        local old_gold = ga_get_i("xar.player.gold.amount")
        local new_gold = old_gold - respawn_cost
        if new_gold < 0 then new_gold = 0 end
        ga_set_i("xar.player.gold.amount", new_gold)
    else
        ga_set_i("xar.player.health.amount",
            ga_get_i("xar.player.health.max"))
        ga_set_i("xar.player.shield.amount", 0)
        ga_set_i("xar.player.armor.amount", 0)
        game_remove_ammo.remove_ammo()
        ga_set_i("xar.player.gun1.ammo",
            game_wep_modes.get_ammo_max(1))
        ga_set_i("xar.player.gun0.ammo",
            game_wep_modes.get_ammo_max(0))
        --
        std.set_bydelta_i("xar.player.gold.amount", -fixed_cost)
        if ga_get_i("xar.player.gold.amount") < 0 then
            ga_set_i("xar.player.gold.amount", 0)
        end
    end
    ga_set_f("xar.key_time.yellow", -1.0)
    ga_set_f("xar.key_time.blue", -1.0)
    ga_set_f("xar.key_time.green", -1.0)
    ga_set_f("xar.key_time.universe", -1.0)

    ga_set_i("xar.player.markers.num_short", 0)

    ga_set_b("xar.first_life", false)

    ga_print("top.respawn_player end")
    ga_flush()
end
