Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Raenir Salazar
Nov 5, 2010

College Slice
:sickos:





On a side note, python is completely unuseable for this sort of task I'm doing; every voronoi library seems designed with like scipy in mind or otherwise missing crucial features like "a list of voronoi faces". The one Python port of the Triangle.Net library which is whose C# Port I'm using is like missing most of the functionality for some weird reason.


Anyways, what finally seemed to work was a combination of padding along the edges (25px) and adding corner sites before computing the delaunay triangulation; which I then smoothed/relaxed with loyld's algorithm that came with TriangleNet.

Even works with a smaller number of points:



Now I'm pondering exactly how to go about terrain generation. The Redblobgames approach is still a little too random for me at least on a world-map scale.

What I'd ideally like is the ability to specify a number of continents, say 3-5 and get somewhere in that range that number of large landmasses.

Everything else past that conceptually there's enough resources on in abundance for things like biomes, although nice mountains is probably going to be challenging but the main challenge is being able to specify hyper parameters like number of continents while still having some nice island chains or archipelagos appearing semi-randomly as a result.

The approach I'm currently considering is kinda similar to some plate tectonics simulations I've seen other procedural projects experiment with but with a twist.

Suppose I randomly divide each cell into land or water,
Then I randomly distribute some number of continents, say 3.
Then assign each cell a speed and a direction,
Where the direction is the closest centroid of a randomly distributed "continent".
Then iteration a number of times as what cells are "land" shifts as they drift towards each other.

This speed is going to need to be scaled according some sense of "size" of the map, a map with 10,000 cells a cell is going to need to move faster or go through more iterations than a map with just 1,000 cells.

Could be interesting to have it so if cells bump into each other they slow down and gain in elevation or move as a group in the average of their combined vectors. Not sure if I'm basically reinventing the wheel for plate tectonic simulations but doing it this way I hope I do something like "Generate three continents" and maybe some random islands also show up as a result.

An alternative that is probably much faster is to do a random flood-fill at N points (N being the number of continents) distributed semi-evenly from each other; but might not get me island chains and the like.

Adbot
ADBOT LOVES YOU

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

leper khan posted:

Can you get away with reloading assets instead of reloading? Otherwise I generally recommend setting up a build pipeline that doesn't include you going through the build menu in unity on your dev machine.

I've been doing a lot of saving and reloading assets, and it doesn't seem to do anything to the preprocessor. And yeah, I've been using the Build Automator asset, plus a script I wrote to update to Steam. They've been great, but they do kind of rely on me being able to change the preprocessor directives.

Raenir Salazar
Nov 5, 2010

College Slice


Finally finagled a bounded voronoi diagram out of my library.

Most importantly, I now have a submesh for every voronoi cell polygon; my next goal is to display each cell with different colours.

lord funk
Feb 16, 2004

Raenir Salazar posted:



Finally finagled a bounded voronoi diagram out of my library.

This is great and I'm enjoying watching the steps.

Raenir Salazar
Nov 5, 2010

College Slice

lord funk posted:

This is great and I'm enjoying watching the steps.

Thanks! As a treat, I managed to find my old code for adjusted the voronoi cell vertices.

Basically as described better than me here: https://www.redblobgames.com/x/1721-voronoi-alternative/

I have a problem where some of the voronoi vertices (the blue points) aren't inside their respective triangles and also sometimes
the edges along the voronoi cells might be kinda stupidly narrow.

Ideally because the delaunay mesh can be used for things like pathfinding between cells it would be nice if the delaunay edge between the centers of two voronoi cells actually crossed the shared edge (i.e the White edges and black edges described in the link).

I'm not 100% yet on when exactly this will matter but its nice to get it out of the way.

After fixing some mind bogglingly inane bugs I got my code to work:



On a whim I decided to test 5,000 sites:



ITS BEAUTIFUL.

Note, I am using some random jitter thinking it might making it nicer, but as it turns out +/- 2.5 pixels is actually really important when you have 5,000 cells on a 1024 by 1024 texture! :haw: result is many cells are no longer convex! To potentially a non-trivial degree question mark?

Potentially a problem, but on the other hand the cells are starting to look distinctly like Paradox provinces, which is a bonus, and kinda a goal; if the "look" of the cells it turns out to not matter under the hood this might be pretty good as long as it has no significant abnormalities like a vertex being moved into a whole over cell etc.

