The Final Frontier

Hi All,

That’s a well used phrase (the title I mean) but it is generally related to Space. Since I got my first iPad I have been playing around trying to learn how to emulate publicised games - mainly classics. One of which is Elite, published in 1984. That was a game changer for the gaming industry. Now, with the help of Craft I can pay a little homage to it - hopefully with more to follow.

I have posted previously showing my interest and had some help from @TechDojo. But for now I have posted a website with a video - a homage to the original BBC Micro Elite and the two geniuses who wrote it.

Elite Homage

Hope you like it.

Edit: Hi all, been messing about with the HTML on the website, just noticed video not loading. Edited and works now but you need double tap the grey box to get the video running. May have to move to YouTube if this gets messy.

Edit2: Modified the web page to get a better link to the video. Also edited a few ‘English’ errors. I suggest you boost the video up to full screen and - when you can see the rotating ships you may recognise something in the top left and bottom left. Forgot to remove them - need to edit them out.

All,

Just tidy up the code and I’ll post later. Also will post the next vid when I can get the ships sorted out.

All,

Here is modified code using the assets available to all Codea users. The only thing you need to do is save the attached blackboard skybox images (just a simple black screen!!!) to somewhere convenient to you and set up the ‘galaxy’ path to that file. You can either tap the screen to change the model or use the parameter slider and the load button to change the model. Note some of these are legless character images. Code below, mostly extracted from the forum. Doesn’t include the sprite at the bottom of the screen, just demonstrates model movement and rotation.


