Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

The Final Frontier

edited February 3 in General Posts: 2,241

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.


  • Posts: 2,241

    Just tidy up the code and I'll post later. Also will post the next vid when I can get the ships sorted out.
  • edited February 5 Posts: 2,241


    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. Not 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 = * 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 = skyMaterial.horizon = color(255) scene.ambientColor = color(255, 0) = craft.cubeTexture(galaxy[space[1]]) = * 5 CameraSettings = 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().

  • edited February 5 Posts: 2,241
    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?
  • SimeonSimeon Admin Mod
    Posts: 5,613

    Nice! I just played with this

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


    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

  • Posts: 2,241

    @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.

  • Posts: 2,241
    Just updated the website, not much added as busy trying to finish next videoo.
  • edited March 19 Posts: 2,241


    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.

Sign In or Register to comment.