Ragdoll physics without box2d

Here’s what I’ve come up with this morning, just a little test to see what’s possible but I need to improve my physics and I’d also like to see what others come up with for realistic movement and such.

function setup()
    --Movement point (the head in this case)
    mp = vec2(WIDTH/2,HEIGHT/2)
    --Movement point delta for additional velocity, not used at the moment
    mpdt = vec2()
    --Vector table for body points
    vtbl = {}
    vtbl[1] = vec2(0,0)--head
    vtbl[2] = vec2(0,-30)--pelvis
    vtbl[3] = vec2(5,-55)--right knee
    vtbl[4] = vec2(-5,-55)--left knee
    vtbl[5] = vec2(5,-75)--right foot
    vtbl[6] = vec2(-5,-75)--left foot
    vtbl[7] = vec2(0,-5)--shoulder joint
    vtbl[8] = vec2(5,-20)--right elbow 
    vtbl[9] = vec2(-5,-20)--left elbow
    vtbl[10] = vec2(5,-35)--right hand
    vtbl[11] = vec2(-5,-35)--left hand
    --Velocity table (if used)
    vel = {}
    --Point table for final positions of joints (table of points that gets drawn)
    p = {}
    --For all the joints create the table of velocity for each joint and the point of each joint
    for i = 1,#vtbl do
        vel[i] = vec2(0,0)
        p[i] = mp+vtbl[i]
    end
end

function touched(t)
    if t.state == BEGAN or t.state == MOVING then
        --Set body position
        mp = vec2(t.x,t.y)
        --Set velocity of joints
        --mpdt = vec2(t.deltaX,t.deltaY)/5
    end
    for i=1,#vtbl do
        if i > 1 then
            vel[i] = vel[i] + mpdt
        end
    end
end

function draw()
    
    background(0)
    --Set the gravity variable
    local grav = vec2(0,-0.1)
    --Localise table vtbl, call it v for the drawing
    local v = vtbl
    for i=1,#vtbl do
        vel[i] = vel[i] + grav*3
        vel[i] = vel[i] * 0.9
    end
    
    --Create and update all joint positions and create *bones*
    vtbl[1] = mp
    vtbl[2] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*30 + vel[2]
    vtbl[3] = vtbl[2]+(vtbl[3]-vtbl[2]):normalize()*25 + vel[3]
    vtbl[4] = vtbl[2]+(vtbl[4]-vtbl[2]):normalize()*25 + vel[4]
    vtbl[5] = vtbl[3]+(vtbl[5]-vtbl[3]):normalize()*20 + vel[5]
    vtbl[6] = vtbl[4]+(vtbl[6]-vtbl[4]):normalize()*20 + vel[6]
    vtbl[7] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*5 
    vtbl[8] = vtbl[7]+(vtbl[8]-vtbl[7]):normalize()*20 + vel[8]
    vtbl[9] = vtbl[7]+(vtbl[9]-vtbl[7]):normalize()*20 + vel[9]
    vtbl[10] = vtbl[8]+(vtbl[10]-vtbl[8]):normalize()*15 + vel[10]
    vtbl[11] = vtbl[9]+(vtbl[11]-vtbl[9]):normalize()*15 + vel[11]
    --Create spacing between elbows,hands and knees
    if vtbl[3]:dist(vtbl[4]) < 10 then 
        vtbl[3] = vtbl[3]+(vtbl[3]-vtbl[4]):normalize()*0.5
        vtbl[4] = vtbl[4]+(vtbl[4]-vtbl[3]):normalize()*0.5
    end
    if vtbl[9]:dist(vtbl[8]) < 20 then 
        vtbl[8] = vtbl[8]+(vtbl[8]-vtbl[9]):normalize()*0.5
        vtbl[9] = vtbl[9]+(vtbl[9]-vtbl[8]):normalize()*0.5
    end
    if vtbl[10]:dist(vtbl[11]) < 30 then 
        vtbl[10] = vtbl[10]+(vtbl[10]-vtbl[11]):normalize()*0.5
        vtbl[11] = vtbl[11]+(vtbl[11]-vtbl[10]):normalize()*0.5
    end
    --Draw the body
    strokeWidth(5)
    stroke(200,200,200,255)
    line(v[1].x,v[1].y,v[2].x,v[2].y)
    line(v[2].x,v[2].y,v[3].x,v[3].y)
    line(v[2].x,v[2].y,v[4].x,v[4].y)
    line(v[3].x,v[3].y,v[5].x,v[5].y)
    line(v[4].x,v[4].y,v[6].x,v[6].y)
    line(v[7].x,v[7].y,v[8].x,v[8].y)
    line(v[7].x,v[7].y,v[9].x,v[9].y)
    line(v[8].x,v[8].y,v[10].x,v[10].y)
    line(v[9].x,v[9].y,v[11].x,v[11].y)
    ellipse(v[1].x,v[1].y,20)
    
