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
Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

ddiddles posted:

Is there any different between the new user experience with UE4 and Unity?

I've had this vague notion that it would be fun to hack on a simple game for a couple years, but every time I start up a unity project, I get the point where I'm building something thats more complex than moving an object around, and I just cant seem to find any guidance on how to do it. Any tutorial is the equivalent of a hello world website. For example, last time I gave up because even creating a simple UI was pretty daunting for a new user.

I fully accept I'm a lazy piece of poo poo who could just read the Unity docs, but I need to be visually hand held through things or it just doesnt stick. Is it any better in UE4? I picked Unity because it seemed like all the UE4 tutorials were blueprint based rather than code, and I'm not really that interested in learning that.

Video games are just a massive pain to make and are really complicated.

If you're having trouble with Unity, Unreal is probably gonna be worse. But Godot may do you better? Check out some tutorials to get a picture of it.

There definitely are youtube videos for creating a UI in Unity that walk you through it. Although with any project they're going to show you the basics and you're going to have to be able to extrapolate your own specific game needs, but we can help ITT.

Or honestly look at something like Game Maker or RPG Maker if you really want to skip the BS and get right to the game part of game making instead of coding an engine.

Adbot
ADBOT LOVES YOU

ddiddles
Oct 21, 2008

Roses are red, violets are blue, I'm a schizophrenic and so am I

Zaphod42 posted:

Video games are just a massive pain to make and are really complicated.

If you're having trouble with Unity, Unreal is probably gonna be worse. But Godot may do you better? Check out some tutorials to get a picture of it.

There definitely are youtube videos for creating a UI in Unity that walk you through it. Although with any project they're going to show you the basics and you're going to have to be able to extrapolate your own specific game needs, but we can help ITT.

Thanks for the suggestion on Godot, for some reason I thought that was a 2D engine only, I'll check it out.

I come from the web dev world where everything is abstracted and wrapped up in libraries so I think my expectations were a bit high.

I have no issue writing scripts/setting up a singular game object to do what I want, its the systems that connect everything together I guess I was getting overwhelmed with.

xzzy
Mar 5, 2009

Game development is going to be overwhelming no matter what, because so many technologies have to come together in place and run in real time. You probably already know this, but just make sure to start small. Trying to recreate a AAA title your first outing will get you nowhere.

Unity is good because it has such a huge knowledge base that you can probably faceroll through any problem. The solutions will come from forum posts, but at least you'll get solutions. The downside to Unity is its a moving target, it's pretty hard to install the latest Unity and have all their awesome new features work together but if you rewind to features available a year or two previous you'll do fine. Godot is the current darling of the gamedev world and has a pretty cool community around it. UE4 is for the turbo nerd types because of its reliance on C++.

ddiddles
Oct 21, 2008

Roses are red, violets are blue, I'm a schizophrenic and so am I
Would you recommend Godot over Unity for a simple networked game? I'm just messing around with active ragdolls cause its fun, but when I went to look for a networking tutorial, Unity told me Unet was garbage and deprecated and no one should ever use it and to switch to DOTS, of which there was zero documentation (admittedly this was when it came out, might be better now).

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
What exactly do you have in mind? "Simple networked game" sets off alarm bells in my head, especially when you then talk about ragdolling and 3D, because just having all of those elements together in the same game suggests that it's probably not as simple as you think it is.

xzzy
Mar 5, 2009

There ain't nothing simple about sending physics over the network.

Yes, DOTS is the new hotness but it also doesn't have much community adoption yet so the knowledge base is a bit slim. You'll be doing a lot of digging on your own.

ddiddles
Oct 21, 2008

Roses are red, violets are blue, I'm a schizophrenic and so am I
I was going to try and recreate the quick 2v2 matches you get in COD but make it more goofy/cartoon-y and with a top down/orthographic camera so I didnt have to deal with two sets of animations. I thought adding in the fun of physics gameplay would be interesting, but you are right, I'm breaking off too much for the first go through, I cant even imagine how you go about syncing a ragdoll to other clients.

The physics part should definitely come later/in another game, I feel like I'm overcomplicating it. My main goal is to just make something stupid you can play with your friends using P2P and it'll run on a 10 year old machine.

Speaking of physics, I found that even syncing a physics based bullet that travels pretty slow can desync very easily, would you recommend just doing a hitcast and simulating bullet travel?

ddiddles fucked around with this message at 20:36 on Nov 6, 2020

more falafel please
Feb 26, 2005

forums poster

ddiddles posted:

