#archived-code-advanced

1 messages Ā· Page 28 of 1

undone coral
#

and actually run the update later, perhaps in LateUpdate in the component

#

however i am sort of confused what you are trying to do... based on the example how is updating a health bar related to setting the adaptive shake

#

you can make a fluid API (what this is called) for anything

#

doesn't mean you should

flint wraith
#

Yeah i did that but it is run before chained functions which already passed values to dotween

flint wraith
jolly token
flint wraith
#

i tried looking dotween code but couldnt find much how they do it

#

i would says making Update function Coroutine and then waiting 1 frame before calling animation

#

just to be clear Update function is UpdateHealthBar, not unity Update

buoyant nacelle
#

Can someone help with the code architecture, please? I did a state machine for my actions (attack, move and idle). I have a state manager (this is my context, mono), character base state (abstract class) and classes that inherit from the abstract (move, attack and idle).

Then, I have PlayerInput controller, which has different actions (mouse click, key pressed, etc), and I want this class to switch state. However, I need to pass in the info (for instance, vector3) from PlayerInput to , for example, moving state. What is the best way to implement it? Is it a good architecture?

Another question I have is my moving state have moving logic and animation logic. How should I separate it to follow single responsibility principle? (animation and logic in different classes?)

lunar jackal
buoyant nacelle
buoyant nacelle
#

or abandon state machine all together?

lunar jackal
# buoyant nacelle or abandon state machine all together?

you can still use the state machine, and subscribe to the events send by your player input, but I would try to abstract the input itself as it's pretty nasty to get e.g. cross controller support even with the new input system if you're putting your inputs in the programming

buoyant nacelle
#

thanks

severe topaz
undone coral
fair hound
#

is there a way to edit instances of a monobehaviour derived script from its inspector reference inside of another script?

undone coral
#

basically postpone running of update until all chained functions are complete
i don't get it, why not just write it that way

#

write the fluent api so that the last call is update

#

it doesn't make sense

flint wraith
# undone coral what does UpdateHealthBar do?

Basically set some sprite colors, transform positions and run dotween with some settings.

I wanted to achieve dotween style of fluent, basically say what you want and then chain the settings. Doing updatehealthbar as last just bit clunkier

#

Was looking at dotween source code but had enough after about 2 hours 🄹

undone coral
#
class HealthBar : MonoBehaviour {
 Sequence sequence;
 int frame;
 private void SetTween() {
  if (frame != Time.frameCount) {
   frame = Time.frameCount;
   sequence?.Kill();
   sequence = DOTween.Sequence();
  }
 }
 public HealthBar SetShake(...) {
  SetTween();
  sequence.Insert(0, transform.DOShake(...));
  return this;
 }
 public HealthBar UpdateHealthBar(...) {
  ...
 }
 void LateUpdate() {
  // or whatever the method is
  if ((sequence?.IsPlaying() ?? true) == false)) {
   sequence.Play();
  }
 }
}

@flint wraith does that make sense?

#

there's something here i don't understand because it seems pretty straightforward to me

flint wraith
#

this is basically dotween style

transform.DoScale(2f, 2f);
or you can do
transform.DoScale(2f, 2f).SetEase(Ease.OutQuart);

in my current model i must do

UpdateHealthBar()
which is ok but if i want to add settings i must do
SetShake(1f).UpdateHealthBar();

meaning UpdateHealthBar MUST be at end

#

basically looking if there is a way to postpone UpdateHealthBar until chains are complete

undone coral
#

i'm pretty sure you can modify the sequence after you have called play anyway

undone coral
#

i mean look at the code

#

it shoudl be apparent that it's separate

flint wraith
flint wraith
fair hound
#

If I have a set of derivative classes I want a user to be able to choose between from within another class, how do I enable that ability? I want there to be able to be multiple instances of the same derivative type, but for each derivative type. My original idea was to have a private array of the base class, and a public array of each derivative type whose elements I feed into the base class array so I can iterate through them all from the one base array. Is there a better way to do this?

violet valve
jade grotto
#

I have an IMeshModifier that offsets the verts of the Graphic but of course GraphicRaycaster is not aware. I temporarily move the Graphic's Rect where its verts get offset to just before GraphicRaycaster runs and back after, works well, but OnRectTransformsDimensionsChanged gets called and everything gets set dirty and performance is terrible

runic girder
#
public class BuildingDismantler : MonoBehaviour {
    [SerializeField] private Sprite _hummerSprite;
    
    private Entity Building => RaycastBuilding();
    private EntityCursor BuildingCursor => EntityCursor.instance;
    
    private bool _isDismantling;
    
    private void Update() {
        if (Input.GetKeyDown(KeyCode.Mouse0)) {
            TryDestroyBuilding();
        }
    }
    
    public void ToggleDismantleMode() {
        if (!_isDismantling) {
            _isDismantling = true;
            BuildingCursor.SetCursor(_hummerSprite);
            StartCoroutine(CheckBuildingContinuously());
        } else {
            _isDismantling = false;
            StopCoroutine(CheckBuildingContinuously());
            EntityCursor.instance.HideCursor();
        }
    }

    private void CheckBuilding() => BuildingCursor.SetColor(Building == null ? 0 : 1);
    private IEnumerator CheckBuildingContinuously() {
        while (true) {
            CheckBuilding();
        }
    }

    private void TryDestroyBuilding() {
        if (Building == null || !_isDismantling) return;
        Building.DestroyEntity();
        ToggleDismantleMode();
    }
    