viewer.mode = FULLSCREEN
function setup()
    --
    galaxy = asset.documents.Dropbox
    path = asset.builtin.CastleKit
    mod, turns = 1, 0
    parameter.integer("mod",1,#data,1)
    parameter.action("Load Model",function() buildModel(mod) end)
    setScene()
    buildModel(mod)
end

function update(dt)
    -- Rotate the entity
    e.eulerAngles = vec3(x,y,z)
    if CurrentTouch.state == MOVING then
    else
        if camZ > 8 then
            camZ = camZ - 1
        else
            rot = rot-1
            if rot > 360 then rot = 0 end
            CameraX = CameraX - 1
            CameraY = CameraY - 0.8
            CameraZ = CameraZ - 1
            turns = turns + 1
        end
        if turns >= 900 then
            mod = mod + 1
            if mod > #data then mod = 1 end
            buildModel(mod)
        end
    end
    scene.camera.position = -scene.camera.forward * camZ
    e.eulerAngles = vec3(CameraY, CameraX, 180)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function touched(t)
    --
    if t.state == ENDED then
        mod = mod + 1
        if mod > #data then
            mod = 1
        end
        print(mod)
        buildModel(mod)
    end
end

function setScene()
    --
    scene = craft.scene()
    skyMaterial = scene.sky.material
    skyMaterial.horizon = color(255)
    scene.ambientColor = color(255, 0)
    scene.sky.material.envMap = craft.cubeTexture(galaxy[space[1]])
    scene.camera.position = -scene.camera.forward * 5
    CameraSettings = scene.camera:get(craft.camera)
    CameraX,CameraY,CameraZ = 0,0,0 
    rot = 0
end

function buildModel(mod)
    -- Create a new entity
    if e then
        e:destroy()
    end
    output.clear()
    e = scene:entity()
    e.model = craft.model(path[data[mod]])
    e.position = vec3(0,0,0)
    e.scale = vec3(1,1,1)*Rscale[mod]/32
    camZ = 100
    CameraX,CameraY,CameraZ = 180,180,0
    turns = 0
end

data = {
        --
        "bridge_obj",
        "gate_obj",
        "king_obj",
        "knightBlue_obj",
        "knightRed_obj",
        "metalGate_obj",
        "shieldBlue_obj",
        "shieldRed_obj",
        "siegeBallista_obj",
        "siegeCatapult_obj",
        "siegeRam_obj"
        }

space = {
        "blackbox"
        }

Rscale = { 10,10,10,10,10,10,20,20,5,5,5}

I will add improvements later - if you can improve this (most probably) please post your code for us. Also moving on to make the next vid.

P.s. when you download the attached image rename it blackbox and add the name to the galaxy asset path in setup().

All,
The two developers of Elite were ahead of their time and managed to fit all the code needed for a 3D space game plus a massive amount of data describing 8 galaxies together with their resident planets, 256 in each galaxy. Also for a trading system across the universe. All in 32K memory staggering. Apparently they used procedural generation with a fibonacci series from a seed, together with a carefully built long string to describe all 2048 planets. I think they used scrolling of binary numbers to achieve this. Tried to figure out how to do that in Lua, but no joy. Anyone have any ideas on that?

Nice! I just played with this

To do procedural generation you might start by coming up with an encoding for a planet. Something like

<diameter><biome><terrain-seed>

Where biome is some enumeration of planet type (gas, earth-like, ice, barren, etc). And terrain seed is the random seed used to generate the terrain. It would be fun to generate an “endless” 2D star map where
you can build a new universe by giving a new initial random seed

Have you looked at the game “No Man’s Sky”? That’s a recent attempt at a space game with a procedurally generated universe

@Simeon - thanks for the feedback, checked on “No Man’s Sky” - intriguing, more or less what I’d ultimately like to get to - I think it will take a little time, but I’m up for it. Thanks.

All,
Just updated the website, not much added as busy trying to finish next videoo.

All,

Just posting a small project to display the Galaxy 1 map for the BBC Micro Elite game. Not the finished product but it works.


-- BBC Micro Elite Game Galaxy1 map
-- by Bri_G with help frm dave1707

viewer.mode = LANDSCAPE_LEFT
function setup()
    --
    sW,sH,cW,cH = WIDTH, HEIGHT, WIDTH/2, HEIGHT/2
    xmax,ymax,xmin,ymin = 100,100,100,100
    planets = {}
    pdist = {}
    docked = 8
    px,py = 420,200
    time = 0
    path = asset.documents[galaxy[1]]  — csv file in Codea root ‘documents’
    csv = readText(path)
    parsePlanet(csv)
    scene = asset.documents.galaxy01
    galpic = image(1024,768)
    setContext(galpic)
        spriteMode(CENTER)
        sprite(scene,WIDTH/2,HEIGHT/2,WIDTH,HEIGHT)
        ellipseMode(CENTER)
        fill(117, 214, 218, 159)
        noStroke()
        for gl = 1, 256 do
            radius = planets[gl].rad/800
            ellipse(planets[gl].pos.x*4,planets[gl].pos.y*3,radius,radius)
        end
    setContext()
end

function draw()
    --
    time = time + 0.1
    sprite(galpic,cW,cH,sW,sH)
    if time < 10 then 
        pushStyle()
            fill(241, 222, 47)
            font("Baskerville-SemiBold")
            fontSize(32)
            textMode(CENTER)
            text("BBC MICRO ELITE - Galaxy 1",WIDTH/2,HEIGHT-40)
        popStyle()
    else 
        showData(docked,px,py)
    end
end

function touched(touch)
    --
    if touch.state == ENDED then
        docked = distance(touch)
        if touch.x < cW then px = 568 else px = 56 end
        if touch.y < cH then py = 300 else py = 40 end
        showData(docked,px,py)
    end
end

function parsePlanet(str)
    -- galaxy_num,system_num,name,x,y,economy_id,economy,govtype_id,govtype,techlev,
    -- productivity, radius,population,description
    for a,_,b,_,c,_,d,_,e,_,f,_,g,_,h,_,i,_,j,_,k,_,l,_,m,_,n,_
    in string.gmatch(str,"(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)(.-)(,)") do
        table.insert(planets,
        {gal=tonumber(a),sys=tonumber(b),name=c,pos=vec2(tonumber(d),tonumber(e)),
        econ_id=f,econ=g,gov_id=h,gov=i,
        tech=tonumber(j),prod=tonumber(k),rad=tonumber(l),pop=tonumber(m),desc=n})
    end
end

function showData(pl,sdx,sdy)
    -- 
    local planet = planets[pl] 
    stroke(255)
    strokeWidth(2)
    noFill()
    ellipseMode(CENTER)
    ellipse(planets[pl].pos.x*4,planets[pl].pos.y*3,80,80)
    fill(255, 243, 0)
    textMode(CORNER)
    fontSize(18)
    text(planets[pl].name,planets[pl].pos.x*4+24,planets[pl].pos.y*3+24)
    fill(255)
    rectMode(CORNER)
    fill(44, 37, 109, 173)
    rect(sdx,sdy,320,440)
    fill(21, 83, 236)
    rect(sdx,sdy+408,320,32)
    fill(255, 243, 0)
    font("Arial-BoldMT")
    fontSize(24)
    txtStart = 410
    text("Planet - "..planets[pl].name,sdx+24,sdy+txtStart)
    fontSize(20)
    text("Economy      :  "..planets[pl].econ,sdx+12,sdy+txtStart-30)
    text("Government :  "..planets[pl].gov,sdx+12,sdy+txtStart-60)
    text("Tech Level    :  "..planets[pl].tech,sdx+12,sdy+txtStart-90)
    text("Productivity  :  "..planets[pl].prod,sdx+12,sdy+txtStart-120)
    text("Radius           :  "..planets[pl].rad,sdx+12,sdy+txtStart-150)
    text("Population    :  "..planets[pl].pop,sdx+12,sdy+txtStart-180)
    text("Position        :  "..planets[pl].pos.x.."_"..planets[pl].pos.y,sdx+12,sdy+txtStart-210)
    text("Description   :",sdx+12,sdy+txtStart-240)
    des = split(planets[pl].desc,30)
    for lp = 1,#des do
        text(des[lp],sdx+12,sdy+txtStart-240-lp*30)
    end
end

function distance(t)
    --
    local pdist = {}
    nearest = 0
    for lp = 1, 256 do
        pdist[lp] = math.sqrt((t.x-planets[lp].pos.x*4)^2+(t.y-planets[lp].pos.y*3)^2)
    end
    id = 256
    small = 1000
    for lp = 256,1,-1 do
        if pdist[lp] < small then
            small = pdist[lp]
            id = lp
        end
    end
    nearest = id
    return nearest
end

function split(str, max_line_length)
    local lines = {}
    local line
    str:gsub('(%s*)(%S+)',
    function(spc, word)
        if not line or #line + #spc + #word > max_line_length then
            table.insert(lines, line)
            line = word
        else
            line = line..spc..word
        end
    end
    )
    table.insert(lines, line)
    return lines
end

galaxy = {
            "Galaxy1"
        }

The csv file and image have been posted in another thread, but will be reposted here for convenience. You will need to edit the paths for this in the above code by adding your own file location. Also exported zip file.

All,
Sorry for bumping this thread but it seemed daft setting up a new thread for an update. To cut a long story short I’ve made a new video for the Archimedes version of Elite. Link below if you are interested.

http://www.briandor.com/Elitists/clones.html

P.s. still needs a little tidying up, but more or less it.
P.p.s tidied up. My apologies for posting video - deleted then updated website and link given to website now.

One comment on the previous wire-frame BBD Elite was to add comments or music. Not very good at commentating (voice a drawl) so any ideas on music?

These are cool and it’s a great project concept.

If you don’t mind, I kind of mushed together the two things you’ve posted, and put them in an easily-importable zip file, so it’s easier for others to play with.

Please let me know if you’d like me to take it down or if there’s anything I got wrong!

@UberGoober - no problem with that but I might update them later - add sound comments etc.

Then there’s the next couple of stages.

@UberGoober - oops thought you meant the videos. That was just a demo of some of the code that I used to make the two videos. Can’t see why anyone would want that - apart from a pointer to how to display 3D objects.

@Bri_G you posted the code here, and I for one was curious what it did, so I just thought I’d make it easier for anyone else.

@UberGoober - no probs, good to know I raised some interest with it.

@dave1707 @Simeon - OK, could someone explain to me how to transfer assets into the Codea application so that they will be exported with the code. I currentlyy have assets in a folder in the root - will they automatically be exported, and asset address be corrected, when I export it?

@Simeon - probable seen this before but - if whilst running, you minimise a FULLSCREEN_NO_BUTTONS project, then maximise back to fullscreen the buttons re-appear.

p.s. no apology for bumping this thread as I was hoping to post the project referred to here and it’s relevant to the thread. Any limit on project size posting?

@Bri_G I thought anything in the project folder went with the project if it was zipped or whatever.

@dave1707 - yeah, but how do you get it into the project folder. Do you mean project folder or Documents?

I have a folder with resource files in Documents and address them as -
asset.documents.FolderName.AssetName. That’s how I have always worked. I have always found that trying to place assets in the assets window difficult and messy - so what’s the procedure? and can you transfer/copy multiple files at once?

While in a project, select assets from the Do menu at the top right of the screen. Find the folder that hss the assets you want to copy. From inside that folder, tap Edit at the top right. You can then tap each asset you want to copy. They will have checkmarks on them. Then at the bottom right, tap Add To. A list of folders should show and there you can select the projects folder.

@dave1707 - finally the trick that’s eluded me sunk in - you need to have your project open - Dooooh Homer moment.

So I am going to try to attach the ‘final’ project - hope it isn’t too big with the resources.

In any case I will be putting a video on the Elitists website in the Galaxies section. I have already added a second video to that from Archimedes Elite (link below).

Link To The Project

Link to Arcelite

All - ignore the link to the project, Dropbox doesn’t appear to give basic links now. I’ll find another way to post it.

@Bri_G I don’t seem to have any trouble downloading the Dropbox project.

However the project won’t run because it expects there to be some kind of asset called Galaxies in my documents folder.

Could you re-zip it and make sure all the assets used are in the project itself?

@UberGoober - will do, I thought I’d sorted the assets position. Can you tell me the details of what assets. You could also unzip the file and check the contents that will tell me. Should be 8 text files and 12 graphic png’s together with the Lua code files.