Procedural Space Ship Demo

Blitz3D Forums/Blitz3D Programming/Procedural Space Ship Demo

Axel Wheeler(Posted 2013) [#1]
Hi there,

I've created a demo that generates procedural space ships.

Features:

- 10 each of 10 different ship types.

- Press Enter to replace them all with new ships

- They move toward the center, so wait a few seconds for them to arrive, or go after them.

- Mouse controls for your "ship". Use buttons for gas/brake.

- HUD shows red dots for ships that are off-screen or too far away to see well.

- Simplistic star field at no additional charge.

- No engines yet, just an exhaust flame hanging out there somewhere toward the rear of each ship. (Thanks Floyd & Kryzon)

Enough talk. Here it is:

http://www.lumpcat.com/files/ShipDemo.zip

Have fun. Let me know what you think...


Axel Wheeler(Posted 2013) [#2]
Forgot to mention it's 1280x1024 fullscreen, so you can see the detail. Is that OK?


RemiD(Posted 2013) [#3]
I would have tried but i can't with this resolution.
I can with :
640*480 32bits
or
800*600 32bits
or
1024*768 32bits

and if possible in windowed mode.


Axel Wheeler(Posted 2013) [#4]
Ok, I've just updated it so it's 1024x768, windowed.

It also starts up much faster now.


RemiD(Posted 2013) [#5]
Ok it seems to work correctly.

However some ships look very similar.

Why not build several cabines shapes and add randomly different storage spaces, engines, weapons, shields around the cabine ? It would add more variety. Just a suggestion.


Axel Wheeler(Posted 2013) [#6]
Thanks for the test.

Yes, there are 10 identical ships of each type. And the types are still sometimes similar as well.

Originally I tried to put big pieces together as you suggest, but I didn't like the results.

Still, there are bits added on to the main hulls:

Engines: Not installed yet (just the flames), although I don't think they will be too different from each other, just dark cylinders.

Weapons: Installed, but fairly similar. I had a unique texture for them at one point but I don't think that's working right now.

Turret: I had them but had to remove them. They will be back, hopefully somewhat different from each other.

Shields: I think of shields as electronic fields, but come to think of it, that could be awesome. You shoot at a ship, and a green sphere at .5 alpha appears and fizzles your phasers.

Cockpit/Bridge: They looked awful, so I removed them. I may revisit this later.

Antennas/misc. doo-dads: To be decided.

One point I didn't mention is that these are intended to be alien space ships, thus the bizarre hull shapes and sometimes colors.

Also, they are all fighters at this point. In the future there will be bigger ships such as battleships and freighters.

Thanks again for the comments!


RemiD(Posted 2013) [#7]
I have noticed a slight shining effect on the ships bodies, is it EntityShininess on a subdivided mesh ?

If yes, i may give it a try for my project.


Axel Wheeler(Posted 2013) [#8]
It's EntityShininess(ship,1) on the mesh, but I'm not sure what you mean by subdivided...

I was thinking about varying the shininess, and adding grubby texture for older ships. But since all the ships are CopyEntity() of their base ship type, it would have to affect all the ships of that type.

In the scene, there would also be a big skybox of stars, and a richly detailed turning planet, and a big ol' space station to boot. Not to mention the player's ship and shots fired with collisions. So I'm trying to be efficient with the ships themselves. Maybe too efficient, but it's easier to add complexity than remove it.


Axel Wheeler(Posted 2013) [#9]
Oops! I forgot to include the function that added the most variability to the ships. Duh. I was debugging something else and needed to remove all other effects.

Anyway, it's back now. Try it out, they look better now for sure.

Still no engines, no cockpit, antennas, etc. Still just 'fighter size' alien space craft.


Axel Wheeler(Posted 2013) [#10]
Updated once more. Now includes a crude graphics mode selector. Bigger and full screen are definitely helpful in seeing the details.


RemiD(Posted 2013) [#11]
By subdivided, i mean a higher number of tris than what is necessary to have the same shape. This allows to have a nice progressive lighting and apparently a nice shining effect with EntityShininess.


Banshee(Posted 2013) [#12]
There is no part of this which isn't utterly cool.

Although I did randomly generate what I can only describe as a penis ship which was somewhat disturbing.


gburgess(Posted 2013) [#13]
This is pretty cool! Love the idea.


Who was John Galt?(Posted 2013) [#14]
Any chance of a screenshot for those of us without PCs?


Axel Wheeler(Posted 2013) [#15]
RemiD: Actually they are just standard Blitz3D spheres (CreateSphere) with VertexCoords modifications. And EntityShininess(ship,1). I think. Of course the guns and flames are added on. And a single texture. I want to create sidepods for some of them (basically little hulls stuck on both sides.)

Banshee: Thanks. Yes, I've seen a few of those as well. What does that say about me? I don't know... :-)

John Galt: Screenies coming...


RemiD(Posted 2013) [#16]
Yes there is more variety in the new demo, and i have seen antennas :)

But some shapes look very weird :O


Axel Wheeler(Posted 2013) [#17]
Ok, here is a zip of screenshots. Banshee, number 15 is for you. I got pregnant taking that screenshot (and I'm a dude); I hope you appreciate it!

http://www.lumpcat.com/files/ScreenShots2013-01-18.zip

And also another update to the demo. You can now zoom using the mouse wheel and give yourself a headache!

RemiD: The story premise (as I've envisioned it) has to do with a star cluster not too far from our sun, but hidden behind a dark cloud. There are lots of alien spacefaring civilizations there that have been around for many millenia, so their ships should look utterly bizarre to us, but possibly related to each other. Hopefully I will be able to make them even stranger!


Who was John Galt?(Posted 2013) [#18]
Looking good! Thanks for the screenies.


Axel Wheeler(Posted 2013) [#19]
The latest update gives them some new modifications, not all of them necessarily attractive.

One of them illustrated a weird problem: I take a random triangle (starting from a standard blitz sphere), and extrude all it's verts out from the center. Then I do the same for the corresponding triangle on the other side (x=-x) of the sphere.

Can you see the problems with this approach?

1. If one or two of the verts is at x=0, it gets extruded twice. I tried to prevent this by detecting x=0 and selecting a different triangle, but it still seems to happen sometimes.

2. If a triangle happens to be selected twice, you get huge extrusions, since they are multiples.

And the biggest proglem:

3. There are no 'corresponding triangles' on a blitz sphere! The quads are all split the same way, like an 'N'. So the three 'corresponding verts' don't actually form a triangle. Still looks surprisingly good I think, and usually you can't tell. But I have to fix it. How? Extrude the whole quad? Create a new type of symmetrical sphere?


Stevie G(Posted 2013) [#20]

3. There are no 'corresponding triangles' on a blitz sphere! The quads are all split the same way, like an 'N'. So the three 'corresponding verts' don't actually form a triangle. Still looks surprisingly good I think, and usually you can't tell. But I have to fix it. How? Extrude the whole quad? Create a new type of symmetrical sphere?



Use a Geosphere.

Function GEOcreate( Parent , Detail )

	Mesh = CreateMesh( Parent )
	S = CreateSurface( Mesh )
	a#=2.0/(1.0+Sqr(5.0))					
	b#=1.0/Sqr((3.0+Sqr(5.0)) / (1.0+Sqr(5.0)))
	v01=AddVertex(S,  0,  a,  b)
	v02=AddVertex(S,  0,  a, -b)
	v03=AddVertex(S,  0, -a,  b)
	v04=AddVertex(S,  0, -a, -b)
	v05=AddVertex(S,  a,  b,  0)
	v06=AddVertex(S,  a, -b,  0)
	v07=AddVertex(S, -a,  b,  0)
	v08=AddVertex(S, -a, -b,  0)
	v09=AddVertex(S,  b,  0,  a)
	v10=AddVertex(S,  b,  0, -a)
	v11=AddVertex(S, -b,  0,  a)
	v12=AddVertex(S, -b,  0, -a)
	GEOsub( S, v02,v05,v07,Detail )
	GEOsub( S, v01,v07,v05,Detail )
	GEOsub( S, v01,v03,v11,Detail )
	GEOsub( S, v01,v09,v03,Detail )
	GEOsub( S, v02,v04,v10,Detail )
	GEOsub( S, v02,v12,v04,Detail )
	GEOsub( S, v03,v06,v08,Detail )
	GEOsub( S, v04,v08,v06,Detail )
	GEOsub( S, v07,v11,v12,Detail )
	GEOsub( S, v08,v12,v11,Detail )
	GEOsub( S, v05,v10,v09,Detail )
	GEOsub( S, v06,v09,v10,Detail )
	GEOsub( S, v01,v11,v07,Detail )
	GEOsub( S, v01,v05,v09,Detail )
	GEOsub( S, v02,v07,v12,Detail )
	GEOsub( S, v02,v10,v05,Detail )
	GEOsub( S, v04,v12,v08,Detail )
	GEOsub( S, v04,v06,v10,Detail )
	GEOsub( S, v03,v08,v11,Detail )
	GEOsub( S, v03,v09,v06,Detail )

	Return mesh

End Function

;======================================
;======================================
;======================================

Function GEOsub( S, v1 , v2 , v3 , Detail )
	
	If Detail > 0 
		nx#=(VertexX(S,v1)+VertexX(S,v2))/2
		ny#=(VertexY(S,v1)+VertexY(S,v2))/2
		nz#=(VertexZ(S,v1)+VertexZ(S,v2))/2
		l#=Sqr(nx*nx+ny*ny+nz*nz)
		n1=AddVertex(S,nx/l,ny/l,nz/l)
		nx#=(VertexX(S,v2)+VertexX(S,v3))/2
		ny#=(VertexY(S,v2)+VertexY(S,v3))/2
		nz#=(VertexZ(S,v2)+VertexZ(S,v3))/2
		l#=Sqr(nx*nx+ny*ny+nz*nz)
		n2=AddVertex(S,nx/l,ny/l,nz/l)
		nx#=(VertexX(S,v3)+VertexX(S,v1))/2
		ny#=(VertexY(S,v3)+VertexY(S,v1))/2
		nz#=(VertexZ(S,v3)+VertexZ(S,v1))/2
		l#=Sqr(nx*nx+ny*ny+nz*nz)
		n3=AddVertex(S,nx/l,ny/l,nz/l)
		GEOsub( S, v1,n3,n1,Detail-1)
		GEOsub( S, v2,n1,n2,Detail-1)
		GEOsub( S, v3,n2,n3,Detail-1)
		GEOsub( S, n3,n2,n1,Detail-1)
	Else
		AddTriangle(S,v1,v2,v3)
	End If

End Function



Axel Wheeler(Posted 2013) [#21]
Thanks for the tip. I tried it. Results:

1. The geosphere does indeed extrude the correct corresponding tris.

2. Certain deformations work fine, others fracture the mesh into parts. I think I could fix this by making sure that not only a given vert moves, but all verts at that x,y,z location.

3. The ships have a different and interesting look. This is because the lines have a kind of zig-zag effect that is different from the 'blitz sphere' version.

It would make an interesting variation. I will try to fix the issue above. Thanks, Stevie!


Axel Wheeler(Posted 2013) [#22]
Ok, so I went with extruding the whole quad for now. Finding the "fourth vertex" of the quad was quite tricky. The method I ended up using was simpler than I started with; A vertex index is exactly 2 * segments + 1 away from the vertex immediately above and below it on a Blitz3d sphere. I just had to figure out which of the four corners was missing.

Initially I had tried to find it using VertexX(), VertexY(), VertexZ(), until I realized that it's not a 2D grid, those values will never line up, of course; it's a sphere! I had gotten used to view the sphere as a 2D projection.

I've updated the demo, which sometimes seems to show the whole quad extruded, but other times the edges look pointy, but I think that's because other manipulations are happening too, which is fine.

There is now a pause key (P) which pauses the action (the ship movement) but NOT the camera, so you can travel around the frozen ships and inspect them up close. This, especially with the zoom (mousewheel), makes it much easier to see what's going on. And it's cool. (but I'm biased).


Banshee(Posted 2013) [#23]
This is still very cool.

How to you intend to improve on the texturing? At the moment it is the single biggest detractor as to the finished quality.


Axel Wheeler(Posted 2013) [#24]
I've been trying to paint a cockpit on it with mixed results.


Axel Wheeler(Posted 2013) [#25]
Banshee: I've been looking at google image search on spaceships. Any suggestions on how they should look? They are procedurally generated along with the ship, so it has to be an algorithm. Thanks.


Banshee(Posted 2013) [#26]
What you have isn't that bad, as a basis to work from - it just needs a few more passes of some other processes to make it more interesting - and perhaps a higher resolution.

The difference between the grey areas and the coloured areas is a good basis from which to work, you can detect those areas and do different things with them. So a second pass could maybe go through the grey areas and add some pipework to them, a bit like this...



A third pass might then slap on an insignia decal, and maybe somewhere near the front on the side you could slap on a few minor decals in a similar vein to how race cars have decals to show marshalls where fire extinguishers are located and electrical hazard warnings.

Finaly, a ship or squadron unique ID slapped across the side like a WW2 fighter:


Then maybe a few kill markings.

Lastly, there is no reason for a space ship to be clean - especially if it enters planet atmospheres, so you could dirty up the texture with a final pass that applies some semi-opaque grit and browning off.

Last edited 2013


Axel Wheeler(Posted 2013) [#27]
For the first graphic it looks like a base of a dark cloudy dirt layer on which an uneven grid of lighter lines. Then some dark partial rectangle shapes. I'll see what I can do!

As far as decals, I need to generate random shapes because they are alien ships.

As far as dirt, this requires good perlin noise, which I am also working on. That will make a big difference too.

Thanks!


Banshee(Posted 2013) [#28]
Runes might hold the answer for decals, things like this:


Or a quick google image search for "runes". Or even a rune font with some gibberish (or cryptic geek message that nobody will ever get :P)


Axel Wheeler(Posted 2013) [#29]
Love the runes. Since these would be procedurally generated (there will likely be hundreds of civilizations in this star cluster) I would want to develop an algorithm to make something like this with no loaded media. An exciting prospect. Ok, I have to try this now!


Wings(Posted 2013) [#30]
Works nice and smoth on my lowend pc intel i7.. (Laptop)
o live the scaling camera and mouse controlls.


Axel Wheeler(Posted 2013) [#31]
New update.

The textures now look a lot better, but there is more work to be done to give them that real 'piping' look. Hmm, maybe a normal map?

Oh, they are shooting now! Explosions, frags, the works. The AI is much better now as well. It's pretty much mayhem salad...

I've been experimenting with two ways of doing runes: 1. positioning curved meshes for the strokes and rendering (i.e. using the 3d card), and 2. cutting black lines/shapes out of colored rectangles (the rune is what's left behind). Neither way works great as yet, but there's more room to experiment.

Enjoy.


Axel Wheeler(Posted 2013) [#32]
Oh, I also want to mention that this program uses:

- AddMeshToSurface by SSwift

- Mesh clipping functions by Big10p

The mesh clipping is an amazing thing that cuts a part off a mesh cleanly (by adding verts and triangles at the clipping plane). I use it to split a ship into 'frags,' when it explodes. So I clip the mesh once, then flip it over on the x axis and clip it again. In theory this should result in two ship parts, but there's a bug in my side of it, because sometimes you can see the same feature (like the nose, say) in both frags. Anyway it then does it once more on each frag, for a total of 4 frags (in each case the source frag is deleted.)

The only problem with this is it causes a noticeable lag, so I'm trying to manage the splitting by doing only one per frame. (It adds each frag-to-be-split to a type, then processes one per frame.) Still, it's too slow on my machine.

In part this may be because I added a feature to the code to close off the hole formed by the split. As it adds each new vert at the edge of the mesh, I add that vert to a type. Then, I sort all the verts by yaw (using Atan2 on it's vertexX and vertexY). Then I add triangles in the manner used on the Blitz3D cylinder primitives. I usually works ok.

If I can't speed it up, I may have to resort to a cruder method of splitting the mesh, without adding verts to create a clean edge. We'll see.


Banshee(Posted 2013) [#33]
That is looking really great! I love it, and on my laptop there is no noticeable slow down at all.

Here is the dragonbreath particle animation from my current dev project, I made it in 3D Studio Max and you are free to use, Axel Wheeler. I think it might add something to your game, especially if the jibblets trailed burning oxygen behind them as the ship breaks up. It's worth a shot anyway, up to you.

http://beckyrose.com/particles.7z


Banshee(Posted 2013) [#34]
If slow down is causing an issue on your target hardware then you might consider making the jibblets double sided and not closing the hole, you could then fill the middle of the ship with some debris pieces, simple primitives with a texture that uses alpha to hide the primitive base of the shape could do it.

I ran it with 25 ship types and 25 of each on maximum res and had no slowdown, so I ran 2 ship types of 500 and again there was no jitter - although the game appeared to run slower overall so I presume you aren't using delta timing.

The new textures are a good step forward, although you have lessened the coverage of the second colour and that made it hard to distinguish teams from each other in the properly massive battles as the ships were more similar in colour.


Banshee(Posted 2013) [#35]
Another nice explosion technique I sometimes use is to create a flat plain at an angle of rnd(360),rnd(360),rnd(360) and slap on a texture like this



Using a blend mode, and making it a % larger each frame, it looks like a shockwave expanding from the epicentre and really finishes an explosion off to look fantastic. You could also experiment with some other textures, I never tried this but a texture like this might also be cool

http://3.bp.blogspot.com/-EYC60wIk_HA/T989pditfgI/AAAAAAAAAMg/zASSQwtShTY/s1600/LightingRing.bmp


Axel Wheeler(Posted 2013) [#36]
Great suggestions. I've been playing Galaxy On Fire 2 for iphone, and the explosions use the expanding ring method you describe. I've been thinking about it. (I thought it was an expanding quad rather than a plane. Either way should work.)

Your particles look great. Both the flames and smoke. Thanks for them.

I'm trying to make everything procedurally, so for example, each ship type could have it's own way of exploding, at least it's own colors and a variation on the particles. I've been trying to incorporate my perlin noise functions (although I may just go with sswift's). This will allow me to generate particles like that as well as dirt and grunge on the ship hulls, and also a more sophisticated sky map with nebulae and dark clouds.

If I do it right, the explosion particles will look somewhat like yours.

Thanks!

Intriguing website at BeckyRose.com, by the way!


Banshee(Posted 2013) [#37]
There's a difference between a quad and a plane? I was thinking four verts, two polys, and in the main loop making it grow :) If it's true black in the middle you can just switch it off once it has grown out of sight - or you could EntityFade at the end of its life or even gradually throughout it.

I think it's ambitious to do all the textures procedurally, some things I would suggest just don't warrant it for the effort vs reward ratio but if you are enjoying the process then hell nobody has the right to say "nuh uh".

I've done some work with mass space ship combat AI before and I notice your current AI goes a bit wonkey in a 1 v 1 scenario with ever decreasing circles and flying through each other.

I used to use speed, so if approached from the rear a ship would slow down and then accelerate as it faced the enemy, and by adding a "dead zone" when they directly face each other they would veer off one way or the other and open up the afterburners. This works quite well, but you soon notice that ships which don't move generally win by turning on the spot like an old game of asteroids, but you can solve that by making the read ahead targeting to be randomly less accurate at faster speeds ( dx/dy/dz = self + rnd( -speed , speed ) ).


Axel Wheeler(Posted 2013) [#38]
Quad v. Plane: CreatePlane() in blitz creates a plane entity, which has no verts or tris, but extends to infinity. It can be textured, positioned and rotated. It faces only one way, so you have to either make sure the player is on the right side or create two planes back to back. Generally a texture will be repeated infinitely, but maybe you can prevent that. That would be necessary for this application. They can be scaled, so the texture can expand.

But a quad would work fine too, and probably better.

As to doing everything procedurally, I'm trying to create a cluster of a few thousand stars belonging to hundreds of empires. At stars near the borders between these empires the neighboring ships fight for control.

One on one combat; I know, that's bizarre. Sometimes they dance around oddly, but eventually one will get bored and head off (to be promptly blown away by the other. I've seen rings of six or so ships in a tight circle.

Yes, the AI is crude, but the current method is also only about 2 days old, so I was surprised it looks as good as it does.

They have a goal speed, and the current speed is averaged with that speed at a 9/1 ratio so it's smoother than it was before. If they get hit they boost out of the way. If they get too close to their target they show down to a crawl.

I think I'm going to create a type to refine their behaviors:

Type Attitude
   Field thisShipType.ShipType
   Field thatShipType.ShipType
   Field enmity#
End Type


This would allow each type to have a degree of enmity (0.0=peace, 1.0=hatred, anything between is degrees of enmity)

That would influence whether they attack a given ship or not. All the permutations of numerous ShipTypes should produce an interesting demo!


Axel Wheeler(Posted 2013) [#39]
Been creating a library around Sswift's perlin noise generator. The hope is to use it to procedurally do the following:

1. Create nebulae in the skybox

2. Create grunge for the ship hulls

3. Create flaming explosion and smoke textures for particles

4. Create realistic planet atmospheres (there should really be planet below these ships, shouldn't there?)

So far it includes the ability to:

1. "Smush" a noise map according to two other noise maps (one for smushing in x, one for y)

2. Apply Perlin Turbulence

3. Create an "island" effect by reducing the values toward the edges.

So far no color, just gray. Stay tuned.

A new update has been posted. Now when the ships blow up the fragments spin around their centers realistically. The explosions themselves are still lame, but there is a flash of light reflecting off nearby ships that looks pretty cool.

Oh, also: When an entire fleet (of one ship type) is destroyed, a new fleet is created! So it goes on forever...