function p.update_discrete()
    --cur_time = ga_get_sys_f("game.time.total")
    local old_moving_in_plane = ga_get_b("var.movement.moving_in_plane")
    local new_moving_in_plane = old_moving_in_plane --Needs to be updated!
    local old_in_air = ga_get_b("var.movement.in_air")
    local new_in_air = old_in_air --Needs to be updated!
    local old_crouching = ga_get_b("var.movement.crouching")
    local new_crouching = old_crouching --Needs to be updated!

    --Seeing if in an alternate mode.
    local cur_move_mode = ga_get_s("var.movement.mod")
    if( cur_move_mode ~= "normal" ) then
        p.update_discrete_alternate()
        return
    end

    --This is the one used by the engine.
    local time_step = 0.04
    
    --If stating on something
    --(and if so, can jump,
    --there is more drag,
    --there is more acceleration).
    local on_sure_footing = ga_move_get_on_sure_footing()

    --Setting drag and magnitude of acceleration.
    local primary_speed_cutoff = 6.0 --not needed

    -------------------------------------------
    --          Crouch and Uncrouching
    -------------------------------------------

    if ga_get_b("var.movement.wants_to_crouch") then
        local tele = std.vec_zero()
        local new_radius     = ga_get_f("var.body.crouch.radius")
        local new_bot_to_eye = ga_get_f("var.body.crouch.bot_to_eye")
        local new_eye_to_top = ga_get_f("var.body.crouch.eye_to_top")
        local worked = ga_move_set_body_ground(
            tele, new_radius,
            new_bot_to_eye,
            new_eye_to_top)

        if worked then
            --Now is crouching.
            ga_set_b("var.movement.wants_to_crouch", false)
            local new_crouching = true
            ga_set_b("var.movement.crouching", new_crouching)
            if( old_moving_in_plane ) then
                --Crouching while moving in the XY plane.
                ga_player_model_q2md2_set_cmd("crwalk")
            else
                --Crouching while still.
                ga_player_model_q2md2_set_cmd("crstand")
            end
        end
    end

    if ga_get_b("var.movement.wants_to_uncrouch") then
        --Normal   bot_to_eye = 1.3
        --Crouched bot_to_eye = 0.6
        --Difference = 0.7
        --So, z must be translated up by 0.7.
        local tele = std.vec(0.0, 0.0, 0.7)
        local new_radius     = ga_get_f("var.body.normal.radius")
        local new_bot_to_eye = ga_get_f("var.body.normal.bot_to_eye")
        local new_eye_to_top = ga_get_f("var.body.normal.eye_to_top")
        local worked = ga_move_set_body_ground(
            tele, new_radius,
            new_bot_to_eye,
            new_eye_to_top)

        if worked then
            --Now is no longer crouching.
            ga_set_b("var.movement.wants_to_uncrouch", false)
            local new_crouching = false
            ga_set_b("var.movement.crouching", new_crouching)
            if( old_moving_in_plane ) then
                --Unrouching while moving in the XY plane.
                ga_player_model_q2md2_set_cmd("run")
            else
                --Unrouching while still.
                ga_player_model_q2md2_set_cmd("stand")
            end
        end
    end

    -------------------------------------------
    --                Momentum
    -------------------------------------------
    -- May modify later.

    local momentum = ga_get_sys_v("game.player.move.last_pos_diff")

    -------------------------------------------
    --             "Acceleration"
    -------------------------------------------

    --Getting the acc due to pressing keys.
    local vec_look = ga_get_sys_v("game.player.camera.look")
    --vec_up   = ga_get_sys_v("game.player.camera.up")
    local vec_left = ga_get_sys_v("game.player.camera.left")

    local plane_look = {}
    plane_look.x = vec_look.x
    plane_look.y = vec_look.y
    plane_look.z = 0.0
    std.normalize(plane_look)

    local plane_left = {}
    plane_left.x = vec_left.x
    plane_left.y = vec_left.y
    plane_left.z = 0.0

    local new_moving_in_plane = false
    local plane_acc = {x=0.0, y=0.0, z=0.0}
    if ga_get_b("var.movement.forward") then
        plane_acc.x = plane_acc.x + plane_look.x
        plane_acc.y = plane_acc.y + plane_look.y
        ga_player_model_set_look()
        new_moving_in_plane = true
        --plane_acc.z = plane_acc.z + plane_look.z
    end
    if ga_get_b("var.movement.back") then
        plane_acc.x = plane_acc.x - plane_look.x
        plane_acc.y = plane_acc.y - plane_look.y
        ga_player_model_set_look()
        new_moving_in_plane = true
        --plane_acc.z = plane_acc.z - plane_look.z
    end
    if ga_get_b("var.movement.left") then
        plane_acc.x = plane_acc.x + plane_left.x
        plane_acc.y = plane_acc.y + plane_left.y
        ga_player_model_set_look()
        new_moving_in_plane = true
        --plane_acc.z = plane_acc.z + plane_left.z
    end
    if ga_get_b("var.movement.right") then
        plane_acc.x = plane_acc.x - plane_left.x
        plane_acc.y = plane_acc.y - plane_left.y
        ga_player_model_set_look()
        new_moving_in_plane = true
        --plane_acc.z = plane_acc.z - plane_left.z
    end
    ga_set_b("var.movement.moving_in_plane", new_moving_in_plane)

    --Normalizing plane_acc vector.
    if ( std.length(plane_acc) < 0.0001 ) then
        plane_acc = {x=0.0, y=0.0, z=0.0}
    else
        std.normalize(plane_acc)
    end

    --Shrinking planer acc if not on sure footing.
    if not on_sure_footing then
        local air_control = 0.1
        plane_acc.x = plane_acc.x * air_control
        plane_acc.y = plane_acc.y * air_control
        --plane_acc.z = plane_acc.z * air_control
    end

    --The "acceleration."
    local acc = {x=0.0, y=0.0, z=0.0}

    --Setting plane compoent of acc.
    local speed_mod = 0.07 --magic number.
    acc.x = plane_acc.x * speed_mod
    acc.y = plane_acc.y * speed_mod

    if( new_crouching ) then
        if( new_moving_in_plane and not old_moving_in_plane ) then
            if( not old_in_air ) then
                ga_player_model_q2md2_set_cmd("crwalk")
            end
        end
        --
        if( not new_moving_in_plane and old_moving_in_plane ) then
            if( not old_in_air ) then
                ga_player_model_q2md2_set_cmd("crstand")
            end
        end
    else
        if( new_moving_in_plane and not old_moving_in_plane ) then
            if( not old_in_air ) then
                ga_player_model_q2md2_set_cmd("run")
            end
        end
        --
        if( not new_moving_in_plane and old_moving_in_plane ) then
            if( not old_in_air ) then
                ga_player_model_q2md2_set_cmd("stand")
            end
        end
    end

    --Q2MD2 animation command for being in air.
    if( not on_sure_footing and not old_in_air )
    then
        ga_player_model_q2md2_set_cmd("jump_up")
        local new_in_air = true
        ga_set_b("var.movement.in_air", new_in_air)
    end

    --Q2MD2 animating command for landing form the air.
    if( on_sure_footing and old_in_air )
    then
        ga_player_model_q2md2_set_cmd("jump_down")
        local new_in_air = false
        ga_set_b("var.movement.in_air", new_in_air)
    end

    --Q2MD2 State.
    if( new_crouching ) then
        if( new_moving_in_plane ) then
            ga_player_model_q2md2_set_state("crouch_run")
        else
            ga_player_model_q2md2_set_state("crouch")
        end
    else
        if( new_moving_in_plane ) then
            ga_player_model_q2md2_set_state("run")
        else
            ga_player_model_q2md2_set_state("")
        end
    end

    --Setting the z component of acc.
    --Jumping.
    if ga_get_b("var.movement.jump") then
        if on_sure_footing then
            --Actually jumping.
            momentum.z = 0.0
            acc.z = 0.225
        end
        ga_set_b("var.movement.jump", false)
    end

    --Gravity.
    local gravity = 0.0
    if ga_get_b("var.physics.low_gravity") then
        gravity = 0.005
    else
        gravity = 0.02
    end
    acc.z = acc.z - gravity

    -------------------------------------------
    -- Incorporating Last Position Difference
    -------------------------------------------

    --Drag
    local air_drag = 0.995
    local ground_drag = 0.0
    if on_sure_footing then
        ground_drag = 0.8
    else
        ground_drag = 0.98
    end

    --("scaled momentum").
    local sm = {}
    sm.x = momentum.x * ground_drag
    sm.y = momentum.y * ground_drag
    sm.z = momentum.z * air_drag

    --Setting the travel.
    local travel = {}
    travel.x = sm.x + acc.x
    travel.y = sm.y + acc.y
    travel.z = sm.z + acc.z

    -------------------------------------------
    --              Ledge Guards
    -------------------------------------------

    ga_move_set_ledge_guards(
        ga_get_b("var.movement.ledge_guard"))

    -------------------------------------------
    -- Telling the Engine to Perform the Travel
    -------------------------------------------

    ga_move_set_desired_travel(travel)
