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
Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

KillHour posted:

Add a gameobject field to the inventory item and drag the actual item into it via the inspector? I think that still works with a prefab.

Hmm so Prefabs are technically GameObjects too?

Adbot
ADBOT LOVES YOU

KillHour
Oct 28, 2007


Rocko Bonaparte posted:

Hmm so Prefabs are technically GameObjects too?

If the prefab is of a game object, yes. They're GameObjects that exist outside of the scene. A few things to note:

- A copy of a prefab can be created in the scene programmatically via the Instantiate method.

- Prefabs will not be included with the built game files unless they are referenced inside an included scene (normally via the method I specified), meaning if you try to instantiate a prefab and it's not referenced anywhere, it will work in the editor but not in a build.

- The exception to this is the Resources folder. Anything inside that folder will automatically be included in the build and can be referenced in the code by some static method I can't remember off the top of my head.

- Editing a prefab directly without bringing it into the scene will permanently change the prefab, even in play mode. This should probably cause an error in the console and doing it in a build may or may not crash the game IDK.

- I don't think that last rule applies to the referenced prefab on the parent since it makes a copy in memory, but it would change any further objects copied from that one so it's probably not a good idea anyways.

KillHour fucked around with this message at 18:54 on Jun 11, 2018

Khorne
May 1, 2002

Xerophyte posted:

If you're always going to be checking for intersections some fixed number of seconds in the future then you should be able to use that limitation when building your acceleration structure. My semi-unfounded expectation is that you're going to be better off with a ring buffer of N quadtrees (or other 2D acceleration structure) evenly sliced over those seconds instead of an octree. That way you can choose to only incrementally refit a limited number of trees/update, and full-time traversals will be about as fast as an octree since you'd go back to the root either way.

If you need to handle a lot of queries or complex motion over a range of times and scales then you can get significantly better efficiency from a more complex acceleration structure than just time slices of a 2D one. I'm not sure that structure should be an octree necessarily since you probably want a lower temporal resolution than spatial resolution and octrees can't do that, but they'll work. Just be really sure that you really need to trade worse acceleration structure build speed for better query speed before you go there. There aren't a lot of use cases outside of "I'm making a relativistic ray tracer" and "I'm doing ballistics simulations for the military", far as I know.
This whole post is real useful. The book is super useful and goes over tons of things I painstakingly learned on my own over the years as well as things I don't know.

Collision detection techniques will work great for what I want to do, because while it's not explicitly a collision in the things colliding sense, it's fundamentally similar. It's interesting how many things could be considered a collision problem.

Khorne fucked around with this message at 16:30 on Jun 11, 2018

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

Rocko Bonaparte posted:

Hmm so Prefabs are technically GameObjects too?

KillHour posted:

If the prefab is of a game object, yes. They're GameObjects that exist outside of the scene. A few things to note:

- A copy of a prefab can be created in the scene programmatically via the Instantiate method.

- Prefabs will not be included with the built game files unless they are referenced inside an included scene (normally via the method I specified), meaning if you try to instantiate a prefab and it's not referenced anywhere, it will work in the editor but not in a build.

- The exception to this is the Assets folder. Anything inside that folder will automatically be included in the build and can be referenced in the code by some static method I can't remember off the top of my head.

- Editing a prefab directly without bringing it into the scene will permanently change the prefab, even in play mode. This should probably cause an error in the console and doing it in a build may or may not crash the game IDK.

- I don't think that last rule applies to the referenced prefab on the parent since it makes a copy in memory, but it would change any further objects copied from that one so it's probably not a good idea anyways.

To further the point: if you very badly don’t want to incur the overhead of the extra (non-visible) object in memory, you can place the prefab in a Resources directory and do a Resources.Load(path) on it. If you do that, you’ll probably want to abstract it, as dealing with paths everywhere isn’t great.

KillHour
Oct 28, 2007


leper khan posted:

To further the point: if you very badly don’t want to incur the overhead of the extra (non-visible) object in memory, you can place the prefab in a Resources directory and do a Resources.Load(path) on it. If you do that, you’ll probably want to abstract it, as dealing with paths everywhere isn’t great.

You're right, it's Resources, not Assets. I fixed it in the OP.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
The problem is more of an aesthetic problem really. I have the player's inventory, which is a list of items and how of them I have. I have a shopkeeper, which has a list of items that can be bought and how much they have (possibly infinite). I might also give the shopkeeper's list a cost. Between buying and selling, I end up putting into/taking from each, and yet I was writing two completely different classes around a list. So it was starting to offend my sensibilities. I might still just go with the generic. The [logic in the] helpers mostly have to deal with [how to manage] items of infinite capacities.

Rocko Bonaparte fucked around with this message at 23:13 on Jun 11, 2018

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Projection matrices are a loving nightmare to debug. Way worse than a multithreading race condition.

I have a view where the perspective is inside-out - further away things are bigger than near things, and when you pan across the scene the far things move faster than the near things. Anything I can try changing in the projection matrix just makes it so I see nothing, of course, because whatever change I make has to be matched up with a corresponding change to the camera, probably. It sucks.

KillHour
Oct 28, 2007


Rocko Bonaparte posted:

The problem is more of an aesthetic problem really. I have the player's inventory, which is a list of items and how of them I have. I have a shopkeeper, which has a list of items that can be bought and how much they have (possibly infinite). I might also give the shopkeeper's list a cost. Between buying and selling, I end up putting into/taking from each, and yet I was writing two completely different classes around a list. So it was starting to offend my sensibilities. I might still just go with the generic. The [logic in the] helpers mostly have to deal with [how to manage] items of infinite capacities.
Use a dictionary of tuples.

<string>name : <gameobject>item, <int>price, <float>cost

Uncle Kitchener
Nov 18, 2009

BALLSBALLSBALLSBALLS
BALLSBALLSBALLSBALLS
BALLSBALLSBALLSBALLS
BALLSBALLSBALLSBALLS

roomforthetuna posted:

Projection matrices are a loving nightmare to debug. Way worse than a multithreading race condition.

I have a view where the perspective is inside-out - further away things are bigger than near things, and when you pan across the scene the far things move faster than the near things. Anything I can try changing in the projection matrix just makes it so I see nothing, of course, because whatever change I make has to be matched up with a corresponding change to the camera, probably. It sucks.

Some might say you might as well write your own martix classes/templates for debugging, but maybe that's getting old school now.

I mean, I like to write my own String or types to not rely on the standard library, but maybe that's excessive? I mean, if you're in a big company, they're gonna use their own standard library specifically for them, but maybe standard library is getting better.

Sorry for the tangent, but it just popped up.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

KillHour posted:

Use a dictionary of tuples.

<string>name : <gameobject>item, <int>price, <float>cost

Okay some of the things I have to do that I don't think I've said before:
1. I have 20 of X and I want to remove one. I want to make sure I have 19 left.
2. I have 1 of X and I want to remove one. I want the record gone.
3. When any inventory item changes, I want to fire events.
4. If an inventory has an infinite quantity, I want adding or removing any number of items to have no effect on the number of items.
...

It's a lot of little bullshit like that which I'm replicating across two different classes working on practically identical lists, and I'd rather just have one type that I can still set up using Odin Inspector.

KillHour
Oct 28, 2007


Rocko Bonaparte posted:

Okay some of the things I have to do that I don't think I've said before:
1. I have 20 of X and I want to remove one. I want to make sure I have 19 left.
2. I have 1 of X and I want to remove one. I want the record gone.
3. When any inventory item changes, I want to fire events.
4. If an inventory has an infinite quantity, I want adding or removing any number of items to have no effect on the number of items.
...

It's a lot of little bullshit like that which I'm replicating across two different classes working on practically identical lists, and I'd rather just have one type that I can still set up using Odin Inspector.

All that stuff is trivial though. And you can use the same dictionary for player inventory as you do for the shopkeeper - the player inventory needs all the same info (what item it is, how many you have, how much it is worth to sell, etc). Just create an inventory component with methods like give(item), take(item), buy(item, cost), sell(item). You can handle all the logic of making sure infinite items never go down and they are removed instead of going negative and whatever else in that component.

big scary monsters
Sep 2, 2011

-~Skullwave~-
I have a Godot3/design question. I have an object spawner that I'd like to be able to spawn different types of packed scenes, chosen at random. At the moment this is achieved by having something like this in a script connected with the ObjectSpawner node:
code:
export (Array) var objectSceneArray
onready var objectReferenceArray = []

func _ready():
	for objectScene in objectSceneArray:
		var loadedScene = load (objectScene.get_path())
		objectReferenceArray.append(loadedScene)
	
	randomize()

func spawnObject():
        var rootNode = get_node("/root/Main/Objects")

	var i = rand_range(0, objectReferenceArray.size())
	var spawnInstance = objectReferenceArray[i].instance()
	rootNode.add_child(spawnInstance)
This works fine as far as it goes. In the editor I can adjust the size of the ObjectSpawner's array and add scenes that I want to spawn. The script will load them at runtime and then instantiate one at random whenever spawnObject() is called. However, what I would really like is to be able to assign each object a spawn probability, so that they don't all have the same chance of spawning - some should be rarer than others. I first thought of doing this by having an array of 2-element arrays (like replace the first line with export (Array, Array) var objectSceneArray) containing both the packed scene and a probability float, but that's really awkward in the editor. In any case I'd rather be able to declare the spawn chance on the objects themselves.

Two problems:
1. I don't know if/how it is possible to access variables on an uninstantiated scene. So how does my ObjectSpawner get the spawn chance from the objects before instancing them? I could create an instance of each, load the probabilities and just not add the instances to the node tree, but that seems pretty ugly.
2. How exactly do I decide spawn chances? I can give each object a chance like 0.5 or 0.1 or whatever, but that requires me to go through all the objects available to the spawner each time to make sure the probabilities add up to 1. Or I can just sum them and normalise to 1, but then it's hard to tell when you're assigning the chance what the actual probability of an object being spawned will be.

Any ideas?

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

KillHour posted:

All that stuff is trivial though. And you can use the same dictionary for player inventory as you do for the shopkeeper - the player inventory needs all the same info (what item it is, how many you have, how much it is worth to sell, etc). Just create an inventory component with methods like give(item), take(item), buy(item, cost), sell(item). You can handle all the logic of making sure infinite items never go down and they are removed instead of going negative and whatever else in that component.

Okay the structural problem I have (had?) is that the inventory the player had was using GameObjects that were the actual items. What the shopkeeper is using is an inventory containing the prefabs to instantiate. I think what I have to do is make peace with giving the shopkeeper an item like the player or a chest or whatever gets, and give the shopkeeper a new object each time one is taken away. It sounds like I can use Instantiate on instances of GameObjects and not just prefabs, and I can probably just make that the default implementation in the abstract class I use for item logic in case I ever need to do something special. So that might be the stumbling block I have in all this.

atholbrose
Feb 28, 2001

Splish!

big scary monsters posted:

1. I don't know if/how it is possible to access variables on an uninstantiated scene. So how does my ObjectSpawner get the spawn chance from the objects before instancing them? I could create an instance of each, load the probabilities and just not add the instances to the node tree, but that seems pretty ugly.
2. How exactly do I decide spawn chances? I can give each object a chance like 0.5 or 0.1 or whatever, but that requires me to go through all the objects available to the spawner each time to make sure the probabilities add up to 1. Or I can just sum them and normalise to 1, but then it's hard to tell when you're assigning the chance what the actual probability of an object being spawned will be.

You can't -- you have to use an actual instance. I use your ugly approach in my game, when loading base instances of items and monsters and such, and it's okay as a one-time cost for that. I create the vars in a while loop so they are automatically cleaned up . You could also change your object spawner array to an array of arrays, like --
code:
[[0.1, "almost_never.tscn"], [1.0, "ten_times_more.tscn"]]
-- which would be a pain to maintain in the properties view -- or simply make another array for the chances.

I'd use integers for the chances, with 1 being the smallest probability. Sum them all up when loading the scenes into the array, and when you want one, generate a random number, and step through the list subtracting the chance until it drops below 0.

KillHour
Oct 28, 2007


Rocko Bonaparte posted:

Okay the structural problem I have (had?) is that the inventory the player had was using GameObjects that were the actual items. What the shopkeeper is using is an inventory containing the prefabs to instantiate. I think what I have to do is make peace with giving the shopkeeper an item like the player or a chest or whatever gets, and give the shopkeeper a new object each time one is taken away. It sounds like I can use Instantiate on instances of GameObjects and not just prefabs, and I can probably just make that the default implementation in the abstract class I use for item logic in case I ever need to do something special. So that might be the stumbling block I have in all this.

Well, prefabs ARE GameObjects, so the shopkeeper has a real copy of it in memory, it's just not part of the scene yet (so it doesn't render or interact with physics or get called as part of the game loop, basically) and it's just one copy, regardless of how many the shopkeeper is supposed to have. I suggest treating the player's inventory the same way - abstracting it until the player actually uses it (Instantiate on equip, basically), then deleting the GO when putting it away. The overhead of instantiating and deleting can be solved by pooling if it becomes a problem. That way you don't have to deal with stuff like "I have to manually disable the renderer on this sword when it's put back in inventory."

I mean, unless the player needs multiple actual different copies of the same object in memory. I can't think of many reasons why you would need that though.

Doing it this way makes implementation of items easier too. Instead of making potions have an OnUse method, they can just do whatever they have to do in the Start method because they get instantiated when they're used. Weapons don't need to all check to see if they're the one equipped, because only equipped weapons are responding to the game loop.

KillHour fucked around with this message at 06:53 on Jun 12, 2018

Mooey Cow
Jan 27, 2018

by Jeffrey of YOSPOS
Pillbug

KillHour posted:

- Editing a prefab directly without bringing it into the scene will permanently change the prefab, even in play mode. This should probably cause an error in the console and doing it in a build may or may not crash the game IDK.