    private Entity RaycastBuilding() {
        var hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
        if (hit.collider.TryGetComponent<Entity>(out var building)) {
            return building;
        }
        Debug.LogWarning("No entity found.");
        return null;
    }
}```
Can this code be considered as a good one? I tried to follow all the principles.
severe topaz
#

@runic girder great, now switch over to NIS (new input system)
also Try without returning a bool makes me uneasy, usually you'd return it to make some kind of error sound if it fails

severe topaz
#

it's easier to switch early in the project, and it's definitely worth it

runic girder
#

This project is about to be released xd

severe topaz
#

well, if it's targeting only MKB (mouse + keyboard) then it's fine for now

runic girder
#

what's MKB?

severe topaz
#

@runic girder your ToggleDismantleMode has a check that's unreachable

#

trydestroy returns if !_isDismantling, so in toggle you don't ever get the first part

runic girder
#

I am actually going to use ToggleDismantleMode on button in editor, so it's fine, is it?

severe topaz
#

yeah, it's fine. i'm also not sure if coroutine stops if you do it like that instead of caching

#

i just tie everything to a bool

runic girder
severe topaz
#

e.g. in coroutine { while(_isDismantling){ ... } cleanup }

runic girder
#

I actually tried to avoid it here. Wanted to use this coroutine only in specific moment

#

Otherwise this coroutine would run endlessly while checking If(_isDemantling)

severe topaz
#

wdym

#

it runs endlessly while checking if(true)

runic girder
#

yeah, but then it's being stopped when program toggles Dismantle Mode off

runic girder
severe topaz
#

i also don't see what's in CheckBuildingContinuously, does it return wait?

runic girder
#

It simply sets the building cursor's color

#

0 = red, 1 = green

#

yeah, and it converts bool to int

severe topaz
#

wait wait

#

while true, it sets color? and it doesn't crash?

runic girder
#

wellllll xddd

severe topaz
#

you didn't even test the code, did you? ahaha

runic girder
#

I actually didn't ahaha

severe topaz
#

it'll definitely crash ahaha

runic girder
#

easy to fix tho

severe topaz
#

in any case, if you don't need checkbuilding separately, i'd just move it right there, it's less confusing that way

#
private IEnumerator CheckBuildingContinuously()
{  _isDismantling = true;
    while (_isDismantling) { BuildingCursor.SetColor(Building == null ? 0 : 1);
      yield return CACHEDwait; }
}
runic girder
#
    public void SetColor(int index) {
        if(_cursor.color != _colors[index])
            _cursor.color = _colors[index];
    }

Fixed

runic girder
#

but wait

#

what's yield return CACHEDwait?

severe topaz
#

if it's not null, you can cache it so that it doesn't generate garbage

#

for a building highlight you probably don't want it to be running at 120 fps, or even 50

runic girder
#
    private IEnumerator CheckBuilding() {
        while (_isDismantling) {
            BuildingCursor.SetColor(Building == null ? 0 : 1);
            yield return new WaitForSeconds(0.1f);
        }
    }

So you mean this, don't you?

severe topaz
#

cache it

#

static WaitForSeconds 100ms = new WaitForSeconds(0.1f);

#

then you can just return class.100ms; from anywhere

#

and it always sits in memory instead of dozens of copies that need to be cleaned up with GC (unless i'm totally misunderstanding how it works)

runic girder
#
static readonly WaitForSeconds CachedWait = new(0.1f);
private IEnumerator CheckBuilding() {
        while (_isDismantling) {
            BuildingCursor.SetColor(Building == null ? 0 : 1);
            yield return CachedWait;
        }
    }

this way?

severe topaz
#

yep

runic girder
#

btw, why should I make it static, Rider says I should do it, but why?

severe topaz
#

1: instances won't generate a new one
2: you can access it from other classes without a reference, instead of making a new one

runic girder
#

perfect, thanks

#

And thank you for such a good code review xd

severe topaz
#

yw, good luck with release

runic girder
#

thx!

shadow vigil
#

Does anyone know the math behind Transform.TransformPoint and Transform.TransformVector methods? I store positions in a struct, so I need something to perform the local to world transformation without the original transform.

buoyant nacelle
#

Right?

violet anvil
#

do we have any way to "intercept" any asset loading of some kind? e.g. when a model is loaded, get that model and add it to a massive buffer alongside many others, and prevent the "original" model load from actually being loaded into memory? my main goal here is to use said buffer for MultiDrawIndirect commands

muted root
#

Hi everybody, is it possible to use physics to grab parts of a mesh ? I have a character with a ponytail which has no bones inside. I was wondering if it was possible to create a script (or if an asset on the store already does that, I don't mind paying) which would allow me to move the ponytail with the mouse at runtime. Like grabbing the end of ponytail with the mouse, drag it around and it would follow the cursor. And if we grab it in the middle of the ponytail, the correct part would be dragged while the end of the ponytail would be affected by gravity and velocity.

#

The assets I found online only use either bone or the whole mesh

muted root
severe topaz
#

there was a really nice asset on the store for that kind of thing

jolly token
muted root
#

Hm, is it possible to add bones in unity ?

muted root
lament salmon
#

Another option is to use blend shapes, but for this you also need a 3D editing software. And bones will yield better results.

lament salmon
muted root
muted root
severe topaz
#

besides that it's better to just make a bone though
just import to blender and do it from there
royalskies has a really nice and short tutorial on that
https://youtu.be/X590IZeyT1s

muted root
lament salmon
#

Have you considered using the Cloth component?

#

For ponytails and such.

muted root
#

yes, I've tested it and it does give a goof result but there is not grabbing feature from what I tested.

lament salmon
muted root
#

The ponytail does get proper physics and interact with chosen colliders.

severe topaz
#

either way yeah it's possible, but is it really a game-changing feature?

#

like, would you spend a month working on that?

muted root
#

Well, yes it would be quite needed since I'm aiming at an
"adult" game in the end where I'd like cloth to be removable with the mouse haha and hair to be pullable šŸ˜‰

#

But when you say it's possible, I still don't see how it would work. All assets I found and even the one you linked are based on bones. So unless I modify hundreds of purchased asset to add bones, I still can't see a solutiion.

#

Which was why I was focusing on how to modify mesh partially, moving vertices individually but the math behind would be complex.

severe topaz
#

boing description says you just add component and it should work

#

no clue about it myself though

severe topaz
#

i'd just add bones since that's the most reasonable thing to do

muted root
#

From what I read "- The core logic for boing behaviors and reactors are simply modifying object transforms, so it should be compatible with all platforms Unity supports."

muted root
severe topaz
#

@muted root but on the other hand, boing is 50% off, although you can see hair breaking there

shadow vigil
severe topaz
#

@shadow vigil yeah, have fun binging on the rest of the videos ✨

crystal galleon
#

I have an issue with the duplication of a class and it's members. I've been looking at Deep Copy options and I'm having trouble coming up with a good one that meets my requirements. I'm duplicating a class that contains members of another namespace down-casted to it's in-namespace base class and I want it to be oblivious to what the derived classes are.

  1. This means that probably Copy Constructor won't work, as that class' duplication method can't access the other classes in other namespaces. This is a limitation of assembly definitions, as it doesn't support cyclic dependencies.
  2. I'm assuming that JSON Serialization creates a deep copy and it also is being a problem since one of the members of the duplicated class can be an UnityEngine.Object and is not Serializable. I do need to save that reference and It's currently declared as [SerializeReference] private Object owner (could add MonoBehaviour support in the future). On this option I tried to find the asset by name (all names are always unique), but doesn't really work as it doesn't let it run during serialization ({ get; set; })
proper walrus
midnight venture
#

ObjectPool should more efficient, if you have more or less stable pool size and LinkedPool perform better, if amount of pooled object fluctuates.

undone coral
undone coral
jade grotto
undone coral
jade grotto
violet valve
oblique crypt
#

quick question so i have coded a state machine to control all of my movement walking running jumping also included flying and all the transition substates . now i want to add 3rd person shooter controls would it be better to expand this state machine or create a second set of scripts

cobalt topaz
#

Does anyone know how to blend two meshes into one. Like I wanna do an ocean with some very low vertex displacement with no subdivided ones. And then I have the waves around the player that should look high quality and very detailed and so on that plane is massively subdivided. How can I now blend the ocean with the player waves?

#

To get a smoother transition between high waves around the player and the low ocean waves

flint sage
#

Tesselation

#

Or 2 meshes

cobalt topaz
#

Like how can I do then tesselation?

#

And I need it as code.

brisk pasture
#

tesselation its a large topic might take a bit but its ideal for this case

cobalt topaz
#

Yeah, I know.

brisk pasture
#

though keep in mind you really do not need to combine or blend meshes

#

you can have 2 meshes look seamless

cobalt topaz
#

But I only see shaders for tesselation. But I need to script it.

brisk pasture
#

just as long as on the boundary the vertex positions and normals are the same

cobalt topaz
#

Yeah, I would need to script it.

brisk pasture
#

yeah what you are asking with the waves, doing it in shader is the ideal place to do it

cobalt topaz
#

But I need to make buoyancy. A boat should drive on it and a player should swim on it

#

And also like explosions and some other stuff....

brisk pasture
#

since simulating water is a lot of per vertex work, so vertex shader is ideal, or compute shader for just doing the work fast and getting some sort of output

cobalt topaz
#

But I need high waves

brisk pasture
#

it is a big topic, but you might be able search for ocean simulations and other stuff to get a grounding in it

cobalt topaz
#

A real stormy, dynamic water

#

I have done a lot of research

brisk pasture
#

yeah assuming you are wanting somehting like sea of theifs

cobalt topaz
#

And came to the conclusion that vertex displacement in scripts is ideal....

brisk pasture
#

yeah that is heavily vertex and compute shader driven

cobalt topaz
#

Yeah

#

But I need to dynamically recalculate the water height at x and z

#

Wait...

#

I could just do my general vertex displacement and then tesselation in a shader

#

Because I would get raw, low quality waves for physics but goodlooking ones as an actual output

brisk pasture
#

yeah could do the mix, generally physics wise it would be smaller

#

still might use a compute shader for that, since the resulting data from it you can use in code, but will run much much faster

#

though really depends on the resolution, if its a small enough amount of points it runs fine in C# can just start off with that

cobalt topaz
#

Yeah

#

But generally, how would I simulate those lots and lots of random waves...

#

I got Gerstner waves for now

brisk pasture
#

would have suggested gerstner or driving it with a texture

#

can get randomness changing some of its input paramaters at runtime or having multiple generations of them

cobalt topaz
#

Perlin Noise?

brisk pasture
#

could work, but even multiple generations of waves you scale down in height and multiply with previous ones can add a lot of variation

#

and let you have detail and multiple scales

cobalt topaz
#

Yeah

#

So, what I would do know, is vertex displacement for a radius of 11f, then tesselation from 10f to +11f.

brisk pasture
#

your asking the right questions, its just going to be fiddly to get the look you want

cobalt topaz
#

The topic is super interesting, in my view.

#

Like simulating nature... There's always some randomness.

brisk pasture
#

yeah, if you do try and multiply in noise, i would use perlin since you need things that do not jump too quikcly betwene values

cobalt topaz
#

Yeah, then simply Mathf Perlin Noise?

brisk pasture
#

depends on your code, and where the work is being done, but yeah should work, but you will have to play with what you pass for the x any y so the scale of the noise is correct for your usecase

cobalt topaz
#

X and Y, not Z?

brisk pasture
#

so those will have to be based on the location you are wanting to get the value for, but you may need to multiply them larger or smaller to loosen up the noise and get more macro scale detials or tighten it up

cobalt topaz
#

Yeah, I am gonna have a lot of public floats for tweaking xD

brisk pasture
#

but yeah since you mentioned needed different levels of detial you can fake it without tesselation

#

would just make a grid of meshes, where the ones closest to the player have a higher vertex density

#

the important part is just making sure the positions and normals of the edges match up with there neighbors

cobalt topaz
#

But like that part of changing the vertex density is my Problem....

#

But the best way would be tesselation?

#

How would I do it then with a shader (having a circular shape)...?

urban warren
#

I have a question. I do very little multi-threading, and I was wondering how would be a good way to go about using multi-threading to create a mesh with a more advanced structure. In this case I mean a BMesh (specifically this lib https://github.com/eliemichel/BMeshUnity).
Like it requires adding items to a list and referencing things and stuff which multi-threading doesn't like.

#

Just kind of looking for a 'high level' overview of how one would approach it.

sly grove
urban warren
#

Doesn't adding things to lists in multiple threads cause problems in C# as two threads may try to put something in the same spot... or something...

#

(It really has been too long since I have done any multi-threading...)

sly grove
#

but that wasn't implied in the original question I don't think šŸ¤”

urban warren
#

Those of course, add the specified vertex/edge/face to a list on the mesh

sly grove
urban warren
#

I guess generation can't really be multi-threaded too well.

#

Though modification can be.

crystal parrot
#

Any vue 3 user here?

cobalt topaz
#

How would you do a tesselation shader for URP?

#

(Based on camera distance)

cobalt topaz
surreal vessel
#

am i crazy for not using a gamemanager?

#

idk just never liked the idea of it

#

could just be that its not useful in the game im making but it just seems to be a catalyst for bad code imo

ashen shard
#

It depends on what you're using instead of a gamemanager

surreal vessel
#

nothing really

#

everything controls itself

ashen shard
#

well

#

nothing crazy about that

surreal vessel
#

fair

#

i just see people mention it so often

#

and it makes me die inside a little

ashen shard
#

It is a really useful design pattern, but yes people tend to use it a bit too often.

#

For example in my game I have a tile/grid system that basically everything has to access, so it makes sense to use a singleton

surreal vessel
#

yeah true i suppose

#

fits some games more than other

ashen shard
#

What sort of game are you making?

surreal vessel
#

uhh

#

hard to describe

#

closest thing is probably a roguelike

undone coral
surreal vessel
#

makes more sense to me than a third party manager to do it

undone coral
#

that listens to input and then also drives animations

#

and does a bunch of other stuff

#

that is "coupled"

surreal vessel
#

nah its all separated components

undone coral
#

hmm

#

really depends on the game, it's an example

surreal vessel
#

i just have a reference to my animator in PlayerShooting and set stuff from ther

undone coral
#

the kind of game you're making decides whether or not something like animations are tightly coupled to input, not your class structure

#

does that make sense?

surreal vessel
#

yeah

undone coral
#

yeah that's all i'm really saying

#

if it's Spelunky, there is very tightly coupled player input, behavior and animation

#

most platformers look that way

#

compared to an RTS, where it is usually totally decoupled

#

you have to do the coupling, if it's right for your game, somewhere

#

some people like to suffer, and couple things using Dependency Injection

surreal vessel
#

oh hell no lol

undone coral
#

some people put the coupling in... a class. which in my opinion, is a good choice

#

of all the bad choices, it's a good one

#

a lot of people are making spelunky, then roll a state machine class, and it's hard

#

they have a state machine engine, and exactly one state machine (their player character in a platformer or FPS)

#

they have dependency injection, and exactly 1 implementation of every interface (service, or whatever)

midnight venture
#

Not sure if it’s actually that common things are tightly coupled in something like spelunky for example. I would guess it’s more like coupling through abstraction and for example all characters are ā€built the same with different kind of componentsā€

undone coral
#

how you choose to express that tight coupling is up to you

#

you can use Zenject to do that, and call it decoupled, and of course, it's actually coupled

#

you can also be in denial that there is some decoupled form of input behavior for that game, and if you try to make that, it won't "feel right"

#

there just isn't. all that retro platformer stick input movement behavior feels the way it does by harnessing the power of tight coupling

#

that's why i bring up RTSes, which have a huge variety of movement behaviors for units, and input is almost always as basic as clicking on a map

#

so of course that is decoupled

midnight venture
#

I’d say tight controls are no way related to tight coupling

undone coral
#

there aren't any RTSes with tightly coupled movement and input

undone coral
#

it's a very very retro thing

midnight venture
#

Spelunky like characters don’t care if their animation is driven by input or ai or whatever as long as the change is instant and there is no inherent delay in something like interfaces

undone coral
#

you can certainly engineer those things however you want

#

kind of the core of @surreal vessel 's question

#

and i get it, you look at a GameManager and it has "all these lines of code" in it

#

many alternatives, for certain genres of games, are worse

surreal vessel
#

yeah and i suppose also depends on the scale of your game

#

my current project is prety ambitious so a gamemanager for one off things wont do

undone coral
#

another perspective is, you can find innovations when you go really hard one way or the other. like if you really want to make an innovative platformer, consider what player input would look like if it was highly decoupled

#

i'm not saying there is an audience for platformers with innovative controls - there problem is not - but you could do something cool there maybe

undone coral
surreal vessel
#

openworld, dungeon crawler, bullet hell, roguelike

undone coral
#

because most of the innovation is in the encounters / enemies / terrain / items / etc.

#

and you build that up iteratively, and the interesting stuff sometimes happens when it's emergent behavior. like your player has the ability to turn land to water, and a water creature can now change its habitat, and this is emergent, it only happens serendipitously because the three systems - player inputs / "spells", terrains, and creatures - are decoupled

surreal vessel
#

yeah

#

things basically control themselves where possible

undone coral
#

it is not valuable to decouple the actually like, turning your joystick into movement

#

and animating the character in response the joystick

#

it just has to work a certain traditional way, that people expect

#

and there's pretty much no innovation there

#

that said, you can subvert expectations*

#

maybe it's a game where you take control of other creatures

midnight venture
#

I think you are just messing up terminology here and talking about something else than ā€classes being dependant of specific classesā€ vs ā€classes being dependant of abstractionā€

undone coral
#

maybe it's a game where you can control things with your joystick, and there's something fun there, like the flow of water or the mood of a creature

#

you can also consider something tightly coupled for your world - maybe the world is generate from a set of storypoints you carefully design, maybe it's something like monument valley levels with npcs with specific dialogue

undone coral
#

or it's a code fragment that is called repeatedly in many places. that is something tightly coupled that is usually disguised as decoupled. some stuff i've seen in real codebases

enemy.GiveItem(item);
GameEvents.instance.OnItemGiven(enemy, item);

or

target.Health -= damage;
if (target.Health < 0) {
 target.DropAllInventory();
 target.Destroy();
 GameEvents.instance.OnTargetDies(target);
}
#

you can create a PlayerInput class and call it from Player... but the methods would only be called from one place

#

or you can have all that code in the same class

#

it's not about how many classes. coupling is the hard meaning of, would this thing only make sense together with this other thing?

#

most platformer input doesn't make sense by itself. it doesn't do anything by itself. for a long time, it was all of Input.GetAxis

midnight venture
#

Anyway, it’s not matter of coupling or using managers or whatnot if things are possible to do (like tight controls), but how simple or hard things get when you start expanding the system. No reason to do decoupling for sake of it, but it’s usually in the end simpler to design for example animation system which can be driven by anything instead of having one system for player, another for second player with a bit different skills and again different kind of animation systems for different kind of ai’s and so on

undone coral
#

yeah but you'd never need to expand something like a platformer's movement behavior. like either it is complete to spec, or it is not finished

#

there are basically no platformers that operate as services games, and none of those introduce "a new way to move around based on your joystick input" if that makes sense

#

for a 2d platformer, the design space of your level geometry is 😱 tightly coupled to your player input, because the movement of the player is

#

i'm not saying you have a piece of code that calls Input.GetAxis to determine how you, in your brain, lay out platforms

#

but that you have to account for how the player moves.

but how simple or hard things get when you start expanding the system
so my point is, you will just never do that. you have to do something like build your player input for a 2d platformer in 1 shot, and it has to be fully specified - maybe not done in an engineering sense, but a fixed design quantity - before you start building your level

#

and in my experience, this is why people building 2d platformers don't really develop skills ot build other games...

#

like shipping a 2d platformer is anti-experience

#

isn't that nuts?

undone coral
#

it isn't relevant

#

you don't control the npcs. so of course they can use a state machine for animation, which is much simpler

#

and i understand the megaman player has something that resembles a state machine, but the actual code for those games looks like a severe case of Updateloopese

#

where the update loop has very fine tuned interactions between which frame of which animation megaman is showing in response to which timers and which inputs

#

you're not wrong, it's just that these sorts of games, they don't ship with flexible animation systems

#

they could ship with them, and it would be wasted effort

#

and probably get in the way of achieving the thing those audiences want, which is almost uniformly megaman controls

#

can you tell i really hate the guts of 2d platformers

midnight venture
#

šŸ˜‚ Yeah, I get what you are saying and not denying this isn’t the case (especially for anything actually 8bit - you totally can’t look at that stuff through the lenses of modern game development), but funnily the roguelite part was one which threw me towards the ā€go with the abstractionsā€ route in this discussion. It’s quite common you actually want to expand lots of systems in games like that and have systems which allows you to develop crazy ideas easily

midnight venture
#

So that one day when you want to give all the enemies skill to block like players block, or climb the ladders or give player ability to control enemies or something you don’t end up with spaghetti

undone coral
#

it's so hard to innovate in the levels & enemies without it being nicely abstracted

#

then again, every time i try to show people, "you're trying to make a CCG in addition to megaman, when you sign up to do an open world roguelike"

#

that gives the poor guy a heart attack

undone coral
#

then you can avoid spaghetti - spaghetti is like, all the interesting card text you want to do, but you have to touch a bajillion things to achieve it

#

signing up to author XMage on top of your other game is a crazy move

#

XMage is nicely abstracted and has thousands of bugs

#

they are tractable to fix but nonetheless, if you wanted the Whole Design Space of Magic the Gathering, you're gonna ouch

#

we really gotta see the source of Rimworld

#

to know how far basic approaches to this stuff can go

midnight venture
#

Wellll, it’s not like physical card games don’t have bugs so to speak. Except in their case bugs are solved by house rules or developer blog posts or by additional rules enforced by tournament organizers etc

#

(Had to check, mtg rulebook is 278 pages long. I must say that is quite a lot for a game which tries to describe everything relevant inside a short card text)

undone coral
#

paper prototyping a roguelite where input doens't matter as much is a Good Idea

#

you can definitely do this, as a creator, and make an innovative one

#

i am biased because i hate megaman controls, but what do i know, look at Shovel Knight

severe topaz
tender solar
#

Hello, I am syncing my project to a new PC and am getting compiler errors relating to duplicate type definition in .Net and MSCorlib. here is one such error: ```Library\PackageCache\com.unity.services.core@1.0.1\Editor\Core\AsyncOperation\IAsyncOperationAwaiter.cs(35,47): error CS0433: The type 'ICriticalNotifyCompletion' exists in both 'AsyncBridge.Net35, Version=0.2.3333.0, Culture=neutral, PublicKeyToken=b3b1c0202c0d6a87' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