end

If you have any input on this then please share!

Also if I do this:

local v = vtbl
    for i=1,#vtbl do
        local vi = v[i]
        --if vi.x < 10 then vtbl[i].x = 10.1 elseif vi.x > WIDTH-10 then vtbl[i].x = WIDTH-10.1 elseif vi.y < 10 then vtbl[i].y = 10.1 elseif vi.y > HEIGHT-10 then vtbl[i].y = HEIGHT-10.1 end
        if vi.y < 20 then 
            vtbl[i].y = 20 
        else 
            vel[i] = vel[i] + grav*5 
            vel[i] = vel[i]*0.8 
        end
    end

This happens - http://youtu.be/coOwMUbcXo4
Anyone got any ideas?

Updated code:

function setup()
    --Movement point (the head in this case)
    mp = vec2(WIDTH/2,HEIGHT/2)
    --Movement point delta for additional velocity, not used at the moment
    mpdt = vec2()
    --Vector table for body points
    vtbl = {}
    vtbl[1] = vec2(WIDTH/2,HEIGHT/2)--head
    vtbl[2] = vec2(0,-30)--pelvis
    vtbl[3] = vec2(5,-55)--right knee
    vtbl[4] = vec2(-5,-55)--left knee
    vtbl[5] = vec2(5,-75)--right foot
    vtbl[6] = vec2(-5,-75)--left foot
    vtbl[7] = vec2(0,-5)--shoulder joint
    vtbl[8] = vec2(5,-20)--right elbow 
    vtbl[9] = vec2(-5,-20)--left elbow
    vtbl[10] = vec2(5,-35)--right hand
    vtbl[11] = vec2(-5,-35)--left hand
    --Velocity table (if used)
    vel = {}
    --Point table for final positions of joints (table of points that gets drawn)
    p = {}
    --For all the joints create the table of velocity for each joint and the point of each joint
    for i = 1,#vtbl do
        vel[i] = vec2(0,0)
        p[i] = mp+vtbl[i]
    end
    td = nil
end

function touched(t)
    mp = vec2(t.x,t.y)
    td = t
    if t.state == ENDED then
        td = nil 
    end
end