- I don't think that last rule applies to the referenced prefab on the parent since it makes a copy in memory, but it would change any further objects copied from that one so it's probably not a good idea anyways.
Changing the values of uninstantiated prefabs is fine, btw. If you do it in the editor, the changes will generally persist even outside playmode (but use the SetDirty() stuff if that's what you want to do), but in a build those values will/may periodically reset when the prefab is reloaded from disk into memory. This usually happens during scene changes. All referenced prefabs are always loaded into memory, and there is no way to access unreferenced prefabs.

Technically they are GameObjects but they exist hidden from the scene in some way (but they count towards "total objects" in the Profiler). You can also clone regular GameObjects in the scene by just running Instantiate on them like you would with a prefab. I use this all the time for stuff like making dynamic lists of GUI elements.

big scary monsters
Sep 2, 2011

-~Skullwave~-

atholbrose posted:

You can't -- you have to use an actual instance. I use your ugly approach in my game, when loading base instances of items and monsters and such, and it's okay as a one-time cost for that. I create the vars in a while loop so they are automatically cleaned up . You could also change your object spawner array to an array of arrays, like --
code:
[[0.1, "almost_never.tscn"], [1.0, "ten_times_more.tscn"]]
-- which would be a pain to maintain in the properties view -- or simply make another array for the chances.

I'd use integers for the chances, with 1 being the smallest probability. Sum them all up when loading the scenes into the array, and when you want one, generate a random number, and step through the list subtracting the chance until it drops below 0.

Yeah, it feels a bit awkward but I think that loading an instance of each object in _ready() and summing the spawn chances as you suggest is the way to go. Glad that at least I'm not missing anything obvious, thanks.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

KillHour posted:

I mean, unless the player needs multiple actual different copies of the same object in memory. I can't think of many reasons why you would need that though.

Doing it this way makes implementation of items easier too. Instead of making potions have an OnUse method, they can just do whatever they have to do in the Start method because they get instantiated when they're used. Weapons don't need to all check to see if they're the one equipped, because only equipped weapons are responding to the game loop.
Would this work with items with passive effects for having in inventory?

KillHour
Oct 28, 2007


It could, depending how you implement it. How is your inventory designed? What does it look like? List? Grid? Tetris? Do items stack? Can the same item be in two different slots? Passive in-inventory effects are pretty uncommon outside of weight burden. Do the passive effects stack?

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

KillHour posted:

It could, depending how you implement it. How is your inventory designed? What does it look like? List? Grid? Tetris? Do items stack? Can the same item be in two different slots? Passive in-inventory effects are pretty uncommon outside of weight burden. Do the passive effects stack?

Right now it's lists. No grids or other shaped-based systems. I thought about it and decided it wasn't going to be a fun part of the game. The item could be assigned to more than one slots. The effects would stack.

I figured due to passive effects that I'd just keep a leading instance of each available object and if one is taken a way from a stack then a new one is created in place and becomes active instead. For shopkeeper inventory I think I'll just assign the inventory to some dummy thing so the shopkeeper doesn't become crazy powerful from passive effects or have his bones crushed from weight. That being said, I'm not doing a ton of items.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Update on the "debugging projection matrices is the worst" front - I ended up writing a goddamn unit test of just the projection matrix, which revealed that the projection matrix was basically the only thing that wasn't broken in my render pipeline. The camera was on the wrong side and facing the wrong way, the aspect ratio was inside-out, a lot of the camera controls were reversed to accommodate that brokenness, etc. all of which combined to make things appear in the right places and approximately the right size and the right way around, but weirdly inside-out because things would get bigger the further from the camera they were (which, again, seemed right at a glance because the camera zoom controls were also reversed). Finally got the bastard sorted out.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I feel for you. I often wind up with a nearly-correct result through a cascade of contradictions. Kind of like trying to do 8 - 4.1 = 4 instead of 2 + 2 = 4.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

roomforthetuna posted:

Update on the "debugging projection matrices is the worst" front - I ended up writing a goddamn unit test of just the projection matrix, which revealed that the projection matrix was basically the only thing that wasn't broken in my render pipeline. The camera was on the wrong side and facing the wrong way, the aspect ratio was inside-out, a lot of the camera controls were reversed to accommodate that brokenness, etc. all of which combined to make things appear in the right places and approximately the right size and the right way around, but weirdly inside-out because things would get bigger the further from the camera they were (which, again, seemed right at a glance because the camera zoom controls were also reversed). Finally got the bastard sorted out.

welcome to graphics programming, where everything's made up and the pixels don't matter

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Oh, I forgot to mention the annoying thing that got me again (I had even ranted about the exact same thing only like a month before) - that the math library I'm using has a function like "4x4matrix.multVec3" for applying a transformation matrix to a vector, but that function does not, in fact, apply the transformation matrix to the vector, for that you have to call "4x4matrix.multVec3Projective". So that added another couple of hours to the debugging time, of going "why the gently caress is this perspective matrix not doing what it's supposed to do".

Because obviously that makes more sense than, say, calling the first one 4x4matrix.multVec3SkipProjection and having the expected results be the default behavior. (I guess I see why they did it, because you want the default to be the slightly more performant one otherwise everyone will always use the slower one, but gently caress, if the efficiency is that important just don't have multVec3 at all, have multVec3Fast and multVec3Proper or something.)

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I'm chasing my tail on prefabs versus GameObjects for inventory stuff. I tried to switch off of using Prefabs, but this lead me to a new set of problems with initialization. The process I was previously using to configure all this was:
1. Putting the list container in a ScriptableObject
2. Editing the ScriptableObject in Odin Inspector to...
3. Drag and drop prefab objects from my assets into the item fields

The shopkeeper had the inventory container using prefabs, while the player had an inventory with actual instances of objects. In reconciling that, I have reopened this initialization problem. In fact, I think some time back I did this all this way due to having to use prefabs within Unity's inspector.

Something I don't understand is that the ScriptableObject is changing out from under me in the editor. I decided in this case that if I'm trying to use actual items that I would add an editor callback via Odin Inspector to react to getting a Prefab object by replacing the object with a fresh instance of the prefab in the scene. If I'm just mulling around with the ScriptableObject, this all looks good. As soon as I try to run it through the editor, these references turn to None.

Xerophyte
Mar 17, 2008

This space intentionally left blank

roomforthetuna posted:

Oh, I forgot to mention the annoying thing that got me again (I had even ranted about the exact same thing only like a month before) - that the math library I'm using has a function like "4x4matrix.multVec3" for applying a transformation matrix to a vector, but that function does not, in fact, apply the transformation matrix to the vector, for that you have to call "4x4matrix.multVec3Projective". So that added another couple of hours to the debugging time, of going "why the gently caress is this perspective matrix not doing what it's supposed to do".

So it's this thing?

If so I don't think it's that the multVec3 version doesn't do the matrix multiplication, it does. It's that specifically perspective projection can't be described with just a matrix multiplication. multVec3Projective first does the [x' y' z' w'] = projection * [x y z 1] multiplication, and then actually returns [x'/w' y'/w' z'/w'].

The short version of why it does that is that what we're effectively trying to do with the projection step in 3D is squeeze all the things you can see into a 1x1x1 (or similar) axis-aligned box. For an orthographic view the stuff we can see is already a box, just one that's got some different dimensions. We can map it to our desired box by scaling, rotating and translating, which along with shear are conveniently the affine transforms that applying a 4x4 matrix on a homogeneous coordinate can represent. Having an orthographic projection matrix Just Works as a straight matrix multiplication without any further tricks.

For perspective we need to somehow map a frustrum (=pyramid with the top cut off) to a box. That mapping isn't affine and we can't represent it with a 4x4 matrix. The missing component is basically the notion that if something is further away then translating it will have an effect proportional to the distance to it. If you have something 1m away and 1m to the right, it'll appear directly in front of something that 10m away and 10m to the right.

In order to get that behavior the perspective projection needs to divide by depth and part of how the matrix is set up is specifically for letting us hack this in later. The last row (assuming column vector math) of the projection matrix will be something like [0 0 1 0] -- it depends on what vector component your graphics framework considers to be the canonical forward direction -- so multiplying with the matrix will throw away whatever the old w was and make it be depth. When we then divide everything by w we get precisely the behavior we wanted: things at x = 10, z = 10 and x = 1, z = 1 will be projected to the same point with the nearer one in front.

I used to know of a nice site that explained this with equally nice diagrams, but I can't find it right now.

Xerophyte fucked around with this message at 16:11 on Jun 13, 2018

Elentor
Dec 14, 2004

by Jeffrey of YOSPOS

roomforthetuna posted:

Update on the "debugging projection matrices is the worst" front - I ended up writing a goddamn unit test of just the projection matrix, which revealed that the projection matrix was basically the only thing that wasn't broken in my render pipeline. The camera was on the wrong side and facing the wrong way, the aspect ratio was inside-out, a lot of the camera controls were reversed to accommodate that brokenness, etc. all of which combined to make things appear in the right places and approximately the right size and the right way around, but weirdly inside-out because things would get bigger the further from the camera they were (which, again, seemed right at a glance because the camera zoom controls were also reversed). Finally got the bastard sorted out.

Now make everything again but inside a shader to reach peak programming.

roomforthetuna
Mar 22, 2005

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

Xerophyte posted:

If so I don't think it's that the multVec3 version doesn't do the matrix multiplication, it does.
Yes, it is essentially that library.
I meant to say "doesn't do all of the matrix multiplication".

As the linked description of multVec3 says, "Transforms the given vector with the given matrix storing the resulting, transformed vector into resultVec. The input vector is multiplied against the upper 3x4 matrix omitting the projective component."

(Which is particularly outrageous that the first sentence says it transforms it with the given matrix, then the second sentence bothers to mention "oh lol not actually the given matrix, just 3/4 of it.")

Which it's reasonable to do to some extent, because a 4x4 matrix doesn't technically multiply against a 3x1 structure, but anyone who has ever done 3D graphics stuff would expect that if you ask for a 4x4 matrix to be applied to a Vec3, either you're asking for matrix * (v.x, v.y, v.z, 1) and throw away the fourth element, or you should be told gently caress you and asked for a more specific request. The idea that you'd expect the request "multiply a vector by this matrix" to mean "multiply a vector by only the top three quarters of this matrix" is just crazy.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Well you're giving it a vec3 and trying to multiply against a 4x4 matrix. Mathematically, that makes no sense. Either you multiply your vec3 by the affine part of the matrix alone (which makes sense for the 90% of cases where you just want to do affine transformations), or you do the perspective divide on the CPU (bizarre, if not wrong in most circumstances). It sounds like what you actually want is a vec4 that has a w component.

roomforthetuna posted:

The idea that you'd expect the request "multiply a vector by this matrix" to mean "multiply a vector by only the top three quarters of this matrix" is just crazy.

No, it's not crazy. For an affine / SRT matrix, it makes perfect sense. And this is the case where you most likely have a vec3.

roomforthetuna
Mar 22, 2005

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

Suspicious Dish posted:

No, it's not crazy. For an affine / SRT matrix, it makes perfect sense. And this is the case where you most likely have a vec3.
But if you were to apply an entire 4x4 affine matrix (like multVec3Projective does) to your vec3 you'd get the same result as you do multiplying only three quarters of it, because the last quarter would be identity-shaped anyway. So you can get the expected result for *both* cases if your standard 'mult' function does it like multVec3Projective, or give the caller a horrible surprise if you have a function that takes a 4x4 matrix and a vec3, call it essentially just "multiply", and have it silently ignore a quarter of one of the inputs, in those cases where that last quarter of the matrix isn't [0,0,0,1].

Requiring me to make it a vec4 before multiplying - or requiring me to call multVec3Projective to get this result - are both fine solutions, I wouldn't mind that at all - what I object to is having this function named as if it performs, as you say, a mathematically illogical operation, rather than naming it "multVec3Affine" or "multVec3IgnorePerspective" or "multVec3ByThreeRows" or something, anything, that indicates how the would-be illogical operation is being altered when you call this function. Calling it just multVec3 is a great way to frustrate me for hours, because my assumption would be that if you're going to 'correct' that invalid operation you're going to do it in the way that fills in missing information (a vec3 as a point in space maps to a vec4 in a very predictable way) rather than the way that ignores provided information.

It's a shame Javascript doesn't lend itself to debug-mode-only asserts, because if it did I'd also be okay with the fix "when you're in debug mode and call multVec3 it checks if the last row of the matrix is not [0,0,0,1] and throws an error telling you you probably meant to call multVec3Projective."

quote:

or you do the perspective divide on the CPU (bizarre, if not wrong in most circumstances)
It's useful for when you want to, eg. transform a click on the window into a raycast through world co-ordinates. (In this case it's transforming on the inverse of the combined camera-and-perspective matrix, but you still need the full transform not just the top three quarters.)

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Is anybody here using Unity on Linux through some black magic? I may be building a new rig around a free processor and the only thing keeping me stuck on Windows these days is Unity.

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

Rocko Bonaparte posted:

Is anybody here using Unity on Linux through some black magic? I may be building a new rig around a free processor and the only thing keeping me stuck on Windows these days is Unity.

The editor is available on the unity forums. Pretty easy to google for it.

IIRC: TextMeshPro doesn’t work, but it’s generally ok

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

leper khan posted:

The editor is available on the unity forums. Pretty easy to google for it.

IIRC: TextMeshPro doesn’t work, but it’s generally ok
Well I was looking for personal takes. I know it's a thing but I wondered how well it was working for anybody in the thread. TextMeshPro not working would make me sad.

In other news, I discovered slapping async in front of stuff apparently doesn't break interface contracts so now I want to take advantage of it, like, everywhere. I am imagining that scene in Life of Brian where the Latin is written everywhere, but replace that with "async."

Edit: In fact, don't be alarmed if my posts randomly start having "async" scattered in them.

Fake Edit: async

Tiler Kiwi
Feb 26, 2011
So, I have Characters, ActorClasses, Weapons, and WeaponAbilitys. Characters have a class and a weapon, and classes need some data about how good the class is with each weapon.

Most of that is fairly easy to set up, but the relation between Class and Weapon is a bit more mean because I'd made each variation of CharacterClass and Weapon just some scriptableobject created from a CharacterClass / Weapon class. So its relational data. So there's several ways I figured I could go about it and I just wanted a bit of feedback if any of them were actually a good way or if I'm just running down a road to nowhere.

1. Just create a "WeaponAbilityMap" scriptable object, put in a list of weapons and classes, and then work out some way to put a value for every pairing, store the data as a tuple or a dictionary or whatever is smart, and then I guess just give it to everything via the editor (or just create some "PseudoDatabase" object that holds a bunch of this kind of data and pass it around to everything). The main problem is that I dunno how to actually set up the editor to do that kind of pairing stuff or to get it behave nicely if I decide to modify stuff later.
e: I suppose I could just initialize the values of stuff in some script somewhere too, instead of trying to fuss with the editor that much? Or I can just bite the bullet here or something.

2. Define a bunch of enums in code for each class and write some static class with a bunch of switch statements. Sounds probably wretched to work with and liable to break but simple in kind of a brute force way I guess. A similar idea would be defining each weapon type as its own inherited class or to have the switch statement check some ID or string name or some such thing but I'm kind of trying to avoid create a bunch of data-as-code stuff as opposed to classes that hold data (which may or may not be smart I guess).

3. Have a bunch of lists in each class for each weapon affinity and drop each weapon type in there manually in the editor. Basically the same kind of complaints in terms of it seeming kind of fiddly and weird to work with. Plus if I want to change the weapon affinity values from a letter to an actual number this wouldn't work at all. Or I could combine this with 1 and have each class get a list of all weapons and define a score for each, but that has the similar thing where I dunno how to make that kind of thing work with the editor in a nice way, and it also sounds more tiresome the more weapon types or actorclasses I try to create.

4. Use SQLite and define stuff in data tables instead of using scriptable objects. The good side is that relational data is now maybe super easy to make and it sounds like I can really go hog wild in putting a lot of data into tables and that sounds actually pretty nice, since I'm probably going to end up with a lot of data. Plus it makes answering questions about the data easier, like "what classes are A rated for this weapon" or other stuff, and it just seems nice to have this data all in a tangible place and not just kind of a concept enforced via a bunch of scattershot scriptableobjects thrown at each other. It's also stuff I'm not as familiar with and I worry that it'll end up being a major pain in the rear end trying to work with this data in any fashion in the editor, or just in general. Plus then I lose the scriptable object data containers. Plus plus its just not something I've heard people talk about much so I'm kind of worried its overkill or just plain silly. But right now its the thing I'm most strongly considering going with.

5. some super simple method that everyone uses that i'm too thick headed and stubborn to figure out

Tiler Kiwi fucked around with this message at 08:47 on Jun 15, 2018

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
My ring menu system just asks for a sprite representation of each thing it has to show. This has been good for me, but I'd like to gray out or otherwise mark up some of the sprites. Say, I don't want the player to sell a plot item from their inventory, but I want them to see that the item is there when they try. I'm thinking maybe a Sprite is not really good enough. What should I do if I:

1. Want to gray out the item, but while respecting transparency.
2. Want to put a red 'x' through it instead
3. Want to start animating the sprites in some fashion. I haven't even pondered this and it sounds like a pain in the rear end.

Tiler Kiwi posted:

So, I have Characters, ActorClasses, Weapons, and WeaponAbilitys. Characters have a class and a weapon, and classes need some data about how good the class is with each weapon.

I could probably rub some more brain cells together on this and actually give a good answer, but I couldn't help but say that I got strong vibes of double dispatch here. I think the problem that is overwhelming you is the act of extending this forever with whatever new variants of each thing and having to describe how they interact with everything else. I figured I'd write something since you put a lot of effort into the question.

Tiler Kiwi
Feb 26, 2011
I think the whole thing is just a combination of N:N relationships being weird, a pointless aversion to just using inheritance / enums, and general piss ignorance about everything data related.

I'm well aware that there's little work arounds for a lot of it, but this kind of issue has come up repeatedly and I've gotten very tired of doing workaround things like making not-enum global static classes for holding not-data in to deal with what "feels" like a conceptually straightforward thing. Or creating inherited classes or interfaces that serve as just glorified labels, or using enums or a bunch of variables to serve as tags, just so I can say "Axeman is good at Ax" or "Horsie is good at grass". I'm just at the point I want data to actually be data and not have to scatter it in code just because OO/Unity is weird about it. Which is maybe being inordinately thick headed about it all but I don't even know enough about this stuff to ask the right questions. I don't know if trying to do a workaround is overcomplicating things because I don't understand data stuff well enough, or if trying to force in concepts I half understand is overcomplicating things because I'm just being a dumb dork about it.

Sometimes this poo poo is the least satisfying kind of frustration. I feel like a dude getting pissed at a paint by numbers kit.

e: The stuff I'm being stubborn over I guess is conceptually similar to whats gone over in this discussion. Namely, just having the "type" of a weapon be a subclass feels uncomfortable since I'm phrasing stuff as "Weapon Has-A Type" rather than "WeaponFoo Is-a Weapon", just like how in that discussion a solution for the conflicts that come up from using subclasses as classifications of employee instead of being defined via composition by being given a role, and maybe even going a step further and having a role just be defined via composition as opposed to subclassing, so you just know every Employeee Has-A Role. Which is conceptually neat and what I gravitated to because it seemed a lot more simplified until I got into the current hell zone.

I suppose the actual solution is to just define more classes, except define them based on a relationship. So it'd hold a list of weapontypes, a list of actorclass, and then you could map each cartesian join with a value that, on initialization, could hand back via some manner to all the stuff in its lists. That has its own problems in terms of not doing something like recreating the join list and losing all data if the pseudo-foreign-key lists change. And then the actual actual solution is to just say gently caress it and use subclases and many enumerators.

Its neato how when I try to make things simple I somehow genius myself into an overcomplex mess anyways. :downs:

Tiler Kiwi fucked around with this message at 12:26 on Jun 18, 2018

Mooey Cow
Jan 27, 2018

by Jeffrey of YOSPOS
Pillbug
You can have ScriptableObjects for, say, a ClassDefinition, and a WeaponDefintion. The ClassDefinition can contain a serialized list of pairs of WeaponDefinition and your value. To make new classes or weapons you just create new instances of those definitions and link them to characters/other objects in the editor. So a Character could a field for a ClassDefinition object and a WeaponDefinition object, and use the list in its linked ClassDefinition object to look up how good the class is with the weapon.

Don't know exactly what you're trying to do, but that seems like an easy way to model "class has weapon stats, character has weapon and class" without having to make any new code for what is essentially just new data.

Tiler Kiwi
Feb 26, 2011
Yeah, that's probably a better way to do things. I'd like the relationships to be a bit more formalized than reliant on me not forgetting to ensure all the combinations are accounted for, but its probably not worth the effort.

I think this all started by me thinking of that and then going "oh but that might get a bit tedious, i'll have to mess around with property drawers and stuff, and there might be duplicates or missed values..., wouldn't it be nice to have something just like one of those xls spreadsheets I used to play around with? its simple enough!"

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Okay I figured I'd try to help since I should at least be helpful with hippy abstract design poo poo even if I'm awful at games.

Tiler Kiwi posted:

1. Just create a "WeaponAbilityMap" scriptable object, put in a list of weapons and classes, and then work out some way to put a value for every pairing, store the data as a tuple or a dictionary or whatever is smart, and then I guess just give it to everything via the editor (or just create some "PseudoDatabase" object that holds a bunch of this kind of data and pass it around to everything). The main problem is that I dunno how to actually set up the editor to do that kind of pairing stuff or to get it behave nicely if I decide to modify stuff later.
e: I suppose I could just initialize the values of stuff in some script somewhere too, instead of trying to fuss with the editor that much? Or I can just bite the bullet here or something.
The folks bragging on about Odin Inspector were right. It can visualize a lot of stuff at least good enough by default. I think it can minimally do dictionaries in an expected way, although I think you've got something more like a table where one axis is one thing and the other axis is another. You might not want to put down the coin so if you're up for a science project, you could probably just paste your basic data types and me or somebody else can show you what it does with it.

quote:

2. Define a bunch of enums in code for each class and write some static class with a bunch of switch statements. Sounds probably wretched to work with and liable to break but simple in kind of a brute force way I guess. A similar idea would be defining each weapon type as its own inherited class or to have the switch statement check some ID or string name or some such thing but I'm kind of trying to avoid create a bunch of data-as-code stuff as opposed to classes that hold data (which may or may not be smart I guess).
Ewww. I think this unwise because every time you ponder adding a new actor, class, or weapon, you're going to have to jump around and fling logic everywhere. This is the kind of thing a lot of patterns specifically try to avoid. That being said, you can try it with, like, three things, and just see which way the logic goes. The proper design should start to emerge from your rage.

quote:

3. Have a bunch of lists in each class for each weapon affinity and drop each weapon type in there manually in the editor. Basically the same kind of complaints in terms of it seeming kind of fiddly and weird to work with. Plus if I want to change the weapon affinity values from a letter to an actual number this wouldn't work at all. Or I could combine this with 1 and have each class get a list of all weapons and define a score for each, but that has the similar thing where I dunno how to make that kind of thing work with the editor in a nice way, and it also sounds more tiresome the more weapon types or actorclasses I try to create.
Meh, I think the data is still more tabular.

quote:

4. Use SQLite and define stuff in data tables instead of using scriptable objects. The good side is that relational data is now maybe super easy to make and it sounds like I can really go hog wild in putting a lot of data into tables and that sounds actually pretty nice, since I'm probably going to end up with a lot of data. Plus it makes answering questions about the data easier, like "what classes are A rated for this weapon" or other stuff, and it just seems nice to have this data all in a tangible place and not just kind of a concept enforced via a bunch of scattershot scriptableobjects thrown at each other. It's also stuff I'm not as familiar with and I worry that it'll end up being a major pain in the rear end trying to work with this data in any fashion in the editor, or just in general. Plus then I lose the scriptable object data containers. Plus plus its just not something I've heard people talk about much so I'm kind of worried its overkill or just plain silly. But right now its the thing I'm most strongly considering going with.
You might as well just do this now so you can mull over this data however you want and then you can export it to something else later if it becomes a problem. I'm betting there are some plugins/helpers/GitHubs to help working with sqlite in the inspector.

quote:

5. some super simple method that everyone uses that i'm too thick headed and stubborn to figure out
Does a human cleric really handle a sword differently than an elf cleric? Maybe it's not worth going through all the permutations but rather just give categorical bonuses and demerits.

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

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

Tiler Kiwi posted:

5. some super simple method that everyone uses that i'm too thick headed and stubborn to figure out
You probably want to talk to the Caves of Qud guy, who had an amazingly good system for this sort of thing.

I think the gist of it was something like don't give everything an interaction with everything, that leads to horrific combinatorial explosion; instead have optional behavior interfaces you attach like properties to anything, and make it so you can define property functions in terms of other properties. For example, maybe the default canWieldOneHandedSword behavior is (canWieldOneHandedWeapon && !forbiddenToUseBlades), and canWieldOneHandedWeapon is (hasDominantArm || (isAmbidextrous && hasAnyArm)).

This way you can do gigantic messes of insane complex interactions (lose your arm, lose your ability to wield a weapon; turn into a quadruped, lose your ability to wield a weapon) barely having to make any change to implement them. And now you're not limiting weapon wielding to player characters, anything that has arms has the prerequisites to use melee weapons. And each individual function is very small and simple, and each property is obvious ("human cleric has arms and is forbidden to use blades" is easier to think about than "human cleric can use mace, cannot use sword, cannot use dagger, cannot use shard of glass?, axe?, spear?").

The down side of this pattern is it's not very data driven, it's code all the way down, which may make it harder to visualize and reason about.

Edit: and it can be hard to determine property precedence, if, eg. orc is explicitly encouraged to use blades, cleric is forbidden to use blades, what of an orc cleric?

roomforthetuna fucked around with this message at 07:52 on Jun 19, 2018

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