Next step is still to actually colour these in but I got side tracked by the above.

Xerophyte
Mar 17, 2008

This space intentionally left blank

Raenir Salazar posted:

Note, I am using some random jitter thinking it might making it nicer, but as it turns out +/- 2.5 pixels is actually really important when you have 5,000 cells on a 1024 by 1024 texture! :haw: result is many cells are no longer convex! To potentially a non-trivial degree question mark?

This indicates that there's a problem in your tile generation. Voronoi cells generated using the 2-norm in Euclidean space are always convex, no matter how the centra are generated.

I'm not familiar with meshing Voronoi tessellations but at least in texture generation this tends to happen when someone is not checking enough centra for closeness at each pixel. For example, a common approach is to generate a Voronoi tiling by first constructing a regular grid over the region of interest and then randomly selecting N Voronoi centers in each grid cell. People sometimes assume that in this method the closest center to a particular point must be either in the point's grid cell or in one of the 8 surrounding cells. That's not necessarily true, and there are situations where the closest center is up to two grid cells away.

Another approach I've seen to generating centers is by randomly offsetting (and possibly deleting) points on a regular lattice. Then the search size depends on the max size of the offset compared to the distance between points on the lattice, which can be moderately tricky to get right.

Raenir Salazar
Nov 5, 2010

College Slice

Xerophyte posted:

This indicates that there's a problem in your tile generation. Voronoi cells generated using the 2-norm in Euclidean space are always convex, no matter how the centra are generated.

I'm not familiar with meshing Voronoi tessellations but at least in texture generation this tends to happen when someone is not checking enough centra for closeness at each pixel. For example, a common approach is to generate a Voronoi tiling by first constructing a regular grid over the region of interest and then randomly selecting N Voronoi centers in each grid cell. People sometimes assume that in this method the closest center to a particular point must be either in the point's grid cell or in one of the 8 surrounding cells. That's not necessarily true, and there are situations where the closest center is up to two grid cells away.

Another approach I've seen to generating centers is by randomly offsetting (and possibly deleting) points on a regular lattice. Then the search size depends on the max size of the offset compared to the distance between points on the lattice, which can be moderately tricky to get right.

Hrm, maybe I wasn't clear, I am after the fact taking the voronoi mesh, which was convex, and then shifting the vertices that comprise each voronoi cell, so these vertices are shifted into the delaunay triangles (because this isn't guaranteed from the voronoi output and is supposedly desirable); as per the link I gave to RedBlobGames. Then I am applying a random jitter on these vertices, randomly shifting them by + or - 2.5px along either axis; the result of which when the cells are barely like 10 pixels across is potentially a significant amount of movement.

If I just have like 600 cells on the same sized area (1024 by 1024) or the same 5,000 on 8,000 by 4000 texture then these effect goes away because now the cells are large enough again that their vertices shifting slightly doesn't change their convexity.

Xerophyte
Mar 17, 2008

This space intentionally left blank
Ah, my bad, sorry. I did not read the link, and did not understand what transform you are doing. I assumed that the adjustment and jitter were to the Voronoi centra. I see how shifting the vertices of the polygon like that will result in concave regions.

Raenir Salazar
Nov 5, 2010

College Slice
No problem!

And it'll only be concave if the cell size is absurdly small or the jitter large. A couple of pixels when the cell is large isn't likely to leave the little "circle" you can fill inside a triangle.

Progress.



I go through a process of taking every cell, re-triangulating by its vertices, transform them into a Unity3D mesh, and then assign UVs to those vertices. I have a 32 by 32 texture divided into 4 colours and I assign a colour randomly between those four quadrants. I then recombine the meshes using the inbuilt Unity means. I'm not sure if there's a fast algorithm to recombine meshes that share vertices.

I think that was a slightly weird way to go about it with a little too much math to pick a quadrant, I think next time I'll just procedurally generate a 1 by N texture where N is my number of colours and then its simpler to pick a single pixel at randomly to assign the colour to the whole "face".