#

Any idea what might be causing this and how to fix? Presumably I can't edit MSCorlib.

#

It's also working just fine on the original PC the project was made for.

severe topaz
tender solar
#

So it's definitely something within the Unity project?

severe topaz
#

wdym unity, it's a C# error

#

it's trying to rebuild it but found 2 types with same name

tender solar
#

Hmm. Updating Visual studio and re-syncing the project from github seems to have fixed it.

#

Though now the .sln says I need to update Unity for Visual Studio to use any code tools.

spice wave
#

Is there some callback function for when an animation transition has ended?

reef lance
#

I am making a server plugin for the game Rust and I want to display some fancy GUI, I know that rust uses Unity's UI system and I want to send a command to the client to draw something, this is done via RPC. Now the problem is that I dont know what data to send, so I started reverse engineering and now im stuck at some method that is loading some unity asset in which I pressume there is a value which was set in the inspector because in the decompiler the field is not initialized

So the tldr is where is that inspector value stored and can I somehow see it?
I tried almost all unity resource extractors/resource viewers none of them give the thing I want

Any help appreciated!

cobalt topaz
#

And the radius position would be the same as the player's.

cobalt topaz
undone coral
cobalt topaz
undone coral
cobalt topaz
#

I just want to get it working.

cobalt topaz
undone coral
#