function draw()
    
    background(0)
    --Set the gravity variable
    local grav = vec2(0,-0.1)
    --Localise table vtbl, call it v for the drawing
    local v = vtbl
    if td ~= nil then
        vel[1] = vel[1] + (mp-v[1]):normalize()*(vec2(td.x,td.y):dist(v[1])/40)
        vel[1] = vel[1] * 0.85
    else
        if v[1].y < 10 then
            v[1].y = 10
            vel[1] = vec2()
        else
            vel[1] = vel[1] + grav*5
        end
        vel[1] = vec2(vel[1].x*0.93,vel[1].y*0.95)
    end
    
    --Create spacing between elbows,hands and knees
    if vtbl[3]:dist(vtbl[4]) < 15 then 
        vtbl[3] = vtbl[3]+(vtbl[3]-vtbl[4]):normalize()*1
        vtbl[4] = vtbl[4]+(vtbl[3]-vtbl[4]):normalize()*-1
        vel[3] = vel[3]+grav
        vel[4] = vel[4]+grav
    end
    if vtbl[9]:dist(vtbl[8]) < 15 then 
        vtbl[8] = vtbl[8]+(vtbl[8]-vtbl[9]):normalize()*1
        vtbl[9] = vtbl[9]+(vtbl[8]-vtbl[9]):normalize()*-1
        vel[8] = vel[8]+grav
        vel[9] = vel[9]+grav
    end
    if vtbl[10]:dist(vtbl[11]) < 20 then 
        vtbl[10] = vtbl[10]+(vtbl[10]-vtbl[11]):normalize()*1
        vtbl[11] = vtbl[11]+(vtbl[10]-vtbl[11]):normalize()*-1
        vel[10] = vel[10]+grav
        vel[11] = vel[11]+grav
    end
    for i=1,#vtbl do
        local vi = v[i]
        if i > 1 then
            if vi.y < 10 then
                vtbl[i].y = 10
                vel[i] = vel[i] + vec2(0,0.1)
            else
                vel[i] = vel[i] + grav*5 
                vel[i] = vel[i]*0.85
            end
        end
    end
    
    --Create and update all joint positions and create *bones*
    vtbl[1] = vtbl[1] + vel[1] 
    vtbl[2] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*30 + vel[2]
    vtbl[3] = vtbl[2]+(vtbl[3]-vtbl[2]):normalize()*25 + vel[3]
    vtbl[4] = vtbl[2]+(vtbl[4]-vtbl[2]):normalize()*25 + vel[4]
    vtbl[5] = vtbl[3]+(vtbl[5]-vtbl[3]):normalize()*20 + vel[5]
    vtbl[6] = vtbl[4]+(vtbl[6]-vtbl[4]):normalize()*20 + vel[6]
    vtbl[7] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*5 
    vtbl[8] = vtbl[7]+(vtbl[8]-vtbl[7]):normalize()*20 + vel[8]
    vtbl[9] = vtbl[7]+(vtbl[9]-vtbl[7]):normalize()*20 + vel[9]
    vtbl[10] = vtbl[8]+(vtbl[10]-vtbl[8]):normalize()*15 + vel[10]
    vtbl[11] = vtbl[9]+(vtbl[11]-vtbl[9]):normalize()*15 + vel[11]
    --Draw the body
    strokeWidth(5)
    stroke(200,200,200,255)
    line(v[1].x,v[1].y,v[2].x,v[2].y)
    line(v[2].x,v[2].y,v[3].x,v[3].y)
    line(v[2].x,v[2].y,v[4].x,v[4].y)
    line(v[3].x,v[3].y,v[5].x,v[5].y)
    line(v[4].x,v[4].y,v[6].x,v[6].y)
    line(v[7].x,v[7].y,v[8].x,v[8].y)
    line(v[7].x,v[7].y,v[9].x,v[9].y)
    line(v[8].x,v[8].y,v[10].x,v[10].y)
    line(v[9].x,v[9].y,v[11].x,v[11].y)
    ellipse(v[1].x,v[1].y,20)
    
end

Video: http://youtu.be/rMosBUyyvhU

Interesting. I’m definitely gonna make some time to play around with this… maybe move it to a class so I can have multiple ragdolls at once…

Yeah I was thinking the same thing once I got better physics

Boy, that little dude in your video is going to have a sore head!

Nice work…

Great job @Luatee. Makes me want to play Ragdoll Masters now.

@Luatee, very cool! For some reason, this made me think of a game where you have to get as close to the ground as possible without touching it… So I took your code and modified it a bit to make that :slight_smile: Hope you don’t mind. Here’s the code



--# Main
function setup()
    Game:init()
end

function touched(t)
    if dead then
        Dead:touched(touch)
    elseif roundend then
        Won:touched(touch)
    else Game:touched(t)
    end
end

function draw()
    if dead then
        Dead:draw()
    elseif roundend then
        Won:draw()
    else Game:draw()
    end
end
    
--# Dead
Dead = class()

function Dead:init(x)
    -- you can accept and set parameters here
    self.x = x
end

function Dead:draw()
    -- Codea does not automatically call this method
    background(0)
    
    text("You failed! Tap to reset.", WIDTH/2, HEIGHT/2)
end

function Dead:touched(touch)
    -- Codea does not automatically call this method
    Game:init()
    dead = false
end

--# Game
Game = class()

function Game:init()
    --Movement point (the head in this case)
    mp = vec2(WIDTH/2,HEIGHT/2)
    lowest = WIDTH/2
    
    --Movement point delta for additional velocity, not used at the moment
    mpdt = vec2()
    --Vector table for body points
    vtbl = {}
    vtbl[1] = vec2(WIDTH/2,HEIGHT/2)--head
    vtbl[2] = vec2(0,-30)--pelvis
    vtbl[3] = vec2(5,-55)--right knee
    vtbl[4] = vec2(-5,-55)--left knee
    vtbl[5] = vec2(5,-75)--right foot
    vtbl[6] = vec2(-5,-75)--left foot
    vtbl[7] = vec2(0,-5)--shoulder joint
    vtbl[8] = vec2(5,-20)--right elbow 
    vtbl[9] = vec2(-5,-20)--left elbow
    vtbl[10] = vec2(5,-35)--right hand
    vtbl[11] = vec2(-5,-35)--left hand
    --Velocity table (if used)
    vel = {}
    --Point table for final positions of joints (table of points that gets drawn)
    p = {}
    --For all the joints create the table of velocity for each joint and the point of each joint
    for i = 1,#vtbl do
        vel[i] = vec2(0,0)
        p[i] = mp+vtbl[i]
    end
    td = nil