(My four colours were black, red, green, and blue; originally white but this made it difficult to debug when initially it turns out all white! Switching white to green let me confirm that yes it was working but my coordinates were wrong; first they weren't in the right quadrants, I had mixed up rows and columns, and then I had the basis wrong as UVs are 0 to 1 along each axis and not the dimensions of the texture).

Raenir Salazar fucked around with this message at 03:07 on Nov 10, 2022

worms butthole guy
Jan 29, 2021

by Fluffdaddy
I've been slowly making a game in MonoGame mostly out of boredom but also as a excuse to learn C# and OOP. For the latter, I'm having trouble deciding what should be OOP or not in a game.

Wondering what approach you goons have taken. I feel like I'm at a point where I need to rewrite my game lol

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Experience, mostly. You gently caress it up, see what went badly, and make different mistakes next time.

There's a lot to be said for getting enough into the prototype stage that you can evaluate whether your game design is actually fun to play before knuckling down to rewrite the dodgiest parts - then your rewrite can focus on supporting your next design iteration instead of the one that you're just about to throw out.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Ok thats good to hear and makes me feel better lol. I think I am at that stage where I could devote a bunch of time to make my prototype work but it might be worth it to rewrite it and change the gameplay up even more.

I think jumping back into MonoGame instead of Unity made me appreciate things like Unity much much more though for prototyping.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Just gonna second what Jabor said. The most important consideration when it comes to making games is actually making the game, which means that oftentimes things like "good software design" end up taking a backseat. This is especially the case if the bad code has very limited scope. For example, it doesn't really matter if a particular bit of AI is a total hack, if that AI is only used for one small thing. It becomes more important to use good designs the more the rest of the codebase comes to rely on a given component.

Oftentimes games end up being split into "core" and "content", where the core provides fundamental infrastructure, and then the content is a million tiny modules that mostly only talk to the core, not each other. Invariably the content side of things ends up being way messier.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Yeah that does make sense. I guess in retrospect my issue is in understanding how games work; for example, I was having trouble getting a sprite to change position because every time Draw() was called it would reset it to the initial position. Which is probably due to me not fully understand how everything works yet lol.

Raenir Salazar
Nov 5, 2010

College Slice
Colour progress:


Now with say 40% chance of being a shade of grey vs 60% chance of some shade of blue.


I got to reuse the HSV unique colour generator from earlier. :shobon:

Bongo Bill
Jan 17, 2012

Object-oriented programming and games don't mix very well. OOP works well for complex programming abstractions and for really well-understood rigid data hierarchies, and neither of those are characteristic of games. But you'll probably learn a lot by struggling with it.

If you want to learn something else, Entity-Component-System architecture is very commonly used in games, and is very different from the kinds of designs that OOP will lead you toward.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Is ECS what Unity uses?

lord funk
Feb 16, 2004

Bongo Bill posted:

Object-oriented programming and games don't mix very well. OOP works well for complex programming abstractions and for really well-understood rigid data hierarchies, and neither of those are characteristic of games. But you'll probably learn a lot by struggling with it.

I'm glad I know OOP well enough to recognize how much it sucks compared to component-based designs. I'm working in Unreal right now and putting stuff inside components / attaching them to things is just *so much better* than OOP.

Raenir Salazar
Nov 5, 2010

College Slice
OOP principles will be useful for *some* things, particularly interfaces. If you're making like an RPG there's going to probably be a lot of good use cases for OOP/inheritance/polymorphism. Anytime you think you have a situation that's like, "I have a bunch of different fruit, that all tastes different and would like a common way of interacting with them..." boom, oops?

lord funk
Feb 16, 2004

Raenir Salazar posted:

OOP principles will be useful for *some* things, particularly interfaces. If you're making like an RPG there's going to probably be a lot of good use cases for OOP/inheritance/polymorphism. Anytime you think you have a situation that's like, "I have a bunch of different fruit, that all tastes different and would like a common way of interacting with them..." boom, oops?

I took an online Unreal C++ course by Tom Looman (which, big recommendation from me, if anyone's interested). In it, he builds an action RPG, and it's exactly the example he uses to recommend against designs like that.

Like, the fruit is an interactable item, and a health giving item, and maybe sometimes a pickup / carry item, and this overlaps sooo much with other things in the game like chests, doors, enemies, rocks, etc.. So it's better to just design the functionality once as a component, and attach it as needed. Really does save a ton of refactoring / reparenting woes, IMO.

It also really helps when checking for item type, because you don't. You just ask: does it have this component class? If so [do thing].

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Out of curiosity, I looked through the places I use abstract classes in my game. Here's a complete listing:

- The CoolShots system has a set of different Observers that take photos when different criteria occur. There's a standard interface for the observers so the general system can check their scores, tell them to take shots, etc
- There's a root "something was destroyed" event which has specific subclasses for ships, buildings, and aircraft
- On a related note, there's a root Damageable class that has implementations for ships, buildings, and aircraft. In retrospect I probably should have separated out "how does this thing die" from "what kind of object is this" -- PlaneDeathEffect is responsible for making planes tumble and smoke as they fall into the ocean, and then returning them to the plane pool, but it's also often used as shorthand for "is the thing I'm looking at a plane", and that's kind of awkward.
- There's a root class for different script triggers in the mission script, e.g. "an objective was achieved", "the player touched an invisible volume", "a ship was destroyed", etc
- The different aspects of setting up free-play/quick-action mode implement a root class. This handles things like "which UI element is left/right/up/down from me" for cursor movement, as well as simplifying applying config changes to the mission
- There's a ShipSteer root class which has SimpleSteer (for AI) and PhysicsSteer (for player) variations. This is more about having ships use physics to turn and track the ocean altitude than it is about deciding where to go. I'm pretty sure I could have handled this better.
- The big one: there's a root class for all weapon types, and the subclasses for different variations. E.g. there's a ballistic version, a hitscan version, a version for weapons that don't care about elevation, etc. ~80% of the code is in the root class, with subclasses typically only overriding one or two functions. Still, I'm reasonably happy with this setup. The subclasses are very tightly coupled to the root class, so refactoring them out would have been moderately painful.
- There's a root class for all cinematics, which handles setup and teardown, and also provides a handy place for commonly-used animation events like "play a sound", "trigger the mission script", or "adjust screenshake"
- There's four different root classes for various different UI widgets used by the options screen

Lucid Dream
Feb 4, 2003

That boy ain't right.
I've gotten pretty far with OOP, but I've definitely run into some of the predictable pitfalls along the way as well. I had "HeldItem" for anything equippable, which then branched out to MeleeWeapon and RangedWeapon, but eventually we wanted to add melee attacks to the guns or wanted to fire a projectile from a melee weapon. Over time more and more functionality moved back to HeldItem... and it became less and less of a problem. With OOP you definitely have to be more careful about properly defining your scope and it's probably best to have relatively shallow inheritance trees. ECS is neat because it's a lot more flexible, but at the same time there is a bit of a complexity overhead. You need to deal with stuff like how granular your components need to be, how they'll communicate, the order that they'll execute, etc. The benefits of ECS are pretty profound though, and It was pretty neat working on a spaceship game and realizing that I could make a space station by just adding the "cargo storage", "sensor suite" and "trading module" to a generic entity, and when I decided "Oh actually I want the space stations to move slowly" I just slapped a thruster and navigation computer component on them. I feel like both OOP and ECS are important and they're not mutually exclusive. Anyone making games should probably experiment with both to see where/how they are best utilized and the kinds of pitfalls you'll run into with them.

worms butthole guy
Jan 29, 2021

by Fluffdaddy
Omg everything everyone has said has been amazingly helpful. Thank you all so much goons

Raenir Salazar
Nov 5, 2010

College Slice

lord funk posted:

I took an online Unreal C++ course by Tom Looman (which, big recommendation from me, if anyone's interested). In it, he builds an action RPG, and it's exactly the example he uses to recommend against designs like that.

Like, the fruit is an interactable item, and a health giving item, and maybe sometimes a pickup / carry item, and this overlaps sooo much with other things in the game like chests, doors, enemies, rocks, etc.. So it's better to just design the functionality once as a component, and attach it as needed. Really does save a ton of refactoring / reparenting woes, IMO.

It also really helps when checking for item type, because you don't. You just ask: does it have this component class? If so [do thing].

I can only really speak to what I've seen during my day job as a game developer on a project that uses c++/unreal and we do use a lot of things that I assume is object oriented or adjacent to it in addition to components. We also use mainly c++ blueprints instead of blueprint-blueprints

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

lord funk posted:

I took an online Unreal C++ course by Tom Looman (which, big recommendation from me, if anyone's interested). In it, he builds an action RPG, and it's exactly the example he uses to recommend against designs like that.
It really is a fantastic example for this. Though to be fair multi-inheritance is a thing in object-oriented world, so you *could* do fruit inheriting from carryable, edible, throwable, etc. and it would be essentially the same thing as components.
But then you'd be tempted to simplify by putting an intermediate food class (carryable, edible), and have fruit inherit from food+throwable, and then later when you want to redefine food as a sandwich or a soup in a bread bowl, everything goes wrong. Component-first protects you from that tendency to prematurely abstract.

12 rats tied together
Sep 7, 2006

the main thing is that inheritance is for specialization, not for code sharing. multiple inheritance is usually bad for this reason because it becomes unclear which of the specializations are"true"

the OOP way to have Fruit be "Carryable" would be to have it be a subclass of an abstract type that has a PlayerPickupBehavior

you would compose all of the items in your game out of various types of behaviors. if NPCs can pick up items, your NPC base class contains the logic for talking to Items (calling NpcPickup() for example). Every item has an NpcPickupBehavior which, for example, lets assume is "NoPickup" which just logs a warning. For special items that can be held by NPCs you simply inject a different behavior.

Notably: some behaviors can be shared between NPCs and PCs, like NoPickup. The goal of OOP is to abstract the things that vary and provides a safe API at each level of abstraction, not necessarily to construct complicated inheritance trees, although that is sometimes necessary in business code

worms butthole guy
Jan 29, 2021

by Fluffdaddy
I did some reading up on ECS and that seems to be what I typically do anyways so that's cool. The only limitation is that of which I already have - I don't know wtf all of C#'s features are so not sure the best way to implement it lol.

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

worms butthole guy posted:

I did some reading up on ECS and that seems to be what I typically do anyways so that's cool. The only limitation is that of which I already have - I don't know wtf all of C#'s features are so not sure the best way to implement it lol.

Probably the right answer is to not implement it yourself, unless your goal is to implement an ECS instead of a game. High performance takes some time/effort for them.

https://github.com/sschmid/Entitas

worms butthole guy
Jan 29, 2021

by Fluffdaddy
I saw that :D and I think MonoGame Extended has a version too, although seems like Entitas would have more support

lord funk
Feb 16, 2004

Agreed with pretty much everything OOP related, and for sure it can work even for complex designs. I'm just really liking the workflow of components these days.

Raenir Salazar posted:

I can only really speak to what I've seen during my day job as a game developer on a project that uses c++/unreal and we do use a lot of things that I assume is object oriented or adjacent to it in addition to components. We also use mainly c++ blueprints instead of blueprint-blueprints

I'm trying hard to find the right balance between C++ blueprints and blueprint-blueprints. I love the idea of having an idea for a new enemy, and just whipping it up in its own blueprint. But as soon as I have to do any math in a blueprint I want to gouge my eyes out, so I head right over and make it in C++.

Raenir Salazar
Nov 5, 2010

College Slice

lord funk posted:

Agreed with pretty much everything OOP related, and for sure it can work even for complex designs. I'm just really liking the workflow of components these days.

I'm trying hard to find the right balance between C++ blueprints and blueprint-blueprints. I love the idea of having an idea for a new enemy, and just whipping it up in its own blueprint. But as soon as I have to do any math in a blueprint I want to gouge my eyes out, so I head right over and make it in C++.

Gotta say, huge massive pain in the Aye! Whenever I need to figure out what's going on with code I'm looking at for the first time when some of it is hidden away behind Blueprints in the Editor :mad:

more falafel please
Feb 26, 2005

forums poster

lord funk posted:

Agreed with pretty much everything OOP related, and for sure it can work even for complex designs. I'm just really liking the workflow of components these days.

I'm trying hard to find the right balance between C++ blueprints and blueprint-blueprints. I love the idea of having an idea for a new enemy, and just whipping it up in its own blueprint. But as soon as I have to do any math in a blueprint I want to gouge my eyes out, so I head right over and make it in C++.

Raenir Salazar posted:

Gotta say, huge massive pain in the Aye! Whenever I need to figure out what's going on with code I'm looking at for the first time when some of it is hidden away behind Blueprints in the Editor :mad:

I'm coming at this from a AAA-ish standpoint, but my feeling is that Blueprint is great for simple logic and hooking up behaviors -- "when an AGamePawn enters this area, trigger this cinematic". It's also good for designers to prototype some functionality and quickly iterate on it. But as soon as there's "real" logic, or a piece of functionality being used in multiple places, or it's time to get it production ready, it's time to give that to a programmer to nativize.

nielsm
Jun 1, 2009



Recommend me an engine/framework: (this question might have been asked 1000 times already)

I want to make a 2D side-scrolling puzzle platformer, inspired by the Lost Vikings. Target platform is PC with keyboard or controller input, no goals for mobile or console support. This would be a hobby project, so any license is acceptable but prefer free-of-charge things. Are there any good+mature engines specifically for this style of game, or is a generic engine (Godot, Unity, something else?) just as good?

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

nielsm posted:

Recommend me an engine/framework: (this question might have been asked 1000 times already)

I want to make a 2D side-scrolling puzzle platformer, inspired by the Lost Vikings. Target platform is PC with keyboard or controller input, no goals for mobile or console support. This would be a hobby project, so any license is acceptable but prefer free-of-charge things. Are there any good+mature engines specifically for this style of game, or is a generic engine (Godot, Unity, something else?) just as good?

You can use basically anything for that and it'll work out well enough. Decide on implementation language and whether you want to be code-oriented or editor-oriented and the choice will make itself.

Cory Parsnipson
Nov 15, 2015
If I have multiple shaders, do they execute in a specific order? Does it depend on what engine I'm using? (It's godot 3.5)

For example, if I have a shader that darkens the screen, and then I want another shader that draws a circle somewhere, how do I know which effect will show up on top/bottom?

I can't seem to find the answer to this anywhere, but I saw a somewhat related question about how to apply multiple shaders to the same sprite and basically they said you can't do that, you need to incorporate all the shader code into one shader, or swap out textures/materials if they don't have to be active at the same time.

e. Actually, I think I just realized that the shader is run sometime shortly after the node/material it's attached to is rendered to the screen buffer. Or whatever godot does to process it's scene tree. Sorry, this is new stuff to me. Are there situations where this ordering is ambiguous and might bring up my original question?

Cory Parsnipson fucked around with this message at 21:07 on Nov 17, 2022

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
One of the things the engine is responsible for is deciding in what order to draw things. Generally there's some amount of automatic sorting (e.g. by distance to the camera) as well as manual sorting (where the developer says "I need *this* to happen before *that*". For example, in Unity there's the concept of a render queue, which is just a number that's assigned to a material, and materials are drawn in ascending order of render queue. By default, all opaque materials have numbers near 2000, and all transparent materials have numbers near 3000, but you can manually assign a queue if you want. If two materials share a queue, Unity just draws them in whatever arbitrary order it wants to -- probably there's some optimizations there to batch draw calls whenever possible.

Cory Parsnipson
Nov 15, 2015
Oooh ok. Thanks, the term "render queue" and it's equivalent in godot has been really helpful!

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
I have a performance issue in my game, where I'm getting a lot of memory churn (about 12KB/frame). I have a system that draws "tethers" between two objects by manually positioning particles along a CinemachineSmoothPath. The path's nodes are updated every frame, then I ask it for positions along the path length, and put particles at those positions. But it looks like Cinemachine does some allocations when the path nodes change:



The code looks like this:
code:
        // Draw a beam from the emitter to us, using our particle system.
        // First, update the path they'll follow. Waypoints are in reverse order
        // (i.e. particles end at waypoint 0). Waypoint 0 ends at plane position
        var planePos = leash.plane.transform.position;
        leashPath.m_Waypoints[0].position = planePos;
        leashPath.m_Waypoints[2].position = leash.origin.transform.position + Vector3.up * 250;
        leashPath.m_Waypoints[1].position = (leashPath.m_Waypoints[1].position + leashPath.m_Waypoints[2].position) / 2;
        // HACK just trying to get CinemachineSmoothPath to behave
        leashPath.m_Waypoints[1].position = (leashPath.m_Waypoints[1].position + leashPath.m_Waypoints[2].position) / 2;
        leashPath.m_Waypoints[3].position = leash.origin.transform.position;
        leashPath.InvalidateDistanceCache(); // HACK: otherwise path gets really weird in the middle

        if (particles == null || particles.Length < leash.effect.main.maxParticles) {
            particles = new ParticleSystem.Particle[leash.effect.main.maxParticles];
        }

        int numParticles = leash.effect.GetParticles(particles);
        float maxAge = leash.effect.main.startLifetime.constant;
        for (int i = 0; i < numParticles; ++i) {
            float t = particles[i].remainingLifetime / maxAge;
            particles[i].position = leashPath.EvaluatePositionAtUnit(t, CinemachinePathBase.PositionUnits.Normalized);
            particles[i].velocity = leashPath.EvaluateTangentAtUnit(t, CinemachinePathBase.PositionUnits.Normalized).normalized * leashPath.PathLength / maxAge;
        }
        leash.effect.SetParticles(particles);
Cinemachine isn't really the correct tool for this, but it let me easily calculate smooth splines that pass through specific points. I'm sure there's a better solution; my hope is that y'all can recommend it to me so I don't have to go digging it up myself.

Raenir Salazar
Nov 5, 2010

College Slice
I exit my cave bearing manuscripts.





The next main task aside from some refactory and rearranging my code to be a little easier to use, was to bring order to the chaos.

My goal is to start working on creating tectonic plates to simulate plate tectonics for the purposes of crafting a more interesting looking procedural world, so looking at other guides/examples online the go-to is I will need a sort of random floodfill on my voronoi map.

A few minor tools I needed was to be able to pick an arbitrary coordinate and associate it with the nearest voronoi cell; I setup a free K-D Tree library inputting in my Voronoi Cell Sites (as Vector3's from TriangleNets Vertex's; I have no idea why the person who ported the library didn't use Unity3D's default engine types or add like a wrapper for Triangle's types :psyduck: so now I have to constantly convert back and forth between a "Vertex" which is just a Vector3 but its doubles while Unity uses floats! And it doesn't just let you interchange them, I gotta cast from double to float and vice versa!!) so now when I picked new points at random using poisson disc distribution; which let me pick sites that were semi-evenly spaced apart while still reasonably semi-random.

After fixing my infinite loops I got a result, which was weird! As if my cells were being offset when being rendered. The problem mercifully was a simple but subtle one; my UV coordinates were slightly wrong!

Normally UVs as I'm sure everyone knows go from 0.0 to 1.0; so if I had 100 cells I assigned it so the vertices of each distinct cell all occupied the same UV coordinate; with the idea I'd create a texture that had N by 1 pixels where each pixel corresponding to a given voronoi cell for colouring purposes. I imagine there are many ways I could do this, like creating a texture that was just, every colour? And then assigning cells UVs according to the pixel coordinate etc; or only creating a texture that only had the number of colours and so on. But this is my hole and it is meant for me!

But anyways, so Face with ID 0 would be 0/100 (if 100 faces), ID Face 1 would be 1/100; but the pixels/faces are from 0 to 99 as integers and 0 to 1 as floats but I was dividing by 100. So 99/100 would be 0.99 instead of 1.0 but the 99th pixel in my 100 by 1 pixel texture is NOT going to be the 100th pixel; so resulting in a slight offset that only became apparent when I was actually very carefully eye'ing the colour of my cells; versus when I was just randomly colouring them and thus didn't notice there was a mismatch.

I probably should've corrected it to be ith Cell ID divided by Total Number of Cells - 1, or something but instead I opted to add a slight offset of (1/2)/N so the pixel coordinate should always now lie in the middle of a pixel and not on the border of one.

My process to debug this was to render/save to disc the incremental steps which revealed something was VERY wrong was somehow I'd see a cell with 8 edges appearing as a cell with only 5, and then the reverse, and then 2 cells being printed at the sametime, etc. Inexplicibly weird behaviour as I ruled out it being an index offset of faces to colours or stealth edges that maybe connected to the wrong edges etc; thankfully nothing seemed to be wrong (yet) with any of my underlying libraries.

The fruit of my labour is thus the above gif, as I took all of the images of my latest batch and put it into gimp. :D However for larger numbers of cells (and thus iterations) this seemed to crash my computer; which maybe indicates an underlying problem or perhaps a memory leak with RenderTextures or something but it doesn't occur with more reasonable numbers so I'll push it aside for now and make more progress.

My next step would be to generate some landmasses; my main constraint that makes many other methods unusable for me is I'd like to be able to specify the number of continents. I.e suppose I want three continents. Perlin/Simplex noise can't guarantee a number of continents nor even specific features and required so much work to extract features that it made it difficult to also be in real time which was my other desire for a generator that would make it easy to iterate through different maps either through real time deformation through sliders or quick generation via a button press.

My Plate generation can easily now be repurposed for making continents; same basic idea, choose N random evenly spread apart points, randomly flood fill until they reach a certain size. My general idea is to specify a Land vs Sea budget, like say a 30-70 split; so if I have 1000 cells; then that means a land cell budget of 300; and if I have three continents then I would randomly distribute the cells between them, like suppose one continent has to be Large, so it gets most of the budget, like 70% of that land budget and the other 2 gets to split the remaining 30%, so 220 goes to one and then the remaining 80 gets split by some random percentage thats between 30 and 80.

Similarly I could set up a budget for "large islands" through a similar process, etc.

So instead of flood filling until I fill out the map, not desired! I could flood fill until I run out of "land cell budget".

I could also turn it around and actually generate seas and landmasses just like plates; so if I have 3 continents then I could have 7 oceans; lets lets me get the "ocean" information bird with the same algorithmic stone?

Although trying to seed "islands" as smaller masses than continents would be trickier this way vs having a budget...

After that, I would assign (2D) force vectors to my plates; which would let me populate a mapping of Convergent, Divergent, and Transform plate boundaries; which based on their Plate-Type (Oceanic vs Continental), Plate-Age (Oceanic tends to be Older IIRC?), Plate-Density, and Speed; let me guestimate the features around the fault lines.

My plan isn't to do a full simulation of having plates bumping into each other to simulate the geologic history of my world etc, I think that is both overkill and probably too much work for my goal of wanting nice mountains, interesting and diverse terrain features and rivers. I think I can just from a polygonal approach, just abstract these things using distance formulas, a little bit of noise, and so on.

My references being mainly from Red Blob Games: http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/ https://www.redblobgames.com/x/1843-planet-generation/

His approach in his first link has his mountains gaining in elevation as you go towards the center of the island; while his continents in his world map generator seem to be from perlin noise/random, so there's an interesting amount of challenge in trying to maneuver through the gaps of where my requirements aren't present on the shoulders of the giants I am climbing onto.

One thing I need to make a note of is I think my "Random Floodfill" is wrong; currently I am taking turns between different centroids when filling from their respective open lists/frontiers; I had initially made the order of these frontiers random when I enqueue the neighbours of the current tiles into the open list. But I think instead what should be random is the order in which I am picking centroids to floodfill from?

e: Seems my intuition was correct!



Randomly picking which blob to flood fill from seems to result in some blobs/plates being larger than others. Presumably the weirder way more concave shapes might not be desirable for tectonic plates but if I figure out the optimal number of plates it is probably fine?



e2: One last issue to work out is improving my picking of initial sites. I am using as mentioned a Poisson Disc Sampling method, but for smaller radii and for a smaller Ns on spacious grids results in large gaps; when I want my points to be somewhat evenly distributed across the space with jitter.

I could make a separate voronoi grid, relax it a bunch of times and use those sites as my plates. But the input number of sites isn't going to be gauranteed to be the output number of vertices for my triangulation.

I think I'll attempt a sort of strategy where I use layered poisson samplings with decreasing R to fill out the space. Like divide up the plane into quadrants, and then do like iterative samplings within each quadrant, than octant etc.

So for a 1024 by 1024 pixel grid, start off with something like a radius of say 256; proceed until the point PDS normally exits and then repeat but with a radius of 128; then 64, then 32, etc. This should hopefully place points all over the place without major gaps.

Raenir Salazar fucked around with this message at 05:48 on Nov 24, 2022

Adbot
ADBOT LOVES YOU

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Are there any interesting assets in the unity store for tools? Also I would be interested in a high-quality model I could take apart and mess with to see how stuff is really done with animations.

I am also thinking about cinematics and shaders.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply