Log In  


So, in between lunch breaks, I've made tiny-but-significant progress in my level generation code. It's part of a "bigger picture" thing, and meant to be useful across multiple projects; since I'm kind of digging into proc-gen core gaming. Even this little project is a proof-of-concept of a major undertaking, depending on if I can squish this into tokens available.

The idea here is to take a number of levels "LV" and make each one a 15-plus-one table - the first 15 being a kind of "perlin noise" function used to script "rooms" into the level, and the last being a control variable "BIOME" which influences the level's colors, themed elements, etc. I'm planning on coupling this with horizontal and vertical "targets" - ones to collect, ones to avoid, ones to attack, etc. Well, a "target" can be oriented both vertically and horizontally, and in varying speeds (more on this after my next WIP major chunk of code, "MAKETARGET()").

So MAKELEVEL(3) would generate 3 "output" tables:

LVL1={n1,n2...n15,biome}
LVL2={n1,n2...n15,biome}
LVL3={n1,n2...n15,biome}

...and then these tables will define the 5x3 screen map of each level.

I'll have to add "biome control" in later scripting, depending on the kind of game it generates, after the level generation. The "doorway" table definition occurs BEFORE it runs... for instance, it makes sense for a platformer to limit "doorways" to being {0,4,5,9,10,14}, where in top-down adventure or RPG games, it could be anywhere.

That said... still checking this for proper P8 syntax, and to see if it can be simplified. Being intermediate-level at best, I have the suspicion this can be streamlined a little bit still. Maybe even a lot.

function makelevel(lv or 15)
 if (lv>15) lv=15
 winlevel=lv
 for lv>0, do
  "lvl"lv={}
  level={scr1=0,scr2=0,scr3=0,scr4=0,scr5=0,scr6=0,scr7=0,scr8=0,scr9=0,scr10=0,scr11=0,scr12=0,scr13=0,scr14=0,scr15=0,biome}
-- create sequence of 16 doors
-- we don't have to use them all
 doorshuf={rnd(1,6),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5),rnd(1,5)}
 ezpath={}
 hdpath={}
 d=0
 n=1
 for n=1 to lv do
  d+=doorshuf(n)
  add doorlist (return doorways,d)
  n+=1
  end
--each exit makes a short,
--high-risk way, then a long
--low-risk alternative
 for n=1 to lv do
  stdoor=doorlist(n)
  endoor=doorlist(n+1)
--vertical paths?
  vstep=(stdoor/5)-(endoor/5)
  if (vstep<0) vstep*=-1
--horizontal paths?
  hstep=(stdoor\5)-(endoor\5)
  if (hstep<0) hstep*=-1
--add values to paths
  for n=vstep to 0 do
   if (stdoor/5)<(endoor/5) 
   then 
   add ezpath "5"
   add hdpath "5"
   else 
   add ezpath "-5"
   add hdpath "-5"
   vstep-=1
   end
  for n=hstep to 0 do
   if (stdoor\5)<(endoor\5)
   then 
   add ezpath "1"
   add hdpath "1"
   else
   add ezpath "-1"
   add hdpath "-1"
   hstep-=1
   end
 end
 add ezpath {"1","-1","5","-5"}
 if (#hdpath<3) add hdpath{"1","-1"}
--shuffle ezpath/hdpath order
 shuf(ezpath)
 shuf(hdpath)
--read paths, edit level table
	local pos=stdoor
	for i=#hdpath,2,-1 do
		local step={
		-1=(makelevel(pos)+=18,makelevel(pos-1)+=4,pos-=1),
		 1=(makelevel(pos)+=20,makelevel(pos+1)+=2,pos+=1),
		-5=(makelevel(pos)+=17,makelevel(pos-5)+=8,pos-=5),
		 5=(makelevel(pos)+=24,makelevel(pos+5)+=1,pos+=5)}
		end
	local pos=stdoor
	for i=#ezpath,2,-1 do
		local step={
		-1=(makelevel(pos)+=2,makelevel(pos-1)+=4,pos-=1),
		 1=(makelevel(pos)+=4,makelevel(pos+1)+=2,pos+=1),
		-5=(makelevel(pos)+=1,makelevel(pos-5)+=8,pos-=5),
		 5=(makelevel(pos)+=8,makelevel(pos+5)+=1,pos+=5)}
		end
	--return generated results as a
	--list of "lvl1,lvl2" tables...
	return "lvl"lv{}=level{}
 end

end

I use a pretty standard LUA shuffle script there, too. And I hope the FOR/DO/LOCAL STEP{..} is effectively equal to a switch/select case statement, because this is where I needed that!

As for the high variables on HDPATH, I'm adding a 16-factor to the typical 4-directional perlin noise, to designate them as "hard path rooms," where harsher penalties for screwups can occur.

WIP P8 file available here: https://app.box.com/s/95hozscthimtty9wsw2febpyfpi0zlw7



Never mind on the "later" part.

function maketarget(obj,scr,x,y,xrange or 0,yrange or 0,speed or 0,loop or 0)
--x/y position relative to map
 xpos=((scr\5)*16+x)
 ypos=((scr/5)*16+y)
--set sine motions to control
 local xmove=2*sqrt(xrange)*speed
 local ymove=2*sqrt(yrange)*speed
--reverse direction! 
 if (xmove=xrange or xrange<0) xmove*=-1
 if (ymove=yrange or yrange<0) ymove*=-1
--diagonals or curves
 if loop=1 then
  xmove=xrange
 elseif loop=-1 then
  xmove-=xrange
 end
--place object on trajectory
--and move accordingly! 
 mset xpos ypos obj
 obj.x+=xmove
 obj.y+=ymove  
end


[Please log in to post a comment]