end

function Game:touched(t)
    mp = vec2(WIDTH/2 + (math.random (-1, 1)),t.y)
    td = t
    if t.state == ENDED then
        td = nil 
    end
end

function Game:draw()
    fill(193, 193, 193, 255)
    
    background(0)
    
    --Set the gravity variable
    if roundend then
        grav = vec2(0,0)
    else grav = vec2(0,-0.1)
    end
 
    --Localise table vtbl, call it v for the drawing
    local v = vtbl
    if td ~= nil then
        vel[1] = vel[1] + (mp-v[1]):normalize()*(vec2(td.x,td.y):dist(v[1])/40)
        vel[1] = vel[1] * 0.85
    else
        if v[1].y < 10 then
            v[1].y = 10
            vel[1] = vec2()
        else
            vel[1] = vel[1] + grav*5
        end
        vel[1] = vec2(vel[1].x*0.93,vel[1].y*0.95)
    end

    --Create spacing between elbows,hands and knees
    if vtbl[3]:dist(vtbl[4]) < 15 then 
        vtbl[3] = vtbl[3]+(vtbl[3]-vtbl[4]):normalize()*1
        vtbl[4] = vtbl[4]+(vtbl[3]-vtbl[4]):normalize()*-1
        vel[3] = vel[3]+grav
        vel[4] = vel[4]+grav
    end
    if vtbl[9]:dist(vtbl[8]) < 15 then 
        vtbl[8] = vtbl[8]+(vtbl[8]-vtbl[9]):normalize()*1
        vtbl[9] = vtbl[9]+(vtbl[8]-vtbl[9]):normalize()*-1
        vel[8] = vel[8]+grav
        vel[9] = vel[9]+grav
    end
    if vtbl[10]:dist(vtbl[11]) < 20 then 
        vtbl[10] = vtbl[10]+(vtbl[10]-vtbl[11]):normalize()*1
        vtbl[11] = vtbl[11]+(vtbl[10]-vtbl[11]):normalize()*-1
        vel[10] = vel[10]+grav
        vel[11] = vel[11]+grav
    end
    for i=1,#vtbl do
        local vi = v[i]
        if i > 1 then
            if vi.y < 10 then
                vtbl[i].y = 10
                vel[i] = vel[i] + vec2(0,0.1)
            else
                vel[i] = vel[i] + grav*5 
                vel[i] = vel[i]*0.85
            end
        end
    end

    --Create and update all joint positions and create *bones*
    vtbl[1] = vtbl[1] + vel[1] 
    vtbl[2] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*30 + vel[2]
    vtbl[3] = vtbl[2]+(vtbl[3]-vtbl[2]):normalize()*25 + vel[3]
    vtbl[4] = vtbl[2]+(vtbl[4]-vtbl[2]):normalize()*25 + vel[4]
    vtbl[5] = vtbl[3]+(vtbl[5]-vtbl[3]):normalize()*20 + vel[5]
    vtbl[6] = vtbl[4]+(vtbl[6]-vtbl[4]):normalize()*20 + vel[6]
    vtbl[7] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*5 
    vtbl[8] = vtbl[7]+(vtbl[8]-vtbl[7]):normalize()*20 + vel[8]
    vtbl[9] = vtbl[7]+(vtbl[9]-vtbl[7]):normalize()*20 + vel[9]
    vtbl[10] = vtbl[8]+(vtbl[10]-vtbl[8]):normalize()*15 + vel[10]
    vtbl[11] = vtbl[9]+(vtbl[11]-vtbl[9]):normalize()*15 + vel[11]
    --Draw the body
    strokeWidth(5)
    stroke(200,200,200,255)
    line(v[1].x,v[1].y,v[2].x,v[2].y)
    line(v[2].x,v[2].y,v[3].x,v[3].y)
    line(v[2].x,v[2].y,v[4].x,v[4].y)
    line(v[3].x,v[3].y,v[5].x,v[5].y)
    line(v[4].x,v[4].y,v[6].x,v[6].y)
    line(v[7].x,v[7].y,v[8].x,v[8].y)
    line(v[7].x,v[7].y,v[9].x,v[9].y)
    line(v[8].x,v[8].y,v[10].x,v[10].y)
    line(v[9].x,v[9].y,v[11].x,v[11].y)
    ellipse(v[1].x,v[1].y,20)
    
    --[[
    for that = 1, 11 do 
        print(that.. ":  ".. v[that].y)
    end
    --]]
    
    if v[1].y <= 11 then
        dead = true
        print("dead af")
    end
    
    print(v[1].y)
    
    if v[1].y < lowest then
        lowest = v[1].y
    end
    
    plowest = math.floor(lowest/10)
    
    if v[1].y > 500 then
        roundend = true
    end
    
    if roundend then
        v[1].y = 500
        print(plowest)
    end
    
    line(0, 500, WIDTH, 500)
    fill(255, 255, 255, 255)
    fontSize(20)
    text("Reach the line to submit your fall", WIDTH/2, 700)