it is much closer to the Unreal / high fidelity gaming pipeline

cobalt topaz
#

It says that HDR is unsupported.

undone coral
#

what is your objective?

#

what are you trying to make?

#

https://youtu.be/ycJ434Lh21w?t=583 here is an example of tessellation in hdrp

In this shader tutorial, I show you how to use tessellation and displacement to create incredibly detailed meshes without paying for high polygon counts. I show how to adjust the tessellation so you get triangles right where you need them and remove them where they're not needed.

Here's last week's video on creating the specular highlights for ...

ā–¶ Play video
#

i'm worried you're talking about surface shaders

cobalt topaz
#

I want that.

#

Highly subdivided waves in a radius (with a shader), and out of that radius no subdivided waves.

undone coral
#

when you say waves, you mean you want to make an ocean?

cobalt topaz
#

I did that.

undone coral
#

like the purpose is to make a water effect?

cobalt topaz
#

Let's say a plane

undone coral
#

are you doing this using shader graph?

cobalt topaz
#

No, code

undone coral
#

so

cobalt topaz
#

Because I need it so that objects can swim

#

Vertex Displacement

undone coral
#

i think you can use built in render pipeline then, and proceed along

cobalt topaz
#

Okay, and then use Surface Shaders?

#

Imagine Sea of Thieves water....

undone coral
#

there's a reason surface shaders were eliminated from hdrp

cobalt topaz
#

ok

undone coral
#

and why they haven't really bothered with reintroducing them in URP

cobalt topaz
#

ok

undone coral
#

i can't tell if you're interested why

#

it sounds like you want to write shader code

#

which is the problem

cobalt topaz
#

No, it is not

undone coral
#

you don't want to write shaders or you do?

#

it depends on the goals

cobalt topaz
#

I don't need to

#

Just copy and paste

undone coral
#

if your goal is to create attractive looking water

cobalt topaz
#

I think you don't understand me.

#

The water shader is working and looks good.

#

I just need tesselation for extra smoothness

undone coral
#

hdrp has a water surface you can experiment with and extend

#

its behavior is similar to what you find shipping in many games, and is meant to be a clone of whatever unreal has

cobalt topaz
#

But I need high waves and low ones-

#

I need to dynamically generate those

#

Low waves around islands and then higher ones based on distance

undone coral
#

there might be assets that do this too

cobalt topaz
#

But when I use the buit-in, I don't have shader graphs right?

#

So, my written water lit shader won't work

undone coral
#

i don't understand, did you write a coded shader, or did you make a shader graph shader

#

i think you'll figure it out sorry i can't be of more help

twilit sable
#

Instantiate(pmag, parent: Magparent.transform, position: new Vector3(0.0657f, 1.3951f, 1.0043f), rotation: rotation2);
How to make it instantiate in local certain coordinates (inside magparent)? Now it spawns in world position (изменено)

sly grove
#

weird to have a hardcoded offset like that though

#

recommend just adding an empty object as a child of Magparent at the correct location

#

and use that position directly

#

e.g. theEmpty.transform.position

twilit sable
jolly token
#

I'm not sure how is this advanced topic, ...for example just rotate offset vector and add your player's position?

past silo
junior nest
#

i am codegenerating a class and then trying to create a scriptable object from that class. However i need to wait until the assetdatabase refresh finished until i can actually create the scriptable object. I thought executing this in [DidReloadScripts] is the way to go but ScriptableObject.CreateInstance() does not create an instance because it cannot find the Type yet.

[DidReloadScripts]
        public static void CreateScriptableObjectAsset()
        {
            var folderPath = "Assets/Scripts/UtilityAI/CodeGen/AutoGeneratedRefs/";
            if (newCodeGenTypeNames.Count == 0) return;
            foreach (var newTypeName in newCodeGenTypeNames)
            {
                if (!string.IsNullOrEmpty(newTypeName))
                {
                    Debug.Log("Trying to create ScrObj for typeName: " + newTypeName);
                    var newScrObj = ScriptableObject.CreateInstance(newTypeName);
                    AssetDatabase.CreateAsset(newScrObj,
                        folderPath + newTypeName + ".asset");
                    AssetDatabase.SaveAssets();
                }else
                {
                    Debug.Log("newTypeName is null ");
                }
            }
            newCodeGenTypeNames.Clear();
        }```
#

anyone knows how i guarantee that all newly created types can be discovered?

#

I know the code generally works because when i restart the editor every asset is generated correctly. Its just a timing issue

compact ingot
junior nest
#

this error pops up once but then with PostProcessor it now runs again and creates the object

#

so its still not waiting just right

compact ingot
#

its typically used to display those "hey you installed package Foo, wanna look at our website" windows

junior nest
#

in my case it wont help. i need to create scriptable object instances that hold a reference to a type that has a implemented a certain interface. those types with the interface are outside of packages and my AI package is trying to reference them

#

i know sounds stupid but there is an idea here šŸ˜„

compact ingot
#

i don't pretend to understand

#

but if its just a question of waiting a bit, why not use an editor coroutine?

junior nest
#

but what to wait for? i kinda dont want to use wait 5 sec. (especially since it might be that i create quite a few such classes in some rare cases and it could take longer)

junior nest
compact ingot
#

is it referenced by, or part of, the assembly you are operating in?

junior nest
#

yes im creating that asset inside my AI assembly where that script is running too. as i said everything is actually created correctly. it just throws this error once before creating it

#

@compact ingot thanks a bunch for your help! i learned alot

#

need my bed now šŸ™‚ ill find a way tomorrow

undone coral
#

so is there any way to profile without a development build yet

#

i think there is an experimental runtime profiling package right?

broken cave
#

hello, has anyone tried synchronizing the selection within UnityEditor.Experimental.GraphView with Selection.objects so you can edit them in the property editor (in my case, nodes are backed by ScriptableObjects)? selecting elements in the GraphView correlated to Selection.objects when Undo.undoRedoPerformed is triggered doesn't seem to help. I see the selection showing up in my undo history, but the GraphView doesn't update with the selection, even though I called AddToSelection with the right elements, which exist in the GraphView.

junior nest
wet burrow
#

More advanced C# than advanced Unity, but it's worth asking here.

public struct CategoryTag
{
    [JsonProperty("id")] public int id;
    [JsonProperty("name")] public string name;

    public static bool operator ==(CategoryTag a, CategoryTag b)
    {
        return a.id == b.id && a.name == b.name;
    }
    public static bool operator !=(CategoryTag a, CategoryTag b)
    {
        return (a == b) == false;
    }
}

I want to use the equals operator with this struct, but it doesn't recognise them so I had to make my own. This caused a green squiggly line over the struct name and these errors:
'CategoryTag' defines operator == or operator != but does not override Object.Equals(object o)
'CategoryTag' defines operator == or operator != but does not override Object.GetHashCode()
Is this a problem? Can I override the GetHashCode() function and then not need to make the custom operators? What's the best way to implement something like this?

pliant crest
wet burrow
# pliant crest just override equals (as well)

But in that case what would I override it with? I know for GetHashCode() I'll need to make a custom function to generate one from the variables, I presume I'd have to make new code for the Equals() override. Simply checking 'equals' for each variable within the struct sounds so easy that there has to be some kind of catch.

pliant crest
#

since its a struct

#

wait hold up

#

why are you overriding the == anyway?

flint wraith
#

but it would return true also if object is not the same

#

well not object, since its struct

plush hare
#
    {

        Transform[] _Transforms = _Transform.GetComponentsInChildren<Transform>();
        for (int i = 0; i < _Transforms.Length; i++)
        {

            T[] _Components = _Transforms[i].GetComponentsInChildren<T>();

            for (int j = 0; j < _Components.Length; j++)
            {

                _Components.enabled = true;

            }

        }

    }``` How do I do this? Component doesn't contain enabled
pliant crest
#

the override is basically pointless

#

so i don't see any reason for them to do it

#

but if you really want to

#

you can just create a unique hash from the fields

#

that you need to compare

#

(which in this case is all of them which is what it already does)

flint wraith
#

yeah was just thinking, struct doesnt have instance

potent wraith
#

Anyone have experience in changing a mesh filter of a player object. I'm trying to do a prop hunt effect. Here is the current code, using a raycast to get the object which is working. But switching the meshfilter of the player is not working It should just be be a Chair for the mesh filter.
Code:

if (Physics.Raycast(transform.position, transform.forward, out var hit, Mathf.Infinity, mask))
        {
            var obj = hit.collider.gameObject;
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
            Debug.Log($"looking at {obj.name}", this);
            Mesh mesh = obj.GetComponent<MeshFilter>().sharedMesh;
            Mesh mesh2 = Instantiate(mesh);
            player.GetComponent<MeshFilter>().sharedMesh = mesh2;

This is what the objects mesh filter changes into(it is supposed to be Chair)

potent wraith
quiet bolt
#

Lol

plush hare
#

Character controller, mesh renderer are a few I tried. Camera seems to be one of the only things that actually worked with that.

sharp lake
plush hare
#

I would get the component using GetComponent<T>() and then cast that to a behaviour

sharp lake
#

u probably need to inherit them from behaviour, might be annoying for overriding all default components u need, but im not sure if thats how u supposed to do this

plush hare
#

I gave up. Instead of disabling them, I just deleted them using the script I showed

jolly token
# wet burrow But in that case what would I override it with? I know for GetHashCode() I'll ne...

Override Equals, check other is CategoryTag otherTag, and if so return this == otherTag. If not return false. The point of Equals override is that it should return consistent result as == operator.

For HashCode simple way is return field1.GetHashCode() ^ field2.GetHashCode() ^ …;. You can choose better way to combine hash to reduce hash collision, but it works as long as same object returns same hash.

radiant junco
#

Hi all. While creating a mesh by script, do I need submeshes to setup different materials/uv?

regal glade
#

is it a bad idea to have lots of rendertextures around or does it not really matter until you hit some critical limit? I read about 200+ for certain mobile devices would cause crashes. I'm running the objects through a computeshader every update, and I'm just not sure I want to copy the pixels from a rendertexture to texture2Ds 50 times per frame instead of just setting RenderTextures as _MainTex in the shader.

sage radish
regal glade
#

hmm alright, thanks.

frozen badger
#

Hey, I've got an interface that need an ID attached to them in order to function correctly, however interfaces can't hold fields. Is there a best-practice solution to get something like a field into an interface? Currently I've got a property that I implement in the classes using the interface, which I don't want to rely on everyone doing.

frozen badger
sly grove
#

Correct

#

Use an abstract class if you want a field

#

You can even use both šŸ˜‰

frozen badger
#

Yeah but the implementing classes are too different to reasonably inherit from the same object

#

So basically I have
public int deckObjectID { get; set; }
in the interface, and then every class has to implement the getter and setter on their own

#

Which is a lot of duplicate code that I'd love to have in the interface, especially considering they all get their ID from the same supplier

sharp lake
#

its not that bad

sly grove
#

Unity thrives with composition rather than inheritance

frozen badger
#

These are not components on gameobjects, unfortunately

#

Basically they all need this, and also in their constructor they need to set the backing field correctly

sharp lake
#

i mean do u need that variable?

#

what if u use deckObjectID instead of it

#

u can use getter/setter as property itself

sly grove
frozen badger
#

Huh, I didn't know I could just re-declare the property with default get set and then that would be fine

frozen badger
frozen badger
sharp lake
#

tbh thats a little weird to have one specific property in such different classes, no idea how u gonna use that property

frozen badger
#

Basically I have a custom collection I called a "Deck"

sharp lake
#

ye its basically 1 line of code per class, isnt that bad

frozen badger
#

I'm still working on it, but basically it's a set of dictionaries controlling the current state of that object

#

I want to be able to reliably control whether or not items in my deck are "available" to be rolled, locked, which means they have been rolled as an option but not claimed yet, or claimed, which means it's active in the game at the moment

#

I want to be able to o(1) get an item from the dictionary so every object needs to supply an ID, basically

undone coral
#

i wouldn't overthink it. how many cards are in your deck

#

there is a reason KeyedCollection with multiple keys doesn't exist

frozen badger
#

It depends on the deck. I named it "Deck" but not because the contents are exactly "cards"

undone coral
#

it is possible to author 100% correctly in typescript, but not 100% correctly in c#

#

well

#

how many

frozen badger
#

For the Item-deck it could be like, 100?

undone coral
#

okay

frozen badger
#

For the hero-deck probably like 15

undone coral
#

i don't think this optimization will yield much

#

100 items is very small

#

i don't understand what this is supposed to store

frozen badger
#

It's a custom collection so it stores a bunch of things

#

But with pre-coded functionality for keeping track of what has been "pulled" already

undone coral
#

okay

frozen badger
#

Like if all of this was just in a list I'd need to manage that separately, probably for each type

undone coral
#

hmm

#

you keep adding more and more stuff that makes it sound like you've veered off very far down Bad Lane

frozen badger
#

I may have

undone coral
#

do you want to get out of the Bad Neighborhood

frozen badger
#

like, when a hero is rolled I don't want to be able to roll him again for the rest of that game

#

I'm hoping I can black box the bad neighborhood

undone coral
#

or do you want to become a boss of crimes against programming

frozen badger
#

like build a giant wall around it

undone coral
#

lol

frozen badger
#

and then I don't have to look into it so much

undone coral
#

but that is so exceedingly simple, that there is definitely something i don't understand yet

#

is this like hearthstone's roguelike format?

frozen badger
#

Like, this is not a card game, but I want the randomness to work the same way as a card game does

undone coral
#

like whatever it's called

#

Card Game Roguelike Where you Go Up A Tower and there's Poison

frozen badger
#

like let's say you pull 3 cards, you pick one and the other 2 go back in the deck

#

and when a card is pulled, it can't be pulled again

undone coral
#

yeah

#

that makes perfect sense to me

frozen badger
#

but this is not a "card" game

undone coral
#

well what kind of game is it

frozen badger
#

and I want many different things to follow that same randomness pattern

undone coral
#

i make a lot of games

#

you can tell me, i will understand

#

"i hear you"

frozen badger
#

it's closer to an RPG, but the games are shorter

#

you win or lose in an hour or two

undone coral
#

okay

#

you mean it's classic final fantasy style combat, and you're pulling encounters from this deck?

#

is that the idea?

frozen badger
#

and the game world is pre-set with items and monsters in these decks that run out over the course of the game

undone coral
#

yeah

#

okay i hear you

frozen badger
#

It's not classic ff combat, but I am pulling encounters from the deck

undone coral
#

that makes sense okay

frozen badger
#

and items, and which characters show up, etc

undone coral
#

so you want to have a Discover mechanic too right?

frozen badger
#

Yeah

undone coral
#

okay great

frozen badger
#

like "Show me 3 healing items and let me pick one of them"

undone coral
#

"put the other two back"

#

makes sense to me

frozen badger
#

exactly

#

And since I have many things I want to behave like this

undone coral
#

yeah

#

i get you

frozen badger
#

I implemented my own collection for it

undone coral
#

so where does the initialized list of monsters and items for this playthrough live?

#

in a List?

frozen badger
#

which takes care of all of this generic pulling, locking, "shuffling" etc

#

Well, right now it is in a dictionary

#

because I wanted to be able to remove a specific instance of a "card" so to speak

undone coral
#

yeah

#

that has made things way harder

#

a deck is a list not a dictionary

#

which is okay

#

you are reimplementing a list on top of a dictionary right now

frozen badger
#

I am not overly worried about looping over the keys etc

#

randomly getting a key index

#

However, each item needs to know its own key

undone coral
#

why?

frozen badger
#

well, otherwise how can I know which item to move around

undone coral
frozen badger
#

It just.. seems wrong to directly compare a complex object

undone coral
#

it won't be complex at all

frozen badger
#

You're saying I loop over my list to find the current object and then move that, right?

undone coral
#

sure, or whatever you need to do

frozen badger
#

like, myList.Remove(myChosenItem);

#

which is fair

undone coral
#

yep, that will Just Work

frozen badger
#

I'll still need my subclasses for this deck though

#

as they have different types of discovery

undone coral
frozen badger
#

but it does get rid of the ID part

undone coral
#

don't make multiple classes

#

you don't need them

#

just make differently named methods for discover

#

i'm writing the example hold on

frozen badger
undone coral
frozen badger
#

so Items can be looked up by their complete name, their item tags

undone coral
#

i mean of course it's a collection, you can have it be T

undone coral
#

don't do new Deck<Monster>

#

but you won't really need to do that. you can put those methods anywhere. hold on a sec let me show you an example

frozen badger
#

For stuff that requires no extra functionality I just use Deck<T>, and then for Items for example I use ItemDeck<T>

undone coral
#

just do MonsterDeck and ItemDeck

#

like i'm showing

#

that implementing the concrete type

#

generics are not for extending behavior, they are for collections and that is all

#

if it's an ItemDeck, it's an ItemDeck, not an ItemDeck<T>

#

it's not an ItemDeck<Potion>

#

it's a PotionDeck

#

you can have an ItemDeck<T> as long as it is abstract

#

but i think that's a bad idea

#

just put the methods

#

that have to deal with these things somewhere else. not in the collection

#

it will be too confusing to put it there

frozen badger
#

But, would you have these inherit from Deck?

undone coral
#

sure

#

but you don't need this

frozen badger
#

public class ItemDeck<T> : Deck<T> where T : GameItem

undone coral
#

lemme show you an example

#

no

#

don't do that

frozen badger
#

As it is it's only an ItemDeck<T> so it can extend Deck<T>

undone coral
#

here's an implementation of a deck

sealed class Deck<T> : IReadOnlyList<T> {
 private List<T> entities = new();

 public Deck(List<T> startingEntities) {
  entities.AddRange(entities);
 }

 public void Shuffle() {
  // shuffle the entities array
 }

 public List<T> Draw(int quantity) { ... }

 public void ShuffleInto(List<T> cards) { ... }
}

// elsewhere!!! the smarts of this is interacting with the UI
Deck deck;
public async UniTask<T> Discover<T>(int count) {
 var drawn = deck.Draw(count);
 var chosen = await GameController.instance.userInterface.ShowAndChooseFrom(drawn);
 // now not drawn
 drawn.Remove(chosen);
 var notDrawn = drawn;
 deck.ShuffleInto(notDrawn);
 return chosen;
}
frozen badger
#

Because all the rolling, locking etc of items is done one time in Deck, but sometimes I need access to stuff in GameItem etc

#

IReadOnlyList?

undone coral
#

it won't matter

#

because all deck needs to be aware of is whatever is in common with monsters and items. which should be the base class of items and monsters

frozen badger
#

Right, but the reason I am using T here is because they have no shared base class

#

except for like, Object

undone coral
#

then it's an object!

frozen badger
#

they are fairly far apart

undone coral
#

well

#

okay this is fine to use for T, but do not make any other specializations

frozen badger
#

Right, but then in a subclass

#

like, ItemDeck

#

I want to be able to access item-specific discovery

#

like discovery based on effect

#

or rolling an item based on rarity

undone coral
#

the problem is that it causes all of your methods that operate on this, in interesting ways, to become typed in a way that is useless to you

frozen badger
#

what do you mean?

undone coral
#

it's hard to explain because you have no experience in this and i have a lot

undone coral
#

like don't overthink this

#

of course you can use generics

#

but don't put this functionality of rolling an item based on rarity

#

into the Deck class, or any subclasses of it

#

write the method Anywhere Else

#

does that make sense?

frozen badger
#

Right, but that is the thing I wanted the deck to do..

undone coral
#

because you're going to have only one instance of an ItemDeck

frozen badger
#

sure

undone coral
#

yes

#

but think... where is that one instance of ItemDeck going to live?

frozen badger
#

In some manager class

undone coral
#

yes

#

so write the method in the manager class

frozen badger
#

but then in a sense, this deck is that manager class

#

the item deck is the manager for items

#

it's the "item manager", right?

undone coral
#

no

#

okay

#

look at my example

#

look at Discover

#

do you see the problem with it right now? the problem was introduced by adding <T>

frozen badger
#

Yeah, your deck is more of a pure container

undone coral
#

no

#
Deck deck;
public async UniTask<Entity> Discover(int count) {
 var drawn = deck.Draw(count);
 var chosen = await GameController.instance.userInterface.ShowAndChooseFrom(drawn);
 // now not drawn
 drawn.Remove(chosen);
 var notDrawn = drawn;
 deck.ShuffleInto(notDrawn);
 return chosen;
}

versus

Deck deck;
public async UniTask<T> Discover<T>(int count) {
 var drawn = deck.Draw(count);
 var chosen = await GameController.instance.userInterface.ShowAndChooseFrom(drawn);
 // now not drawn
 drawn.Remove(chosen);
 var notDrawn = drawn;
 deck.ShuffleInto(notDrawn);
 return chosen;
}

what becomes way more complicated because of <T>?

#

this should illuminate why you need an Entity - you can have something else, but the alternative is way too nuanced to discuss right now

frozen badger
#

Ah, but the actual UI part of this wouldn't be in the deck

undone coral
#

i know!

#

it's not

#

this is "somewhere else"

#

it doens't matter where it is

#

but that's what's valuable

#

and do you see

#

like writing the collection manipulation logic takes milliseconds

#

writing the UI is painful

frozen badger
#

Basically right, I need the base class Deck to work on all types

undone coral
#

and because you introduced T, ShowAndChooseFrom<T>(List<T> listOfAny) becomes way more complicated than ShowAndChooseFrom(List<Entity> cards)

#

you need a base class for your items and monsters

frozen badger
#

sure

#

So you're saying, in Deck, treat everything as Object

undone coral
#

and 99% of the time, your UI will not care if it's an item or a monster. it will care what it should show where

frozen badger
#

and then in a subclass

#

treat everything as the class I need it to be

undone coral
#

no, in deck, treat everything as an Entity

#

and make a sealed class Deck<T> where T : Entity if you want to have specialized collections

#

a lot of people make this mistake

#

they think about the collections being specialized and adding functionality

#

you'll notice in the CLR there is no ListForItemsThatAreCards<T> : List<T>

#

that's just not what generics are for

#

it feels like it's what they are for

#

they're not for grouping a bunch of methods together. do that somewhere else

#

put it in your game manager

frozen badger
#

Hm

undone coral
#

it makes sense for the deck to have a shuffle method

#

but also, it does not. trust me. in my game, i don't have Shuffle in Deck

frozen badger
#

It also makes sense for the deck to have a draw random method right

undone coral
#

no

frozen badger
#

like what would you have in the "Deck" at all?

undone coral
#

for something like hearthstone, just additional data about the deck

frozen badger
#

if I take away the draw, the discovery, the specialized functionality, the search

#

right but this is not a card game

undone coral
#

right

#

the reason those things should live in game manager

frozen badger
#

the "Deck" is specifically there to be a collection of functionality

undone coral
#

is that people will do stuff, like use an item, that changes the rules

#

something like Shuffle is tightly coupled to the rest of your game

frozen badger
#

regarding randomness for objects as if it was a card

undone coral
#

for example, you might have an item that skips shuffling, or an item that lets you keep all three items you discover, etc.

frozen badger
#

Right but as I said this is not a card game

#

this is only randomness as cards work

#

as opposed to say how dice work

undone coral
frozen badger
#

if you roll 1 on a dice, you can roll 1 on your second dice

undone coral
#

you will wind up with the deck having to peek at the item - this is a problem you ALREADY have

#

which it shouldn't do

frozen badger
#

but if you pull the ace of spades, you can no longer pull the ace of spades, right?

undone coral
#

that's just specific to your game

#

i'm saying the kind of game you're making

#

you will wind up having items and monsters or other stuff

#

that will make 1 change to the rules

#

that will require an invasive change to your Deck class

frozen badger
#

Right but none of those rules can be "prevent shuffling"

#

because the deck isn't there to "be shuffled"

#

it's not an actual deck of cards that are say, pulled each turn

undone coral
#

maybe it' snot shuffling but it can be many other things

#

the key problem you came here with is using a dictionary instead of a list

frozen badger
#

Sure

undone coral
#

you actually have everything else under control. don't declare a Deck class at all really

frozen badger
#

and it is probably better to do a list

undone coral
#

just use a List

#

and any specialization, write a method somewhere else. in GameManager

frozen badger
#

But I need a bunch of different objects to then control the randomness

frozen badger
#

like, locking drawn cards

#

so they are not drawn again

undone coral
#

you just remove items from a list

frozen badger
#

right but then the cards that are not chosen have to be put back

undone coral
#

i mean, we can talk about how to implement that with a list

#

it's pretty easy

#

well

#

i showed you a Discover implementation

frozen badger
#

Sure

undone coral
#

here it is with a plain list

frozen badger
#

Right, but in terms of our "decks" I have very few of the variables in yours

#

the deck has no descriptor, no name, is attached to no player or hero

#

it also has no ID

undone coral
#
public async UniTask<Entity> Discover(IList<Entity> deck, int count) {
 var drawn = Draw(deck, count);
 var chosen = await GameController.instance.userInterface.ShowAndChooseFrom(drawn);
 // now not drawn
 drawn.Remove(chosen);
 var notDrawn = drawn;
 ShuffleInto(deck, notDrawn);
 return chosen;
}
#

then you don't need a Deck

frozen badger
#

Right, but having all of that stuff in a game manager

#

controlling how to draw items, events, heroes, monsters, etc

#

becomes a very big game manager

undone coral
#

i don't know what to tell you

frozen badger
#

and it's not even the main part the game manager would do, right?

undone coral
#

these games are complex

frozen badger
#

It seems like the name "Deck" confuses it

#

it's really a system for controlling the randomness

#

not at all related to actual cards

undone coral
#

you can make something worse, that takes 5,000 lines and distributes it int hte wrong place, among 20 files, that have to invasively know about everything anyway

#

and then you wind up with 15,000 lines

frozen badger
#

merely following the same pattern of randomness as a deck of cards would

undone coral
#

anyway this is my perspective, i have a lot of experience in this. ultiamtely you are leaning on

#

the psychological ickiness of looking at a file from a mature, complete game

frozen badger
#

and I wanted to separate this functionality out into its own class specifically controlling that

undone coral
#

saying it's "too big"

#

like you know in your heart of hearts i'm right

frozen badger
#

Well, it's a question of "where do I put it" right

#

it definitely could go both places

undone coral
#

your game rules should go in one file.

#

they are tightly coupled

frozen badger
#

yeah but this is not a part of my games rules

#

as my game is not a card game

undone coral
#

if you have any spell like functionality in your game, i am telling you now, it is very invasive

frozen badger
#

like imagine that I am making world of warcraft right

undone coral
#

it IS part of your game rules

frozen badger
#

and instead of a loot table, I would use card-like randomness

#

I would not put this item rolling functionality into the game manager, right?

undone coral
#

i think it's the best place to put it

frozen badger
#

Even though it could be there, I would probably separate out everything related to rolling loot into its own file

undone coral
#

for the same reason that basically every collection type omits functionality like this

frozen badger
#

Well, I could indeed ditch the T

#

and just use "object" in the base class

undone coral
#

okay well

#

i think there's a lot for you to digest here

frozen badger
#

so it would be Deck that just constantly refers to "Object"

#

Yeah, thanks for the input

undone coral
#

you don't necessarily need Entity, you need Renderable

frozen badger
#

renderable?

undone coral
#

and you also need HasId

#

yeah because you're going to have a method in your UI

#

that takes a thing and tries to show it on screen

#

sometimes it's an item and sometimes it's amonster

frozen badger
#

Ah, no, these do not go on screen as-is

undone coral
#

and all the hard part of making a discover ui is showing the three rectangles and setting up the event handlers and doing the animation

#

hmm

frozen badger
#

as they are not actually cards

undone coral
#

well i have been asking you

#

what kind of game this is

frozen badger
#

they go backstage

undone coral
#

it will help me give you more specific examples

frozen badger
#

Sure

undone coral
#

it's still got Spells

#

as soon as your game has Spells in it, conceptually speaking

frozen badger
#

Basically I have UI elements that are fed backstage objects

undone coral
#

it will look like this

frozen badger
#

if you imagine it was a card game and was hearth stone, I would have the "Card" and the "CardEffect" as separate objects

#

the "Card" would be the UI object and when it is fed the backstage-object it sets its data based on the backend

#

and that is how most of the things work

#

so none of these are monobehaviors and none of them are "physically in the game" so to speak

#

although some of them are scriptableobjects

undone coral
#

maybe the only way to truly understand why you should make your 5 discover methods in your game manager

#

is to go ahead and try to finish a game where you start by writing them in a deck class

#

for example, you might have a monster whose behavior reacts to what card was drawn

#

you'll eventually achieve this by firing a DiscoveredCard event

frozen badger
#

That makes sense if it was a card game

undone coral
#

and that should illustrate a concrete example of how a Deck class would have to be invasively aware of the rest of the game

#

listen i don't play wow, so i can't give wow examples

#

lol

#

but you gotta work with me here

frozen badger
#

But there's no way for a monster to react to a drawn card

#

a monster isn't a "card" any more the second it leaves the deck

#

in that sense

#

it's only a card in the nature of "being drawn"

#

and being searchable, and being limited in quantity

undone coral
#

well i think you can imagine

#

you want some behavior in a monster

#

that interacts with literally anything else in the game

#

you'll need an event system

frozen badger
#

Like, if you want to simulate the randomness of dice, you Random.Range(0,6) right?

#

that gives you basically perfect dice

#

but if I want the randomness in cards, I can't just go Random.Range(0,52)

undone coral
frozen badger
#

Yeah but my game is not a card game

undone coral
#

so a monster that reads "all your dicey dungeons dice come up as even numbers now" is interesting

frozen badger
#

I don't have these cards on my hand and then play them on the field

undone coral
#

all of these games are card games. WoW mechanics are routinely prototyped as card games

#

because they're all spells

#

it's just text

#

it's some game rules and they're interesting

frozen badger
#

it's, when you roll a random thing, it should behave as a card

undone coral
#

i know it's not a Card Game but it is a card game

frozen badger
#

when you roll it, only

#

do you get what I'm trying to say?

undone coral
#

it's true for real, blizzard does prototype its games with cards

frozen badger
#

Like, the moment the rolling is done it ceases to be a card 100%

undone coral
#

like they start by describing the overwatch class as a card

#

i know

frozen badger
#

Sure

undone coral
#

i'm saying there's text written on the monster right?

#

it has some rules

#

i mean, it will eventually, to make a more interesting game

#

it casts fireball, fireball is a spell

#

whatever

#

and fireball has some text

frozen badger
#

Sure, so I have items that do things and you could call it a card if you wanted to

undone coral
#

yes

frozen badger
#

things like teleport character or heal character or whatever

undone coral
#

right exactly

frozen badger
#

but none of these things interact with the drawing of cards

undone coral
#

well they will

#

you might as well prepare your stuff to do that

frozen badger
#

no, because it's not a card game in that sense

undone coral
#

because 100% of your game is going to look like that

#

anyway that's it, that's my perspective

#

you can poke around the spellsource repo, literally thousands of cards, and see how card text is implemented

#

because it's how a lot of these games wind up looking

frozen badger
#

You ever play uh... Xcom?

undone coral
#

yes

frozen badger
#

okay, so you either hit or miss right

#

when you shoot

undone coral
#

xcom is definitely architected the way i am describing though

frozen badger
#

you roll 1/100 and then check against your hit chance

#

the randomness is dice-randomness

#

imagine if instead you did the randomness through cards

undone coral
#

xcom is really supporting my case

frozen badger
#

the rules for card-randomness is:
A card exists only once.
The order of cards matter.

#

right?

undone coral
#

for example, "immune to being critically hit (unless flanked)" is an ability

frozen badger
#

Sure, but that's unrelated to the randomness

undone coral
#

that is printed on a character

#

hmm

frozen badger
#

I am talking about the rolling of hit % here

#

which, in xcom, is dice-randomness

undone coral
#

"-60% critical chance against this unit."

#

that's also an ability

frozen badger
#

Right, but that's still not related to the type of randomness

undone coral
#

well like i said, this function you are worried aobut, it's very small

#

the random dice part is 4 lines. and by the way, it is invasive

frozen badger
#

But do you understand what I mean by random type?

undone coral
#

because i have to store the seed somewhere

frozen badger
#

Like let's say my xcom guy shoots 3 times

#

and I only have 1 crit in his deck

undone coral
#

and i'm not going to store it in the deck

frozen badger
#

he can only crit once

#

that doesn't make it a "card", but it changes how his randomness works

#

he can't roll crit 3 times

undone coral
#

so you would have to invasively populate the Deck class with references to a Random class instance

frozen badger
#

every not-crit increases the chance that the next one is a crit

undone coral
#

i think i finalyl gotchyu

frozen badger
#

Well it is the whole point of the class

#

like let's say I have a huge table of items and I just roll which item to give right

undone coral
#

yes, but it will have an instance of Random with a seed right?

#

i think i got you

#

i did it

frozen badger
#

Uh, I use the static unity random

undone coral
#

i mean you can not use a seed

frozen badger
#

which is pre-seeded

undone coral
#

well that's a mistake

#

all these games have seeds

#

that are carefully controlled

#

even randomness is invasive!

#

look i'm trying to make your life easier not harder

#

it turns out everything is invasive in a video game like this

frozen badger
#

yeah but in my case I mostly pull cards based on the order

#

right?

undone coral
#

maybe. anyway good talk

frozen badger
#

so, the "seed" is gone in that sense

undone coral
#

i gotta go

frozen badger
#

Yeah thanks for the help

undone coral
#

i think the game will be fiun

frozen badger
#

I appreciate it

#

I will try to show you when the randomness thing works as I want it to

undone coral
#

"this monster always appears in a discover"

#

"until it is picked"

frozen badger
#

If there was such a thing that would be in the game mode

undone coral
frozen badger
#

Like the game mode would specify the starting conditions anyway

undone coral
#

it would mean some part of the random drawing would have to invasively know about the items inside the deck

#

okay what about

#

"put a monster into the deck that always appears in discover until it is drawn"

#

it's a monster called Corruptor and it puts a corrupt blood into your encounters pile

#

this is actually a really common mechanic across all these games

frozen badger
#

Yeah but you still are stuck on the word cards

#

Focus on dice for a sec right

undone coral
#

sure

frozen badger
#

If I roll a dice and get a 6, what is the chance that the next roll is a 6?

undone coral
#

"Next time you choose an encounter, one option is always replaced by Corrupt Blood until you choose it"

undone coral
#

i'm just trying to illustrate that you can call the method "PickEncounter" or whatever, and it will invasively have to know a lot about everything

#

your actual deck class can have the shuffle methods or whatever, it can be simple

#

that stuff isn't hard to write

#

you can move those methods if and when you need to invasively know about something when you shuffle

#

but it will

#

i already know it will

#

knowing nothing about your game

#

moving things will be easy

frozen badger
#

But you're still attached to cards as cards, not as a system for randomness

#

Again, consider dice

undone coral
#

sure when you roll dice

#

rolling dice will evnetually need to invasively know about something

#

okay i gotta go for real

frozen badger
#

Rolling 6 does not affect the chance of rolling a 6 again

#

Pulling an ace changes the chance for pulling another ace

#

And that behavior is the point of the deck.

obsidian glade
# frozen badger And that behavior is the point of the deck.

briefly read through this discussion - if the purpose here is simply to act as a random number generator with certain properties, why not use it like that and keep it simple - use a mediator that assigns values arbitrarily as needed, your generator logic only spits out a random number, and your mediator returns the object it assigned the id to

#

I suppose you can compress all of that into a generic Deck<T> object, but the key point is the objects you provide aren't having to supply their own ids, nor keep track of their own id

frozen badger
#

I went over to the "directly remove the object from a list by equality comparison" as suggested by doctorpangloss

#

so the ID itself has been removed, as has the need for an interface

frozen badger
tender light
#

So what is your issue now? @frozen badger

frozen badger
#

I am doing better now, Just ended up in a somewhat winded discussion

#

I got rid of the ID, but kept the <T>

obsidian glade
#

yeah, didn't mean to dig up an issue again as it seems like you've already resolved it - mostly just my own curiosity in how to handle it

tender light
#

Yeah I read through it now. It looked like you had 2 completely unrelated conversations going on there near the end.

frozen badger
#

I mentioned it but I think the word "Deck" may have alluded to a card game that didn't exist and caused confusion

#

it was more "Deck" as in the data structure

tender light
#

I don't believe that was the issue. From my prespective doctor just tried to explain to you that manipulating a collection should be done from the outside. That the API of whatever data structure should only contain elementary operations and nothing more. Everything that has multiple effects on a particular data structure should probably not be declared as part of the API. In this case he gave multiple great example of where adding Discover method as part of a deck is a bad idea because it causes the deck to have to emit events etc... instead of it being done from some game manager type class