Space Conflict started life as a 20-liner by IBOL
(link), I was impressed by it and started helping him improve the game. David Gervais made some nice graphics and IBOL released a new version with the updated graphics:
link. We talked about making a new space game together, we had very ambitious ideas about infinite galaxies and procedurally created alien races and planets to explore, but there was too much confusion and we never got started. IBOL has since gone inactive but those ideas stuck with me and I have begun the project on my own.
There is one rule that I've set myself for this project: everything must be generated from code; the ships, planets, aliens, names, even the music and sounds must be procedurally generated -- this is the reasoning behind the corny working title. The first version of the game will be fairly simple and play like the original Space Conflict, but the original code can't be salvaged (believe me I've tried), I will have to start from scratch.
I decided to start with the spaceships. I've recently updated the code and I think they are close to the quality I'd like to see in the game. I just need to figure out how to dynamically create modified templates that will give each race a unique style, and maybe some decals too.
I'll post a list of what I'm planning to do next in the next couple of days. I'm open to help if anyone is interested in this project, if you are competent with procedural generation, AI or general RTS coding then you would be of great use to me, but I'm certainly not relying on forming a team. All this procedural generation might seem like overkill but A: this is practice for a much more ambitious project that will be about exploring and discovering new worlds. B: it's cool!
----
SPACESHIP GENERATOR
Change Log and Screenshots
* Version 1.0 -
img
* Version 2.0 - Complete redesign.
img
* Version 2.1 - Refined the algorithms.
img
* Version 2.2 - Fixed some bugs, and improved both colour and shape algorithms.
img
* Version 2.22 - Fixed more bugs and added dynamic templates for distinct racial styles.
img
* Version 2.23 - Improved some aspects of the code.
img
* Version 2.24 - Minor improvements.
Latest Version Source (v2.24):
remstart
-=- Pixel Spaceships -=-
by Obese87 - 26/02/2013
- Special Thanks -
IBOL - http://forum.thegamecreators.com/?m=view_profile&i=474d4cd4624721af99f8c2558cf18d79
Dave Bollinger - http://www.davebollinger.com
--------------
- Proposed Features -
* Shading to be done logically not randomly.
* Components to be generated with their own templates then stitched together to allow for any size ship.
* More detailed template with scalar probabilities to allow much more specific variation.
remend
version$ = "2.24"
sync on
sync rate 100
randomize timer()
#constant sw = screen width()
#constant sh = screen height()
`display area
#constant xOff = 10
#constant yOff = 25
#constant dw = (screen width()-10)
#constant dh = (screen height()-50)
dim ship(13,17) as dword
dim template(13,17) as dword
dim colour(5)
#constant _trim = 1
#constant _body = 2
#constant _body2 = 3
#constant _cockpit = 4
#constant _decal = 5
gosub initializeTemplate
global scale=2
#constant imax = 3
#constant jmax = 2
#constant spacingX = 16
#constant spacingY = 19
fs = 6 //similarity between ships of the same faction
bg = 0 //background style
dim b(2)
b(0) = 1
b(1) = 96
b(2) = 0
rem = Main ====================================================
Do
backdrop(b(bg))
xmax = dw/(imax+1)/(spacingX*scale)
ymax = dh/(jmax+1)/(spacingY*scale)
for j = 0 to jmax
for i = 0 to imax
gosub initializeTemplate
if factions then gosub generateFactionStyle
for y = 0 to ymax-1
for x = 0 to xmax-1
if factions=0 then generate_Colours(fuzzyColour(rgb(80,80,80),0,40))
Generate_Ship()
xx = xOff+ x*spacingX*scale + (i*dw/(imax+1))
yy = yOff+ y*spacingY*scale + (j*dh/(jmax+1))
draw_ship(xx,yy)
rem colour swatches
if swatches
for c = 0 to 4
ink colour(c+1),1
cx = xx+c*scale*2.4
cx2 = xx+(c+1)*scale*2.4
cy = yy
box cx,cy-scale*2,cx2,cy-2
next c
endif
next x
next y
next i
next j
`output text
set cursor 0,0
ink -2,0
print "SCALE: ";scale
center text sw/2,sh-32,"PRESS ANY KEY TO GENERATE MORE SHIPS"
center text sw/2,sh-16,"PRESS UP/DOWN TO ADJUST SHIP SCALE. PRESS RIGHT TO TOGGLE FACTIONS ON/OFF."
text 0,sh-16,"v"+version$
`suspend for input
repeat
sc = (scancode()>0)*(sc+1)
up = upkey()*(up+1)
dn = downkey()*(dn+1)
rk = rightkey()*(rk+1)
ck = controlkey()*(ck+1)
bk = keystate(49)*(bk+1)
sk = keystate(39)*(sk+1)
sync
until sc=1
if up=1 or up>10 then inc scale
if dn=1 or dn>10 then dec scale
if scale<1 then scale=1
if scale>5 then scale=5
if rk=1 then factions = 1-factions
if ck=1 then swatches = 1-swatches
if bk=1 then inc bg : if bg > 2 then bg = 0
if sk=1
if image exist(1) then delete image 1
get image 1,xoff-6,yoff-6,dw+6,dh+12,1
for i = 0 to 255
dir$ = "screenshots/"
if path exist(dir$) = 0 then make directory dir$
fn$ = dir$+"v_"+version$+"_b"+str$(bg)+"_f"+str$(factions)+"_s"+str$(scale)+"_"+str$(i)+".png"
if file exist(fn$)=0
save image fn$,1
exit
endif
next i
endif
set text size 50
set text opaque
center text sw/2,sh/2.2,"GENERATING..."
set text size 10
set text transparent
sync
loop
END
//
generateFactionStyle:
generate_Colours(fuzzyColour(rgb(80,80,80),0,40))
generate_Ship()
for ty = 1 to 16
for tx = 1 to 6
if template(tx,ty) < 3
select ship(tx,ty)
case 1 : template(tx,ty)= 1 + ((rnd(fs)/4)>0)*2 :endcase
case 2
if ((rnd(fs)/4)>0)
template(tx,ty) = 3
else
template(tx,ty) = 2 - rnd(4)/2
endif
endcase
case default:endcase
endselect
endif
if template(tx,ty) = 4 then template(tx,ty) = 4 + (ship(tx,ty)=_cockpit) - (ship(tx,ty)<4)
next tx
next ty
return
initializeTemplate:
rem Ship template (0=blank,1=skin,2=optional body,3=essential body,4/5=cockpit)
t:
data 0,0,0,0,1,1
data 0,0,0,1,1,2
data 0,0,1,1,2,2
data 0,0,1,2,2,2
data 0,1,1,2,2,2
data 0,1,2,2,2,3
data 0,1,2,2,2,3
data 1,2,2,2,3,3
data 1,2,2,2,3,4
data 1,2,2,2,4,4
data 1,2,2,2,4,5
data 1,2,2,2,3,4
data 1,1,2,2,3,3
data 0,1,1,2,2,3
data 0,0,1,1,2,2
data 0,0,0,0,1,1
restore t
for y=1 to 16
for x=1 to 6
read template(x,y)
next x
next y
return
`//
rem = Functions ===============================================
function draw_ship(x,y)
rem draw ship
for v = 0 to 16
for u = 0 to 12
c = colour(ship(u+1,v+1))
if c
ink c,1
box x+u*scale,y+v*scale,x+(u+1)*scale,y+(v+1)*scale
endif
next u
next v
endfunction
`//
function Generate_Ship()
rem reset values
for x = 1 to 12 : for y = 1 to 16 : ship(x,y) = 0 : next y : next x
rem base ship model
for y = 1 to 16
for x = 1 to 6
SELECT template(x,y)
`Void
case 0 : ship(x,y)=0 : endcase
`Rare body
case 1
`ship(x,y)=3
if rnd(16)=0 then ship(x,y)=rnd(2)+1
endcase
`Optional Body
case 2
`ship(x,y)=0
if rnd(4)=0 then ship(x,y)=rnd(2)+1
endcase
`Essential Body
case 3
ship(x,y)=rnd(2)+1
endcase
`Rare Cockpit
case 4
if rnd(3)=0
ship(x,y)=_cockpit
else
ship(x,y)=rnd(2)+1
endif
endcase
`Common Cockpit
case 5
if rnd(8)
ship(x,y)=_cockpit
else
ship(x,y)=rnd(1)+1
endif
endcase
ENDSELECT
next x
next y
rem (Maybe if I added a buffer I could reduce the number of loops...)
rem flesh out
for y = 1 to 16
for x = 1 to 6
if ship(x,y) = 0
if ship(x-1,y)>1 or ship(x+1,y)>1 or ship(x,y-1)>1 or ship(x,y+1)>1
if template(x,y)>0 then ship(x,y)=rnd(2)+1
endif
endif
next x
next y
rem tidy up loose pixels
for y = 1 to 16
for x = 1 to 6
if ship(x,y)>0
if y<=8 then yin=y+1 else yin=y-1
if ship(x+1,y)+ship(x,yin)+ship(x+1,yin)+ship(x-1,yin) = 0
ship(x,y)=0
x=0:y=1
endif
endif
next x
next y
rem Mirror the ship
for y = 1 to 16 : for x = 1 to 6 : ship(13-x,y)=ship(x,y) : next x : next y
Endfunction
`//
function generate_Colours(a)
`trim = intensity(a,.5)
trim = a
body = fuzzyColour(trim,5,10)
change# = ((rnd(15)/100.0)+.55) * (rnd(1)*2-1)
body = intensity(body,2^change#)
trim = intensity(trim,2^(0-change#))
body2 = blend(body,trim)
decal = fuzzyColour(body2,100,100)
cockpit = fuzzyColour(invert(body),10,30) : cockpit = intensity(cockpit,1.5)
colour(_trim) = trim
colour(_body) = body
colour(_body2) = body2
colour(_decal) = decal
colour(_cockpit) = cockpit
endfunction
`//
function blend(c1,c2)
r = (rgbr(c1)+rgbr(c2))/2
g = (rgbg(c1)+rgbg(c2))/2
b = (rgbb(c1)+rgbb(c2))/2
c = rgb(r,g,b)
endfunction c
//
function addHue(c,ir,ig,ib)
// WARNING: This function keeps colour values in bounds so colour data may be lost.
rem the maths says: if 0<=r<=255 then r=r elseif r<0 then r=0 elseif r>255 then r=255
r = rgbr(c)+ir : r=r*(r>=0)*(r<=255)+(r>255)*255
g = rgbg(c)+ig : g=g*(g>=0)*(g<=255)+(g>255)*255
b = rgbb(c)+ib : b=b*(b>=0)*(b<=255)+(b>255)*255
c = rgb(r,g,b)
endfunction c
`//
function bounceHue(c,ir,ig,ib)
// WARNING: This function keeps colour values in bounds so colour data may be lost.
rem the maths says: if 0<=r<=255 then r=r elseif r<0 then r=0-r elseif r>255 then r=512-r
r = rgbr(c)+ir : r = (0<=r)*(r<=255)*r*2 + (r>255)*512 - r
g = rgbg(c)+ig : g = (0<=g)*(g<=255)*g*2 + (g>255)*512 - g
b = rgbb(c)+ib : b = (0<=b)*(b<=255)*b*2 + (b>255)*512 - b
c = rgb(r,g,b)
endfunction c
function intensity(c,i as float)
// WARNING: This function keeps colour values in bounds so colour data may be lost.
rem the maths says: if 0<=r<=255 then r=r elseif r<0 then r=0 elseif r>255 then r=255
r = rgbr(c)*i : r=r*(r>=0)*(r<=255)+(r>255)*255
g = rgbg(c)*i : g=g*(g>=0)*(g<=255)+(g>255)*255
b = rgbb(c)*i : b=b*(b>=0)*(b<=255)+(b>255)*255
c = rgb(r,g,b)
endfunction c
//
function contrast(c,f)
c = addHue(c,f,f,f)
endfunction c
`//
rem randomizes a Colour by a random amount between +/-min and +/-max
function fuzzyColour(c,min,max)
c = bounceHue(c,rndChange(min,max),rndChange(min,max),rndChange(min,max))
endfunction c
`//
function invert(c)
c = 16777215 - c
endfunction c
`//
rem Random Change: can be positive or negative, at least +/-min, at most +/-max
function rndChange(min,max)
v = (rnd(1)*2-1)*(rnd(max-min)+min)
endfunction v
`//
function backdrop(bg)
lock pixels
for y = 0 to sh-1
for x = 0 to sw-1
color = ((x&&bg-1)+(y&&bg-1))*2
pDot(x,y,color)
next x
next y
unlock pixels
endfunction
`//
`pDot - by Coding Fodder - Downloaded from: http://dbcc.zimnox.com/
function pDot(x as dword, y as dword, color as dword )
if x < bitmap width() and y < bitmap height()
y = y * get pixels pitch()
x = x * ( bitmap depth() / 8 )
pointer = get pixels pointer() + y + x
*pointer = color
endif
endfunction
Executable attached -->
-------------------------
To Do List:
Procedurally Generated Content
* Spaceships
* Planets
* Music & Sound
Game Code
* Housekeeping
* Controls
* AI
Formerly OBese87.