end
    

--# Won
Won = class()

function Won:init(x)
    -- you can accept and set parameters here
    self.x = x
end

function Won:draw()
    -- Codea does not automatically call this method
    background(0)
    
    text("Congratulations! Your score was: ".. plowest, WIDTH/2, HEIGHT/1.8)
    text("(Lower score is better)", WIDTH/2, HEIGHT/2)
    text("Tap to reset", WIDTH/2, HEIGHT/2.2)
end

function Won:touched(touch)
    -- Codea does not automatically call this method
    Game:init()
    roundend = false
end

Definitely not the best way to do it, but it works and its fun.

Gameplay is simple: You are falling and you tap higher up to go up. You want to come as close as the ground as possible without hitting it.

Here’s it with the ragdoll quickly converted to a class, now it has 20 ragdolls randomly placed at the start. Looks nice, but at 20 it slows down quite a bit…

Interestingly, the slow down is drawing, not the maths… if you comment out the draw, but calculate the movement it’s still 60 fps… so it’s the slow line performance in Codea… added noSmooth() to speed it up which takes it up to 45fps or so.



--# Main
function setup()
    --Set the gravity variable
    grav = vec2(0,-0.1)
    
    dolls = {}
    for i=1,20 do
        table.insert(dolls, RagDoll(math.random(WIDTH), math.random(HEIGHT)))
    end
end

function touched(t)
    for k,v in ipairs(dolls) do
        v.mp = vec2(t.x,t.y)
        v.td = t
        if t.state == ENDED then
            v.td = nil 
        end
    end
end

function draw()
    noSmooth()
    background(0)
    --Draw the body
    for k,v in ipairs(dolls) do
        v:move()
        v:draw()
    end
end
--# RagDoll
RagDoll = class()

function RagDoll:init(x,y)
    --Movement point (the head in this case)
    self.mp = vec2(x,y)
    --Movement point delta for additional velocity, not used at the moment
    self.mpdt = vec2()
    --Vector table for body points
    self.vtbl = {}
    self.vtbl[1] = vec2(x,y)--head
    self.vtbl[2] = vec2(0,-30)--pelvis
    self.vtbl[3] = vec2(5,-55)--right knee
    self.vtbl[4] = vec2(-5,-55)--left knee
    self.vtbl[5] = vec2(5,-75)--right foot
    self.vtbl[6] = vec2(-5,-75)--left foot
    self.vtbl[7] = vec2(0,-5)--shoulder joint
    self.vtbl[8] = vec2(5,-20)--right elbow 
    self.vtbl[9] = vec2(-5,-20)--left elbow
    self.vtbl[10] = vec2(5,-35)--right hand
    self.vtbl[11] = vec2(-5,-35)--left hand
    --Velocity table (if used)
    self.vel = {}
    --Point table for final positions of joints (table of points that gets drawn)
    self.p = {}
    --For all the joints create the table of velocity for each joint and the point of each joint
    for i = 1,#self.vtbl do
        self.vel[i] = vec2(0,0)
        self.p[i] = self.mp+self.vtbl[i]
    end
    self.td = nil
end

function RagDoll:draw()
    --Draw the body
    local v = self.vtbl
    strokeWidth(5)
    stroke(200,200,200,255)
    line(v[1].x,v[1].y,v[2].x,v[2].y)
    line(v[2].x,v[2].y,v[3].x,v[3].y)
    line(v[2].x,v[2].y,v[4].x,v[4].y)
    line(v[3].x,v[3].y,v[5].x,v[5].y)
    line(v[4].x,v[4].y,v[6].x,v[6].y)
    line(v[7].x,v[7].y,v[8].x,v[8].y)
    line(v[7].x,v[7].y,v[9].x,v[9].y)
    line(v[8].x,v[8].y,v[10].x,v[10].y)
    line(v[9].x,v[9].y,v[11].x,v[11].y)
    ellipse(v[1].x,v[1].y,20)

end

function RagDoll:move()
    local vel = self.vel
    local mp = self.mp
    local v = self.vtbl
    local td = self.td
    local vtbl = self.vtbl
    
    if td ~= nil then
        vel[1] = vel[1] + (mp-v[1]):normalize()*(vec2(td.x,td.y):dist(v[1])/40)
        vel[1] = vel[1] * 0.85
    else
        if v[1].y < 10 then
            v[1].y = 10
            vel[1] = vec2()
        else
            vel[1] = vel[1] + grav*5
        end
        vel[1] = vec2(vel[1].x*0.93,vel[1].y*0.95)
    end

    --Create spacing between elbows,hands and knees
    if vtbl[3]:dist(vtbl[4]) < 15 then 
        vtbl[3] = vtbl[3]+(vtbl[3]-vtbl[4]):normalize()*1
        vtbl[4] = vtbl[4]+(vtbl[3]-vtbl[4]):normalize()*-1
        vel[3] = vel[3]+grav
        vel[4] = vel[4]+grav
    end
    if vtbl[9]:dist(vtbl[8]) < 15 then 
        vtbl[8] = vtbl[8]+(vtbl[8]-vtbl[9]):normalize()*1
        vtbl[9] = vtbl[9]+(vtbl[8]-vtbl[9]):normalize()*-1
        vel[8] = vel[8]+grav
        vel[9] = vel[9]+grav
    end
    if vtbl[10]:dist(vtbl[11]) < 20 then 
        vtbl[10] = vtbl[10]+(vtbl[10]-vtbl[11]):normalize()*1
        vtbl[11] = vtbl[11]+(vtbl[10]-vtbl[11]):normalize()*-1
        vel[10] = vel[10]+grav
        vel[11] = vel[11]+grav
    end
    for i=1,#vtbl do
        local vi = v[i]
        if i > 1 then
            if vi.y < 10 then
                vtbl[i].y = 10
                vel[i] = vel[i] + vec2(0,0.1)
            else
                vel[i] = vel[i] + grav*5 
                vel[i] = vel[i]*0.85
            end
        end
    end

    --Create and update all joint positions and create *bones*
    vtbl[1] = vtbl[1] + vel[1] 
    vtbl[2] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*30 + vel[2]
    vtbl[3] = vtbl[2]+(vtbl[3]-vtbl[2]):normalize()*25 + vel[3]
    vtbl[4] = vtbl[2]+(vtbl[4]-vtbl[2]):normalize()*25 + vel[4]
    vtbl[5] = vtbl[3]+(vtbl[5]-vtbl[3]):normalize()*20 + vel[5]
    vtbl[6] = vtbl[4]+(vtbl[6]-vtbl[4]):normalize()*20 + vel[6]
    vtbl[7] = vtbl[1]+(vtbl[2]-vtbl[1]):normalize()*5 
    vtbl[8] = vtbl[7]+(vtbl[8]-vtbl[7]):normalize()*20 + vel[8]
    vtbl[9] = vtbl[7]+(vtbl[9]-vtbl[7]):normalize()*20 + vel[9]
    vtbl[10] = vtbl[8]+(vtbl[10]-vtbl[8]):normalize()*15 + vel[10]
    vtbl[11] = vtbl[9]+(vtbl[11]-vtbl[9]):normalize()*15 + vel[11]
end

function RagDoll:touched(touch)
    -- Codea does not automatically call this method
end

Thanks guys, I thought I might aswell no ones tried it yet, the maths for the ragdoll at the moment is pretty simple, the only thing that I think would slow it down would be the indexing of tables all the time and the drawing of lines, I might recreate it when im home as that was a pretty quick mock up of what I wanted to achieve, but it works none the less, thanks for the comments and feel free to use it however you want. Im thinking of adding dismemberment once rewritten