end

function p.update_discrete_alternate()
    local mode = ga_get_s("var.movement.mod")

    if  mode == "ladder_x_pos" or
        mode == "ladder_x_neg" or
        mode == "ladder_y_pos" or
        mode == "ladder_y_neg"
    then
        --It would not be hard to multiply lad_up
        --by -1 if the viewer is looking down, etc.
        local lad_up = {x=0.0, y=0.0, z=0.3}
        local lad_left = std.vec(0.0, 0.0, 0.0)
        local lad_off = std.vec(0.0, 0.0, 0.0)

        if mode == "ladder_x_pos" then
            lad_left = {x=0.0, y=0.03, z=0.0}
            lad_off = {x=-0.2, y=0.0, z=0.0}
        end
        if mode == "ladder_x_neg" then
            lad_left = {x=0.0, y=-0.03, z=0.0}
            lad_off = {x=0.2, y=0.0, z=0.0} 
        end
        if mode == "ladder_y_pos" then
            lad_left = {x=-0.03, y=0.0, z=0.0}
            lad_off = {x=0.0, y=-0.2, z=0.0}
        end
        if mode == "ladder_y_neg" then
            lad_left = {x=0.03, y=0.0, z=0.0}
            lad_off = {x=0.0, y=0.2, z=0.0} 
        end

        --Inverting the movement vectors based on
        --where the player is facing.
        local vec_look = ga_get_sys_v("game.player.camera.look")
        if vec_look.z < 0.0 then
            lad_up.x = lad_up.x * (-1.0)
            lad_up.y = lad_up.y * (-1.0)
            lad_up.z = lad_up.z * (-1.0)
        end
        if  (mode == "ladder_x_pos" and vec_look.x < 0.0) or
            (mode == "ladder_x_neg" and vec_look.x > 0.0) or
            (mode == "ladder_y_pos" and vec_look.y < 0.0) or
            (mode == "ladder_y_neg" and vec_look.y > 0.0)
        then
            lad_left.x = lad_left.x * (-1.0)
            lad_left.y = lad_left.y * (-1.0)
            lad_left.z = lad_left.z * (-1.0)
        end

        local travel = {x = 0.0, y = 0.0, z = 0.0}

        if ga_get_b("var.movement.forward") then
            travel.x = travel.x + lad_up.x
            travel.y = travel.y + lad_up.y
            travel.z = travel.z + lad_up.z
        end
        if ga_get_b("var.movement.back") then
            travel.x = travel.x - lad_up.x
            travel.y = travel.y - lad_up.y
            travel.z = travel.z - lad_up.z
        end
        if ga_get_b("var.movement.left") then
            travel.x = travel.x + lad_left.x
            travel.y = travel.y + lad_left.y
            travel.z = travel.z + lad_left.z
        end
        if ga_get_b("var.movement.right") then
            travel.x = travel.x - lad_left.x
            travel.y = travel.y - lad_left.y
            travel.z = travel.z - lad_left.z
        end
        if ga_get_b("var.movement.jump") then
            travel.x = travel.x + lad_off.x
            travel.y = travel.y + lad_off.y
            travel.z = travel.z + lad_off.z
        end

        ga_move_set_desired_travel(travel)
    else
        ga_print("*** Error: unknown movement mode found: " .. mode)
        ga_exit()
    end
end