I was going to try and recreate the quick 2v2 matches you get in COD but make it more goofy/cartoon-y and with a top down/orthographic camera so I didnt have to deal with two sets of animations. I thought adding in the fun of physics gameplay would be interesting, but you are right, I'm breaking off too much for the first go through, I cant even imagine how you go about syncing a ragdoll to other clients.

The physics part should definitely come later/in another game, I feel like I'm overcomplicating it. My main goal is to just make something stupid you can play with your friends using P2P and it'll run on a 10 year old machine.

Speaking of physics, I found that even syncing a physics based bullet that travels pretty slow can desync very easily, would you recommend just doing a hitcast and simulating bullet travel?

If the bullet's trajectory is deterministic once it's fired, there's no reason to sync that over the network. As long as all clients (and the server if there's a separate server) know the origin/orientation of the bullet, they can all simulate it locally. Depending on your network model, you may need one of the machines to be authoritative about what that bullet hits, but the visual/audio/etc simulation can be done separately.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

ddiddles posted:

Thanks for the suggestion on Godot, for some reason I thought that was a 2D engine only, I'll check it out.

I come from the web dev world where everything is abstracted and wrapped up in libraries so I think my expectations were a bit high.

I have no issue writing scripts/setting up a singular game object to do what I want, its the systems that connect everything together I guess I was getting overwhelmed with.

It can definitely be frustrating, but there are some good libraries.

You may want to try one of Unity's microgame project demos, you can take that and its basically an out of the box playable game but you have all the project code so you can tweak it from there.

They just put out this lego game and its pretty wild

https://store.unity.com/lego-microgame

https://www.youtube.com/watch?v=vME10ufz9Hc

ddiddles posted:

Speaking of physics, I found that even syncing a physics based bullet that travels pretty slow can desync very easily, would you recommend just doing a hitcast and simulating bullet travel?

more falafel please posted:

Depending on your network model, you may need one of the machines to be authoritative about what that bullet hits

yeah you're going to get into situations of having a master server, and this pretty quickly gets into the weeds of the challenges on the engineering side of networking.

Something like that, you're likely to spin your wheels for a long time trying to implement some crazy rollback netcode rather than making a game, so I would try to keep it as simple as possible.

So while you don't have to do hitscan, it sure helps. Things like that. Cutting corners where it won't ruin everything is important. Even with hitscan there's still lots of issues.

Zaphod42 fucked around with this message at 20:55 on Nov 6, 2020

ddiddles
Oct 21, 2008

Roses are red, violets are blue, I'm a schizophrenic and so am I

Oh nice, didnt realize they released a new project, thats awesome.

Thanks for the suggestions and advice dudes, I think the take away is I'm running before I'm walking, gonna rethink my idea to be single player since I have the active ragdoll kind of working already and tackle networking at a later date.

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

ddiddles posted:

Thanks for the suggestions and advice dudes, I think the take away is I'm running before I'm walking, gonna rethink my idea to be single player since I have the active ragdoll kind of working already and tackle networking at a later date.

Networked multiplayer at least doubles the scope of any game, so yeah, for a first effort I highly recommend going singleplayer if possible. Good luck!

Phigs
Jan 23, 2019

If you want to have your hand held you might want to check out one of the longer paid tutorial series. They tend to be more in-depth and have you building actual projects along the way instead of just showing you one out-of-context technique. They won't show you anything you couldn't learn elsewhere, but you're paying for the hand-holding really.

When I was looking there was a commonly recommended course on Udemy by Ben Tristram (only buy Udemy courses on deep discount, I think you can always get a sale or coupon for like 90% off). I also heard that the unity learn stuff is free now? If so there might be a couple courses there that fit the bill.

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
Got around to finally finishing my friend's suggestion:



This is actually pretty good, presumably it'll work in the Paradox engine's code.

Still kinda sorta have a problem of slivers, but they are easier to spot at least and maybe easier to solve.

I could ignore them, and let them be really small sea zones (not ideal).
Use a flood fill algorithm (that can handle concave polygons) to find them and merge any "rooms" under a certain size that aren't a land tile into the smallest adjacent sea tile "room".

However there's a second case; there's a concave sea tile that earns my direct ire over in the top right quadrant by a little island that's really concave.

Ideally I would break off the part of the tile that's jutting out and merge it to one of the adjacent ones, probably the one is shares the longest border with (easier than finding the one it's addition would make the least concave).

Hrm.

Raenir Salazar fucked around with this message at 04:16 on Nov 7, 2020

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
Current task, reinventing the wheel (of graph theory).



Basically I want to eliminate overly concave tiles like this one, particularly the bit that's hanging off on the right.

I can live with it keeping what remains, but can also live with a greedy algorithm that also eliminates the next most protruding bit; but around like to keep what remains.

Currently a rule I am thinking might work is if a given sea subcell, has only 1 connection to the rest of the main sea cell, AND it borders a land subcell which is bordered by say at least 3 sea subcells from the same sea tile; this the current subcell is a protrusion.

If any subcell has at least two connections to sea subcells from the same sea tile main cell than it's fine.

Another possibility for finding protruding bits is just to do like a search that detects the dead-end "branch" and then flags it to be reassigned to different neighbouring cells.

Of course I'd also like to flip the discarded subcell into one of the neighbouring (sea) tiles. A secondary problem here is determining which cell shares the largest border with it or would be the least-most concave if appended to it.

If I take the bottom left bit, it only have 1 option, so that's easy enough. However if I were to break off the next bit, it has two sea tiles it borders, and borders two sub cells of each.

I could flood fill and compare the number of bordering pixels, but this feels unnecessary.

Maybe something along the lines of "number of border connections and number of border connections any of those bordering cells have".


So looking at the example above, after purging the first cell, the next most protruding subcell borders 2 subcells from the bottom right sea tile; and just two sub sea cells from the dark tealish looking water tile towards the top right. Which is a tie.

So in this case we know the cell has a friendly neighbour and they both border the same dark teal sea tile which might imply a degree of breadth to the border. However visually we know it borders dark teal a lot more. But I'm not confident that this is really guaranteed too always give good-enoughish results.


Another possibility is just come up with deriving a measurement of relative concavity based on the two or more possible resulting graphs and just pick the best one or if none are really better than skip.

But that is of course it's own challenge.

Almost feels like reinventing how Stellaris calculates empire cohesion but in this case trying to infer an extremely minor different between what at a glance seems like two fairly symmetrical changes.

Handing that second subcell to bottom right blue looks like its protruding more than than if I gave it to dark teal but looking at the connections it doesn't seem all that different.

LordSaturn
Aug 12, 2007

sadly unfunny

I immediately, instinctively recoil from solving this problem as posed. How about taking each sea region and lerping the center points towards the region's center (average of all points) by 5-10% or so?

I'd also consider defining some way of saying which member cell is the "most peninsular" and culling that repeatedly until you're satisfied with your lack of peninsulas. Number of outside neighbors? Ratio of outside neighbors to inside neighbors? <inimum pie-slice angle to contain all inside neighbor links? Anything but actually thinking about graph theory, god forbid.

EDIT: I really like the first solution, but it does assume you can recalculate your voronoi diagram. I used to have a voronoi soap-bubble sim that just did this once per frame, so I'm proposing some similar "get it a little closer to ideal" approach that you could iterate a couple of times, maybe have inside neighbors exert an attractive force on each other?

LordSaturn fucked around with this message at 06:19 on Nov 12, 2020

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
Recalculating my voronoi isn't really an option I think, I basically just want to take the existing diagram and sanity check it because if I have to regenerate it then I think it might just create more opportunities for issues that need to be fixed. Also doesn't really mesh well with how I'm producing the map.

Current process is:
-Generate Points (evenly spaced rows with an alternating offset, by coincidence this forms hexagons)
-Generate the delaney diagram (this is using the Triangle.Net C# library/port, its a bit of a blackbox, so I'm under a bunch of limitations not knowing what half the things it can do except by trial and error).

Do the above three steps *again* but for the sea zones, there's about 1/10 (~100 vs 1000 land cells for testing purposes).

Note that because I am reassigning tiles so the actual number of land tiles is going to be less than 1000.

-Take the delaney mesh and create a voronoi diagram (same library as above)
-Use a flood fill algorithm to paint in each cell. If its a land tile (based on checking the height map I generated) paint it some random (but unique) red-green hue colour. If its below some threshold, assigned it one of the pre-generated colours for the sea zone the cell's site happens to reside within from the sea zone diagram. Basically I take the "land cell" which is my base layer, take it's site and check which cell it is within from the sea zone voronoi diagram and assign it the colour based on the sea cell id.

Currently I'm implementing a graph data structure for storing the resulting voronoi diagram with two layers (one for the overall "tiles" and a second one for the underlying subcells) since I imagine it might have a lot of use later on. Especially when it comes to carving out rivers or something later, and more quickly calculating which areas are coastal, etc.

Because I basically only really have a texture as a end result there aren't a whole lot of options to go back and fix things, I can probably recolour specific subcells but I'm working on implementing some datastructures to store that information better.

I have half a mind to implement something that will end up checking every sea tile and fixing it to not have those "teeth" looking bits as easier than making a solution that only fixes the worst protrusions and nothing else.

I haven't put much further thought into it, but basically want to limit my fixes to just flipping the resulting voronoi subcells and not fudging with their shape.

TheHoosier
Dec 30, 2004

The fuck, Graham?!

Another dumb question:

I want to call a method when a transform.parent.GetChild(thing + 1).gameObject gets to the end of the child count. Like Angry Birds: You use a bird, then you get the next bird, then the next bird until you run out. I want to reload the scene when I would reach the end of the "birds".

quote:

void NextBirdUp()
{
int childCount = transform.parent.childCount;
int index = transform.GetSiblingIndex();
GameObject nextBirdUp = transform.parent.GetChild(index + 1).gameObject;
nextBirdUp.SetActive(true);
}

I combed the docs and I think i'm missing it. Something like
if(nextchildcalledinarray > childCount)
{
GameOver()
}

I want to trigger GameOver when it would usually trigger the 'Transform child out of bounds' exception. The # of birds would be different for each scene so I'm trying to code a catch-all that's more efficient than doing a different method for each level.

As always, thanks for the help.

KillHour
Oct 28, 2007


Always get the first child and unchild them as you use them, then you can check the number of children before trying to grab the next one?

Honestly, I wouldn't lean on the parent-child thing for this. I would keep a list/queue of birds as a variable and work with that.

TheHoosier
Dec 30, 2004

The fuck, Graham?!

KillHour posted:

Always get the first child and unchild them as you use them, then you can check the number of children before trying to grab the next one?

Honestly, I wouldn't lean on the parent-child thing for this. I would keep a list/queue of birds as a variable and work with that.

So maybe try object pooling instead? I figured that for a small # of gameobjects that parent-child might be better but that's my lack of experience/knowledge for you.

KillHour
Oct 28, 2007


TheHoosier posted:

So maybe try object pooling instead? I figured that for a small # of gameobjects that parent-child might be better but that's my lack of experience/knowledge for you.

Object pooling is about disabling objects instead of deleting them so you can reuse them later to save performance. I don't think you need to worry about that. What I'm getting at is you don't need to use the scene hierarchy to keep track of them.

Let's say you have a class/component called Bird that inherits from Monobehaviour and does all the well... bird stuff. You might have a BirdManager component that has a List<Bird> where you keep track of all your active/available birds. You can just remove birds as they're used, and when the list is empty, you're done. If you don't need to access any bird except the next one, you can use a Queue<Bird> instead.

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=net-5.0
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.queue-1?view=net-5.0

TheHoosier
Dec 30, 2004

The fuck, Graham?!

KillHour posted:

Object pooling is about disabling objects instead of deleting them so you can reuse them later to save performance. I don't think you need to worry about that. What I'm getting at is you don't need to use the scene hierarchy to keep track of them.

Let's say you have a class/component called Bird that inherits from Monobehaviour and does all the well... bird stuff. You might have a BirdManager component that has a List<Bird> where you keep track of all your active/available birds. You can just remove birds as they're used, and when the list is empty, you're done. If you don't need to access any bird except the next one, you can use a Queue<Bird> instead.

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=net-5.0
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.queue-1?view=net-5.0

Awesome, I'll try it and report back if I somehow gently caress it up

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

TheHoosier posted:

I combed the docs and I think i'm missing it. Something like
if(nextchildcalledinarray > childCount)
{
GameOver()
}

I agree that there's more reliable ways to do it than using children, but as far as I can tell this should work exactly like you're asking, I don't see the issue.

you may need to do >= childCount if its 0-indexed but otherwise, should work.

TheHoosier
Dec 30, 2004

The fuck, Graham?!

Zaphod42 posted:

I agree that there's more reliable ways to do it than using children, but as far as I can tell this should work exactly like you're asking, I don't see the issue.

you may need to do >= childCount if its 0-indexed but otherwise, should work.

It still returns a Transform child out of bounds exception. It may be an issue of where each code is triggering. I set a Debug.Log to keep track of how many "dead birds" we're on with each iteration of nextBirdUp and it throws the exception before logging another instance of nextBirdUp when the last bird dies, so the if(x >= childCount) doesn't trigger.

I'm going to watch more videos and read more about using Lists; I thought I constructed it correctly, but received a 'Object Reference Not Set to Instance of Object' error when instantiating from the list.

in main 'Bird' script/component under the NextBirdUp():

var nextBirdUp = GetComponent<BirdManager>().Birds[0];
Instantiate(nextBirdUp, transform._startingposition, Quaternion.identity);

the List is in a BirdManager script/component:

public List<GameObject> Birds = new List<GameObject>();
I set the Size in the Inspector to 2, and loaded the existing bird gameobjects into index 0 and 1. Is that where I went wrong? Should I have done Birds.Add(redPrefab), Birds.Add(greenPreFab), etc. instead?


I may set it aside and do some more courses/lessons, then come back to it later. Or I may get frustrated enough to start posting tons of bad code who knows!!

Metos
Nov 25, 2005

Sup Ladies
If you dragged in the prefabs then what you actually have is a reference to the uninstantiated object. You can use that to instantiate, but can't use it in the game because it's not real yet.

You should instantiate it, then add the instantiated bird to the list using the .add method.

Going further ahead: This is where the object pooling mentioned previously would be useful, not for the disabling objects after they're done with part but for being able to get the right instantiated birds in the first place. You would call something like ObjectPooler.GetBird(BirdType.Red) which would return a reference to an instantiated red bird, which you'd then add to the list and position appropriately.

Fano
Oct 20, 2010
Hi folks, looking for some guidance on a problem I'm having since I think I may have coded myself into a bit of a corner and I'm early enough in the process that I want to try and do this in a proper way.

I'm currently working on a card game in Unity where I'm storing each card's data as a ScriptableObject:
C# code:
public class CardData : ScriptableObject
{
    public string CardName;
     // ... other properties
    public List<CardAttribute> Attributes;
}

public abstract class CardAttribute : ScriptableObject
{
	// base attribute class
}
As you can see, each card can have multiple attributes, one such example is a monster card attribute which stores Attack Damage and Health:
C# code:
public class MonsterAttribute : CardAttribute
{
    public int Attack;
    public int Health;

    // Not serialized
    public int CurrentAttack { get; set; } 
    public int CurrentHealth { get; set; }
}
Since these are simply data containers that are referenced by multiple copies of the same card, I cannot track an individual card's state using these attributes, so I have a different class that tracks the state of an individual card instance:
C# code:
public class CardState 
{
    private CardData _data;

   /* Other state info e.g. who owns this card? where is it on the board? */

    public CardState(CardData data)
    {
        _data = data;
    }
}
The issues that came up with this model may seem obvious - if I have two instances of some monster card that reference the same data, then changing the health of the MonsterAttribute would change it for all of the cards that shared the same data instance, I needed a way to track card attributes per-instance, so I very quickly threw this together:
C# code:
public class CardState 
{
   /* Other state info e.g. who owns this card? where is it on the board? */

    private CardData _data;
    private List<CardAttribute> _modifiableAttributes;

    public CardState(CardData data)
    {
        _data = data;
        _modifiableAttributes = new List<CardAttribute>();

        foreach(var attr in _data.Attributes)
        {
            var modifiable = attr.Clone(); // each attribute must now implement a clone method
            _modifiableAttributes.Add(modifiable);
        }
        // All other code now references _modifiableAttributes instead of the attributes held in CardData.
    }
}
The clone method in the monster attribute looks something like this:
C# code:
public override CardAttribute Clone()
{
    // can't use new keyword because CardAttribute inherits from ScriptableObject
    var copy = CreateInstance<Creature>();
    copy.Attack = Attack;
    copy.Health = Health;
    return copy;
}
This approach worked to fix my bug, but I'm starting to feel some code smells around creating scriptable object instances at runtime for the sake of tracking individual card state, it also warrants mentioning that there are many different types of card attributes in my game and not all are modifiable, but I am currently just cloning everything for the sake of consistency.

I am wondering if there is a better pattern for this kind of problem, it is currently pretty much a textbook prototype pattern but I am worried about eventually incurring some performance costs due to having to use ScriptableObject.CreateInstance() in the cloning logic for potentially dozens of attributes spread across 120 or so cards that are in play at one time. I thought about creating a separate set of classes to decouple the actual data from the scriptable objects that hold them, but as the number of attributes grow this seems like a maintenance nightmare.

Fano fucked around with this message at 21:19 on Nov 23, 2020

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
EDIT: naturally after posting this, I got it figured out. For the sake of completeness:

- Create a Matrix4x4 in the postprocessor script, that uses the camera's rotation. Pass that into the shader, along with the screen width and height (because i.vertex is in pixels)
- Divide the X/Y coordinates of i.vertex by width/height, then rescale to the range [-1, 1]
- Multiply that result by the camera rotation matrix
- Use the result of that multiplication to sample the cubemap

I'm working on my game's skyboxes, and how they interact with fog. Standard single-color fog doesn't look very good because the skybox's color can vary significantly depending on the direction you're looking in. Here's a minor example (without fog):





I figured I could write a replacement fog shader (replacing the global fog effect that deferred rendering uses) that would sample the skybox cubemap to determine what fog color to use. The problem I'm encountering is that the "vertex" coordinates passed to my fragment shader in the postprocessing effect don't seem to bear any relation to world coordinates. This makes some sense as they're really talking about pixels in a screen after everything's rendered already, but I'm at a bit of a loss as to how to convert them into texture coordinates for my cubemap.

Here's what the shader looks like currently (it's a mangled copy of the DeferredFog shader):
code:
Shader "Hidden/PostProcessing/SkyboxFog"
{
    HLSLINCLUDE

#pragma multi_compile __ FOG_LINEAR FOG_EXP FOG_EXP2
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Builtins/Fog.hlsl"

    TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
    TEXTURE2D_SAMPLER2D(_CameraDepthTexture, sampler_CameraDepthTexture);
    TextureCube _skyboxTex;
    SamplerState sampler_skyboxTex;

#define SKYBOX_THREASHOLD_VALUE 0.9999

    float4 Frag(VaryingsDefault i) : SV_Target
    {
        half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);

        float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.texcoordStereo);
        depth = Linear01Depth(depth);
        float dist = ComputeFogDistance(depth);
        half fog = 1.0 - ComputeFog(dist);

        // Sample skybox. i.vertex.xyz is wrong here
        float4 fogColor = _skyboxTex.Sample(sampler_skyboxTex, i.vertex.xyz);
        float4 c = lerp(color, fogColor, fog);
        return c;
    }

    float4 FragExcludeSkybox(VaryingsDefault i) : SV_Target
    {
        half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);

        float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.texcoordStereo);
        depth = Linear01Depth(depth);
        float skybox = depth < SKYBOX_THREASHOLD_VALUE;
        float dist = ComputeFogDistance(depth);
        half fog = 1.0 - ComputeFog(dist);

        return lerp(color, _FogColor, fog * skybox);
    }

    ENDHLSL

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

            Pass
        {
            HLSLPROGRAM

                #pragma vertex VertDefault
                #pragma fragment Frag

            ENDHLSL
        }

            Pass
        {
            HLSLPROGRAM

                #pragma vertex VertDefault
                #pragma fragment FragExcludeSkybox

            ENDHLSL
        }
    }
}
I can use the post-process effect script to pass camera data like the transform or forward vector into the shader. What I don't know is the correct matrix operation to use to get the sampling coordinates I need. I don't suppose anyone here has some insight? Thank you!

EDIT 2: well, maybe I don't got this.

https://i.imgur.com/hPO5CLp.mp4

The shader is the semitransparent overlay. You can see that its projection is wrong, and it thinks the +Y face of the cubemap is at the bottom (yet somehow the letters and arrows in the test pattern aren't upside-down). Do I gotta know stuff about the camera's field of view too? :(

EDIT 3: well, I got it finally.

https://twitter.com/byobattleship/status/1331369633929052161

TooMuchAbstraction fucked around with this message at 23:52 on Nov 24, 2020

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
Centroids of all "blobs".



Blobs are comprised of the voronoi cells, grouped together by colour. So all the same coloured water cells that come together to form a blob are a blob, and the above image shows their centroids.

Currently for convenience I made all land tiles since they are all unique colours blobs with only 1 child cell. Honestly this feels like a not-bad idea, and might be faster down the road to determining tiles that border the water.



Here I've calculated the border cells. Since I figure it's a useful attribute to know.



For comparison.

From here I think I now have everything I need to make an attempt at solving the issue of sea zones that are too small, or sea zones that are too concave or snakey, or have overhangs/valleys.

e to add: Another edge case I noticed is some water blobs might actually be "split" another probably excellent case to solve for.

e2: Its freaky to me that this seems to produce a perfect triangulation when I draw the connections.



e3: Almost perfect. Honestly if TriangleNet had been able to produce this from the getgo, or if I knew HOW to produce this from the getgo, I'd have had to go through a lot less work.

e4:

Actually come to think of it I see some interesting observations:




If we compare the problem area to its graph nodes, we can basically see whats going wrong here. The center for the yellow tile doesn't connect to the sea blob to the right of it, because it's enclosed by a different sea tile. So the blow square connects to the yellow square but the yellow square doesn't connect to the other blue square to its right. Which would imply it is "enclosed" by the first blue square.

Perhaps by looking at this upper-level graph there's an even faster way of detecting problem tiles and correcting them. Something like:

For any two blobs A and B that connected to form AB, any blob C that connects to A must also connect to B. And if this doesn't hold there's a problem?

Raenir Salazar fucked around with this message at 02:40 on Nov 27, 2020

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
So one problem I think I've determined is that the Scanline algorithm is slightly off.



According to my tests and displaying the connections for the nodes, that teal cell above and the lightish blue cell below are supposed to connect where the arrow I drew is pointing. And the brown is NOT supposed to connect to the blob to the right.

Either 512 by 512 is too small a resolution to catch it when the border between two cells is particularly narrow, or the scanline algorithm is having trouble with something that makes it stop too short, I'm investigating.

e2: I think I fixed it.



The problem seems to be that I wasn't consistently rounding the coordinates I was passing in, so my distance calculation formula was tainted. I happened to have a similar issue of a cell blocking off another cell where it shouldn't somewhere else during my trial and error attempts at a solution to help guide me towards what I think is the correct solution to result in a consistent handling of the coordinates and rounding them to integers.

Raenir Salazar fucked around with this message at 03:54 on Nov 27, 2020

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Is anybody else skimming sales on the Unity Asset Store? It looks like DoTween is $7.50, for one 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
I picked up some skyboxes, otherwise it mostly looks like asset packs that are a little too specific for me to use.

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

Rocko Bonaparte posted:

Is anybody else skimming sales on the Unity Asset Store? It looks like DoTween is $7.50, for one thing.

I've spent like $100 on this sale alone :retrogames:

Grabbed a nice water shader and outline shader to save me the trouble of doing those. Plus more low poly assets which saves me from making programmer art.

xgalaxy
Jan 27, 2004
i write code
The new Sackboy platformer is made with Unreal Engine.
Even more evidence I can use when people claim it’s an FPS only engine.

The game looks beautiful 🤩

xzzy
Mar 5, 2009

Anyone got any experience with Bakery? Unity's GPU lightmapper is hot garbage on my system, at least with 2019. Unless I turn everything down to minimum it bails out saying it can't allocate memory, and even then it has issues on a moderately populated scene. Unity claims the memory consumption is better with 2020 but I can't update yet.

My GPU isn't top of the line but it's not ancient either (1660 super).

anatomi
Jan 31, 2015

I haven't used Bakery, but I've read nothing but nice things about it (except from AMD users).

KillHour
Oct 28, 2007


Zaphod42 posted:

I've spent like $100 on this sale alone :retrogames:

Grabbed a nice water shader and outline shader to save me the trouble of doing those. Plus more low poly assets which saves me from making programmer art.

I should totally clean up and sell my outline shader.... How much did you pay?

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

KillHour posted:

I should totally clean up and sell my outline shader.... How much did you pay?

It was $6 to be fair (on sale , $12 normally) one of the cheaper things I got. And if it was too much more I'd probably just take the time to half-rear end my own implementation. Still, seems pretty popular.

I have no idea how much people make off asset marketplaces, I imagine its like games and most things where some people basically get no sales and a few people get a ton. Worth a shot I guess!

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
Made some progress but more of the variety of "found a bunch of bugs that tainted my data" which I had to hunt down the root causes of.

e: Progress:



Basically solved the problem of some tiles being split because of land tiles dividing them, (which caused all sorts of non-euclidian havok with the adjacencies!) so I managed to split all those tiles into new tiles.



Things that remain to do:
-Handle water tiles that are too small (size 1).
-Merge water tiles that are in interior lakes and are inaccessible.
-Detect and handle "bridges" i.e where because of the overlap, some tiles have a "overhang" dangling out.

I spent a lot of effort writing up some debugging tools like the lines you see and the gizmo cubes but I also went and wrote debug text for the coordinates and IDs of the sites/cells (what you see is the blobs, but the blobs are all made up of at least 1 or more cells) which helps with debugging some issues; much was very very whacked. But I hunted down those bugs and things I think are pretty good to move forward with.

The big question I'm circling around is the issue of resolving bridges. I think I can detect them pretty good with a breadth first search and flagging cells that are problems, although it seems its possible for multiple bridges to exist, so I need to make sure I can keep these distinct. But also the fact remains how to resolve possibly ambiguous circumstances in terms of getting the best visually looking result.

One of the questions that result from this is whether to merge a dangly cell with another cell, or split it off to make a new tile and then grab surrounding cells. There are many edge cases and no good general solution.

But I'm slowly working through them, I have a few decent rules.



Raenir Salazar fucked around with this message at 08:22 on Dec 10, 2020

OtspIII
Sep 22, 2002

I've got a question for more experienced Game Maker types!

With Unity, there's a trend where the more experienced you are with Unity the less you use it as anything other than a rendering engine. I tend to have as little code on my MonoBehavior scripts as possible that aren't about visual display, and do most of my game logic in a separate backend that then feeds state into my MonoBehaviors to visualize.

Do people tend to do this in Game Maker as well? GML doesn't seem nearly as suited for this style as C#, but decoupling visuals and state makes life so much easier in certain areas that I'm wondering if people end up going down that path anyway.

Also, if this is something that you have done--how do you structure it (in rough terms)? The new Struct system seems like it could work for this, but as far as I can tell it's less than 6 months old.

Raenir Salazar
Nov 5, 2010

"According to Wikipedia" there is a black hole that emits zionist hawking radiation where my brain should have been

I really should just shut the fuck up and stop posting forever
College Slice
Sadly I don't have any insight for you. :(


But anyways, new update, finally got around to taking a crack at an algorithm for detecting branches.



For comparison:




All this is very interesting.

Now the question is what sort of strategy needs to be undertaken to handle these branches.

Nubs, which are Size == 1 branches, are just be either ignored (esp. if surrounded by land mostly as no good target exists), or flipped to a different adjacent blob that would result in a more convex-ish shape (this part may be a tad difficult as a concave hull doesn't really exist).

There's a case where a "branch" (or what I also call a limb because it's like an vestigal appendage) is basically the entire tile (no three cells make a triangle) in which case I guess I check if the size of the branch is the size of the blob and ignore.

Basically I'm not sure how to solve it in a general way, I can take a guess as to why it happens, but I can't guarantee this would work for any occurrence while not overdoing it in situations that are fine?

The only case I'm a little flummoxed on is under what circumstances leads to the branch thats in the middle-ish top-right area, where the branch gets pinched from the sides by the two adjacent cells leaving to an extremely thin (1 pixel!) connection between the two black cells.

I think it maybe comes down to the distance between the two sites of the two black cells is longer than the distance between the two not connected nearby cells by a significant amount but it seems very random and only happens like the once.

My thinking is, if a branch is at least two cells that are adjacent, and these two cells are both adjacent to at least one water cell, flip that cell to them (after breaking off the entire branch into a new blob).

But limiting it to only really the situations where its called for is the hard part currently since this algorithm doesn't have any concept of "looks nice".

Adbot
ADBOT LOVES YOU

BoneMonkey
Jul 25, 2008

I am happy for you.

OtspIII posted:

I've got a question for more experienced Game Maker types!

With Unity, there's a trend where the more experienced you are with Unity the less you use it as anything other than a rendering engine. I tend to have as little code on my MonoBehavior scripts as possible that aren't about visual display, and do most of my game logic in a separate backend that then feeds state into my MonoBehaviors to visualize.

Do people tend to do this in Game Maker as well? GML doesn't seem nearly as suited for this style as C#, but decoupling visuals and state makes life so much easier in certain areas that I'm wondering if people end up going down that path anyway.

Also, if this is something that you have done--how do you structure it (in rough terms)? The new Struct system seems like it could work for this, but as far as I can tell it's less than 6 months old.

I've not used unity. But from my understanding gamemaker does a lot less out of the gate for you, so I end up writing a lot of my own stuff for whatever I need. Which is good for learning but terrible for UI.

Generally speaking the GML inbuilt functions are faster than anything you can write in GML yourself. (I think this is because GML is dynamically typed?) But I have had to build my own collision system and the like.

Fyi gms2 has had structs and functions forever, they were called scripts and objects. Scripts were worse than functions and are basically gone in the form they used to be. Objects are still around and are basically bloaty structs with with events that run during certain conditions.

I think GMS2 is good at two things, getting prototypes up and running really fast and it's amazing tool to learn with. It lets you get up and running quickly but then pushes you to the deep end fairly fast, because if you wanna do anything beyond the basics you have to work it out yourself. But if you already know how to use unity I'm not completely sure why you would want to switch over?

Godot is free, and if you want to investigate a more DIY approach then Raylibs looks very cool if you are interested in C.

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