Simple 3D FPS movement demo (moonlit cabin in the woods)

Hi, Everyone.

I’m interested in creating 3D FPS type apps and made this simple demo to help others who are also interested in the same. It’s based on @John ’s OrbitViewer dependency and knowledge learned from others on this forum and adds keyboard input This demo uses free model downloaded from (choose .obj format when download—unable to attach to this post as forum disallows attaching .obj models). You may choose your own assets to substitute (if so, remember to change asset.documents statements to point to your assets).

Good luck! :slight_smile:

– 3D FPS demo
function setup()
viewer.mode = FULLSCREEN

-- need to enable keyboard with below command to get input (even if use external keyboard)

-- Create a new craft scene
scene = craft.scene()

-- skybox (developers special function for-- really a box around scene painted inside with a cross format map texture)
-- *Note: grimmnight texture free download (per download site to be credited to "Hipshot" at = craft.cubeTexture(asset.documents.grimmnight_large)

-- Create a ground entity from primitives
-- *Note: "forest-floor-terrain" free download from
Ground = scene:entity()
Ground.model = craft.model.cube(vec3(1.2,0.01,1.2))
Ground.material = craft.material(asset.builtin.Materials.Basic) = readImage(asset.documents["forest-floor-terrain.jpg"])

-- import 3D model of house(.obj format) from document folder in Codea
-- *Note: "old_house" model and "wood" texture are free downloads from TurboSquid website
House = scene:entity()
House.model = craft.model(asset.documents.old_house)
House.material = craft.material(asset.builtin.Materials.Basic) = readImage(asset.documents.wood_D_jpeg)
-- *Next line rotates the house 180 degrees around y axis so will later line up with moon in sky
House.eulerAngles = vec3(0, 180, 0)
House.scale = vec3(0.005,0.005,0.005)

-- Link "Cameras" dependency to this project; contains OrbitViewer class that you can add to camera to zoom and pan around an object in the scene (syntax: add(OrbitViewer, TargetModelToLookAt, startingZoomDistanceAwayFromTarget(e.g. 10 = -10 z units from Target), minimumZoomDistanceAwayFromTarget (e.g. with - value can actually focus in past target), maximumZoomDistanceAwayFromTarget)
-- Helps to assign OrbitViewer camera to a variable so can set its properties (e.g. v)
v =, House.position, 10, -2, 20)
-- *Next line rotates the camere 180 around y axis so when program runs camera looks at front of cabin and moon in sky
v.ry = 180

function update(dt)
    -- Update the scene (physics, transforms etc)

function draw() 
    --update then draw 3D "scene"

function keyboard(key)
    -- this function detects keyboard input and then stepwise moves the OrbitViewer camera in 3D space 
    -- function moves the camera; object moves opposite way so set up FPS perspective (i/j/k/l/u/m=fwd/l/back/r/up/dwn)
    -- rx = rotate around x axis (changes y); ry = rotate around y axis (changes x)
    -- control speed of movement by changing constant value to add to viewer position (v) when move
    -- *Note: this function adds to OrbitViewers built in screen touch panning (finger movement) and zooming (pinching)     
        if key == "i" then v.zoom = v.zoom -0.5
        elseif key == "j" then v.ry = v.ry - 1
        elseif key == "k" then v.zoom = v.zoom + 0.5
        elseif key == "l" then v.ry = v.ry + 1
        elseif key == "u" then v.rx = v.rx + 1
        elseif key == "m" then v.rx = v.rx -1


@SugarRay - very atmospheric demo. Neat. Thanks

You’re welcome, @Bri_G. Thanks for checking it out! :slight_smile:

Perfect for beginners to learn the craft!

Great :slight_smile: