Display posts from previous

Sort by

First of all, thank you for everybody (espeically our potentially confused non-American forum-goers :V) for being patient while we all enjoyed our Thanksgiving break ^^ Since more holidays are coming up again soon, I'll be posting one more devlog this year after this post. My last devlog of 2017 will be two weeks from today, on Friday, December 15th. After that, my devlogs will resume again on a normal two-week schedule on Friday, January 12thFriday, January 5th. (edit 12/18/17: yay earlier devlog!)

Josh and Adam don't have exact devlog plans like this, but I would expect them to be similarly interrupted by the holidays. Although I can tell you that y'all will probably be quite pleased by the progress they've been making during this devlog silence. ;00 We always appreciate your patience <3

If you need a daily shot of LT, you can follow me on Twitter, where I post screenshots almost daily. In addition I'll also link every LT tweet on these devlog threads. That way, those of you who don't have a Twitter can check back here for those screenshots Although the tweets will be more frequent than devlogs, expect my LT-related tweeting to be sparse around Christmas through New Year's Eve.

Implemented a policy for protecting against crashes & bad geometry as a result of trying to apply a warp on a bad poly.

Began work on Style

Boring Architecture Stuff

Joints, as y'all remember, are used to define patterns of shapes and create clusters of shapes. I added two crucial pieces of data to this to really bring out the strength of Joints: a Scale and an Up vector. Joints now store Position, Direction, Up, and Scale. (If you're familiar with Unity, they're basically Transforms at this point that don't have any other components like a mesh.) The Scale allows the user to define how a Shape will grow or shrink in size when placed on the Joint. The Up vector is a mathy thing that gives more strength (and prevents errors) when using the Direction property to define what direction the shape will face in when placed on the Joint. To complement this, I made sure that all of the basic Shape creation functions (like ellipsoid, box, and icosahedron) as plain as possible. They just give you a shape, and require no input regarding rotation, translation, or scale, as all of that is handled by Joints now. I also ensured that all basic shape functions return a shape that fits inside a (1,1,1) box, and added an AABB function to get size information about shapes. All of this work combined means that we now have more intelligent ways to combine shapes based not only on some abstract position, but also on a position relative to a shape's scale.

Here's a small demonstration of AABBs & the new scaling system working. The scaffolding blocks to the left of the sphere are using the sphere's AABB information to be placed perfectly at the edge of the sphere and span the length of the sphere.

Here are two demonstrations of the new Joint properties. Both images use the function to generate JointFields from a shape; they generated a Joint for every quad on the large box, then added smaller boxes to every one of those joints. The second one demonstrates using the Joint's new Scale property to scale the size of each smaller box based on its Y-location on the larger box.

I also spent a day ensuring that every basic shape function produced perfect data. Specifically, I eliminated any 'bad' polys and ensured all of the shapes are manifold. (A 'bad' poly is defined here as having a zero-length normal and/or fewer than 3 verticies.) The Irregular Prism was creating one bad poly, so I got rid of it. The Box was non-manifold, so I re-wrote it to be manifold. For the purposes of fixing the Box, the mesh being 'manifold' means that there are no duplicate verticies with the same location. Put another way, two indicies in a poly may refer to the same vertex, but all verticies with a unique position have only one listing in the Vertex list. This isn't the complete definition of manifold, just to be clear!!!, but it worked for the purposes of fixing the Box algorithm.

After ensuring that no basic shapes generated bad data, I implemented a new policy for protecting against attempting to warp invalid polys. This is a bit of a tricky situation, because while I can guaruntee that the original input to a slew of warping functions is perfect, I fear that our infinite universe with its random combination of warps could still create bad polys. For example, tessellations greatly reduce the size of each poly every time they're applied, since you're splitting one poly into multiple pieces. This could theoretically create a situation where a triangle became narrow enough that it was essentially a line, and therefore had a 0-length normal. So, for the purpose of preventing crashes & junk shapes in release, we SKIP performing any operations on invalid polys. From the testing I did, this 1) creates shapes that only have 'good' polys operated on, which still look good, and 2) prevents potential crashes and ugliness from the spreading of NANs and other unwanted mesh data. I'm going to continue thinking about this problem further, as it's a rather dry, but still suuper-important one in the world of limitless procedural geometry.

Before the break, I had begun working on Style. Style is the object to generate and store all of the properties that make a faction's aesthetic unique. Honestly, I'm not super happy with how my first implementation of Style worked out. I think my biggest struggle with it is that I don't have a good foundation to test it on yet. It'll be more useful to start iterating on Style when I have at least one complete station part or one complete ship type to work on. Before Thanksgiving break, I had been working on building station parts from a perspective of starting with extreme randomness, and THEN trying to refine it. Josh had also previously tried this method, and we both found it to be ineffective. Instead, next time I attempt building functional-looking parts, I'm going to start with a low randomness/ high functionality algorithm and THEN stretch the algorithms until I reach the limits of what still looks recognizable. I believe that I'll have much better results with both making recognizable parts AND iterating on the Style architecture if I come from that perspective.

Fun Shapes & Warp Stuff

I added a 5-faced pyramid shape. I also contemplated n-faced pyramids, which would also allow cones, but then got distracted by something else I think. Now that I'm here writing about it, I'll probably do that tonight & update y'all later. LOL.

Josh, in his spare time, wrote a bevel function, because, of course, Josh. It's quite incredible- it can take ANY shape and round ALL of the edges by an arbitrary amount. The 'amount' is a number between 0-1 which describes how rounded the corners will be- 0 leaves them sharp, and 1 rounds them all the way to the next edge.

I added a few different variants on tesselation, and generally made the algorithms & their uses smarter. We now have several options for tesselation & triangulation:

A fan-shaped triangulation, which creates 0 new verticies. This doesn't preserve the angles of the original poly, and thus is currently only applied at the last step of shape creation, right before the shape is converted into an engine-level mesh, which is used for rendering.

A centroid-based triangulation, which doesn't preserve angles, and is used to break up polys with >3 indicies.

A triforce-shaped triangulation, which preserves the angles of the original poly. Currently, it can only be applied to tris, so right now a centroid-based triangulation is applied to any polys with >3 indicies before applying the triforce triangulation. This is great for creating detail is meshes before applying warps like greeble().

A tesselation for quads that splits them into smaller quads. A quad is a poly with 4 indicies- basically a rectangle or square. Tessellating quads into more quads preserves the original intention of the poly better than splitting it into tris. It's used in our shape:tessellate() algorithm in conjuction with the triforce-shaped triangulation to create more detail on shapes before applying ceratin warps.

Here's a hand-drawn picture from yours truly to show what the different triangulations look like:

Aaaaand finally, I wrote a Greeble function!!! w00t!!! Greebles are small, repeated details added to the surface of a mesh to give it the appearance of detail and scale. For a classic example, think Star Wars ships:

My plan moving forward is quite exciting: between now and the new year, I want to jam on generating a complete bomber-sized ship. I feel pretty good about the library of shapes, warps, and tools to use and combine them that I have built up. Previously, I wanted to work on station parts first, but I hit a wall with them because of their complexity. Station parts need to look extremely functional, which leaves little room for experimentation and a lot of room to get frustrated about whether something looks 'real' enough or not. I can leave that frustration for later, once I have a grasp on generating something small & have built a more robust Style system. A small ship would just be more exciting and a bit simpler. In addition, this would give me a more solid base to work on to iterate on the Style implementation.

Expect exciting devlogs coming up! Thank y'all so much for joining me in the 3rd devlog of my LT journey. Remember that I've got one last devlog after this until 2018! But you can always catch me on the forums, Twitter, or the IRC in the meantime

P.S.: for anybody who enjoys my blog tutorials - I WILL be writing a greebling tutorial & a triangulation tutorial soon! Let me know in the comments which of those or other topics you'd like to see.
Here are the tutorials on procedural greebles and tessellation and triangulation!

"You’ve got to work on something dangerous. You have to work on something that makes you uncertain. Something that makes you doubt yourself... because it stimulates you to do things you haven’t done before. The whole thing is if you know where you’re going, you’ve gone, as the poet says. And that’s death."
- Stephen Sondheim

Nice progress.
Do you already cull non visible polys / polygons inside a solid body? Or is the algorithm preventing them in the first place?

I also think the object would now profit from having a dynamic shadow casting onto itself. Is there any plans for a shadow system?

Depends on whether you're asking about culling at render time or shape generation time. We do have backface culling at render time, which does not remove polys from the mesh- it just doesn't draw them if you can't see them. At generation time, however, we may be applying a random combination of warps to a shape, which would create a situation where it would be difficult to impossible to predict or find polys that aren't visible outside the mesh. Does that answer your question? ^^

"You’ve got to work on something dangerous. You have to work on something that makes you uncertain. Something that makes you doubt yourself... because it stimulates you to do things you haven’t done before. The whole thing is if you know where you’re going, you’ve gone, as the poet says. And that’s death."
- Stephen Sondheim

Fantastic work, LT is definitely going to have some astounding ships and stations.
A couple things though,
What do the collision boxes for these shapes look like? my main concern here is that visually there will be empty space, but you slam into the invisible wall of a mismatched collision box.
Can these warp functions be ran in an arbitrary sequence an arbitrary number of times? if so could I request a torus that's been extruded, beveled, extruded, beveled, extruded, axial pushed, greebled, and then beveled one last time and if it looks pretty cool, could you make a cluster of them?
Have you thought about having concentric frame tessellations?

For some inspiration, have a look at some of my favorite structures in nature, diatoms!

Challenging your assumptions is good for your health, good for your business, and good for your future. Stay skeptical but never undervalue the importance of a new and unfamiliar perspective.Imagination Fertilizer

Any chance that you will get your own section in the book "Architecture of a Universe", Lindsey? And can we high tier backers get one of your drawings to accompany the scribblings of Josh? Although it will be awesome to receive a page from Josh it would be equally as awesome to receive one of your concept drawings.

I'd push my luck and ask if François could include a sheet of music from his score for Limit Theory but perhaps that's a step too far.

"The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time." —Tom Cargill

Before the break, I had begun working on Style. Style is the object to generate and store all of the properties that make a faction's aesthetic unique.

Well, thar archimatrix stuff forgothisname posted in the other devlog thread had some interesting concepts that may be usable for that end.

You can create prefabs which also encapsulate rules on placement.
So if you can get a similar system running it would be very beneficial for such ends.
At least for detail/surface elements.
Take object -> apply "style" elements.

Maybe warps and transformations can be packaged and reused as well in a similar fashion?

A different thought on the style thing would be to generate models with some parametric sheme and with enough parameters left free to change them into a large variety of ship/-classes.
So the engine doesnt have any clue about the style, but still creates similarily styled ships by varying the parameters.

Both shemes require a powerful parametric design framework which is probably a big obstacle in itself

Great stuff Lindsey, thanks for taking the time to update us and provide shinies. It's great to see a team working on LT; I can't imagine what a relief it is for Josh.

My perception is that problems like this - which are particularly difficult to hand-code - are generally solved by machine learning these days. Have you guys considered, now that you have the basic shapes and transforms, knocking together a ship editor and releasing it? Then we can all play around and submit our ships back to you guys so that you can train a machine learning algorithm?

It would offer another solution to the problem in addition to whatever hand-tuned algorithms the dev team come up with.