Arcen Games

Other => Game Development => : Shrugging Khan July 28, 2013, 10:16:37 AM

: Shrugger! Unity!
: Shrugging Khan July 28, 2013, 10:16:37 AM
So now that I've more or less survived my first few months of computer science, I thought I'd make a little game to motivate me for the coming second term.

"Let's make a sandbox exploration game", thought me, and realised that I didn't have the tech savvy to make it playable.
"How about a physics-based RTS?", suggested another part of my brain. Yeah, physics, that's complicated stuff.
"An FPS about natural selection and tactics?" - Dear Lord, no, we'd need really good AI to make it worth it.
"A space 4x with realistic scale!", was a thought. "Wait, mathematics and such? Relativistic physics? Ha ha ha!", was another.

And after a few weeks, yet another idea cropped up.

"A 3D roguelike?", I asked myself, and failed to think of any reason why that'd be too hard. So I fired up unity, imported some standard assets, and immediately started bludgeoning my desk in fury.

"Y u no multidimensional arrays, javascript!?", I raged. "You there, GameObject! How hard can it be to have a simple color instead of shaders and textures and god knows what?", I interrogated Unity. "WHY HAVE YOU STOPPED WORKING, SCRIPT!?", shouted I, my hands searching in vain for a throat to strangle - all I had done was rearrange a few folders.

In short, I am a complete and utter idiot. And I have many questions.
The first shall be this:

1. Issue One: Multidimensional Arrays, or alternatives thereto

I want to create a three-dimensional level to play in, using simple cubes. I thought it'd be fun to write an algorithm to plan the level, with multiple floors, rooms, staircases, corridors and whatnot. The plan was to store the layout in a matrix; or perhaps rather to have the matrix represent the level, with three dimensions denoting coordinates, and each element containing information regarding block type, structural integrity, temperature or whatnot.

Alas, my meagre coding experience did not suffice. I didn't even manage to make the bloody matrix happen! So, how can I create a simple array with three or five or eight or perhaps a dozen dimensions to store my level map in? How can store further arrays within this array?

Or is there a simpler, perhaps a simply better way to do it?
My guess is there's some object-oriented solution I'm not thinking of, or some other way of making such a map happen. Not that I'd actually know - as mentioned above, I am an idiot.

So, if anyone can make sense of all this, and perhaps provide some insight...I'd be much obliged!
: Re: Shrugger! Unity!
: x4000 July 28, 2013, 01:38:50 PM
First suggestion: use C#. Everything is more vague in JavaScript, I feel like. Speaking as one who used js moderately heavily for 8 years in a web environment.

In c# you can do multidimensional arrays with new object[][]. In JavaScript the only way I know to do it is something like new Array( new Array() ). Etc.  In c# you can also do new object[,]. Those are all two dimensional arrays, but for three it's the same.

I can't help you much with gameobjects or 3d in unity, though, because we use drawmesh and drawmeshnow (pro features) along with custom textured quads out of vertex arrays. We obviously do use shaders, but nothing all that complex and we mostly use them by setting the current material directly or by using materialpropertyblocks (or whatever those are called, it's been a while since all that is long-since wrappers a by our own code.

We only even use a single script, very short, attached to the camera. Everything else is custom class-based code elsewhere in the codebase that the script invokes once per frame.

Anyway, so we're of limited help on traditional unity things, just to warn you.
: Re: Shrugger! Unity!
: Draco18s July 28, 2013, 06:05:56 PM
This rant may provide if not insight, then sympathy (http://www.kongregate.com/forums/4-game-programming/topics/279024-rant-10-reasons-why-i-dislike-unity-as-a-developer).

That said, Unity is really difficult to work with in some ways, but really awesome in other ways.

What version are you working with, 3.5, 4?

One thing to avoid: OnGUI.  Do not use the built-in GUI tools, it will only end poorly.  Either spend the money on a gui package (like iGUI*) or use an orthogonal camera and 2D planes and mesh-text.

Shaders: you can probably get away with the various supplied shaders and freely available shaders out there if you're doing something like a dungeon crawling roguelike.  You aren't doing anything that would require rim lightning or translucency or subsurface scattering.  You need rocks.

*Note: I don't like iGUI much, but it's still better than native and not that expensive.
: Re: Shrugger! Unity!
: x4000 July 28, 2013, 07:43:15 PM
The only thing that I use OnGUI for is for textboxes/textareas.  If anyone knows of a third party solution that provides sprite-based support for those, I'll be all over it because that's the last piece that we have not been able to ditch.
: Re: Shrugger! Unity!
: Draco18s July 28, 2013, 08:03:31 PM
The only thing that I use OnGUI for is for textboxes/textareas.  If anyone knows of a third party solution that provides sprite-based support for those, I'll be all over it because that's the last piece that we have not been able to ditch.

How's $10 sound (http://u3d.as/content/aptual-ltd-/sprite-text-custom-bitmap-fonts/2N4)? ;D
: Re: Shrugger! Unity!
: x4000 July 28, 2013, 08:05:59 PM
That's not a textbox or a text area, that's just a label -- we already have something quite robots, even beyond what you've got there.  A textbox is like the subject field on this page, whereas the text area is like the body.  Those are extremely hard to program in any language (I've done it before, and it was kind of buggy, and it was extremely hard to do).
: Re: Shrugger! Unity!
: Draco18s July 28, 2013, 08:46:10 PM
That's not a textbox or a text area, that's just a label -- we already have something quite robots, even beyond what you've got there.  A textbox is like the subject field on this page, whereas the text area is like the body.  Those are extremely hard to program in any language (I've done it before, and it was kind of buggy, and it was extremely hard to do).

Cursory search, ah well.
: Re: Shrugger! Unity!
: x4000 July 28, 2013, 08:47:53 PM
No worries.  Believe me, I periodically scour for that. ;)
: Re: Shrugger! Unity!
: Shrugging Khan July 29, 2013, 08:37:57 AM
Bah, no need for a GUI!

Still, thanks for the tips. Going to try a few things and report back later with more questions.
: Re: Shrugger! Unity!
: Billick July 29, 2013, 09:16:42 AM
Is it possible to use any of the C#/.net/WPF GUI stuff together with Unity, or does that just not work?
: Re: Shrugger! Unity!
: x4000 July 29, 2013, 09:35:19 AM
Unity supports C# via mono, but you can't use something like wpf or windows forms -- those are not opengl/directx based (both run in software mode, not hardware-accelerated).
: Re: Shrugger! Unity!
: Shrugging Khan August 02, 2013, 04:19:28 PM
Awwwright! So I now have working but horrifyingly inefficient procedural world generation (It generates a flat plain and a featureless tower, with semi-random colours. Go me!), and a day-night cycle with weird colours.
So far, so nothing at all yet. Questions!

1) I originally tried to make large structures out of uniform small cubes, but that quickly left me with over 10000 cubes to generate, and caused Unity to crash.
Now, I'm considering two options: Using larger gameObjects (pillars, walls, whole buildings) for all larger structures, with small blocks only where necessary, or using procedurally generated polygons instead of cubes (I don't even know if that's possible, or if I have the geometry skills for it).

Is there another way, perhaps, to simply increase the resource efficiency of the original, quasi-minecraft-style block system? Like only generating the world one area at a time rather than all at once, only rendering those cube faces facing the player (and within his FOV), or some obscure coding trick I'm not aware of?

2) I'm trying to instantiate a bunch of critters with AI scripts attached to them. This seems to be simple enough using addComponent to add the script, but I wonder if I should do it differently. Is this method good enough, or am I being an Idiot and there's much better ways to do it?

3) For things like creature attributes, NPC equipment and whatnot - what's the best way of storing that data? Right now I'm just using int[, , , , , ,] arrays, but I can't imagine that that's the best way to do it.
The same question applies to the previously mentioned world generation array, in which I store block coordinates and types. Is that even a good method?

4) What's the best way to write down things like enemy types, items, skills etc.? Just right there in the scripts, or maybe with something like XML files? I have no buggering idea how that even works, but it'd be nice to know what angle to aim for.
: Re: Shrugger! Unity!
: x4000 August 02, 2013, 04:25:35 PM
1. Yes, you just need to have a disconnect between how your world is generated versus how it is displayed.  IE, generate your cubes however you want, in terms of knowing what they are and where they are, but this is your own custom code and has nothing to do with Unity GameObjects or whatever.  Then whatever cubes are in the view, use reusable Unity GameObjects for those.  Depending on your draw distance, hopefully you're not seeing thousands of those.

2. No idea, never have used AI scripts or addComponent, sorry.

3. Object oriented programming with custom properties, for sure.  Or are you using Javascript?  I can't recall.  JS really is inferior for structured data...

4. Up to you, really.  Mostly we put it in the code because it's quick to do and quick to access, and we don't really want those things being externally changed.  But some things we do read in from external files, like particle effects or whatever.  It depends on the specific use case, honestly.
: Re: Shrugger! Unity!
: Draco18s August 02, 2013, 04:29:00 PM
1) I originally tried to make large structures out of uniform small cubes, but that quickly left me with over 10000 cubes to generate, and caused Unity to crash.
Now, I'm considering two options: Using larger gameObjects (pillars, walls, whole buildings) for all larger structures, with small blocks only where necessary, or using procedurally generated polygons instead of cubes (I don't even know if that's possible, or if I have the geometry skills for it).

Separate your visuals from your procedurals.

Minecraft essentially has a 3 dimensional array of integers that it uses to hold the world information.  Each integer refers to a complex block class, which is instantiated once.

The visuals are a lot of rendered face, but only the visible ones.
: Re: Shrugger! Unity!
: Shrugging Khan August 03, 2013, 06:37:26 AM
I'll have to get back to you about the visual/procedural issue (I get your points, but the actual way to do it eludes me still).

Regarding Object Oriented Programming for NPC attributes and the like, can anyone give me some basic pointers? My OOP-Fu is rather weak, I'll admit. It's my general failing, to rely too long on simple tools where more refined ones would be more appropriate...hence my using simple arrays instead of something sensible.

What do I need? Basic C# scripts, or a different format? Classes? Methods? Properties? All of that stuff is quite a mess in my head, so if someone could give me a brief overview of what is needed, I#d be much obliged.
: Re: Shrugger! Unity!
: x4000 August 05, 2013, 10:03:33 AM
Regarding OOP, the general process is this:

1. Set up a separate file, with a class definition in it.  Put various properties and methods on that class.
2. Instantiate that class as an object as much as you need to, in order to store your data.

From a 10,000 foot overview, that is all OOP is.  You define classes with methods and properties that are well-organized and which make sense to a human reading them, and then you make 0-n objects out of those classes. 

These are not scripts or attached to your existing GameObjects unless you want them to be.  Though you need some way of indexing all of this non-script data.  You can either do that with the Singleton design pattern (you can google that) or a class with static properties that provide those ongoing references.  Or you can put the ongoing references on your camera or some other always-exists GameObject in your unity game.  But I personally prefer using a Singleton class.

In terms of the specifics of OOP, there are obviously more things than just the 2 above, but those are the basic outline of everything else you could do.  For instance, other things you might do:

A. Set up sub-classes of higher-order classes.  Either an abstract parent class (google "abstract classes" in C#), or a regular parent class that has some virtual methods, or just a regular parent class.  Books on basic OOP make a big deal out of the ability to do these sorts of things, and it is powerful, but they carry it to an extreme degree in their examples, frequently.  Most of the actual libraries in actual commercial software (the .NET libraries themselves) don't have too extreme of inheritance going on.

B. You can set up various metadata classes that contain information about all the types of objects of X.  Think of this like an encylopedia: each instance of the BlockObjectTypeData class might have all the properties associated with a BlockObjectType enum value, and then you have a BlockObject class whose instances are the actual working data about your current scene.  But rather than duplicating all that info from BlockObjectTypeData, which can be substantial, they just reference it instead.  Way more efficient on RAM, and initialization time.

Among many other things you can do, but honestly it's easy to over-engineer OOP apps just as much as any other kind of app.  Following the KISS principle is generally best.  But I can't recommend learning about Design Patterns any more highly, as that often has loads of great architectural ideas.
: Re: Shrugger! Unity!
: Draco18s August 05, 2013, 10:52:53 AM
One of the patterns I want to get into using is the decorator pattern.  Just because it's so damn useful (from a completely non-code perspective).

Problem is I have no idea how to go about doing it.  Closest I've come is Minecraft's block/item code which looks like a decorator pattern, but it actually isn't.

Eg. you can do new BlockType(1, Material.STONE).setResistance(10.0F).setUnlocalizedName("MyBlock").setHardness(2.0F);
Which is how to create objects with properties in the decorator pattern.

Internally, for Minecraft, all this does is this:
Block b = new BlockType(1, Material.STONE);
b.resistance = 10.0F;
b.unlocalizedname = "MyBlock";
b.hardness = 2.0F;

(or putting those function calls in the constructor, etc. etc.)
Those properties are technically protected, but functionally it's the same thing.  The fact that those setter functions return the block itself isn't actually relevant.  Block classes are treated as singletons, but they aren't forced to be singletons (i.e. you can instantiate a second copy if you want to for whatever reason--comes up a few times, like glowstone lamps, which are instantiated with a different light value and different block ID, even though it could have been done with metadata).

Unlike the decorator pattern which actually takes an object passed in, adds methods and properties (so it becomes a more or less unique class), and returns the resulting object.

As an example using AI War, you could have a base Ship class and decorate it with the Repairer class.  Now it's an engineer.
Take the same Ship, decorate it with a Weapon class, now you've got a basic fighter.
Take the Ship class and decorate it with Regenerator (implies ImmuneToRepair) and Melee.  Now it's a Vorticular Cutlass.

Now you only need classes for the various functionality rather than unique classes for each ship type (or a bloated base class that has options for everything; ie. isRegenerator, isMelee, isRadarDampening, etc).

This lets us do cool things like:

Ship s = new Ship().Regenerator().Repairer().Teleporter();

For an entirely different kind of engineer without having to write any new code.
: Re: Shrugger! Unity!
: Shrugging Khan August 05, 2013, 03:06:58 PM
Interesting enough, that stuff. I can see rather plainly that there's a lot of work, both in theoretical learning and in trial-and-error ahead of me. Thanks for the explanations; I'll report back as soon as I've some successes or new failures to tell of  :D
: Re: Shrugger! Unity!
: Draco18s August 05, 2013, 04:00:53 PM
both in theoretical learning and in trial-and-error ahead of me

One never stops learning. ;)
: Re: Shrugger! Unity!
: x4000 August 05, 2013, 04:17:55 PM
We do the equivalent of the decorater pattern via flags and other properties on our centralized typedata classes.  It would let us build customized cross-class ships if we felt like it, but instead we use that to make our actual new ship classes in expansions and so forth.  Similarly something like AddTeleporter() would be fine if you wanted to group a set of values sets into one call.
: Re: Shrugger! Unity!
: Draco18s August 06, 2013, 09:21:49 AM
We do the equivalent of the decorater pattern via flags and other properties on our centralized typedata classes.  It would let us build customized cross-class ships if we felt like it, but instead we use that to make our actual new ship classes in expansions and so forth.  Similarly something like AddTeleporter() would be fine if you wanted to group a set of values sets into one call.

Similar to Minecraft, yeah.
: Re: Shrugger! Unity!
: Shrugging Khan August 07, 2013, 03:18:44 PM
So I've been merrily working on, making little cubic and spherical and cylindrical things chase and eat each other. Fun times!

Now that that particular bit of natural selection is working, I've been trying to get onto the whole OOP train as you two suggested, and I've hit the first major roadblock.

WTF am I supposed to start with?
I don't even understand what kind of file to create and work with. I've got a light grasp of OOP with Java, but that doesn't translate too easily into Unity.

So, really, just a simple question: What kind of file(s) do I create in order to start experimenting?
: Re: Shrugger! Unity!
: x4000 August 07, 2013, 03:45:50 PM
In Javascript or C#?

In JS I have no idea.  In C#, you will be creating some .cs files.  Those will be class files automatically if they are not scripts attached to gameobjects.
: Re: Shrugger! Unity!
: Draco18s August 07, 2013, 03:54:03 PM
You can do the same thing in JS.  Just be aware that unless it is a class that somehow inherits MonoBehaviour, you won't be able to attach the script to an object at all.

Which for most things is fine, you just have to be aware of it.
: Re: Shrugger! Unity!
: Shrugging Khan August 07, 2013, 05:08:24 PM
I've been using nothing but c# ever since you argued so strongly in favour of it ;)

So I just use those .cs files and those are equivalent to a class?
: Re: Shrugger! Unity!
: Draco18s August 07, 2013, 05:10:17 PM
Yep!
: Re: Shrugger! Unity!
: Shrugging Khan August 28, 2013, 03:35:25 AM
Awwwright!

So I spent almost all my free time (read: non-social, non-play time) tinkering around, and I do think I've learned a lot. A bit too late for an OOP-centred exam that I will almost certainly have to repeat, but absolutely in time for Unity!

Now, next question.

Are there any rules (of thumb), guidelines, formulas, tests or general considerations regarding HOW I organise my objects and information? As in, when do I fill Objects with countless attributes and methods, and when would I better keep those within separate sub-objects and attach them to whatever Object has need of them? When is it smarter to store information in individual objects, and when is it smarter to store it in a single super-object? Is it generally best to minimise the number of layers of objects and sub-objects, or does it not usually matter how deep that rabbit hole goes?

And so on, and so on...any help is dearly appreciated, of course.  :)
: Re: Shrugger! Unity!
: x4000 August 28, 2013, 06:59:03 AM
That's more of a taste/design question than a technical one, so grains of salt with my answer. But my approach is basically:

1. If it is all once conceptual thing (a "game entity" for instance) it has a single class with all of its mutable data on it.
2. If it is conceptually different ("background tiles" for instance) I don't try to mash those in to the former.
3. If it is a common property shared between all objects of a sub type, then I have a single instance of a "typedata" class type that is paired with an enum value (so one instance of game entity typedata for each game entity type).
4. Worker methods that talk about many of the object type at once (find a game entity, alter many at once, etc) go on some larger central classes (for instance a Game or World class).

This leads to large class files, which is why not everyone will agree. But it also leads to less confusion about where things are, and shorter intellisense calls. Dog.collarbuckle rather than pet.dog.collar.buckle or what have you.

Those are my opinions, but I do not feel anyone who disagrees is "wrong" in any sense. It all boils down to what most matches your mode of thinking. As long as it is clearly and consistently organized (ie you have some simple rules and follow them consistently), you're good to go.
: Re: Shrugger! Unity!
: Draco18s August 28, 2013, 09:53:14 AM
Are there any rules (of thumb), guidelines, formulas, tests or general considerations regarding HOW I organise my objects and information? As in, when do I fill Objects with countless attributes and methods, and when would I better keep those within separate sub-objects and attach them to whatever Object has need of them? When is it smarter to store information in individual objects, and when is it smarter to store it in a single super-object? Is it generally best to minimise the number of layers of objects and sub-objects, or does it not usually matter how deep that rabbit hole goes?

I'm going to have a slightly different approach than X here, but largely speaking the two of us think alike.  I've gotten tons of helpful code and theory from him and Keith.

Anyway.

1) Avoid God Objects.  A "god object" is a single class or instance that Know Everything.
2) Avoid public properties where possible, only expose what needs to be exposed.
3) Likewise don't cross reference if you can avoid it.  The main game class will know about the Player and the Dungeon, both of which will know about the main class, but the Dungeon shouldn't know about the Player and vice versa.  (Possibly bad example, but its the best I can come up with on short notice).  Inevitably you'll find exceptions even when you were certain that A shouldn't need to know anything about B.*
4) Class inheritance!  Extends!  Implements!  Glorious features.  public class Player extends GameObject implements IMovable {}
(GameObject here being a generic class, not Unity's GameObject class, which is static and can't be extended)

As a generic suggestion, go get Minecraft Forge (http://files.minecraftforge.net/) source (and Eclipse (http://www.eclipse.org/downloads/packages/eclipse-ide-java-developers/indigosr2) to run it), poke around with Minecraft's internal structure a bit.  Get a feel for how the code is organized.  Its by no means perfect, but having spent several months modding I picked up a few habits that I rather like, just due to the organizational benefit.  I also fell in love with Eclipse, though I haven't had the time to set it up as a generic IDE for Unity or Flash (the version of MonoDevelop for Windows that ships with Unity is garbage).  It's Refactoring tools are lovably amazing.  Want to rename a class?  Right click, refactor -> rename, bam.  Anywhere it's been used in your entire project now use the new name.  I would love to have that power for the Flash game I'm working on.  I'd like to rename RewardItem to ItemReward, just so that when I try to type a var as RewardItem I don't have to scroll down through Reward00 through Reward50 to get to it (or typing out "RewardI").


*My dungeon floor objects should never need to know anything about the player, after all, this is just the walkable map and some other objects!
/me implements shadows
:
public function onEnter() { //run when the player first enters the floor.
if(main.currentMapID <= 10) {  //no shadows below floor 10
shadows.visible = false;
}
else if(main.currentMapID < 40) {  //deepending shadows until 40, 40+ full dark
a = (main.currentMapID - 11) / 30;
shadows.alpha = a;
}
/me implements the torch so that the player can see in deep shadows
Crap.  Floor needs to know about the player now....
:
//shadows less dark if the player has the torch
if(shadows.visible && main.player.flags.hasTorch) {  //hackney reference to the player
shadows.alpha /= 3;
}
: Re: Shrugger! Unity!
: Shrugging Khan September 06, 2013, 05:35:48 AM
Alright, so at the moment I have one StartScript that spawns GameObjects and attacheds various scripts to them, a ListsScript that contains a number of Lists pointing to all the spawned GameObjects and their sub-scripts, with different lists for different script types.

This has ended me up with glorious lines like
:
this.gameObject.GetComponent<ObjectScript>().mainSYS.GetComponent<ListsScript>().objectList.Remove(thisObject.gameObject.GetComponent<ObjectScript>);A bit hard to read, I must say.

How bad or normal is this?
I've begun to add direct pointers to scripts, lists and objects in the scripts to simplify things, but I'm not sure how stylistically sound or technically efficient this is.
: Re: Shrugger! Unity!
: x4000 September 06, 2013, 05:48:25 AM
Well... in general C# coding practices, that would not be great.  In Unity, I think it's not that efficient.  Ideally you want fewer GetComponent calls, mainly.  It's okay to be calling House.Dog.Hair.Fleas.Kill() or whatever, although usually there has to be a REALLY good reason for that many chains.  But it's not exactly inefficient or something, it's just long code.  In your case, I'm pretty sure there is a nontrivial cost to every call of GetComponent, though, and so depending on how many times that gets called per second, it might even hurt your framerate.
: Re: Shrugger! Unity!
: Shrugging Khan September 06, 2013, 05:55:52 AM
So long chains are ugly but acceptable, whereas GetComponent() calls are to be avoided where possible. Got it!

There's gonna be a lot more pointers from now on, I suppose.
: Re: Shrugger! Unity!
: x4000 September 06, 2013, 05:56:28 AM
Yep!
: Re: Shrugger! Unity!
: Draco18s September 06, 2013, 09:54:39 AM
So long chains are ugly but acceptable, whereas GetComponent() calls are to be avoided where possible. Got it!

GetComponent, GetDefinitionByName, etc. are generally fairly intensive calls.  I'm using GetDefinitionByName in one of my (Flash) projects right now, but it's a once-off per-run thing to simplify the code for me to write (so instead of saying new Level01(); new Level02(); new Level03(); etc up to Level50, I can just put it in a loop, new GetDefinitionByName("Level"+i)();)

Did I also list some of the other things I have for Unity for optimization?

As few particle systems as possible
Texture size (smaller better; sprite sheets better than smaller individual files)
Remove empty animations (this has to do with imported models)
Avoid mesh colliders (if it moves in Unity at all, Unity has to recalculate the mesh every frame when its moving)
: Re: Shrugger! Unity!
: Shrugging Khan September 06, 2013, 11:33:02 AM
About the Mesh Colliders; would they be less troublesome if all my meshes consisted of geometrically simple shapes; i.e. a few cubes and tetrahedrons stuck together?
: Re: Shrugger! Unity!
: Draco18s September 06, 2013, 11:53:56 AM
About the Mesh Colliders; would they be less troublesome if all my meshes consisted of geometrically simple shapes; i.e. a few cubes and tetrahedrons stuck together?

Combined collission meshes made up of handful of cubes is the way to go about it whenever possible.  Spheres never need recalculation (rotation is irrelevant to them) and cubes are very fast.

(http://docs.unity3d.com/Documentation/Images/manual/class-BoxCollider-2.jpg)

Mesh colliders, regardless of how many verts, are very slow to recompute because Unity can't take advantage of the known shortcuts for the simple (cube, sphere, cylindrical) colliders.  It's always best to remove the mesh collider and replace it with a simple collider, even if the mesh is identical to one of them.
: Re: Shrugger! Unity!
: Shrugging Khan September 08, 2013, 09:27:38 AM
Alright, I'll take it to heart.
: Re: Shrugger! Unity!
: Shrugging Khan September 16, 2013, 03:01:29 PM
So, after another lot of playing around with everything, creating a simple but functional ecosystem and a somewhat crude simulation of plate tectonics, I think I've learned a few things.

More questions!

What's the best way to create a Save Game?
What's the best way to store information that is not needed at present, but might come in handy again later in the future?

And how generously can I initialise variables, lists and arrays without it becoming a resource issue?
: Re: Shrugger! Unity!
: x4000 September 16, 2013, 03:09:16 PM
Save game: some form of serialization, either binary or via custom string serialization.  Binary serialization can be brittle in my opinion.  So most likely it's like creating a form of flat file where you write out data in a textual format.  There are various approaches, though, ranging from more to less sophisticated.  We use two separate ones in our games, one for high performance and the other that allows hand-editing (aka settings files on the latter).

In terms of your second question, I'm not really sure what you mean.  Storing any information would be via some sort of variable, somewhere.  Either on an object, or on a singleton class, or whatever.  When you need to use the data is irrelevant; how it is logically organized is what matters most.

In terms of initializing variables, lists, and arrays, that's again a pretty broad question.  It depends on what kind of stuff you are doing.  The primitive types all have fixed sizes which you can look up details on in a general C# reference.  Strings are interned, and string interning in general is something worth reading up on.  Arrays vary as to what they are based on if they are primitive arrays or object arrays or lists.

It takes a goodly while to run out of data space, but AI War has managed to do it from time to time.  It's tracking an obscene amount of data compared to any other game I know, though, so I doubt you will have problems.  Things like textures and other graphical data is not stored in the mono memory space unless you have it opened for read/write access on a texture or whatever.  Which is not the usual thing.
: Re: Shrugger! Unity!
: Shrugging Khan September 16, 2013, 04:03:37 PM
Regarding the second question, my problem is storing information on procedurally generated bits of world (geology, biosphere and atmosphere, for example, so it could amount to quite a large amount), that the player is not currently close to.  They'd need to be saved in case the player returns there, and parts of that data would occasionally need to be read in order to calculate things like global weather patterns (yeah, I know, not really practical...but let me dream a bit), but otherwise they wouldn't need to be kept around.

Now, I know fairly little of the distinction between hard drive, RAM, virtual memory and god knows what else, so I'll just turn this into an utterly unprofessional metaphor: If a save game is putting something into a chest and burying, so that it's safe and unchanging until needed again, then how could I just put something into the shed, where the smell doesn't bother me, but I could still occasionally check its temperature?

Wait, I don't think that metaphor helped at all.
Never mind, some sleep might be in order.
: Re: Shrugger! Unity!
: keith.lamothe September 16, 2013, 04:18:57 PM
Regarding the second question, my problem is storing information on procedurally generated bits of world (geology, biosphere and atmosphere, for example, so it could amount to quite a large amount), that the player is not currently close to.
You can save it to disk and read it back in as needed.  That's what we did in AVWW1/Valley2 with one file for each "chunk" (contiguous side-view space).

That said, I'm really happy our more recent games don't require such a model.  FWIW.


As far as tiers of storage and whatnot:

1) Registers: these are the literal sets of latches (or whatever they're called) in the CPU's arithmetic logic unit (ALU) that are directly connected to the Adder circuit and other such things that perform machine instructions.  So adding two numbers already in registers is generally a single-cycle operation.

2) L1 Cache: this is a small pool of RAM-like (iirc) memory on the CPU itself, physically close to the action and very high-speed design/tech for minimal latency of retrieval.

3) Generally there's an L2 cache that's bigger and slower than the L1.  Some machines have an L3 cache that's even bigger and even slower, iirc.

4) RAM: these are the sticks you actually plug into your machine when building it.  They're much slower than cache (iirc) but can be much bigger.  Nowadays most applications can run entirely in RAM on a decent machine (with 8+ GB of it), though this has not always been the case.  So generally in an app you don't have to worry about anything "lower" than this for actual operation.  But if you need more than, say, 1.4GB of actual data you need to investigate a 64-bit app (not possible with Unity right now, iirc) or some kind of disk-saving shenanigans like we did with AVWW1/Valley2.

5) Disk: the catch-all.  Could be platter-based HDDs or solid state drives, or some combination.  Platter-based drives (the standard until SSDs came around) are sloooooooooow.  Retrieval of information involves actual physical motion of the platter.  They've gotten really good at doing that quickly in the relative sense, but it just can't compare with normal electrical signals that generally move around near c (iirc).  So Solid State Drives are rather nicer in this regard, though they are not without their many foibles (and they can't compete with decent RAM speed-wise, nor are they really intended to in terms of the bus architecture and so on).

I didn't list Virtual Memory separately since that's just a chunk of your disk (HDD/SSD) space carved out to serve essentially as an "overflow room" for your RAM.  So if all the applications currently running on your machine need more total memory than you have RAM, your OS "pages out" parts of RAM it doesn't think you'll need soon to this virtual memory "pagefile".  If your RAM is full and you don't _have_ a pagefile (disabling it is common practice with an SSD, to extend drive life), or your pagefile is also full, expect some fairly messy crashes.  Generally doesn't happen nowadays though.


Edit: whoops, meant to add that as a programmer in many environments (including Unity's available languages), you have neither the ability nor the need to have any idea of or control of what happens with the Registers or Caches.  That's all handled for you, for better or worse.  Your choices entail how much stuff you create (that goes in RAM), and what you write to or read from disk.
: Re: Shrugger! Unity!
: Shrugging Khan September 16, 2013, 05:37:28 PM
Well, that's some interesting information either way. So I take it my only real option with Unity and C# is to create storage files on the hard drive, and read from those when necessary?
: Re: Shrugger! Unity!
: keith.lamothe September 16, 2013, 05:40:14 PM
Well, that's some interesting information either way. So I take it my only real option with Unity and C# is to create storage files on the hard drive, and read from those when necessary?
For loads of data that you don't think will fit in your available RAM?  Yea, disk.

First thing, though, is to analyze whether you really need that much memory.
: Re: Shrugger! Unity!
: athros September 17, 2013, 03:13:37 PM
What's the best way to create a Save Game?
What's the best way to store information that is not needed at present, but might come in handy again later in the future?

And how generously can I initialise variables, lists and arrays without it becoming a resource issue?


Well, that's some interesting information either way. So I take it my only real option with Unity and C# is to create storage files on the hard drive, and read from those when necessary?

I'm writing a roguelike (prototype phase), and I do all of my generation at the start. I serialize all of that into a flat JSON text file, and read it back in floor by floor for persistence. It loads relatively quickly (1-2 seconds) on my iPad, but generation can take upwards of 3 minutes (almost unacceptable - I'm still working on tightening the generation code). Once all of that is done, that's the save file for the game. I don't really know Unity that well. All of this is using Python, and coding on my iPad in an app.

Because the JSON is the save game, I can serialize the state of the game after every action taken, ensuring a consistent state even if the player has to exit for a phone call, different app, whatever. There is no discernible slowdown, and profiling shows it takes way less than a second.

I can't load the entire file without crashing the iPad, so I have to work with a file. If this is for the PC, you might want to look at what you need to store in memory, and then determine how much you want to store above and beyond that.
: Re: Shrugger! Unity!
: Shrugging Khan September 17, 2013, 04:59:08 PM
I'm going to have to ask; what is a JSON file?
: Re: Shrugger! Unity!
: Draco18s September 17, 2013, 05:11:50 PM
I'm going to have to ask; what is a JSON file?

It's like XML but not.
http://en.wikipedia.org/wiki/JSON
: Re: Shrugger! Unity!
: athros September 17, 2013, 05:48:54 PM
I'm going to have to ask; what is a JSON file?

JSON is a plain text file format - http://json.org/
Here are some examples - http://json.org/example.html
: Re: Shrugger! Unity!
: Shrugging Khan October 04, 2013, 10:10:19 AM
So, while me and my brother have been busy putting together a bit of a space fleet combat simulation, I secretly took some time off from that to continue working on my earlier project.

Only now I ran into a problem that probably doesn't at all belong here, yet requires a solution before I can proceed:

To what a degree does non-solar starlight illuminate the surface of the earth?
Let's assume that there are no clouds, no air pollution, no aerosols and generally...just boring old air in the atmosphere.

Thank you for any information or links  :D
: Re: Shrugger! Unity!
: Draco18s October 04, 2013, 10:15:21 AM
"Not enough to see by."

A new moon plus a clear sky without any light pollution from cities, etc. etc. etc. leaves you in a very dark field with a fantastic skyscape, but you're still likely to trip over the deck chair.
: Re: Shrugger! Unity!
: keith.lamothe October 04, 2013, 10:16:46 AM
but you're still likely to trip over the deck chair.
Prompting a change in game design and the birth of a new genre: "Deck Chair Annihilation Simulator 2013"
: Re: Shrugger! Unity!
: Shrugging Khan October 04, 2013, 10:22:47 AM
Argh, practicality...alright, I'll have my beautiful dynamic night sky without the stars actually projecting lights onto the ground.

Next question! Is there any way to use .AddComponent<>() and .GetComponent<>() simultaneously?
: Re: Shrugger! Unity!
: keith.lamothe October 04, 2013, 10:25:24 AM
Argh, practicality...alright, I'll have my beautiful dynamic night sky without the stars actually projecting lights onto the ground.
Oh good grief.  Actually having that many light sources?  I guess bonus points for procedural modeling of dynamic star characteristics and delaying the effect of those changes by the corresponding distance in lightyears ;)
: Re: Shrugger! Unity!
: Draco18s October 04, 2013, 10:27:28 AM
Argh, practicality...alright, I'll have my beautiful dynamic night sky without the stars actually projecting lights onto the ground.
Oh good grief.  Actually having that many light sources?  I guess bonus points for procedural modeling of dynamic star characteristics and delaying the effect of those changes by the corresponding distance in lightyears ;)

http://gamelab.mit.edu/games/a-slower-speed-of-light/
: Re: Shrugger! Unity!
: keith.lamothe October 04, 2013, 10:30:38 AM
http://gamelab.mit.edu/games/a-slower-speed-of-light/
I should have known.
: Re: Shrugger! Unity!
: Draco18s October 04, 2013, 10:31:39 AM
http://gamelab.mit.edu/games/a-slower-speed-of-light/
I should have known.

Its really trippy to play.  Built in Unity, and I believe the code is open source.
: Re: Shrugger! Unity!
: keith.lamothe October 04, 2013, 10:42:17 AM
Its really trippy to play.
Because of the deck chairs?
: Re: Shrugger! Unity!
: Draco18s October 04, 2013, 10:44:11 AM
Its really trippy to play.
Because of the deck chairs?

No, at movement speeds approaching the speed of light it becomes very difficult to navigate.  Also you go blind as everything hue-shifts to/past UV or IR.

Edit:
WAIT A MINUTE.
I SEE WHAT YOU DID THERE.
: Re: Shrugger! Unity!
: keith.lamothe October 04, 2013, 11:03:46 AM
Edit:
WAIT A MINUTE.
I SEE WHAT YOU DID THERE.
It may have taken the light a minute to get across.
: Re: Shrugger! Unity!
: Shrugging Khan October 04, 2013, 05:15:10 PM
Oh good grief.  Actually having that many light sources?  I guess bonus points for procedural modeling of dynamic star characteristics and delaying the effect of those changes by the corresponding distance in lightyears ;)
I was actually working on procedural sunspots and supernovae for the individual stars when I realised that I am once again putting far too much work into details that I should take care of much, much later...if ever.

I'm going back to modelling the asthenosphere now; not much point in having a roguelike without a planet to stand on.
: Re: Shrugger! Unity!
: keith.lamothe October 04, 2013, 05:52:23 PM
I'm going back to modelling the asthenosphere now; not much point in having a roguelike without a planet to stand on.
Ah, but there's a great deal of point in a roguelike where, by a few actions and some particularly remarkable RNG rolls, you no longer have a planet to stand on! :)
: Re: Shrugger! Unity!
: Draco18s October 04, 2013, 05:55:15 PM
I'm going back to modelling the asthenosphere now; not much point in having a roguelike without a planet to stand on.
Ah, but there's a great deal of point in a roguelike where, by a few actions and some particularly remarkable RNG rolls, you no longer have a planet to stand on! :)

Portable Hole, meet Bag of Holding.
: Re: Shrugger! Unity!
: Shrugging Khan October 05, 2013, 04:19:13 AM
Well, blowing up the planet is certainly an option.

Anyways, you're all probably a lot better than me at math; what kind of formula could I use to spawn stars in a higher density towards the galactic plane?

Right now, I just spawn them at the centre of the scene, give them a random rotation, and tell them to move back by a few thousand kilometres (inb4 realistic distances - I tried, but unity did not like).

Oh, and if the entire sky were treated as a hollow sphere with the stars tacked onto the inside, then how would it have to rotate for the relative motion to emulate the rotation of the planet (at any given latitude)?
: Re: Shrugger! Unity!
: Draco18s October 07, 2013, 10:09:33 AM
Anyways, you're all probably a lot better than me at math; what kind of formula could I use to spawn stars in a higher density towards the galactic plane?

If we assume that you're placing stars along an X and Y axis, where X is longitude and Y is latitude (so Y90 is the north pole  and Y-90 is the south pole), then something like this:

Y = random(90) - random(90);

That'll get you a bell curve towards the equator plane (which is roughly where the galactic plane is).

Oh, and if the entire sky were treated as a hollow sphere with the stars tacked onto the inside, then how would it have to rotate for the relative motion to emulate the rotation of the planet (at any given latitude)?[/b]

This is where local rotation comes in.  Rotate the sphere by the latitude value, then use your localRotation.eulerAngles to spin it along its vertical axis (y?)
: Re: Shrugger! Unity!
: Shrugging Khan October 08, 2013, 11:07:26 AM
Thankee! I'll make good use of that info.

PS: Other little question - when you put a Reaction wheel on a spacecraft (in space) but mount it far away from the centre of mass, how will that affect the rotation of the craft?

PPS: Nevermind, I think I found out. The reaction wheel will be less efficient the further out it is, won't it?
: Re: Shrugger! Unity!
: Draco18s October 08, 2013, 01:16:57 PM
PPS: Nevermind, I think I found out. The reaction wheel will be less efficient the further out it is, won't it?

I don't know what a reaction wheel is, but generally speaking in physics, the farther away from the center of rotation your force is being applied, the more effect it has.

It's called Mechanical Advantage (specifically: a lever).
: Re: Shrugger! Unity!
: Shrugging Khan October 08, 2013, 02:29:30 PM
That would be my usual understanding, too. But the thing with machines in a vacuum is that you can't work with leverage. Spacecraft usually use flywheels for precision work on their attitude (else: manoeuvring thrusters); see http://en.wikipedia.org/wiki/Reaction_wheel for more information on that one.

: Re: Shrugger! Unity!
: Draco18s October 09, 2013, 10:15:34 AM
Oh!

I don't know the answer to your question, but I do understand how they work.  They work on the principle of action-reaction.  It's not so much that they make the spacecraft rotate by spinning them, but rather the change in the spin on them changes the spin on the spacecraft.

I don't think you'd actually have to worry about that level of detail in a simulation.  Reaction Wheels are for very very tiny adjustments.
: Re: Shrugger! Unity!
: Shrugging Khan October 23, 2013, 07:24:15 AM
On an unrelated note; do I have any physical (CPU / RAM) disadvantages from declaring public variables, objects or methods, as opposed to nonpublic ones?
: Re: Shrugger! Unity!
: Draco18s October 23, 2013, 08:24:06 AM
On an unrelated note; do I have any physical (CPU / RAM) disadvantages from declaring public variables, objects or methods, as opposed to nonpublic ones?

No.  Public/private is just error checking preventing you, the coder, from changing values you shouldn't be.
(Not entirely true, there are differences at runtime, but the gain/loss of resources is unbelievably tiny; takes upwards of 10 million accesses to accumulate 1 ms of lost processor)
: Re: Shrugger! Unity!
: keith.lamothe October 23, 2013, 08:41:34 AM
Yea, I suggest making everything private unless it needs to be broader, just to avoid unintentional access/modification from other classes.

It isn't hypothetical; a lot of my bugs are actually from braindead typos like picking the wrong field.  Though most of those I catch in internal testing before they sneak out.

On a similar note, I find it preferable to not do getter/setters except when the associated logic is complex or the field in question really needs the protection.  Saves coding time and cpu time.  Of course, this is from my perspective of "only an Arcen programmer will ever maintain this code", which is radically different than writing a library or whatever.

That said, the "readonly" modifier is great for fields you don't plan to change after construction.  We have tons of those in our enum/typedata-pattern classes.  Granted, I've only _once_ accidentally modified a typedata field that I meant to access, but I don't think Space Tanks have ever quite forgiven me for intermittently revoking their ability to enter transports.  During the game.  ALL Space Tanks.  Everywhere.
: Re: Shrugger! Unity!
: Shrugging Khan October 23, 2013, 10:41:00 AM
I also pretty much dropped the teaching of "Getters and Setters everywhere!" (as taught at our university), and only use them where it actually provides necessary functionality.

But alright, thanks gents. I'll stop feeling guilty about all those public values, then.
: Re: Shrugger! Unity!
: Draco18s October 23, 2013, 10:50:35 AM
I also pretty much dropped the teaching of "Getters and Setters everywhere!" (as taught at our university), and only use them where it actually provides necessary functionality.

Pretty much.  For a semi-RPG I built I was performing some cryptography on the player's stats, so that it was harder to use CheatEngine to access and modify the values.  So I used getter/setter to translate between the obfuscated value and the actual value.

Minecraft also has getters for a lot of values simply because it allows for a lot of power in terms of future or mod content.  So you can have a block that looks different based on side and metadata, or items that have different icons based on NBT data.

But in general it's probably fine to skip them if you don't see a use for it.
: Re: Shrugger! Unity!
: windgen October 24, 2013, 04:35:32 AM

> I suggest making everything private unless it needs to be broader, just to avoid unintentional access/modification from other classes.

Python has a good solution to this dilemma.  Instead of a "private" keyword that gives you a compiler-enforced "this field can't be accessed from other classes," the Python Way is to use an underscore in front of the names of fields that are intended to be internal as a strong suggestion that outside classes shouldn't use it.

When you get right down to it, sometimes it's good to be able to access private fields if you really need to.  The underscore tells you "This isn't intended to be part of the public API, so it may break in later releases without warning, and it's also probably totally undocumented so you ought to read the code to be sure it does what you think it does."

There are countless times I've wanted to access a private field in some library, and I have to either re-implement that part of the library, or make my own fork, for no good reason other than the library author made the field private because they weren't creative enough to envision my use case.

Then again, if you're writing application code that's not going to have any downstream users, "private" doesn't matter so much, because if you discover later that you need to access it, you can always just change the declaration yourself.
: Re: Shrugger! Unity!
: Draco18s October 24, 2013, 08:53:28 AM
There are countless times I've wanted to access a private field in some library, and I have to either re-implement that part of the library, or make my own fork, for no good reason other than the library author made the field private because they weren't creative enough to envision my use case.

Reminds me of the ItemStack sensitive version of getIcon for Minecraft, which was marked as Final.

http://www.minecraftforge.net/forum/index.php/topic,12446.0.html

Just read Lex's replies when I tried to ask for Forge to un-finalize the function.

Three days later someone else made the same suggestion and the change was made.
: Re: Shrugger! Unity!
: keith.lamothe October 24, 2013, 10:02:19 AM
Yea, my tendency towards "private" was in the context of writing code that's entirely internal to Arcen.

If I ever write library code again, many things will need to be different :)  Though there I would probably expose it through getter/setter stuff.
: Re: Shrugger! Unity!
: Draco18s October 24, 2013, 10:20:58 AM
Yea, my tendency towards "private" was in the context of writing code that's entirely internal to Arcen.

If I ever write library code again, many things will need to be different :)  Though there I would probably expose it through getter/setter stuff.

Well yeah.  The way you're doing stuff is completely reasonable.  Mojang wrote their code in a perfectly reasonable fashion.  I was just complainging about the Forge guys who are supposed to be making an API...and finalizing a method of the API for no reason other than "because it was final in Mojang's code."

I.e. "made the field private because they weren't creative enough to envision my use case."
: Re: Shrugger! Unity!
: keith.lamothe October 24, 2013, 10:25:03 AM
I.e. "made the field private because they weren't creative enough to envision my use case."
Sounds like it's time for Velociraptor Creativity Camp: where Velociraptors teach you to be creative... or lunch.
: Re: Shrugger! Unity!
: Draco18s October 24, 2013, 10:27:13 AM
I.e. "made the field private because they weren't creative enough to envision my use case."
Sounds like it's time for Velociraptor Creativity Camp: where Velociraptors teach you to be creative... or lunch.

You haven't been seeing the comments on the project about delivery, have you? >..>

OMG SO COMPLICATED WHY DO WE HAVE TO DO IT THIS WAY!?!?!?!!!!1
1 minute later:
Oh, I should have read the whole thing.  That was really easy.
: Re: Shrugger! Unity!
: Shrugging Khan October 27, 2013, 06:36:35 PM
So I've been playing around with celestial bodies. I got the sun to be visible from 1 AU away, but trying to make the spaceships and planets do a little gravitational dance just made unity choke and die on floats by the power of eleven. Apparently, Unity is really, really, really really really bad at distances greater than about a thousand kilometres or so, with physical forces going haywire and the camera throwing errors all over the place.

Can anyone tell me some tricks to keep distances and scales realistic? I tried to just shrink everything by a factor of one million, but that gave me the opposite problem of meshes not rendering correctly anymore and the camera being unable to zoom in close enough without producing clipping errors or just not displaying things anymore. Even shrinking things by 1000 caused these problems, and dividing all sizes and distances by 100 just seemed insufficient.

By now my most promising solution is to scrap the solar system and go for something more manageable - a dwarf planet or a modest asteroid perhaps. But that's really not a solution so much as surrender, so I'd be rather happy if there were some way to make things work.

Any ideas?

PS: I've also considered making the sun and planets rotate around the centre of the game area in such a way as to simulate proper movement, but I don't really know how one would do that.
: Re: Shrugger! Unity!
: keith.lamothe October 27, 2013, 07:07:06 PM
If you want to model realistic astrophysics, even for a single star system and even in simplified form, you're probably going to have to do that yourself rather than relying on the Unity physics model.  Unity's model is meant for game environments, not, well, _real_ environments :)  It would similarly choke on simulating a single room if you actually got down to the molecular level.  Or even substantially coarser than that.

So once your model is telling you where things should be, you then hand the "executive summary" (that is, the minimum "what should I show the player?") of the info to Unity via rendering calls.  So it remains blissfully unaware of the utter insanity you're actually doing, and doesn't throw errors ;)
: Re: Shrugger! Unity!
: Shrugging Khan October 27, 2013, 09:02:38 PM
Well, if I'm going to have to trick Unity, then why use it in the first place? xP

Kidding, of course...I was hoping it might be possible to bludgeon Unity into doing what I want without too much trouble; but given that I'm just trying to make something fun for my little brother at the moment, I'll put homemade astrophysics simulations off for some later date.

I'll keep your suggested approach in mind for later, though. I DO want my pretty little orbits, some day!

PS: Just for curiosity's sake; do you mean that the way to go about the simulation would be to do everything according to proper mathematical formulas without involving Unity physics in the first place, or something else?
: Re: Shrugger! Unity!
: Draco18s October 27, 2013, 11:24:31 PM
http://www.youtube.com/watch?v=8Z1fhClypjg
: Re: Shrugger! Unity!
: keith.lamothe October 27, 2013, 11:37:18 PM
Well, if I'm going to have to trick Unity, then why use it in the first place? xP
You. Have. No. Idea.

A sizeable portion of my last 2-3 years is bound up in that question.


PS: Just for curiosity's sake; do you mean that the way to go about the simulation would be to do everything according to proper mathematical formulas without involving Unity physics in the first place, or something else?
Basically just do the math yourself, yea.  You'll probably want to use a lot of simplifications and approximations even there.  Even just the bare metal of the processor (no engine-based, or OS-based, or whatever tomfoolery at all) isn't going to do millions of square-root operations per second (iirc).
: Re: Shrugger! Unity!
: Draco18s October 27, 2013, 11:39:08 PM
Well, if I'm going to have to trick Unity, then why use it in the first place? xP
You. Have. No. Idea.

A sizeable portion of my last 2-3 years is bound up in that question.

And that, dear friends, is how new engines are born. (http://forums.dumpshock.com/style_emoticons/default/wobble.gif)
: Re: Shrugger! Unity!
: keith.lamothe October 27, 2013, 11:48:47 PM
And that, dear friends, is how new engines are born. (http://forums.dumpshock.com/style_emoticons/default/wobble.gif)
When Unity got to the point where we could produce a viable linux port from an existing game in less than 24 hours (on the first try) I softened a bit.

And in general it's getting better over time.

But we definitely do "our own thing" and forget the engine at least 90% of the time.


You can generally count on the engine to do well those things which the engine developers had in mind.  The rest you have to pull out of a hat.  And you have to bring your own hat.
: Re: Shrugger! Unity!
: Shrugging Khan October 28, 2013, 04:45:31 AM
Well, you might remember that three months ago I didn't even know that hats were a viable option for headwear. Those hat-making skills are something I've yet to acquire  :D

But now I really have to ask; what parts of Unity, other than drawmesh, are you actually using?


Edit: With the planet scaled down to 1km in diameter and weighing in around 8000 tons, as well as the gravitational constant multiplied by 10^13, I've been able to get something resembling reasonable orbits. The frame rate goes down the loo whenever one of the spaceships orbits too far from the planet, though (around 60 fps when everyone is within 10 kilometres, 30 when someone approaches 25km, under 10 FPS when a single ship goes beyond 80km).

Now, I've scripted it so that anyone more than 25km from gets deleted from the scene, and everyone draws TrailRenderers. Well, surprisingly enough, all the ships were gone within 20 minutes, with their trails presenting spiral patterns. Seems like they spiralled further and further out as they orbited!

If anyone here has some knowledge of orbital physics, or perhaps a few more hours of Kerbal Space experience than me, could you explain to me WTF is happening there? Is this some quirk of Unity's physics, or have I actually messed this one up myself?
: Re: Shrugger! Unity!
: Draco18s October 28, 2013, 07:57:59 AM
If anyone here has some knowledge of orbital physics, or perhaps a few more hours of Kerbal Space experience than me, could you explain to me WTF is happening there? Is this some quirk of Unity's physics, or have I actually messed this one up myself?

http://what-if.xkcd.com/68/
: Re: Shrugger! Unity!
: keith.lamothe October 28, 2013, 10:28:10 AM
But now I really have to ask; what parts of Unity, other than drawmesh, are you actually using?
Er, well, not much really. 

Input for keyboard and mouse (sometimes Event for the mouse; there are times when one is more accurate than the other). 

We still use OnGUI for the Textbox (until we get around to making our own textbox, anyhow) but we replaced all our other GUI calls with our own stuff (using normal rendering and input handling, because Unity's GUI stuff is loony in a few respects, especially with more than 2 "layers" on the screen at once). 

The primitives for sound playback.

File I/O for getting the textures and music off disk.  Most of the sounds themselves we actually use Unity's baked-in-asset approach to avoid having to load those sounds off disk every single time we want to play them.

Can't think of anything else off the top of my head, actually.  Though Chris did more of the engine-level interactions.

as well as the gravitational constant multiplied by 10^13
What could go wrong?
: Re: Shrugger! Unity!
: Draco18s October 28, 2013, 10:56:07 AM
We still use OnGUI for the Textbox (until we get around to making our own textbox, anyhow) but we replaced all our other GUI calls with our own stuff (using normal rendering and input handling, because Unity's GUI stuff is loony in a few respects, especially with more than 2 "layers" on the screen at once). 

The primitives for sound playback.

File I/O for getting the textures and music off disk.  Most of the sounds themselves we actually use Unity's baked-in-asset approach to avoid having to load those sounds off disk every single time we want to play them.

Start releasing those as plugins the rest of us can have :D
At like $5-20 there will be a lot of small time developers that would jump at it.  Most GUI systems available that aren't Unity's native are like $100+  (even iGUI Basic--which is just a WYSIWYG editor for the native GUI system--is $35!)

File I/O is something that a lot of developers don't even realize Unity can do.  Actually directed someone your way just the other week about this (they hadn't even realized AI War was built in Unity ;))
: Re: Shrugger! Unity!
: keith.lamothe October 28, 2013, 11:07:05 AM
As I mentioned elsewhere, we really _don't_ follow even the basic-sanity rules for library coding, because we aren't coding libraries :)  Much of it is reasonably modular, but documentation is extremely rare (aside from very clear symbol names, which are largely self-documenting) and much of the code relies on programmer knowledge and self-discipline to not cause massive problems.

It's a lot like a lumber mill built by two guys with nearly 0% concern for safety.  5-foot-radius sawblades spinning at maximum speed hanging from minimum-strength supports in the middle of an empty room with no safety shields and raw wood being thrown at them by various devices.  You could call it "efficient", you could call it "horrifying".

So we'd never really be able to sell it, in good conscience, unless we took the time to really rewrite a lot of it.  And frankly that time is more profitably spent writing more games :)

That said, we're quite happy to share our techniques and such for getting Unity to cooperate.  No need for others to suffer the same way ;)

THAT said, often someone else's needs will differ so much from ours that looking at our approach may actually slow them down, particularly if they try to run with it until they hit a wall.
: Re: Shrugger! Unity!
: Draco18s October 28, 2013, 11:59:41 AM
Offer it for free and label it "as is" with "no warranty." ;D

Fair point though. :)

(Personally I'd spend a buck or two to get a system that works well, even if I have to figure out how to use it myself; set up a wiki for it and your users will document it for you!  I've spent a lot of time documenting Mystcraft's API (http://binarymage.com/wiki/doku.php?id=mods:api) because it had none and I wanted to use it; it's even constantly changing, requiring me to re-figure things every release or two*).

*I'm actually not supporting the current release(s).  Mostly because they're buggier than usual and 95% of the changes are just API changes, meaning that there's little reason for users to upgrade.
: Re: Shrugger! Unity!
: Shrugging Khan November 13, 2013, 07:50:22 AM
I'm trying to find a way to standardise the measurement of difficulty of a shot to be fired, using range, projectile speed, and the target's observed ability to accelerate.

Could I simply use something like ((range * targetAcceleration) / projectile speed) = shot difficulty, or would that get me useless results?
: Re: Shrugger! Unity!
: keith.lamothe November 13, 2013, 09:20:04 AM
I'm trying to find a way to standardise the measurement of difficulty of a shot to be fired, using range, projectile speed, and the target's observed ability to accelerate.

Could I simply use something like ((range * targetAcceleration) / projectile speed) = shot difficulty, or would that get me useless results?
I think range / shot_speed is reasonably meaningful, so I guess throwing accel in the numerator would work and make some sense.

But my question is: what exactly are you trying to model here? 

The difficulty of computing what point to shoot at to get the shot to intersect the target, given the target's current position and momentum.

The difficulty of knowing the target's position and momentum precisely enough to compute the above.
- due to sensor inefficiency and/or jamming
- or due to distance and the finite speed of light

The difficulty of predicting changes in the target's momentum.

Mechanical variation and/or failure in the weapon (or targeting routing hardware, whatever), such that it doesn't actually shoot at the point designated, or at the time designated.

Etc.

Accel would only seem relevant to that third one.  And I guess that it would be very relevant there: given a known position, momentum, and acceleration, there's a "cone" emitting from that position of where it would be physically possible for the ship to be at time t.  If you know your shot will cross the distance in 0.5s, and the "width" of the cone at t=0.5 is less than the "radius" of the target, then firing at the center of the cone would effectively ensure intersection (exactly what part of the ship you hit may vary).  Once the target's possible positions no longer have an intersection, then a miss would be possible even with perfect sensors, targeting, and firing.  The miss chance would probably have more to do with how much the target is trying to evade and whether there were any predictable biases of the evading helmsman, etc.

Of course, I'm assuming only one significant point of thrust on the target; if it's a fighter with a massive lateral thruster strapped to one side then its "cone" gets way more complicated.

Anyway, just trying to figure out what you're actually doing here.  If it's just lasers and other light-speed weapons at short range with reliable (and undamaged) weaponry without some terri-jamming there wouldn't really be a miss chance.  If it's mass drivers at 10 light-seconds with a ton of ECM then probably just call it a 10% hit chance for dumb luck ;)  Or reconfigure the mass drivers for "meteor shower".
: Re: Shrugger! Unity!
: Shrugging Khan November 13, 2013, 12:55:12 PM
I'm actually working with gunpowder cannons for weapons and coal shovellers for a crew...kidding. Still, boring old ballistic projectiles! (LASERs exist, but are considered high-tech, while Missiles are illegal).

The entire "shot difficulty" affair is meant to give the crew a meaningful variable to which to compare to their track record of previous hits, so that they can decide whether or not they are likely to hit any given target. For example, if they have been able to successfully hit targets with a shot difficulty of 10, then if they are in a situation in which firing is considered to be at difficulty 15, they would likely hold fire until better conditions were established - unless they are forced to fire by direct orders or other circumstances. Or it could let them calculate a hit probability, take stock of their remaining ammo, and make a decision on whether or not they can afford to fire.

The entire concept of a single "shot difficulty" variable might be too much of an oversimplification to work, but I wasn't too sure either way.
: Re: Shrugger! Unity!
: keith.lamothe November 13, 2013, 12:57:44 PM
Hmm, yea, not sure what to advise there.

How are you computing whether something actually hits?  Actual collision detection?
: Re: Shrugger! Unity!
: Draco18s November 13, 2013, 02:56:56 PM
I think if that you're computing a unitless number (in the example, higher is more difficult, by an arbitrary amount) then its on the player to gauge how good they are.  It is essentially the star system for sodoku: 1 star is easy, 5 star is hard, how good are you?

How a "hit" is calculated should be independent of this, if you're using player skill and should only effect the AI's decision on when to fire but not anything else.
: Re: Shrugger! Unity!
: Shrugging Khan November 13, 2013, 03:04:54 PM
Slow down gents. Yes - actual collision detection. When firing a gun, a portion of the ships mass is converted into a new GameObject with a rigidbody, collider and a physicalObject script attached. The rigidbody is immediately accelerated by an amount of force dependant on the amount of gunpowder used, and from there on out it's treated as a physical object like any other. When it hits something smaller than a moon (debris, rocks, ships, other projectiles), the physicalObject script gets some relevant information from the collider and proceeds to ponder the nature of the collision according to my limited understanding of kinetic physics. (projectile material and mass, angle of impact, deflection, penetration, deformation, heat from friction and so on.)

It's all rather overengineered (and unfinished, at present), but I like it this way. Fewer shots are possible before the CPU waves the white flag, but every shot is special :>

Anyways, yeah. I'm not determining the actual hit probability here; just what the crew of the ships assumes it to be, in a rule-of-thumb fashion. It's really meant for comparison rather than as an actual measurement of probability.
: Re: Shrugger! Unity!
: keith.lamothe November 13, 2013, 03:08:26 PM
just what the crew of the ships assumes it to be

Hmm, you may need to factor in the crew's average, median, and maximum blood-alcohol level.  Or equivalent, depending on alien biochemistry.  Also, whether or not the proper shanty is being sung.


Anyway, I think your suggested (range/shot_speed)*accel is a decent approximation :)
: Re: Shrugger! Unity!
: Shrugging Khan November 13, 2013, 03:19:04 PM
It's actually a bit of a plot point that militia ships are not allowed to be computer controlled (missiles are subject to the same law), and tend to be manned by scores of barely-qualified personnel that tend to live off biscuits and morale. I thought it would be more interesting this way - I don't want to break the laws of physics to make a space game interesting, but having limiting legalities seemed to be an acceptable way of keeping the combat relatively personable. Otherwise it would have likely been nothing but tiny drone craft throwing missiles at each other from half the solar system away. A bit like The Forever War, really...but that's not very fun. That, or it would be a physics orgy of orbital mechanics. As I plan it right now, by keeping advanced machinery out of the combatants' hands, it will be a lot more close-range and exciting.

So yeah, I'll just use some sort of ( Range / Projectile Velocity), multiplied by the target's agility unless the shooter has the initiative.
: Re: Shrugger! Unity!
: Aklyon November 13, 2013, 06:14:16 PM
Might not help much, but all of this talk of aiming correctly reminds me of Transcendence.
That had a facings system, but if you could aim well and/or drift right, you could snipe large things from maximum range of your current weapon, assuming your current weapons would actually do more than chip damage against said large objects :) . Having bad aim tended to get you nowhere fast unless you were using an omnidirectional instead and sacrificing power for much more forgiving aim.
: Re: Shrugger! Unity!
: Shrugging Khan December 07, 2013, 05:56:23 AM
Been working on my geology project again. Simulating aeolian erosion as a simple random vector that checks whether a geological unit is open to the wind (or covered by its neighbours), I'm using a formula that calculates the wind vector's y component as
:
Mathf.Pow(Random.Value, windFlatness)with windFlatness obviously determining whether the wind actually comes from random angles with a tendency towards the horizontal, or just from any random angle above the horizontal. Now, my question is: How badly would increasing windFlatness affect performance?

: Re: Shrugger! Unity!
: Draco18s December 07, 2013, 09:40:21 AM
I am not sure that that is going to do what you want it to do.

Not without knowing the range of values for windFlatness
: Re: Shrugger! Unity!
: keith.lamothe December 07, 2013, 09:41:45 AM
Performance-wise, Mathf.Pow with non-integral exponents isn't any fun.
: Re: Shrugger! Unity!
: Shrugging Khan December 11, 2013, 09:36:37 AM
What's the performance-optimal way to make objects keep track of time?

All of my physical objects are using an attribute to store time passed, and per-frame checks in Update() to see whether the time has reached the point at which they need to do something. In the past, I did it like this:

:
int time = 0;
int frequency = 12;

Update() {
   time ++;

   if (time % frequency == 0) {
      time = 0;
      DoThings();
  }
}

Some variations also checked if the timer had exceeded a certain limit, or reset the timer only once it reached a certain limit.
Now, I noticed that that system is fine when the frame rate isn't an issue, but it kinda breaks down when it comes to flexibility. So I tried this:

:
float time = 0;
float frequency = 12;

Update() {
   float += Time.deltaTime;

   if (Mathf.RoundToInt(time % frequency) == 0) {
      time = 0;
      DoThings();
  }
}

But that's a lot more resource-hungry, not to mention that it triggers several times in a row (with the RoundToInt) or almost never (without it), so it's not even a solution.

I'm probably trying to work out a roundabout solution while much simpler ones already exist...I think?

Help, please? :/
: Re: Shrugger! Unity!
: keith.lamothe December 11, 2013, 09:43:17 AM
What's the performance-optimal way to make objects keep track of time?

All of my physical objects are using an attribute to store time passed, and per-frame checks in Update() to see whether the time has reached the point at which they need to do something. In the past, I did it like this:

:
int time = 0;
int frequency = 12;

Update() {
time ++;

if (time % frequency == 0) {

}
}
I guess it depends on what you're trying to do and how many things you have doing it.  One low-change optimization there is to drop the % operation (involves division, which generally consumed significantly more processor cycles than add or branch instructions) in favor of "time >= frequency", and doing "time -= frequency" inside the branch.

But the more fundamental issue is: if Update is called once per frame (and never any other time), then why is this concept of time independent of how long it's been since the last frame?  In our stuff we set our "Game.Instance.GameDeltaTime" field to Unity's "Time.time" at the beginning of each Update call, and use the former whenever we need to increment something's idea of how much time has passed.  Though we only store "time remaining until" or "time saved towards" variables when specifically necessary.

Of course, Time.time is a float, so operations on it are substantially slower than the int math you're doing there, but the most important optimization is correctness :)  The question here is "what is correct?".
: Re: Shrugger! Unity!
: keith.lamothe December 11, 2013, 09:48:01 AM
Just saw your second post.

Do you need "simulation time units" that are of a fixed length?  Like "each must represent 1 second of 'game time' " (or 100 milliseconds of game time, or whatever).  This is how we did it in AI War, though the step-size varies by the Performance Profile option.  I think of this as the "sim frame" model, because the frames are defined units of time.

Or can they be whatever length and it just has more or less happen for large or small steps?  That's what we did in AVWW.  I think of this as the "sim step" model, because the steps are just whatever time elapsed since the last time we did it.
: Re: Shrugger! Unity!
: Shrugging Khan December 11, 2013, 10:28:49 AM
So far I've been using the above method for just about everything from plant growth over plate tectonics to the AI.

But it really seems roundabout to me. So, boiling the question down a bit again...what way would you recommend to tell a script to  "do this every [length of real time]!"?


Edit: It took a moment, but I just got the
:
time = Time.time;
if (time >= frequency) {
   time -= frequency;
   DoThing();
}
bit. Doesn't sound all that bad - but what if I had to call it, say, five thousand times per frame?

Edit2: Oh, and what about gimmicks like InvokeRepeating?
: Re: Shrugger! Unity!
: Draco18s December 11, 2013, 10:37:20 AM
bit. Doesn't sound all that bad - but what if I had to call it, say, five thousand times per frame?

Edit2: Oh, and what about gimmicks like InvokeRepeating?

5000 times per frame is not an issue.  When DoThing() is the expensive part, the rest of it can be called a lot without impacting performance.

As for InvokeRepeating, that has function/event overhead, but it probably utilizes similar code.

Fake edit:

Oh:
http://answers.unity3d.com/questions/189917/any-costs-i-should-know-about-associated-with-invo.html

InvokeRepeating would actually be less than using the Update() function.  This is probably because it uses one central update function that invokes function calls in only the objects that need it, where as Update() is called for all objects, even the ones that don't need it (using up function call overhead).
: Re: Shrugger! Unity!
: Shrugging Khan December 11, 2013, 10:42:33 AM
Bugger! Gotta dig into some InvokeRepeating documentation, now. Thanks!

I wonder if a script using InvokeRepeating stops doing so when its associated GameObject is destroyed. Hum...!

BTW, can anyone give me some tips on how to use classes to store information without having it clash with unity's GameObject-and-Component system?
: Re: Shrugger! Unity!
: Draco18s December 11, 2013, 10:51:56 AM
BTW, can anyone give me some tips on how to use classes to store information without having it clash with unity's GameObject-and-Component system?

Scripts attached to objects are classes.  It's just implied if you leave the class definition part out.  If you want to explicitly type your scripts, they're a class that extends MonoBehaviour
(And no, I didn't spell that wrong, they're using the British spelling of "behaviour")
: Re: Shrugger! Unity!
: Shrugging Khan December 11, 2013, 10:54:13 AM
So, if I wanted to have some sort of "CharacterInfo.cs" class, could I use it WITHOUT having to attach it to a Unity GameObject, but IN COMBINATION WITH scripts that are attached in such a way?
: Re: Shrugger! Unity!
: Draco18s December 11, 2013, 11:00:06 AM
So, if I wanted to have some sort of "CharacterInfo.cs" class, could I use it WITHOUT having to attach it to a Unity GameObject, but IN COMBINATION WITH scripts that are attached in such a way?

Ok, yes.  You can create scripts that do not inherit MonoBehaviour and still use them (eg. utility scripts like Math, complex datatypes like Vector3, and interfaces like ISerializable).  You just can't extend them and attach the child class to a game object.  Any attached script MUST, at some point in its class hierarchy, extend MonoBehaviour.
: Re: Shrugger! Unity!
: keith.lamothe December 11, 2013, 11:10:18 AM
One thing I should mention is that we only have one "object" in the Unity sense (the main camera) and its Update() method basically invokes our entire sim for the frame/step.

If you have multiple Unity-level objects, and especially if you have a _lot_ of them, then you're dealing with a very different "overhead ecosystem" than us.
: Re: Shrugger! Unity!
: Shrugging Khan December 11, 2013, 11:24:42 AM
Well, if I had the slightest idea of how to do it the Arcen way, I probably would - if only so as to get around some of Unity's bad sides.

So...teach me the way, master?  ;D

Edit: Then again, I'd have to code my own physics. Not sure if I'm up to that task.
: Re: Shrugger! Unity!
: keith.lamothe December 11, 2013, 11:35:59 AM
Ha.  Master of Disaster, perhaps.


And yea, if these objects are all entities for which you want robust physics then Unity objects is probably the way to go with them.  At least for now, until you've accomplished your bigger goals.  Later on you may prefer doing your own physics, so you have more control over them.  But for now it would probably just bog down your project.

That said, if there's any significant chunk of these objects which are not really physical entities or otherwise can be handled with a very simple homebrew physics model (or none at all), then you perhaps could pull them under the umbrella of the camera object's Update function.

As for doing it, it's pretty easy, basically you just define a method on each "non-physics" object for "DoSimStep(float EffectiveDeltaTime)" or something like that, and then in the camera's Update logic you make sure all of those get called.  Often it makes sense to nest things inside each other, so you might call World.DoSimStep(effectiveDeltaTime), which then loops over all MetaMapNode's and calls node.DoSimStep(effectiveDeltaTime) and then loops over all RaceState's and calls race.DoSimStep(effectiveDeltaTime), etc.  To adapt some examples from what I'm working on currently.
: Re: Shrugger! Unity!
: Shrugging Khan December 12, 2013, 09:14:23 AM
Been using InvokeRepeating(), and I'm very happy with the result. Cleaner code and improved performance!

But I need some of these repeating methods to be called at irregular intervals; would it be viable to Invoke() the method anew - with a random delay - at the end of itself, rather than to use InvokeRepeating(), or would that cost me the performance advantage?
: Re: Shrugger! Unity!
: keith.lamothe December 12, 2013, 09:23:02 AM
You're off in strange lands where I don't think I can help you ;)

That said, do you want those irregular bits to happen at intervals smaller than the time between two calls from InvokeRepeating, or larger than?

If smaller than, you could just have your logic that InvokeRepeating calls keep track of when you want those irregular bits to happen, and when time comes, do them.
: Re: Shrugger! Unity!
: Shrugging Khan December 12, 2013, 10:49:49 AM
Gah, no thanks...keeping track of things is exactly what I did away with by switching to Invokeries. I guess I'll just try to have methods use Invoke("method", Random.Range(minDelay, maxDelay) to set up their next repetition. We'll see how it works out  :o
: Re: Shrugger! Unity!
: Shrugging Khan December 15, 2013, 11:43:33 AM
Now, the weirdest thing is happening to me. I have an array of floats that determines the composition of the mantle, and in theory it's only set once and after that it's only read, never modified. But for some reason it gets reset to all zeroes at some point, and I can't for the life of me figure out why - it worked fine until I changed a few entirely unrelated things, then it suddenly went bonkers on me. I can't remember what exactly I last changed, but I already inserted Debug.Log() printing that array above and below every line that even just mentions it, but nothing - the array is fine for a few frames, then it suddenly gets reset.

Is there some less-known reason why an array might suddenly reset all its elements to 0?

EDIT: I managed to circumvent the issue by declaring a duplicate of the array and using it instead. This one never gets reset, and neither does the original. WTF?

EDIT2: Coincidentally stumbled across the explanation at the university today. "Side effect". Pah.
: Re: Shrugger! Unity!
: Shrugging Khan December 27, 2013, 04:26:46 AM
Working on Overcomplicated3DSpaceRTS again, I'm currently digging into communications and reconnaissance. Obviously, I bit off a bit more than I could chew. The issue that presented itself concerns physics, and I hope someone here knows a thing about them.

Is there a difference in technological difficulty in detecting radiation of different wavelengths of the electromagnetic spectrum?
And if so, what is necessary to make it work?


As always I'm grateful for any help.
: Re: Shrugger! Unity!
: Draco18s December 27, 2013, 08:38:07 AM
Is there a difference in technological difficulty in detecting radiation of different wavelengths of the electromagnetic spectrum?
And if so, what is necessary to make it work?

YES.

Certain wave lengths--like x-rays--will pass right through ordinary mater and not bounce unless you use very very slight alterations in its direction.

Sometimes other challenges.

http://en.wikipedia.org/wiki/X-ray_telescope
: Re: Shrugger! Unity!
: Shrugging Khan December 27, 2013, 06:28:51 PM
It recently occurred to me that perhaps I did not need to write price lists and functionality for detection equipment meant for the entire EM spectrum, after all.

Aside from visible light and infrared, what else would even be relevant in a space setting with present-day technology? Radiation from shipboard/orbital nuclear power plants maybe (whatever wavelength that may have)? What else comes to mind?
: Re: Shrugger! Unity!
: Draco18s December 27, 2013, 07:04:55 PM
X-Ray. :D
: Re: Shrugger! Unity!
: Shrugging Khan December 28, 2013, 02:58:51 AM
You seem unhealthily infatuated with X-Rays. Care to give me a hint as to the tactical or strategic significance of X-Rays? ;)
: Re: Shrugger! Unity!
: Draco18s December 28, 2013, 10:45:47 AM
You seem unhealthily infatuated with X-Rays. Care to give me a hint as to the tactical or strategic significance of X-Rays? ;)

Honestly no idea :P
I just know that x-ray telescopes exist and that they're damn hard to focus.  Too sharp of a reflection angle and they just pass right through.

(This is why you have to hold a stupid plastic thing in your mouth when the dentist x-rays your teeth: they don't bother reflecting at all: you're actually biting down on the film!  Or detector, if they've modernized)
: Re: Shrugger! Unity!
: keith.lamothe December 28, 2013, 12:43:58 PM
I think X-rays are also the operative band for "bomb-pumped lasers" (when the bomb in question is fission or fusion), a possibly effective way to use energy weapons when you're not close enough to use ones mounted on your ship, and without the difficulty of actually physically striking the enemy ship with a projectile at distances where you don't even have a real-time fix on their location from shipboard sensors.

But you wouldn't really need detection gear for X-rays in that case.  If they hit, you'll know it.
: Re: Shrugger! Unity!
: Shrugging Khan December 28, 2013, 04:56:44 PM
@ Draco :  Well, one thing your links made clear is that I will make X-Ray detection equipment (and such working at similar wavelengths) especially costly to include on a ship  :P

I think X-rays are also the operative band for "bomb-pumped lasers" (when the bomb in question is fission or fusion), a possibly effective way to use energy weapons when you're not close enough to use ones mounted on your ship, and without the difficulty of actually physically striking the enemy ship with a projectile at distances where you don't even have a real-time fix on their location from shipboard sensors.

But you wouldn't really need detection gear for X-rays in that case.  If they hit, you'll know it.
But what if they just hit the next ship in the fleet? Then you'd have to look out for follow-up shots so you can make out where they're firing from! :D

Alright, so we have Infrared, visible, X-Ray...Radio waves, obviously!
What other wavelengths would be used in weaponised lasers?

And one older question still stands - guess I'll have to do some research - what kind of radiation would nuclear drives or NPPs emit?
: Re: Shrugger! Unity!
: Draco18s December 28, 2013, 05:39:37 PM
What other wavelengths would be used in weaponised lasers?

Radio, heck even visible light, is a shitty wavelength for weaponizing.  Too low energy.  Visible light has a habit of scattering and diffusing rapidly when it hits dust.  Radio waves are so low energy that they can't actually interact with matter in a noticeable way.

And one older question still stands - guess I'll have to do some research - what kind of radiation would nuclear drives or NPPs emit?

Very high energy.  Gamma, alpha, and beta are the most common.  Alpha and beta are harmless (stopped by a sheet of paper and 1/4 inch plywood, respectively) where as gamma will hug.  You.  Up.

Gamma rays typically have frequencies above 10 exahertz (or >1019 Hz), and therefore have energies above 100 keV and wavelengths less than 10 picometers (less than the diameter of an atom)

For a point of reference, red light is...670 nanometers if I remember correctly.  Yeah.  All the way down to violet at 400 nm.  So picometers worth of wavelength is orders of magnitude more energetic.

Generally speaking when gamma rays interact with matter they cause the excitation of electrons, which then radiate off as another frequency of light (and strip the atom of the electron itself).  [/not science; based on an understanding of wikipedia]
: Re: Shrugger! Unity!
: Shrugging Khan December 28, 2013, 07:00:17 PM
Ouch...guess I made myself sound like an idiot. I didn't mean to say that I was going to have waponised lasers based on radio or visible light, just that detection equipment for these wavelengths would be in the game  :o

Gamma radiation...check!
: Re: Shrugger! Unity!
: mrhanman December 28, 2013, 11:11:50 PM
Don't forget microwaves.  Often used for communication and the heating of hot pockets.
: Re: Shrugger! Unity!
: keith.lamothe December 28, 2013, 11:45:45 PM
And there are certainly sci-fi races to which "battleship full of human crew members" and "hot pocket" are, for all truly important purposes, equivalent.
: Re: Shrugger! Unity!
: Draco18s December 29, 2013, 12:16:01 AM
/me laughs
: Re: Shrugger! Unity!
: Shrugging Khan January 02, 2014, 03:55:27 PM
I'm trying to find a smart solution for the following problem:

Several spacecraft are moving at various velocities, possibly accelerating constantly or at random intervals. The captain of one of the ships has, for reasons unknown, decided to ram another one - or at least navigate close enough for a friendly waving of hands.

Now, our Capitan faces the first problem - he needs to point his craft at the next vessel over, using his modest RCS - as quickly as possible. So he goes and fires it continuously at full power. While doing so, he tries to determine at which point he will need to fire it in the other direction in order to cancel the rotation.

What formula would you use to calculate whether that point has been reached?
: Re: Shrugger! Unity!
: Draco18s January 02, 2014, 04:17:10 PM
I would hand you a very complicated looking sliding-wheel device (like a decoder ring) if I had it, but I don't.

My math teacher in high school had it though, and it was used to figure out how to rotate an object with thruster jets, just as you describe.
: Re: Shrugger! Unity!
: Shrugging Khan January 02, 2014, 04:30:05 PM
Any idea where I could find one; ideally in digital form?  :D

Edit: Complete with the formulas and all, preferably.
: Re: Shrugger! Unity!
: Draco18s January 02, 2014, 04:46:13 PM
Any idea where I could find one; ideally in digital form?  :D

Edit: Complete with the formulas and all, preferably.

Nope.  I don't even know what it was called.  Plus, the last time I saw it was....2000?

Teacher just passed it around and when I got it I took a good look at it and exclaimed, "You don't have to be a rocket scientist to understand this!  You would have to be to use it though..."
: Re: Shrugger! Unity!
: keith.lamothe January 02, 2014, 04:47:29 PM
Do you already have formulae for computing the point of turnover when making a least-time zero-zero intercept with a fixed point?  I'm figuring you'd need that anyway for general navigation.  It seems that the problem of "when to I switch from angular-accel to angular-decel" (basically, "angular turnover") would be solved the same way :)
: Re: Shrugger! Unity!
: Shrugging Khan January 02, 2014, 06:32:35 PM
So far, navigation worked on a basis of "take as much angular drag as you need" for rotation and "use this script I copied out of google" for thrust, and I'm trying to replace those placeholders with something more to the point. So I guess I should take a stern look at that intercept script and figure out what makes it tick, then try to rewrite it to work for rotation instead?  :o

Ah, turns out the intercept script I used back in summer wasn't at all meant for navigation, and I actually adjusted adapted a "fire gun and compensate for lead" script...which lead to the ships "navigating" by flying at each other at full thrust, passing each other, and decelerating after THAT point.

So no, it appears I have nothing sensible at all  :o
: Re: Shrugger! Unity!
: keith.lamothe January 02, 2014, 07:21:28 PM
So far, navigation worked on a basis of "take as much angular drag as you need" for rotation and "use this script I copied out of google" for thrust, and I'm trying to replace those placeholders with something more to the point. So I guess I should take a stern look at that intercept script and figure out what makes it tick, then try to rewrite it to work for rotation instead?  :o

Ah, turns out the intercept script I used back in summer wasn't at all meant for navigation, and I actually adjusted adapted a "fire gun and compensate for lead" script...which lead to the ships "navigating" by flying at each other at full thrust, passing each other, and decelerating after THAT point.

So no, it appears I have nothing sensible at all  :o
Ah, yes, looks like they're just going for "least time" intercepts based on the target's current position, velocity, and acceleration.  That can indeed generate intercepts, and if you're going for ramming speed that's probably exactly what you want (though target evasion is naturally a problem; suggest to this captain that it is unwise to try to ram a target more maneuverable than one's own ship).

If you're trying to board the enemy, or if you're trying to engage fixed defenses without flying past them, you want a "zero-zero" intercept, or close to it.  Meaning coming to zero distance-to-taget and zero velocity.  You may actually want to maintain some velocity at intercept, and you may want to not actually collide with the target, so you're not actually aiming for 0 and 0, but close enough.

If you're not particular about how long it takes to achieve that zero-zero condition then you can have a three stage trip: accelerate, hold constant velocity, and then decelerate.  If you're trying to go for a "least-time" AND "zero-zero" intercept (I may be abusing the terms to combine them, but you get the idea: zero-zero in minimum time) then you'll actually want to do a full-bore accel up to the instant at which you must engage full decel to avoid overshooting the target.  It's tremendously wasteful of energy but that may not be an operative concern for the captain.  It also assumes no maximum velocity, whereas realistically you can't accelerate past c and practically you probably need to stop well short of that to avoid losing that hood ornament (and the forward half of your hull) to particle collisions.

Anyway, if your ship has max accel equal to max decel, I think the solution to finding "turnover" (the time, or point, at which you switch from accel to decel) is fairly simple: find how long it takes you to travel half the distance at max accel.  That way your velocity-over-time graph looks like an isoceles triangle, where the top point is turnover.

Recall that d = 1/2 * a * (t^2) where d is distance, a is accel, and t is time.  This assumes an initial velocity of zero; that can be factored in without too much pain if necessary.

So if you're 10 light-minutes (call it 180 million km) from a target planet, are at rest, and have a maximum accel of 500 gravities (call it 4.9 km/s^2), then you want to accelerate until you're 90 million kilometers away and then slam on the brakes all the way in.  To find that time:

(beware: I should not be trusted with math, and I may have pooched this badly)

90,000,000 km = 1/2 * 4.9km/s^2 * Ts^2

180,000,000 km = 4.9km/s^2 * Ts^2

36,734,694 = T^2

6061 = T

or a turnover time of about 1.7 hours.  You'd reach a maximum velocity of roughly 30 thousand kilometers per second (10 percent of c) and decelerate from there.



I think ;)

: Re: Shrugger! Unity!
: Shrugging Khan January 03, 2014, 04:10:15 AM
Fortunately, we're dealing with much shorter distances here. Relativistic physics need not concern us overly much  :P

Well, planning the acceleration and deceleration on a 50-50 base is fine if the target doesn't do anything, but everyone's moving around! Bastards! So the ideal turnover point might actually shift around!
Could I still calculate that point by some handy formula, or does this transgress into mathematics too advanced for us to handle?  :o
: Re: Shrugger! Unity!
: keith.lamothe January 03, 2014, 09:56:29 AM
Fortunately, we're dealing with much shorter distances here. Relativistic physics need not concern us overly much  :P
The example I gave was something like 20% longer than the distance from the earth to the sun.  Are you dealing with millions of km, thousands, or what? :)

Well, planning the acceleration and deceleration on a 50-50 base is fine if the target doesn't do anything, but everyone's moving around! Bastards! So the ideal turnover point might actually shift around!
Could I still calculate that point by some handy formula, or does this transgress into mathematics too advanced for us to handle?  :o
Well, again, are you trying to ram the target, or board it?

If ramming, then you don't really need a turnover point.  The idea is to hit turnover right in the enemy ship's engine room, with as much velocity as possible ;)  Bonus points for delivering a greeting card from Sir Isaac Newton.

But with a target whose position, velocity, or even acceleration are not constant, things do get more complicated, as it requires prediction of where the target will be at a given time, and ifguring out if you can be there at that time.

And if those changes to target position, velocity, or acceleration are not even known beforehand, then obviously you cannot generate a guaranteed solution at all.

At that point, what you can do is plot a sort of conical volume showing all possible points where the target could be after x seconds.  Then it's a matter of plotting your course and acceleration such that "your cone" envelops "their cone" (for the section up to time T, where T is the longest time it would take you to reach any point within that section), with an actual course heading that will generate a collision on the target's most likely actual course.  Then just recompute that course every time there's any alteration in the target's acceleration or heading, etc.  Of course, if you can't find a course an acceleration that give you that kind of envelopment, then the target ship is capable of evading you regardless of how you fly (whether or not they actually would evade you is up to them).

But this is probably only feasible with relatively low accelerations, and the ability to change headings relatively fast (not overcoming momentum in the old direction quickly, but generating momentum in the new direction quickly).  If you've got ships that can pull 100,000 gravities or whatever then those cones might look more like spheres and I'm not sure what impact that would have on the practical value of the technique.


On the other hand, if you're actually trying for something like a zero-zero intercept with the evading target then... um, shoot its engines out? :)  More seriously, you're going to want some way of predicting the target's location, velocity, and accel (as in the case of forming up with a friendly target) OR some way of disabling the target's ability to change its accel and heading OR some way to "grapple" the enemy ship (or tractor beam it, or whatever) once you're close enough.  Or I guess maybe you just have to get within weapons range and make it so there's no target to get close to anymore.

But the basic idea is similar to the ramming case, you basically check for that conical area overlap and do a full burn towards the target, but periodically check "if I engage full decel now, how far will I go before I reach zero velocity?" and when that number is >= "my remaining distance to target", engage full decel.  And then potentially keep re-checking to see if the target putting on more accel or whatever makes it so that you want to start accelerating again.


Anyway, I think the basic solution to "but what if the situation keeps changing?" is "then re-run the math every time the situation changes" :)  Or every time it's changed enough to be significant, etc.


In terms of concrete distances, velocities, accelerations, and objectives (least-time vs zero-zero, i.e. ramming vs boarding), can you give me an example of what you're trying to do?
: Re: Shrugger! Unity!
: Shrugging Khan January 03, 2014, 03:57:29 PM
An example...ultimately, I'm just trying to replace my ramshackle placeholder methods of making things move with something more navigationally sound. I didn't think it would be that hard to calculate things like these, so I just went and asked  :o
By now, I'm fairly sure I need to do more research and wrap my head around some basic physics formulae that  had forgotten since school.

For example, I'm trying to make ships, starting out at large distances (a few tens of thousands of kilometers), accelerate towards one another in order to engage in close-range combat (anything close enough for the crew to successfully hit the enemy). Now, some overshooting jousting is alright, and so is stopping short and going for a standoff, but right now they either overshoot by ridiculous degrees, sit still and fire artillery-style, or engage in ridiculous handshake-distance dogfights depending on how agile, accurate or fast I make them - a system in which decisions concerning acceleration and deceleration are made purely based on "who's more agile" and "who has longer range", but entirely without any considerations of one's ship's present velocity, its velocity relative to the enemy, or the thrust of either one.

Now, that applied to actual movement rather than rotation, but the problem is the same - I'd like to find a straightforward formula with which to let the AI make reasonable decisions as to whether they should accelerate or decelerate whatever manoeuvre they're currently carrying out.
: Re: Shrugger! Unity!
: keith.lamothe January 03, 2014, 04:10:51 PM
Now, that applied to actual movement rather than rotation, but the problem is the same - I'd like to find a straightforward formula with which to let the AI make reasonable decisions as to whether they should accelerate or decelerate whatever manoeuvre they're currently carrying out.
It's similar for angular velocity as for "normal" velocity, I think.

Basically, if you want to change to a different heading in the least possible time (such that you can stay there, rather than overshooting it), a simple brute force approach is:

1) Engage maximum angular acceleration towards that heading.
2) Periodically check "if I engaged maximum angular deceleration right now, what would my heading be when I'd fought my angular velocity down to 0?"
3) And if that result is at or past your target heading, engage maximum angular deceleration.


Anyway, I don't think you're dealing with something that calls for very advanced math.  For me I just visualize it as a graph of velocity over time:
a) The y-value of the curve at any given x is the velocity where time=x.
b) The slope of the curve at any given x is the acceleration where time=x.
c) The area under the curve to the left of any given x is the total distance travelled by time=x.


Also, one key thing in your case is to not let yourself get tangled up trying to solve multiple not-fundamentally-related problems simultaneously.  For example:
- figure out how you want to handle zero-zero intercepts
- and then figure out how you want to handle least-time intercepts
- and then figure out how you want to account for predictable changes in target accel/velocity/position
- and then figure out how you want to account for unpredictable changes in such things

Honestly, by the end you've moved from a purely mathematical problem to one bordering on the psychological; all the math can do then is tell you what you need to do to make sure the target can't get away (whatever it decides), or whether you can't guarantee that physically.
: Re: Shrugger! Unity!
: Shrugging Khan January 03, 2014, 04:58:16 PM
So THAT's how reasonable people do it!

Yeah, my failing is definitely at least partially due to lacking basics. Guess it's back off to Wikipedia and looking up Angular Acceleration formulae for me...I mean, I can hardly make my AI do the right thing when I can't even figure out the way to do it myself.

Thanks for all the help; I hope it isn't too frustrating to try and help and slow learner like me :)
: Re: Shrugger! Unity!
: keith.lamothe January 03, 2014, 05:21:47 PM
So THAT's how reasonable people do it!
Never assume I'm a reasonable person ;)

Yeah, my failing is definitely at least partially due to lacking basics. Guess it's back off to Wikipedia and looking up Angular Acceleration formulae for me...I mean, I can hardly make my AI do the right thing when I can't even figure out the way to do it myself.
It's not all that fancy, accelerating from rest gives a distance of 1/2*a*(t^2).  Or, in other words:
1) take the time
2) square it
3) multiply by accel
4) divide by 2
5) done :)

So if your thrusters let you change your angular velocity by 10-degrees-per-second every second, then you know that blasting those thrusters at full for 1 second will actually change your heading by (10*(1^2))/2 = 5 degrees, leaving you with an angular velocity of 10.  Doing it for 2 seconds changes your heading by (10*(2^2)/2 = 20 degrees, with a final angular velocity of 20.  3 seconds gives a total delta of 45 degrees, with a final angular velocity of 30.  And so on.

On the flip side, if you currently have an angular velocity of 30, you know it will take you 30 / 10 = 3 seconds to decelerate to an angular velocity of 0.  And since your acceleration and deceleration power is the same you already know that you'll come to a stop 45 degrees from where you are now (distance from decelerating-to-rest is the same as distance from accelerating-from-rest if decel = -accel).

So if your desired heading is more than 45 degrees further along than you are now, just keep those thrusters burning.

If your desired heading is less than (or equal to) 45 degrees further along than you are now, go to max decel (by firing the thrusters that will turn you in the other direction, probably).


Thanks for all the help; I hope it isn't too frustrating to try and help and slow learner like me :)
Not frustrating at all :)  I just hope I'm not oversimplifying things, as sometimes I take questionable short-cuts in math ;)


Edit:
Another way of thinking of the "how far will I go if I accelerate at X for Y seconds?" thing is:

a) First, imagine your velocity-over-time curve while travelling at a constant velocity (accel = 0) of 10 meters-per-second for 10 seconds.  It's a pretty boring "curve", and if you plot it and shade the area under it you just get a 10x10 square, right?  Well, the area of that square (100, naturally) is the distance you travelled.

b) Next, imagine the same curve but with a constant acceleration of -1 meter-per-second-squared.  So your velocity starts at 10 m/s and reaches at 0 m/s at the very end of the 10 second interval.  If you plot that "curve" you get a right triangle with a base of 10 and a height of 10.  Or an exact half of the square from example a.  Naturally, its area is half that of the square, meaning you will come to rest 50 meters from wherever you were at time=0.

c) Same deal if you started at 0 m/s and held a constant acceleration of 1 meter-per-second-squared for 10 seconds.
: Re: Shrugger! Unity!
: Shrugging Khan January 04, 2014, 08:34:19 AM
Alright, so if I were to try and make them discern the right time to revert thrust, the formula would look something like...

if ( ( angularVelocity / ( acceleration / mass ) ^ 2 ) > ( 2 * distance / ( acceleration / mass ) )
    {
        flip();
    }

...I get the feeling that's not entirely right on my part  ???
: Re: Shrugger! Unity!
: keith.lamothe January 04, 2014, 09:52:30 AM
Alright, so if I were to try and make them discern the right time to revert thrust, the formula would look something like...

if ( ( angularVelocity / ( acceleration / mass ) ^ 2 ) > ( 2 * distance / ( acceleration / mass ) )
    {
        flip();
    }

...I get the feeling that's not entirely right on my part  ???
The main thing that looks wrong is your factoring in of mass.  Did you mean thrust/mass instead of accel/mass?  Thrust/mass would be part of computing your accel (I think).  The difference in what I'm saying is that I'm assuming you already know your max acceleration and deceleration.  So I'd probably do something like

float myCurrentAngle = this.GetCurrentHeadingInDegrees(); // just assuming you've got this stored somewhere, or easily computed

Point targetPoint = enemy.Location; // assuming you want to directly face where it is now, though you may want to face where you think it will be at some point in the future instead

float desiredAngle = AngleBetweenPointsDegrees(my.Location,targetPoint); // computing this isn't too hard

float desiredDelta = desiredAngle - myCurrentAngle;
if(desiredDelta < 0) desiredDelta += 360f; // you'd actually want to compute if it'd be shorter to turn the other direction if you weren't already in a hard turn, but for simplicity

float myAngularVelocity = this.GetCurrentAngularVelocity(); // again, assuming you have this stored somewhere, or easily computed; assuming positive

float myAngularAcceleration = this.GetMaxAngularAcceleration(); // ditto; assuming positive

float timeRequiredToDecelerateToRest = (myAngularVelocity / myAngularAcceleration);

float deltaThatWouldResultFromImmediateDecelerationToRest = myAngularAcceleration * timeRequiredToDecelerateToRest * timeRequiredToDecelerateToRest;

if(deltaThatWouldResultFromImmediateDecelerationToRest >= desiredDelta) flip();


Naturally it could be compressed into far fewer lines, but I find "one step per line" to be helpful for self-documenting code; the comments wouldn't be needed at all for simply understanding what it does.


Of course, this is all on a 2D plane; if you're not clamping all units to the ecliptic or whatever that gets messier :)
: Re: Shrugger! Unity!
: Draco18s January 04, 2014, 10:27:10 AM
So THAT's how reasonable people do it!
Never assume I'm a reasonable person ;)

And never underestimate the unreasonable lengths that reasonable people will go to.
If you want a reasonable solution, ask an unreasonable person. ;)

(Just like if you want a job done efficiently, ask a lazy person)
: Re: Shrugger! Unity!
: Shrugging Khan January 04, 2014, 04:14:38 PM
Of course, this is all on a 2D plane; if you're not clamping all units to the ecliptic or whatever that gets messier :)
Why would I do that? The point of 3D is having three dimensions!

So...yeah. I'm probably going to spend most of tomorrow experimenting; I doubt I'll be able to make do with placeholder systems when an actual solution seems so close at hand. Any last tips regarding the transformation of your code to something three-dimensional?  :)
: Re: Shrugger! Unity!
: Draco18s January 04, 2014, 04:48:54 PM
Of course, this is all on a 2D plane; if you're not clamping all units to the ecliptic or whatever that gets messier :)
Why would I do that? The point of 3D is having three dimensions!

How I Learned to Stop Worrying and Love Quaternions.

(No really: you're going to have to get comfortable with them if you want to do any kind of rotation in 3D space without going into gimbal lock).
: Re: Shrugger! Unity!
: keith.lamothe January 04, 2014, 04:50:38 PM
Of course, this is all on a 2D plane; if you're not clamping all units to the ecliptic or whatever that gets messier :)
Why would I do that? The point of 3D is having three dimensions!
I hope you can find a species capable of reacting in a fully 3D environment, so that someone can actually play your game :)

So...yeah. I'm probably going to spend most of tomorrow experimenting; I doubt I'll be able to make do with placeholder systems when an actual solution seems so close at hand. Any last tips regarding the transformation of your code to something three-dimensional?  :)
What I wrote doesn't even fully handle 2 dimensions, as it basically only handles turning in one direction.  In 3D you have rotation in two dimensions and such.  Honestly I don't know where I'd start :)  But you can probably at least make it not do excessively dumb things.
: Re: Shrugger! Unity!
: Draco18s January 05, 2014, 12:33:36 AM
Of course, this is all on a 2D plane; if you're not clamping all units to the ecliptic or whatever that gets messier :)
Why would I do that? The point of 3D is having three dimensions!
I hope you can find a species capable of reacting in a fully 3D environment, so that someone can actually play your game :)

They'd have to be some kind of bird.  Or fish.

Reminds me that I played (about an hour) of Evachron Mercenary.  3 axis of movement and rotation is a pony.
(Ended up crashing myself into a planet because warp drive :V apparently "slightly away" from a planet sized object is not enough)
: Re: Shrugger! Unity!
: Shrugging Khan January 05, 2014, 06:32:14 AM
Fish? Animals, including humans, evolved from aquatic creatures, didn't they?
At any rate, it's supposed to be a strategy/tactics game with OPTIONAL first-hand control of the ship.
Rank progression is planned to be along the lines of
These are just examples, of course. The player would start out as a lowly cog in the machinery of a ship or facility, then work his way up towards responsibility, with piloting a vessel being one possible task. Almost all of the others would mostly relate to operating machinery, gathering data or giving orders.
This way, a player would have to get to know his (procedurally generated) fleet before actually wielding any authority.

If he isn't KIA, that is. Permadeath!

----------------------------------------------------------------------

That said, I'll probably end up using a mixture of safety margins, approximations and angular-drag-related cheats to make things work until I wrap my head around the actually correct mathematics of the issue. I get a feeling this will end with lots of blood, Quaternions and broken PIDs.
Right now I'm using a magical Flywheel to grant ships limited Angular Drag in exchange for lots of energy expenditure, while having the AI RCS operators do some very suboptimal calculations based on "we can turn roughly THIS fast without getting ahead of ourselves". It's distasteful, and has //PLACEHOLDER written all over it (seriously), but I have to make some flashy things happen to keep my brother interested - can't spend all week telling him to correct my physics calculations.

That's not to mean that the correct formulae are off the hook; this particular affair is simply postponed until I'm back at the university.
: Re: Shrugger! Unity!
: Shrugging Khan January 08, 2014, 06:01:29 AM
So the code to determine whether or not to flip acceleration currenty looks as following:
:
float brakeTime = ship.angularVelocity.magnitude / shipInfo.maxRotationAccel;
float brakeAngle = 0.5f * shipInfo.maxRotationAccel * Mathf.Pow (brakeTime, 2);
float angleToTarget = Vector3.Angle(ship.transform.position - targetPosition, -ship.transform.forward);

if (brakeAngle > angleToTarget) {
return true;
} else {
return false;
}
It doesn't work yet - at all. The ships keep twisting around like drunk dancers. I'm guessing that maxRotationAccel isn't calculated correctly; but could someone take a look at the method above? Does the formula look about right like that, or might the issue be contained therein after all?

Thankee ~
: Re: Shrugger! Unity!
: keith.lamothe January 08, 2014, 08:44:37 AM
So the code to determine whether or not to flip acceleration currenty looks as following:
:
float brakeTime = ship.angularVelocity.magnitude / shipInfo.maxRotationAccel;
float brakeAngle = 0.5f * shipInfo.maxRotationAccel * Mathf.Pow (brakeTime, 2);
float angleToTarget = Vector3.Angle(ship.transform.position - targetPosition, -ship.transform.forward);

if (brakeAngle > angleToTarget) {
return true;
} else {
return false;
}
It doesn't work yet - at all. The ships keep twisting around like drunk dancers. I'm guessing that maxRotationAccel isn't calculated correctly; but could someone take a look at the method above? Does the formula look about right like that, or might the issue be contained therein after all?

Thankee ~
Can you put in some debug logging to sanity-check the results of those first three lines?  Particularly angleToTarget.  Do the results make sense?

brakeTime looks fine.  Though bear in mind you don't have to write "Math.Pow(brakeTime,2)", "brakeTime*brakeTime" works just fine.  Hopefully Math.Pow recognizes that case and does exactly that, but if it doesn't the more general-case calculations for Pow are much slower.

Is angleToTarget always between 0 and 360 (not including 360)?

What units is maxRotationAccel in?  How about Vector3.Angle()?

Make sure all angles are in either degrees or radians, mixing them doesn't work so well.  I speak from the experience of doing that MANY times ;)

Also, as I think I mentioned this really only considers turning one way: if it overshoots by much then this logic will just send it around in another full revolution.  You can avoid that by having it run the computation twice: once with maxRotationAccel, and again with -maxRotationAccel.  Of course, that's purely for 2D-plane, so I hope you're at least doing these tests with everybody on the ecliptic or something like that :)  Get it working in the simpler case, then move to the more complex.
: Re: Shrugger! Unity!
: Shrugging Khan January 08, 2014, 09:16:30 AM
Sanity checking is in, and angleToTarget actually calculates incorrectly. Which is funny, because an almost identical formula yields correct results in a different method. I'll just use the values from that latter one.

maxRotationAccel and Vector3.Angle are both in degrees (AFAIK), while rigidbody.angularVelocity is in radians per second. I've added a conversion in the current version of the method above, but it didn't help much.

angleToTarget is always between 0 and 180 degrees.

--------------------

My thinking regarding the three-dimensionality of it was that Flip() would not carry out the full flip, but only slow the rotation a bit, then let the normal RotateToIntercept() take over again. Repeating this process would progressively correct the course. Does...does that work the way I think it should?

Anyways, which line exactly do you mean when you recommend calculating things with -maxRotationAccel instead of maxRotationAccel? Both?

And one further observation: My ships really like to spin around their z axis. I do not know why.



: Re: Shrugger! Unity!
: Draco18s January 08, 2014, 09:39:01 AM
almost identical formula yields correct results

Key words, "almost identical" ;)
: Re: Shrugger! Unity!
: Shrugging Khan January 08, 2014, 10:31:21 AM
They're getting their data from different pointers, but ultimately they're supposed to be using the same variables  :P

I realised I was calculating the counter-rotation meant to cancel out the angular velocity without factoring in the radians-degrees conversion. Corrected that. Didn't help. Ships still doing an awful lot of turning around the Z axis  >:(

Edit: Made sure that the gameObject's centre point and the physics' rigidbody.centreOfMass are aligned. Didn't help.

Edit2: HAH! The calculated angle was right after all; it was just displayed as being off because the value to be displayed was being overwritten by another instance of the GUI script attached to a different ship. IT TOOK ME ONLY HALF THE WEEK TO FIND THIS.

Edit3: So the issue with how much force was applied was due to an error in the radians-to-degrees-to-radians-to-degrees-and-again conversion. Huh. Still doesn't correctly calculate when to derotate, though.

Edit4: Turns out the problem never was when to derotate, but how strongly! Just needed to multiply the negative torque with the strength of the rotator device, and presto...it works. A MIRACLE!
: Re: Shrugger! Unity!
: Shrugging Khan January 14, 2014, 12:42:29 PM
Following yesterday's burst of genius, I'm stupid again.

How do I calculate the time needed to accelerate and decelerate in order to rotate by a certain angle?

Scenario: Flying roughly towards a target, but possibly too fast. If the ship needs to decelerate - meaning turn around and fire the main thrusters along the velocity vector, which implies a near-180 degree turn - it will first have to actually turn around. The time to turn will have to be factored into the calculations discerning whether or not the time to brake has come.

I'm guessing it'd be something like
:
angleToGo / (0.5 * angularAcceleration)But that's pure guesswork.
: Re: Shrugger! Unity!
: keith.lamothe January 14, 2014, 01:53:29 PM
How do I calculate the time needed to accelerate and decelerate in order to rotate by a certain angle?
As before, d = 1/2*a*t^2, so t = sqrt(2d/a) (if I did that right). 

So if you want to turn 180 degrees and have an angular acceleration of 5 degrees thats:

t = sqrt(2*180/5)

t = sqrt(72) ~= 8.49 seconds

Of course, that's to rotate 180 degrees, but at that point you'll have an angular velocity of 42 degrees per second and spin right on by.


So you if you instead target 90 degrees:

t = sqrt(2*90/5)

t = sqrt(36) = 6

So in 6 seconds you'll hit 90 degrees, and then if you switch to max angular decel you will come a stable 180 degree heading in a total of 12 seconds from the beginning of the maneuver.


So overall the time to go from angle start to angle end, assuming an initial angular velocity of zero and an angular accel of acc, would be:

t = 2*sqrt(2*((end-start)/2)/acc)

Or more simply:

t = 2 * sqrt( (end-start) / acc)


Though remember, I should not be trusted with math ;)  I probably made some big boo-boo in there.
: Re: Shrugger! Unity!
: Shrugging Khan January 14, 2014, 02:09:37 PM
Thanks again!
I'll just experiment a bit, so we'll see rather soon how much boo-boo is in there.

I assume start-end represents the total angle to be traversed?  :)

Edit: Obviously, it does. Sorry, not really all that conscious today  :o
: Re: Shrugger! Unity!
: keith.lamothe January 14, 2014, 02:12:30 PM
I assume start-end represents the total angle to be traversed?  :)
Right.  If going from start to end involves crossing the 360-degree boundary then obviously you'd actually want 360-(start-end) instead of end-start.

Edit: well, it depends on which way you're going I suppose; anyway, that part of the math is relatively straightforward once you break it down into the different cases :)
: Re: Shrugger! Unity!
: Shrugging Khan January 14, 2014, 02:38:38 PM
I'm trying to keep it simple but functional for now. If the AI can turn, brake, intercept, rendezvous and match velocities reasonably well, then I'm quite happy to be able to move on to different subjects - advanced navigation can wait until shipbuilding, group tactics, ship functionality, crew abilities, performance-friendly physics and correct fleet-ship-component-crew-information interactions are done.

Lotsa work  :D
: Re: Shrugger! Unity!
: Draco18s January 14, 2014, 05:08:01 PM
Just don't start doing things like thruster damage and have to calculate your accel and deccel with different max values!
: Re: Shrugger! Unity!
: Shrugging Khan January 15, 2014, 05:14:15 AM
Oh, but I do. Effective thruster output is recalculated every time it's damaged, its fuel is changed, or its fired - on account of the mass of the ship changing. Of course, if the crew has no-one tasked with doing these calculations, then the maximum thrust won't be updates in the ship's internal information system and the navigator will be having trouble.

Granted, at present all damage is instantly fatal, there is only one fuel type and fuel isn't actually used up (to simplify testing), but eh - it's all somewhere in the unused code.
: Re: Shrugger! Unity!
: keith.lamothe January 15, 2014, 09:11:01 AM
Of course, if the crew has no-one tasked with doing these calculations, then the maximum thrust won't be updates in the ship's internal information system and the navigator will be having trouble.
Can this happen because the accountant was away from his post trying to get to the beer hall, but blocked by a horde of kittens?
: Re: Shrugger! Unity!
: Shrugging Khan January 15, 2014, 10:16:12 AM
Not yet, because none of those elements (except for the accountant and a non-functional beer hall) are implemented at present.

But if all goes according to plan, then it will be entirely possible for the accountant (crewmember tasked with with Analytics, Bureaucracy and Domestic Management)  to be on his way to the beer hall (Container module with habitation modification and beer-type resources), only to notice that the module he tried to pass through on the way had its entire internal space taken up by kittens (cargo / fuel / compressed oxygen / an enemy boarding party / passengers / alcoholics / actual kittens).

Since nobody else on board was trained in ANA, BUERO and DOM abilities, no interim accountant could be appointed by the Command section, and the ship would fly on outdated navigation data. THAT part is actually implemented already.
What's missing there is the ability of the crewmembers to try and make the calculations anyways, with all the possible mistakes that entails.

It's supposed to be that kind of game.


Edit: Just in case you think I'm joking - I'm not. Kittens are actually a viable resource (or would they count as crewmembers? That I don't know.)  for keeping up troop morale. Of course, some soldiers might object to having innocent noncombatants on a vessel of war, but that's a different factor.
: Re: Shrugger! Unity!
: keith.lamothe January 15, 2014, 10:42:37 AM
I hope the general modes of ship destruction leave largely-intact pieces instead of just vaporizing.  That way we can see the Accountant's engravings of the kittens.  And the Navigator's engravings of the Accountant.
: Re: Shrugger! Unity!
: Shrugging Khan January 15, 2014, 12:00:58 PM
Unless you're *really* saving money (or trying to churn out ships as quickly as possible), the standard setting for ship component construction is for them to have re-sealing equipment on board in case the adjacent component gets blown off by incoming fire, a collision or a separator charge. So it's perfectly possible to cut a ship in two (or twenty), with the surviving crew still going about their business in accordance with their orders...or, perhaps in the absence of relevant orders, with the crew trying to keep up morale by documenting their fleet's struggle with the enemy, the long journeys, and their accounting department.

Actions without orders aren't implemented yet, though.

Edit: Given that I'm already running into performance issues, I'm suspecting that this game might turn out quite a bit like DF in the long run - death by low FPS.
: Re: Shrugger! Unity!
: Draco18s January 15, 2014, 12:52:16 PM
Edit: Given that I'm already running into performance issues, I'm suspecting that this game might turn out quite a bit like DF in the long run - death by low FPS.

#Configuraions
MaxCrewSize:3
MaxFleetSize:5
MaxShipComplexity(Modules):10
MaxSolarSystems:4
MaxPlanetsPerSystem:3

NANOEMBARK, HERE I COME!
: Re: Shrugger! Unity!
: Shrugging Khan January 26, 2014, 05:14:50 PM
Ship construction, component variations, prettier visuals, thrusters-you-can-switch-off (I failed to notice that the AI was unable to throttle down), smoother rotations, brake-to-rendezvous and a single class to handle all things related to the camera and the GUI...done!
Well, functional, at least. Still needs lots of work - but it works!

Now I'm looking at refining the rotate-to-aim code again, because they're still doing some spinning around the Z axis, and I finally understood why - because they just compare their angular velocity's magnitude to the angle-yet-to-traverse, the AI has no way of noticing when it's going in circles around the direction it's meant to point at. I'm bad at explaining this, so let me illustrate it with an example:

Unless the angular velocity is so large that it triggers the AI's "fukc directions, we're spinning too fast, just de-rotate!" safety, they will continue to rotate *around* the right direction.

Now, I realise this is probably not exactly anyone's speciality (it certainly isn't mine), but can anyone explain to me how to check whether a Vector of rotation is, roughly speaking, going "the right way"?

I've done some testing, but so far I wasn't able to get a good grasp of it. So thanks if anyone can help a little  :)
: Re: Shrugger! Unity!
: Draco18s January 27, 2014, 09:55:19 AM
They're doing a barrel roll. :P
: Re: Shrugger! Unity!
: keith.lamothe January 27, 2014, 09:56:24 AM
I would suggest computing your desired rotation in two parts: left-right, and up-down.  So you'd be applying two different thrusts (if you were off on both) : one on the left-right until you hit turnover, at which point you'd decelerate to angular rest _on that plane_ ; and then another on the up-down until you hit _that_ turnover, and then you'd decelerate to rest on that plane.

Both could run simultaneously, and one may or may not hit turnover or at-rest before the other.

But if I'm thinking of this right the two should work if you treat them as orthogonal (non-interacting) to each other.  I don't think it would necessarily be ideal because it's probably like traversing the height and base of a right triangle instead of traversing its hypotenuse, but one thing at a time :)
: Re: Shrugger! Unity!
: Shrugging Khan February 05, 2014, 01:46:16 PM
Well...this is weird. I finally upgraded from a single AI method to a full AI class, and now the rotations work again without the rotation code having changed at all. Huh.

That said, some of my classes have recently broken the 1,000 line mark. Hooray!
And my editor has broken its code folding feature. Pain!

Also, turrets are in. And different weapon types (LAZORS!). And more randomisation in the ship constructions. And my brother wrote a name generator, so the sailors now have names. I suspect he did it just so I'd feel bad about getting them killed. I also tossed out a batch of obsolete classes and tidied up a lot of old code.

It almost appears as if I were programming faster and with more concentration the more I should actually focus on my coming exams. Silly idea, isn't it?

Well, getting back to those growing classes...at how many lines would you say a class is too big? When does it, in your eyes, become too unwieldy? Or is it actually the opposite and you'd rather have huge but fewer classes than a large number of smaller ones?
: Re: Shrugger! Unity!
: keith.lamothe February 05, 2014, 02:21:07 PM
Well...this is weird. I finally upgraded from a single AI method to a full AI class, and now the rotations work again without the rotation code having changed at all. Huh.
It was just holding out for a promotion.

Well, getting back to those growing classes...at how many lines would you say a class is too big?
I'd have to recuse myself on that one.  I think one of AIW's _methods_ has over 10,000 lines.  The thing that sets up all the ship stats (giant switch statement).

Though that's uncommonly huge for us.

But main classes getting over 5000 lines isn't uncommon for us.

Most of the classes are pretty small, though, and we tend to have a fairly large number of files from all the splitting up.

Generally I don't navigate the code files by scrolling, but rather by doing a text-find and something like "DoShipStep" to jump to the method where each of Fed's ships does its in-combat logic, etc.

So it's more of a "random access pattern" ;)

Though with the many files that follow the enum/typedata/instance pattern I do often rely on the fact that the enum values are all at the top.
: Re: Shrugger! Unity!
: Shrugging Khan February 05, 2014, 05:01:21 PM
Alright. Ships, Components, Cultures, Fleets, and Factories are all procedurally generated. Rotation works. Propulsion works. Weapons work. Turrets work. The AI knows what it's doing. There's battles, and although they're very very short due to the absence of cover, armour or anything else resembling defence, they do happen and play out roughly as they should.

I guess that's a minor milestone!

Thanks for all the support. Considering that half a year ago I couldn't program at all, you two really helped me  :D
: Re: Shrugger! Unity!
: keith.lamothe February 05, 2014, 05:03:28 PM
Congratulations for coming so far in half a year :)

Programming is learned by slamming your head into a brick wall over and over again until the wall falls down.
: Re: Shrugger! Unity!
: Aklyon February 05, 2014, 05:37:15 PM
Congratulations for coming so far in half a year :)

Programming is learned by slamming your head into a brick wall over and over again until the wall falls down.
But what if the wall falls down intact?
: Re: Shrugger! Unity!
: keith.lamothe February 05, 2014, 06:14:16 PM
Congratulations for coming so far in half a year :)

Programming is learned by slamming your head into a brick wall over and over again until the wall falls down.
But what if the wall falls down intact?
That's the idea, actually.  You just walk over it.

Programming is also about knowing when to make a minimum of assumptions, and when to make as many as you possibly can :)
: Re: Shrugger! Unity!
: Draco18s February 09, 2014, 07:23:32 PM
The AI knows what it's doing.

Oh sh*t
: Re: Shrugger! Unity!
: Shrugging Khan February 10, 2014, 03:55:22 AM
Don't worry, you can always hide behind some debris or a capital ship - they don't do collision avoidance yet.

Sound is in, HUD is in, the number of background objects was significantly increased, to the point of them becoming foreground objects and a safety hazard - but pretty! And fun. My brother also insisted on seeing capital ships, so we changed the randomisation code to sometimes make everything a lot bigger, with a lot more turrets.

The F1-AR3 Orion was a LEMUR-Class destroyer armed with one superheavy autoloading artillery piece, 18 Autocannons and 3 Laser turrets, weighting in at 4 tons and requiring almost all of the fleet's budget. Immediately after being given the Weapons Free!, she filled the battlefield with fire and lag, until a single bullet from a small fighter craft pierced her unarmoured hull and killed her only pilot.

We have now added a rudimentary hit point system to give ships durability based on their mass; this will remain in place until component damage is properly implemented.

My brother now lobbies for ships to have bayonets. I am beginning to doubt his decisions.
: Re: Shrugger! Unity!
: Draco18s February 10, 2014, 09:18:12 AM
until a single bullet from a small fighter craft pierced her unarmoured hull and killed her only pilot.

Someone used The Force.

My brother now lobbies for ships to have bayonets. I am beginning to doubt his decisions.

http://365tomorrows.com/08/31/bleeding-edge/
: Re: Shrugger! Unity!
: keith.lamothe February 10, 2014, 09:36:13 AM
Unmanned bayonets moving at relativistic velocities would be enormously effective against... well, anything they could hit.

Manned bayonets moving anything like that fast would require a Hive Mind race or... well, I guess we've seen societies that produce guys like that, so yea ;)


Though it would look a bit odd for the chief engineer to go from monitoring the fusion plant to starting up the drumming for "Ramming Speed!"
: Re: Shrugger! Unity!
: Shrugging Khan February 10, 2014, 10:43:00 AM
Actually, ramming is currently the default option for ships that run out of ammo.
: Re: Shrugger! Unity!
: keith.lamothe February 10, 2014, 10:56:33 AM
That's some serious crew discipline :)
: Re: Shrugger! Unity!
: Shrugging Khan February 10, 2014, 11:51:10 AM
Well, their only other option is watching their comrades fight and die around them, or running away to hide in a lifeless debris field. At least they can still feel useful that way :P

Or maybe I should just implement resupplies and victory conditions.
: Re: Shrugger! Unity!
: Draco18s February 10, 2014, 12:25:21 PM
Manned bayonets moving anything like that fast would require a Hive Mind race or... well, I guess we've seen societies that produce guys like that, so yea ;)

That's why I linked the story.  They had a culture that demanded hand-to-hand combat, even in space, so their tech reflected that.

And they were god damn effective.  One because their armor was basically indestructible (on account of having been manufactured to cut through most anything), two because the only spot where damage was meaningful was very tiny, and three because they won games of chicken without flinching.

Doesn't even require relativistic speeds.  Simply "moving fast enough" is enough to really bugger up your opponent if his ship can't handle being cut in half (loss of crew? No, we can seal breached areas.  On the other hand...the bridge isn't connected to the engines any more...).

And yes, I can pretty much dig up a 365th Tomorrow for just about any topic inside science fiction.
: Re: Shrugger! Unity!
: Aklyon February 10, 2014, 12:58:00 PM
Actually, ramming is currently the default option for ships that run out of ammo.
Is there shouting involved? (http://www.schlockmercenary.com/2005-12-20)
: Re: Shrugger! Unity!
: Draco18s February 10, 2014, 01:06:54 PM
In that story?  Unlikely. :P
: Re: Shrugger! Unity!
: Aklyon February 10, 2014, 01:15:39 PM
No, I was asking Khan. its not likely to be in that story unless its by the guys being rammed :)
: Re: Shrugger! Unity!
: Draco18s February 10, 2014, 01:23:23 PM
No, I was asking Khan. its not likely to be in that story unless its by the guys being rammed :)

Touche. :P
: Re: Shrugger! Unity!
: Shrugging Khan February 10, 2014, 02:34:48 PM
Is there shouting involved?
It definitely ought to be. Thanks for the suggestion  ;D
: Re: Shrugger! Unity!
: Shrugging Khan February 14, 2014, 09:00:45 AM
Little question for the space fans in here:

How can an attack by a weaponised LASER be detected and/or traced back to its source?

This obviously assumes a miss, but feel free to describe cases of direct hits, too.
: Re: Shrugger! Unity!
: keith.lamothe February 14, 2014, 09:12:15 AM
Little question for the space fans in here:

How can an attack by a weaponised LASER be detected and/or traced back to its source?

This obviously assumes a miss, but feel free to describe cases of direct hits, too.
Assuming multiple optical (or whatever part of the spectrum is involved) sensors mounted on different spots on the hull, the line could probably be visualized and triangulated.  Depending on temporal resolution and range it might actually give two possible origins, but probably the ship knows which side the enemy was coming from.

For a direct hit, assuming the sensors aren't knocked offline, I figure the same approach would work, but it'd be clearer which side got hit (even if it punched through, though if that happens the sheer transfer energy of the hit would probably be fairly catastrophic).

Though in general I suspect that a warship armed for short-range engagement, in energy range, where the enemy doesn't already know its location... the enemy won't have much of a chance to reply.  Of course it depends on relative durability and power, etc.

And of course there's stand-off weapons like missiles that shoot lasers when they explode, where tracing it won't help you, but anyway.
: Re: Shrugger! Unity!
: Shrugging Khan February 14, 2014, 09:18:13 AM
So what kind of sensor technology would I use to even notice that a beam has been fired in the first place?

Unless it cooks my fuel tank, then it'll be kinda obvious.
: Re: Shrugger! Unity!
: keith.lamothe February 14, 2014, 09:26:02 AM
So what kind of sensor technology would I use to even notice that a beam has been fired in the first place?
Well, if it's coherent visible light, then worst to worst you've got the MkI eyeball.

If it's an x-ray laser or whatever, then an xray sensor is going to pick up that there's something going on out there, and have a pretty shrewd notion of the general direction where it's most active (i.e. the line itself).  An array of such sensors could then be used to triangulate.  I think :)

Unless of course the beam is so incredibly focused that there's simply no scatter at all.  In which case I suppose even a visible-range laser would be effectively "invisible" unless it was aimed directly at you.  But I don't think I've run across a sci-fi setup where the lasers (visible or otherwise) were that focused.  And with any kind of ambient particle density there'd be some kind of scatter off that.

Unless it cooks my fuel tank, then it'll be kinda obvious.
Sure, I guess in lieu of competent sensors one could deploy a vast network of tethered fuel tanks to catch all those misses and let you know when you're being shot at :)
: Re: Shrugger! Unity!
: Draco18s February 14, 2014, 09:29:56 AM
So what kind of sensor technology would I use to even notice that a beam has been fired in the first place?

Pretty much you have to wait until it shows up and either hits you or zips on past.

Anyway, lasers are pretty much useless at long range.  The primary factor is relativistic distances make aiming almost impossible.  If it's going to take 6 seconds for the laser to travel from Here to There, then your target has 12 seconds to not be There anymore.

(6 seconds before you even find out they moved, followed by 6 seconds of flight time).

Smart missiles are the only way to go at it at those distances.  They might be slower, but when they get close they can course-correct.

Also, destroying the hull isn't the greatest plan either.  If you can get in close, just bombard the target with microwave radiation.  Cook them alive, then take command.
: Re: Shrugger! Unity!
: keith.lamothe February 14, 2014, 09:40:44 AM
Yea, energy weapons at ranges of more than about 2 light seconds get pretty dicey, and not just because of aiming.  You'd need a pretty big honking laser to do serious damage against any serious passive defenses over 600,000 km away.

At the same time, even missiles are going to have a hard time landing a direct hit on something far away and evading.  Either they're going too slow to catch it (or at least not get shot down by point defense) or they're going really really stinking fast... and fly right by because they can't overcome a 0.5c vector by more than a few degrees even with massive acceleration, etc.

So you get the missiles to shoot the energy weapons instead ;)

Or you resort to some more direct approaches like popping the enemy warship in the microwave and wait til it goes "ding".  What sort of menu you have there depends widely on the standard technology involved in that particular setup.  Decent radiation shielding, for instance, might be thoroughly absent in one sci-fi setting, and completely defeat "death by cooking" in another.
: Re: Shrugger! Unity!
: mrhanman February 14, 2014, 10:35:09 AM
The laser would have to have some of its light deflected off gas/dust particles and such to be detected at all.  Being in a nebula would therefore make it easier to detect than if you were in intergalactic space, for example.  It might be interested to factor that into the detection rates.  Assuming location matters at all, of course.
: Re: Shrugger! Unity!
: Shrugging Khan February 14, 2014, 12:49:46 PM
Arrrrgh! I think I need to fill you in on something here.

The game is set in debris fields measuring a few dozen to a few thousand kilometers in diameter (presently utilising only the lower end of that range), with plenty of bad weather - microscopic rocks, metal dust, gases - floating around, and this weather gets worse the more things get blown up. It can be cleaned up by dedicated recycler ships (think Planetes), but that takes a while.

The main limiting factors on long-range engagements are cover, reduced visibility due to weather and deliberate screening, and low accuracy and projectile velocities due to crappy technology and questionably competent crews.

The main weapons in use are various sorts of simple guns, ranging from breech-loading rifles in space to massive autoloading artillery batteries. Plus, there's plenty of carp being strapped onto ships as armour. Advanced weaponry like LASERs and magnetic accelerators are available to fleets that invest heavily in technological sophistication, but that means that those same fleets fall very short in many other aspects like bureaucratic efficiency, infrastructure or manpower. Gentlemen, this is how we do balance here.

Missiles, Drones and all other sorts of automated equipment are actually illegal, and using them might cause the Space Police / Totalitarian Government / Paranoid Warlord from the next satellite over to fly by and pummel the local combatants with their better-equipped and substantially better funded forces. This doesn't make them impossible to use, but any fleet using them openly should only do so once strong enough to take on those external threats. That'll be game over for now, since there's not much left to do after that.

All of this obviously serves the purpose of creating a setting in which MEN OF IRON do battle in SHIPS OF RUST while looking their opponents IN THE EYES. Which also means that relativistic physics and postmodern hiding-behind-your-drones-and-missiles warfare are not going to play any central roles.

------------------------------------------------------

So as for the LASERs, it's only possible to spot them with sufficient scattering? Suits me and my space weather system perfectly. Thanks! :D
: Re: Shrugger! Unity!
: keith.lamothe February 14, 2014, 12:59:49 PM
Plus, there's plenty of carp being strapped onto ships as armour.

Fish-based armor?

This changes everything.



Don't get in punching range.
: Re: Shrugger! Unity!
: Draco18s February 14, 2014, 09:02:17 PM
Carp are underpowered in Dwarf Fortress (http://1d4chan.org/wiki/Katanas_are_Underpowered_in_d20#Carp_are_underpowered_in_Dorf_Fortress).
: Re: Shrugger! Unity!
: Shrugging Khan February 15, 2014, 05:11:37 AM
As a Historical European Piscial Arts amateur, I have to tell you that carp are decent fish, but I would still pick a pike to protect myself with.
Pike. Heh.

--------------------------------------

Right now, the following technologies are more-or-less implemented:

Weapons: Powder guns, beam emitters and magnetic accelerators ( and missiles).
Thrusters: Liquid bipropellant, Monopropellant, Solid-Fuel and Ion accelerators.
Rotation/Translation: Thruster-based RCS, Reaction Wheels
Matter/Energy converters: Combustion Engine, Nuclear fission reactor, Smelter, Workbench, Laboratory, Waste reprocessing
Stealth: Spray-painting equipment, IR smoke, Fiber-optical camouflage

As you can see, I'm keeping it fairly abstract. Any centrally important technologies I forgot?
: Re: Shrugger! Unity!
: Aklyon February 15, 2014, 01:18:53 PM
How would you rate sturgeon (http://dwarffortresswiki.org/index.php/DF2012:Sturgeon) then? :)
: Re: Shrugger! Unity!
: Shrugging Khan February 15, 2014, 06:22:35 PM
How would you rate sturgeon (http://dwarffortresswiki.org/index.php/DF2012:Sturgeon) then? :)
That...was well after my time in DF, so I'm really lacking first-hand experience on the species.
: Re: Shrugger! Unity!
: Aklyon February 16, 2014, 07:53:21 PM
How would you rate sturgeon (http://dwarffortresswiki.org/index.php/DF2012:Sturgeon) then? :)
That...was well after my time in DF, so I'm really lacking first-hand experience on the species.
They are essentially the new carp.
On they would be, if not outdone by the giant doom sponge (http://dwarffortresswiki.org/index.php/DF2012:Giant_sponge) of (mostly) unmovingness.
: Re: Shrugger! Unity!
: Shrugging Khan March 12, 2014, 04:47:39 AM
I'm working out the details of how Space Weather™ will work, with Micrometeorites, Radiation, Solar Winds and all that.

Do you most gentle men have some interesting things to share about those? Some ideas relevant to a space action-rts/management game set in a deep space/orbital scrapyard/debris field/asteroid belt?

For examples
Thanks for any input, as always  :)

PS: Oh, and I've recently noticed that the sun illuminating my game's locale is actually somewhat unrealistic, since it was created while I played around with scales and masses (for gravity) that Unity could handle. Now, to crank up the realism somewhat, I'd like to use a star that could viably exist, and that provides a usable level of brightness. Does anyone have an idea as to which real star could be used as a model, and at what distance from it the game should ideally be set?
: Re: Shrugger! Unity!
: Aklyon March 12, 2014, 07:50:38 AM
Well, I don't know about your real-ish Space Weather, but Larklight has some rather interesting things happen in the aether. Schools of space fish, for example.
: Re: Shrugger! Unity!
: Draco18s March 12, 2014, 09:02:24 AM
Micrometeorites can often be less than 10 cm in diameter and reach speeds up to mach 3.

And that's just the trash we have in orbit around the planet.

15 km/second for space debris and 72 km/second for meteoroids.

http://www.esa.int/Our_Activities/Operations/Space_Debris/Hypervelocity_impacts_and_protecting_spacecraft

Also fancy pictures.
: Re: Shrugger! Unity!
: Shrugging Khan March 12, 2014, 10:06:28 AM
Nice link, Draco. Thankee!
10cm and mach 3 means that those micrometeorites are as large as the smallest projectiles in the game, and a lot faster at the same time. Which means that for anything that large, I can just use the standard impact code for projectiles and other physics objects. Do you think I should handle smaller impacts the same way, or rather just treat them as an abstract "erosion" variable?

Well, I don't know about your real-ish Space Weather, but Larklight has some rather interesting things happen in the aether. Schools of space fish, for example.
While I'm personally partial to armoured space carp, I'm afraid they probably won't feature very prominently.
: Re: Shrugger! Unity!
: Draco18s March 12, 2014, 10:25:13 AM
You're welcome.

I wouldn't worry about smaller objects, unless you wanted to abstract them.  Or you could use the same physics, but say that the objects are smaller and faster (F=ma, after all).

Oxygen gas in space probably isn't a real issue.  Fluorine on the other hand is one of the most reactive gasses around.
http://www.scienceforums.net/topic/11696-most-corrosive-liquidgas-come-one-come-all-to-share-your-opinions/?p=183658

FOOF is in that list (F2O2).  Do not play with FOOF.  Do not let friends play with FOOF.  Don't let anyone within 100 miles (200 upwind) play with FOOF.

http://pipeline.corante.com/archives/2010/02/23/things_i_wont_work_with_dioxygen_difluoride.php
: Re: Shrugger! Unity!
: Shrugging Khan March 28, 2014, 10:54:39 AM
Doing impact calculations now.
So I have two bodies of different masses. They crash into each other at a certain relative velocity. How do I calculate the energy of the impact?
:
Energy = Velocity * MassObviously, but how do I factor the fact that there are two objects into it?
Or is there actually no way to calculate the 'overall energy' of an impact?

Yes, my last physics lessons are rather far in the past.

Thanks for any tips!
: Re: Shrugger! Unity!
: keith.lamothe March 28, 2014, 11:15:31 AM
I may be confusing this with something else, but isn't it mass * velocity * velocity?

To account for the two different parties I think two principles should handle it:
- velocity is the sum of the two, accounting for angle (so if it's a head-on it's v1+v2, if it's a t-bone then it's just the speed of the one hitting the side of the other, and if it's at a 45-degree angle it's the aggressor + half of the other one, I think)
- for every action there is an equal and opposite reaction.  In other words, that 100kg shell going 0.5c (100,000 grams at 150,000,000 m/s = 2,250,000,000,000,000,000,000 somethings) is going to wreck that million-ton starship, but the shell is a goner.  Of course it may already be a goner pre-impact due to collision with particles, dunno.

If you're doing ship-vs-ship collision the initial energy is presumably computed the same way, but the consequences are more complex because the energy doesn't propagate instantly or uniformly through either hull.  The structure may bear and absorb some of the force, or break in some places and dissipate some of the force that way, etc.
: Re: Shrugger! Unity!
: Shrugging Khan March 28, 2014, 12:35:15 PM
Of course it's
:
Mass * Velocity²Silly me.

I've got the relative velocity calculation working (I think), the missing link right now is how to handle the masses.

Right now I'm guessing the 'overall' energy of the impact is
:
(Mass1 + Mass2) * RelativeVelocity²...is it? I'm not at all sure about this, but my google-fu is weak today. Maybe It should be
:
(Mass1 * Mass2) * Velocity²?

I'm actually playing around with the idea of including structural deformation, rather than to just let structural stress build up until a component disintegrates. Since most spaceship components are simple rectangular prisms, it shouldn't be too hard to let them get squashed a little. Ideas, ideas...

Edit: Wait, wait, it's
:
0.5 * mass * velocity²for a single body's kinetic energy. What does this tell us?
: Re: Shrugger! Unity!
: keith.lamothe March 28, 2014, 12:52:25 PM
I think the total available (the proper term might be "latent", I forget) kinetic energy in a collision would be (mass_1 * total_relative_velocity^2) + (mass_2 * total_relative_velocity^2).

Or maybe half that, if that bit with 0.5 you found is applicable.

But the question is how much of that available energy will actually be released in the collision?

Bear in mind that the incoming ship (or shell, or whatever) is actually colliding with stuff all the time on its course.  But those little dust particles don't provide enough resistance (counter-force) to release any significant portion of the main actor's available kinetic energy.

Similarly, if a really high-energy projectile were to punch through a starship and keep going, not all of its available energy is released in the collision.

On the flip side, unless the projectile and ship are going head-on against each other and the impact completely stops (or reverses) the ship's vector, then only a portion of the ship's kinetic energy was actually released in the collision.  In fact in that case I think it's probably sufficient to only consider the bullet's energy and the impact of that on the ship, rather than treating it as a two-way thing.  Unless the ship is going rather fast indeed.  I guess it depends on just how pedantic you want to be :)

But ship-vs-ship would definiitely be two-way.  My guess is, in cases where the collision will actually stop both ships (and thus involve all or nearly all of their kinetic energy) to apply mass1's force to mass2, and then apply mass2's (pre-collision) force to mass1.  And see if that does kind of what you want.
: Re: Shrugger! Unity!
: Draco18s March 28, 2014, 01:01:13 PM
Are you trying to get the resulting velocities?  Or the energy (measured as...?)

Elastic or inelastic collision?  Or some hybrid?*

*Technically all collisions are a mix of both.
: Re: Shrugger! Unity!
: Oralordos March 28, 2014, 01:20:29 PM
I don't remember the formulas off the top of my head but I think you can find them under elastic and inelastic collisions. Try looking up conservation of momentum laws. There should be some stuff about some of the energy is kept to keep the colliding items moving, and some is used for the damage.
: Re: Shrugger! Unity!
: Shrugging Khan April 04, 2014, 12:56:56 PM
Alright, thanks for the Physics tips. I ended up building yet another placeholder system, since neither armour nor materials are currently implemented, but eventually a more accurate abstraction incorporating deflection, penetration and deformation will take its place.

In other news, we've recently doneAnd some others I can't remember. As always, everything is procedural.
Almost feels like it might grow up to be a game one day.
: Re: Shrugger! Unity!
: keith.lamothe April 04, 2014, 01:23:46 PM
In other news, we've recently done
Congratulations on making so much progress :)


(Replacing "All the Dakka all the Time")
Hurh? (genuinely confused expression) ... Why replace optimal approach?

;)


Interesting Terrain...it's not Terrain if it's in space, is it?
Slamming into a mountain is still slamming into a mountain, even if said mountain lacks the benefit of a supporting planet.


Almost feels like it might grow up to be a game one day.
Certainly sounds like it!
: Re: Shrugger! Unity!
: Shrugging Khan April 15, 2014, 06:10:11 AM
I'm failing at maths and physics again.
In order to calculate the amount of time required to flip the ship around (relevant to getting the right time at which to switch from acceleration to deceleration), I need the angular acceleration potential of the ship, and that should be it. So...
(shipAngAcc in °/s², timeToFlip in seconds. 90° * 2 because we need to accelerate, then decelerate the rotation.)
:
Mathf.Sqrt((90° / shipAngAcc) * 2) = timeToFlipDoes this look about right?

------------------------------------------------------

Recent advances in glorious soviet engineering:

New shipbuilding procedure is resource-intensive but finished. Might have to make it a coroutine to stop the game from freezing for a few frames every time a new prototype is introduced (mass produced ships just use the component coordinates from the first one, which is a lot faster). Either way, we now have symmetrical ships with turrets and sensors on the outside, thrusters and spinal weapons in line with the Centre of Mass, and tougher parts being placed towards the front, all while keeping a minimal profile.

Guns have been balanced a great deal to no longer result in reload times exceeding the average ship lifetime by a factor of 30. 20,000 RPM guns have also been balanced out, since the safety equipment for them outweighed the rest of the ship and looked rather silly.

Made lots of little sanity checks (Isn't that an Arcen term?) elsewhere, too, such as keeping fleet bureaucracy from ordering ships to be build that couldn't be afforded, having blueprints re-prototyped if the first attempt failed. That said, insanity still prevails when it comes to turrets only firing every now and then, and then only in one short bursts (spinal guns are considerably more trigger happy) and to ships having no collision avoidance (and accidental ship collisions leading to more kills than gunfire or deliberate ramming).
: Re: Shrugger! Unity!
: Draco18s April 15, 2014, 11:42:21 AM
(shipAngAcc in °/s², timeToFlip in seconds. 90° * 2 because we need to accelerate, then decelerate the rotation.)
:
Mathf.Sqrt((90° / shipAngAcc) * 2) = timeToFlipDoes this look about right?

Based on some fiddling in Excel, it's pretty darn close (I only tested with precise resolution of 1 second and mentally guessing at the tenths, but it looks fairly close).

I do get a calculated 13.4 seconds for an acceleration of 1 degree, and determining that at 13 seconds it's rotated 91 degrees....so I'm not sure what's up with that.

I'm going to say it's right and that my per-step calculation is off (that is, after 1 second it has accelerated up to 1 degree of rotation per second, but hasn't actually rotated a full degree yet, leading to the ~0.47 second discrepancy).
: Re: Shrugger! Unity!
: keith.lamothe April 15, 2014, 11:48:20 AM
I'm failing at maths and physics again.
In order to calculate the amount of time required to flip the ship around (relevant to getting the right time at which to switch from acceleration to deceleration), I need the angular acceleration potential of the ship, and that should be it. So...
(shipAngAcc in °/s², timeToFlip in seconds. 90° * 2 because we need to accelerate, then decelerate the rotation.)
:
Mathf.Sqrt((90° / shipAngAcc) * 2) = timeToFlipDoes this look about right?
My brain isn't firing on all cylinders right now, but:

1) I need to turn 180 degrees.

2) My ship has (for example) an angular acceleration of (4 degrees-per-second) per-second

3) Using d = (1/2)*a*(t^2), I get:
180 = (1/2)*4*(t^2)
180 = 2(t^2)
90 = t^2
sqrt(90) = t
9.48 ~= t
So 9.48 seconds to flip without coming to rest.  Which isn't the answer we're looking for, but anyway.

4) Just targeting 90 degrees, with the deceleration from there being a mirror of that:
90 = (1/2)*4*(t^2)
sqrt(45) = t
6.71 ~= t
So 6.71 seconds to reach 90 degrees, and then 6.71 to come to rest at 180.  So in the neighborhood of 13.4 seconds for the full maneuver.

To sanity check:
1st second - start at 0 degress-per-second, end at 4 degrees-per-second, so 2 degrees travelled
2nd second - start at 4 degrees per second, end at 8 degrees-per-second, so 6 degrees travelled this second, 8 total
3rd second - from 8 to 12, so 10 this second, 18 total
4th second - from 12 to 16, so 14 this second, 32 total
5th second - from 16 to 20, so 18 this second, 50 total
6th second - from 20 to 24, so 22 this second, 72 total
7th second - accelerate for 0.71 seconds, from 24 from 26.84, avg 25.42, so 18 for this interval, 90 total
7th second part 2 - decelerate for 0.29 seconds, from 26.84 to 25.68, avg 26.26, so 7.6 for this interval, 97.6 total
8th second - from 25.68 to 21.68, avg 23.68, 121.28 total
9th second - from 21.68 to 17.68, avg 19.68, 140.96 total
10th second - from 17.68 to 13.68, avg 15.68, 156.64 total
11th second - from 13.68 to 9.68, avg 11.68, 168.32 total
12th second - from 9.68 to 5.68, avg 7.68, 176 total
13th second - from 5.68 to 1.68, avg 3.68, 179.68 total
14th second - from 1.68 to 0 in 0.42 seconds, avg 0.84, so 0.35 this second, 180.03 total (the extra because I rounded pretty loosely earlier)

So 13.42 seconds via a rough approximation model.


So looks like your:

"Mathf.Sqrt((90° / shipAngAcc) * 2) = timeToFlip"

would work better as:

"Mathf.Sqrt(90° / (shipAngAcc / 2) ) * 2 = timeToFlip"

If I'm to be trusted with math, that is.  And I'm not.


Recent advances in glorious soviet engineering:

New shipbuilding procedure is resource-intensive but finished. Might have to make it a coroutine to stop the game from freezing for a few frames every time a new prototype is introduced (mass produced ships just use the component coordinates from the first one, which is a lot faster). Either way, we now have symmetrical ships with turrets and sensors on the outside, thrusters and spinal weapons in line with the Centre of Mass, and tougher parts being placed towards the front, all while keeping a minimal profile.
Glorious indeed!

Though a coroutine still runs on the main thread, it would just be something you could spread over multiple frames.   You could multithread to really offload it from the main work, but that gets into a whole other can of worms where you'd need to send that other thread a copy of all the relevant data that was even theoretically capable of changing during its execution, or else have a lot of locking on "shared" mutable data.  So I hope coroutining fits your case (and you don't need to use Unity's coroutining for that, you can just write it to be done in multiple pieces, and do one piece each frame or whatever), or you find some other way of optimizing it :)


Guns have been balanced a great deal to no longer result in reload times exceeding the average ship lifetime by a factor of 30.
Sounds like you could have gone the other way and saved a lot on ammunition stowage!  "Um, comrade, why does gun have only one bullet?"  "Relax, comrade! We only get one shot."


20,000 RPM guns have also been balanced out, since the safety equipment for them outweighed the rest of the ship and looked rather silly.
What is this "safety equipment" you speak of?


Made lots of little sanity checks (Isn't that an Arcen term?)
What have we to do with sanity?


such as keeping fleet bureaucracy from ordering ships to be build that couldn't be afforded
Alas, sometimes realism must give way to game design considerations.


(and accidental ship collisions leading to more kills than gunfire or deliberate ramming).
It is as it should be!  It isn't so much crews taking ships into battle as it is terrified skaters going onto the ice with intermittent rocket boosters attached to each skate.
: Re: Shrugger! Unity!
: Shrugging Khan April 15, 2014, 07:08:27 PM
I'll test the two formulas for time-to-flip and see which one gets better results. Thanks for helping, you two   :D

Though a coroutine still runs on the main thread, it would just be something you could spread over multiple frames.   You could multithread to really offload it from the main work, but that gets into a whole other can of worms where you'd need to send that other thread a copy of all the relevant data that was even theoretically capable of changing during its execution, or else have a lot of locking on "shared" mutable data.  So I hope coroutining fits your case (and you don't need to use Unity's coroutining for that, you can just write it to be done in multiple pieces, and do one piece each frame or whatever), or you find some other way of optimizing it :)
My plan was to deliberately spread it over multiple frames, and to my limited knowledge Unity's Coroutines would offer the most elegant way of doing it. Just handle the initial planning method as a coroutine, the subsequent specialised methods should also be able to use Yield - which I would then insert at the end of all those massive for loops.

To illustrate: Sticking together parts linearily and attaching spinal components (guns and thruster mostly) is fairly performance-friendly. Building a low-profile core in three dimensions happens via random trial and error, so it gets better the longer it's left to itself. Attaching turrets or sensors is the main issue - these are attached as rings, and as such have to test a variety of z-axis positions and angles of rotation to get a low profile. And unlike linear or core parts, which are mostly just axis-aligned cubes, these external devices can also be spherical or rotated. So it has to run a lot of tests to get usable results - and spreading those out over time would be both a boon to performance and a much more tangible prototyping experience; especially because you could watch the process :P

Sounds like you could have gone the other way and saved a lot on ammunition stowage!  "Um, comrade, why does gun have only one bullet?"  "Relax, comrade! We only get one shot."
Single-shot guns actually are a thing, as are ammunition shortages (although I've commented them out for testing...long ago), as are ideological differences concerning the value of the individual soldier.

What is this "safety equipment" you speak of?
Mostly just a large cylinder made of several thousand tons of iron, wrapped around the gun.

What have we to do with sanity?
Your games actually have to use sanity checks. 'Nuff said, eh?

Alas, sometimes realism must give way to game design considerations.
Bureaucratic failure is supposed to be part of the game, not its default state :P

It is as it should be!  It isn't so much crews taking ships into battle as it is terrified skaters going onto the ice with intermittent rocket boosters attached to each skate.
'Battle'. Heh. Right now it's mostly just single pilots finding themselves alone in giant capital ships, flailing wildly with the turrets while having other ships, debris and the terrain itself explode into fragments all around them as they overshoot their navigational targets by several kilometers, only to laser their own Rotation Control Systems off. I think one pilot even managed to shoot himself with a turret. And one gun shot itself.

...I like to think that those events do not actually reflect upon the state of the project.
: Re: Shrugger! Unity!
: keith.lamothe April 15, 2014, 07:20:25 PM
My plan was to deliberately spread it over multiple frames, and to my limited knowledge Unity's Coroutines would offer the most elegant way of doing it. Just handle the initial planning method as a coroutine, the subsequent specialised methods should also be able to use Yield - which I would then insert at the end of all those massive for loops.
Yea, it's probably good enough to prove the concept with.  I'm just pathologically suspicious of engine features like coroutines: I'd rather do the breaking-into-bits myself, rather than wonder what's going on inside the black box.  But there's a lot to be said for rapid prototyping, and something to be said for giving the engine a chance and changing to a different approach later if it proves necessary (the striking regularity with which it does, in fact, prove necessary is a large source of said pathological suspicion).


especially because you could watch the process :P
The engraving shows a dwarf and a prototype capital ship.  The prototype menaces with masterwork adamantine spinal-mount grasers.  And a point defense cluster that somehow blocks both the main viewport and the main thrusters.


Mostly just a large cylinder made of several thousand tons of iron, wrapped around the gun.
Ah, yes, that kind of safety equipment.  Make ship safe, by launching safety equipment at high velocity at enemy ship! ... no?


I think one pilot even managed to shoot himself with a turret.
Given what you've told me of this universe, I am not at all sure said shot was unintentional.


...I like to think that those events do not actually reflect upon the state of the project.
Sounds like it's coming along quite nicely, actually (for once, I intend no comedic sarcasm).
: Re: Shrugger! Unity!
: Shrugging Khan May 13, 2014, 03:53:56 PM
Getting back to Orbital Mechanics, I've started taking the hard route and doing it the KSP way - writing a separate physics system for them. The problem comes in the interactions between the Orbital Physics and the Rigidbody Physics.

1. How can I make Rigidbody interactions have proper effects on the Orbit? Difficulty: Adjusting the orbit to small collisions and thrust. I have a theory that I should just track the changes in velocity from one frame to the next and consider that kinetic energy, but I'd also have to subtract the orbital motion from that, and oyoyoy...

2. How can I let Orbital changes and Gravity have the right effects on the Rigidbodies? Difficulty: I somehow suspect that rigidbodies don't take kindly to being constantly pushed around by non-unity-physics forces, since I've already seen some strange behaviour when a rigidibody in motion was translated between two frames and it ended up somewhere it didn't expect to be.

3. Orbits require large, massive bodies, which greatly increases the distances in play. Even if it's just an earthlike 15,000 km or so, I'm guessing that the physics simulation will get pretty wonky that far away from the origin...

A separate issue is that I have no idea on how to actually calculate orbital mechanics. If anyone knows a good page to read - this non-mathematician would be quite grateful.
I don't want to open the can of worms that is writing an all-new physics engine, unless you really think that's the best way ;P

And obviously none of this is anyone's speciality here, so miscellaneous input is just as appreciated as qualified knowledge  :D
: Re: Shrugger! Unity!
: Shrugging Khan May 15, 2014, 07:36:30 AM
And yet another thing - I'm calling a lot of methods with strings as parameters, which are then compared to others - but I've heard it said that comparing strings is very inefficient. Would it make a significant difference if I replaced them all with enums?

To illustrate, I do a lot of
:
GUI_AddLine("WeaponsList", gun.name, gun.ammo.ToString());In which all present GUI elements have their names compared to "WeaponsList" to see whether such a thing already exists, then the weapon's name is compared to all the entries in the list to see if it's a duplicate. This kind of thing happens for all other sorts of affairs to - probably several hundred times per frame.

So...would replacing as many as possible of those string-based descriptions with enums à la
:
enum GUI_ElementType { WeaponList, NavigationData, FleetData, PlayerData }improve performance in any noticeable way?

Thankee for any help :)
: Re: Shrugger! Unity!
: Draco18s May 15, 2014, 09:19:33 AM
And yet another thing - I'm calling a lot of methods with strings as parameters, which are then compared to others - but I've heard it said that comparing strings is very inefficient. Would it make a significant difference if I replaced them all with enums?

Yes.  Enums are great.  You as a programmer still the the benefit of using Strings, but the computer can go and use integers.  Enums can even contain other values (like a class).

For instance, Minecraft uses an enum for material type, so you get things like:

ToolMaterial.DIAMOND.efficiency
: Re: Shrugger! Unity!
: keith.lamothe May 15, 2014, 10:57:10 AM
Enums are massively more efficient than strings.

Generally speaking string comparison should only be done when really necessary (matching user input to something, for example), or when it saves you a lot of dev work and is only run a few times in the program.  Like I'll sometimes actually take an enum's .ToString() and check for .StartsWith("Deprecated_") or whatever on that string, rather than have a switch with cases for all the deprecated enum values (we often have to retain the deprecated ones to avoid breaking deserialization of old save game files), as that removes the need for me remember to do that for each one.  But it only has to do that string compare once per enum, at the very beginning of the program running so it doesn't really slow anything down.

It's also wonderful to be able to right-click an enum value and do "find all references" and you can see everwhere it's used in the code.  That's because the relationship is statically defined, in a way the compiler can understand, rather than the dynamic association implied by the string value, which has no "real" relationship with a particular weapon-type-data (or whatever) until runtime.


Btw, strings in general are the source of many performance gotchas.  No fault of theirs, really, they're doing a very specific job and they do it well.  But often programmers do not know what that job really is (providing immutable sequences of characters).

So, for instance, if you do a lot of string concatenation (basically using the + operator with string operands) you're probably causing a metric ton of transient heap allocation, theoretically as bad as n^2 where n is the length of the string.  Where if you used a character buffer (the framework's StringBuilder is acceptable, though one can do better) it's often just n*2, particularly if you can predict the final length ahead of time.

Doesn't mean every single string.concat should be converted to a buffer instead (that would consume unnecessary developer time and not gain much in a lot of cases), but something to know about if you didn't already.  Of course, it 's possible we already had that discussion earlier in this thread ;)
: Re: Shrugger! Unity!
: Shrugging Khan May 21, 2014, 11:17:46 AM
Gradually phasing out all the strings in favour of enums; where possible. Thanks for the advise :)

Also once again fixed the sounds to cause less ear bleeding, did some work on the mouseover information and icon-accompanying text, and generally changed a lot of completely under-the-hood things. When will I ever get around to putting in new content?

Right now my project is breaking up the giant classes (Component, Resource, Crew), because I noticed their sheer size being the greatest deterrent to my working on exactly those things (machine functionality, resource handling and crew AI).

Is it a smart Idea to have the following setup?

Component:MonoBehaviour is the main component script - attached to a physical GameObject -, and mostly exists to contain multiple abstract SubComponents, each of which is inherited by a specific device (scAutoloader, scPump, scThrustVectoring, etc.). The latter classes mostly provide functionality, such as Autoloaders ejecting spent shells and loading new ones, Pumps moving liquids and gases from one component to another, and Thrust Vectoring changing the direction the nozzle of a propulsion system points in. SubComponent provides structural information like mass, volume, durability, temperature and so on.

Not sure if that's even the right way to describe it, but I'll happily hear your negative judgement on it if that's what it deserves.
: Re: Shrugger! Unity!
: keith.lamothe May 21, 2014, 11:24:04 AM
Component:MonoBehaviour is the main component script - attached to a physical GameObject -, and mostly exists to contain multiple abstract SubComponents, each of which is inherited by a specific device (scAutoloader, scPump, scThrustVectoring, etc.).
We only actually have one MonoBehaviour (the camera) and it does everything.  Though I understand you're using the individual game objects so you can have Unity tell you when they're slamming into each other and such (iirc).

On the class hierarchy, I'm not sure I understand what you mean.  Is it something like this:

class Component
{
List<SubComponent> SubComponents;
}

abstract class SubComponent
{
}

class Autoloader : SubComponent
{
}

class Pump : SubComponent
{
}

class ThrustVectoring : SubComponent
{
}

?

Or something else?
: Re: Shrugger! Unity!
: Shrugging Khan May 21, 2014, 11:52:57 AM
Precisely so!

And yeah, I'm using MonoBehavior mostly just for the physics.
: Re: Shrugger! Unity!
: keith.lamothe May 21, 2014, 12:06:08 PM
Ok, I don't see anything particularly wrong about using inheritance for that.

We don't use it that way for our core-sim stuff (we use inheritance heavily in our GUI stuff, where there are relatively few objects and relatively many widely-distinct concepts) to avoid the overhead, and also because the intellisense often works better if it's not having to plow through virtual function tables.  It's also generally less code our way, I think.

So in our case we would do (and this isn't a suggestion, just fyi) :

class Component
{
List<SubComponent> SubComponents;
}

enum SubComponentType
{
None,
Autoloader,
Pump,
ThurstVectoring,
Length
}

class SubComponentTypeData
{
SubComponentType Type
}

class SubComponent
{
SubComponentTypeData TypeData
}

Where the type-data class would only have one instance per SubComponentType value (other than Length) that is instantiated during app-load and would contain the "invariant" info on that kind of subcomponent.  The SubComponent class would have potentially many instances (instantiated whenever needed, during the sim), and would contain the mutable information, and would be what was actually serialized to disk/network when being saved/sync'd, etc.
: Re: Shrugger! Unity!
: Shrugging Khan May 29, 2014, 07:44:26 AM
It mostly works now, except for one little issue.

I'm creating the subcomponents in a factory class to pass them to the component class, à la component.AddSubcomponent(subcomponent). Now, as previously stated, those abstract subcomponents are inherited by a variety of specific classes such as scInfraredSensor, scThrustVectoring or scAutoloader. When how can I, within the AddSubcomponent class, check what the specific class of the subcomponent is?

Thanks for any help, Google didn't present me with a solution so far ;P

PS: More specifically, I'm trying to get GetType() and typeof() to play nice, but comparing the two always returns false :/
PPS: Also played around with equals() and is, to no avail.
PPPS: Nevermind. ALL of the methods I tried worked, I just made a copypasting error.
: Re: Shrugger! Unity!
: keith.lamothe May 29, 2014, 09:31:44 AM
Sounds like you figured it out :)  I generally use "is" if I must check a type in production code (and I avoid that outside GUI or possibly other low-frequency code).

I'm not sure if it's actually a well-founded-concern, but my concern with type checking is that it will incur some of the overhead usually associated with reflection.

So having that enum in our pattern helps there, as that's just an integer-equality test.

But since I haven't actually measured the performance of the two side-by-side I dunno if it's a big deal.
: Re: Shrugger! Unity!
: NichG June 07, 2014, 12:32:15 PM
Getting back to Orbital Mechanics, I've started taking the hard route and doing it the KSP way - writing a separate physics system for them. The problem comes in the interactions between the Orbital Physics and the Rigidbody Physics.

1. How can I make Rigidbody interactions have proper effects on the Orbit? Difficulty: Adjusting the orbit to small collisions and thrust. I have a theory that I should just track the changes in velocity from one frame to the next and consider that kinetic energy, but I'd also have to subtract the orbital motion from that, and oyoyoy...

2. How can I let Orbital changes and Gravity have the right effects on the Rigidbodies? Difficulty: I somehow suspect that rigidbodies don't take kindly to being constantly pushed around by non-unity-physics forces, since I've already seen some strange behaviour when a rigidibody in motion was translated between two frames and it ended up somewhere it didn't expect to be.

I'm not sure about how this should work with Unity in particular, but essentially what you're doing by putting the object on a on-rails orbital track is you're splitting its total motion/physics into two pieces. One piece comes from the solution of the equations of motion for an object under the effect of gravity; the other piece comes from whatever detailed motions the object performs due to collisions/rotation/etc within the context of that orbiting reference frame.

One way to think about the orbiting reference frame is that its a choice of reference frame such that the fictitious force due to the frame's acceleration exactly counter-balances the force of gravity, so the motion of a single rigid object within the orbiting reference frame is in free-fall (e.g. you don't need to worry about gravity because its taken care of by choosing the orbiting reference frame).

Once you have two objects, the problem is that they are in slightly different orbits, so if you go to a shared reference frame containing both objects then the result is that gravity once again matters and needs to be calculated carefully. As far as I'm aware, KSP uses 'on-rails' orbits only when objects are not interacting, and when they are interacting it switches to something in which gravity/etc are fully taken into account - that's why objects sometimes jump around when you enter non-physics-timewarp.

What you can in principle do is to create a 'center of mass orbit frame' when two objects come near to eachother. This is basically the orbit of the average of the objects' motions. However, there isn't that much mathematical benefit in doing so because you still are going to have to take into account differential gravity (e.g. tidal forces) due to different distances within the frame from the primary. Of course if the interaction range is much smaller than the distance to the primary, you may choose to just assume that these tidal forces are zero.

When objects left collision distances of eachother, you'd then recalculate their individual orbits and update their orbital parameters.

3. Orbits require large, massive bodies, which greatly increases the distances in play. Even if it's just an earthlike 15,000 km or so, I'm guessing that the physics simulation will get pretty wonky that far away from the origin...

Double precision means that roughly speaking you've got 12-14 orders of magnitude of smooth resolution and then a few orders of magnitude that may have small, visible glitching. So with double-precision floating points you can resolve motions on the order of millimeters while still retaining distances of the order of 15000km. Its generally better however to separate things into two parts if there's a huge gap in the numbers like that - store the 'orbital-scale' numbers in one variable while storing the local position of sub-objects and nearby objects relative to their shared center-of-mass or something like that. That way, you don't have the issue that a 15000km orbit screws up the millimeter-scale rigid body stuff. Separating out the orbital physics like you're intending to should help you do this, though you'll have to be careful at the point where the two scales intersect (e.g. asking whether or not two orbiting objects are within 1km of eachother to initialize the detailed positional information).

A separate issue is that I have no idea on how to actually calculate orbital mechanics. If anyone knows a good page to read - this non-mathematician would be quite grateful.
I don't want to open the can of worms that is writing an all-new physics engine, unless you really think that's the best way ;P

And obviously none of this is anyone's speciality here, so miscellaneous input is just as appreciated as qualified knowledge  :D

The idea with orbital mechanics is that you can separate out the shape of the orbit (a particular ellipse or hyperbola) from your position along the orbit. Calculating the specific position that corresponds to a specific time still requires numerical integration or solving a transcendental equation, but the benefit is that basically you're always just solving versions of the same problem and so the error doesn't grow with time.

It looks like 'Orbital Elements' is one of the keywords to search for in finding information about this kind of thing. What you're going to want is a way to calculate orbital elements given 'orbital state vectors'. There's a stackexchange for this particular question which might help:

http://space.stackexchange.com/questions/1904/how-to-programmatically-calculate-orbital-elements-using-position-velocity-vecto

The other part you need is to be able to calculate the time evolution of the angle around the orbit. To do this you need to solve the equation for the 'true anomaly'. It seems like this is generally done by starting with the 'mean anomaly' M, which is the fraction of the orbital period that has passed since perigee (so sort of like an interpolating parameter). This is then related by a pair of transcendental equations to the true anomaly:

M = E - e sin(E) (the 'e' here is eccentricity; you want to solve this for E)
cos(E) = (e + cos(nu))/(1+ e cos(nu)) (the 'nu' here is the true anomaly, which is basically the angle around the orbit; you want to solve this for nu)

This page discusses it in more detail and gives a handy approximation, depending on how accurate a solution you need: http://www.braeunig.us/space/orbmech.htm

: Re: Shrugger! Unity!
: Shrugging Khan June 07, 2014, 05:41:30 PM
Who are you, where have you come from, and what in the name of god made you read my thread?  :o

That said, thanks for the tips. I'm still tinkering around with the abstract model, and trying to read up on orbital simulations - I really need to give the links you posted a good looking-at, since I'm pretty short on good resources.

One thing I have to ask you right away though: Unlike KSP, this here can't get away with having close-in physics just within 1 or 2 kilometres from the POV. Engagements happen at up to several hundreds of kilometres, with multiple such engagements taking place at various locations within the scene. All of those require proper physics, all at the same time. The testing I've done so far has given me jittery physics from about 2000km out from the origin.

Obviously, using double precision would give me a lot more room, but AFAIK Unity insists on doing its coordinate and physics stuff in single precision floats. Damn them! Scaling the whole game down doesn't work (naturally), and moving the whole world relative to the POV also isn't a solution because it's not player-centric.

So right now I'm kinda afraid the only solution is to force the POV to stick to a particular engagement and simulate everything that's further away as an abstraction. Or ditching Unity. Meh.

--------------------------------------
In other, better news:
: Re: Shrugger! Unity!
: NichG June 07, 2014, 10:45:02 PM
Who are you, where have you come from, and what in the name of god made you read my thread?  :o

Just a wandering physicist noticing a thread asking about orbital mechanics :)

That said, thanks for the tips. I'm still tinkering around with the abstract model, and trying to read up on orbital simulations - I really need to give the links you posted a good looking-at, since I'm pretty short on good resources.

One thing I have to ask you right away though: Unlike KSP, this here can't get away with having close-in physics just within 1 or 2 kilometres from the POV. Engagements happen at up to several hundreds of kilometres, with multiple such engagements taking place at various locations within the scene. All of those require proper physics, all at the same time. The testing I've done so far has given me jittery physics from about 2000km out from the origin.

Obviously, using double precision would give me a lot more room, but AFAIK Unity insists on doing its coordinate and physics stuff in single precision floats. Damn them! Scaling the whole game down doesn't work (naturally), and moving the whole world relative to the POV also isn't a solution because it's not player-centric.

So right now I'm kinda afraid the only solution is to force the POV to stick to a particular engagement and simulate everything that's further away as an abstraction. Or ditching Unity. Meh.

Yeah, this is troublesome. The best I can suggest would be to figure out a way to treat each engagement as a separate Unity scene and then pull that data over to render in a 'fake' scene that is used only to establish the POV. I don't know how feasible that is though.
: Re: Shrugger! Unity!
: Draco18s June 07, 2014, 11:37:02 PM
Yeah, this is troublesome. The best I can suggest would be to figure out a way to treat each engagement as a separate Unity scene and then pull that data over to render in a 'fake' scene that is used only to establish the POV. I don't know how feasible that is though.

You wouldn't be able to.  A "scene" in Unity is "everything going on right now."  An unloaded scene is like an ejected DVD: can't read, can't write.
: Re: Shrugger! Unity!
: Shrugging Khan June 08, 2014, 02:54:03 AM
Not to mention that engagements, as they currently are, really aren't separate entities - a powerful scout ship sitting next to one such engagement might be providing long-range sensor support to ships floating around somewhere else entirely, long-range precision weapons might be used from one end of the theatre to the other, fleet communications are all over the place anyways and if I really were to split things up into smaller chunks, then where will all the poor little stray shots go? They'd never be able to accidentally do a "Debris incoming" situation on anyone! D:

Edit: Right, orbits. Almost forgot! So ATM I'm thinking we might really simulate the orbits, with celestial bodies being completely on-rails sans physics. The active scene would be limited to about 1000-3000km, and anything travelling further out would be abstracted, put on rails, have only occasional AI checks to see whether they want to (and are even able to) do anything about their orbit, and be reintroduced to the active scene only if their orbits carry them back in or if the AI somehow makes it back under its own power. How to do interactions between on-rails AI entities...I dunnoe, yet.
: Re: Shrugger! Unity!
: NichG June 08, 2014, 01:08:45 PM
What's the scale on which you actually need to resolve the interaction between game objects, versus the scale you need to render smooth motion to the player? E.g. if you rounded everything off to the nearest 10 meters for things like sensor ranges, weapon ranges, etc, would that be okay?

Because if so, what you can do is use a much coarser representation for the physics parts of the game (essentially your own engine, separate from Unity's, which would mean you could get around many of these problems), and then just use the RigidBody stuff and actual objects in scene for the purposes of rendering convincing motion - that is to say, you only do this for things near the point of view.

This may also help make things computationally less expensive. I don't know how important detailed rigidbody physics is going to be to engagements though.
: Re: Shrugger! Unity!
: Shrugging Khan June 08, 2014, 01:56:32 PM
I'm not quite sure how far we could go, actually.

To give you an idea of how things work: There are no arbitrary sensor or weapon ranges - sensors use raycasts to check for line-of-sight, whereas weapons actually spawn bullets as physical objects. Said bullets tend to be spheres between 0.01 and 0.2 metres in diameter, moving at 1000 to 5000 metres per second. That's the deal for conventional guns, anyways. Railguns/Coilguns have more exotic calibers with far higher velocities, and Beam Emitters use raycasts. And then there's ship-to-ship collisions, of course.

Ships are made from multiple components, which in turn can be pretty much any size from 0.01m upwards. So small drones could be half a metre long, while a civilian settlement of moderate size (there's no systemic distinction between these things) might be several kilometres in diameter.

And the biggest problem yet is how the ships move. Once again I need to point at KSP - the ships don't just rotate at a fixed rate or move at arbitrary speeds; they apply angular or linear acceleration and physics take over from there. But in theory that's not overly complex, so we could probably disable the rigidbody physics at >1000km from the POV and just run our own, slightly abstracted simulation. So you're probably onto something there.

Still, bullets and raycasts. We can't get away with rounding things off to 10 or even 0.1 metres, that's a no-go.


-----------------------------------------
Alright, so here's the plan as it stands. Concerning the distance/float issue, mind you - we'll talk about orbits later.

I'm guessing we'd distinguish between a rigidbody/Unity physics zone extending to maybe 1000km around the POV, and a double-precision zone further out in which we need to track everything in our own double-precision coordinate system, move things according to our own calculations, and slap the rigidbodies back onto them when they come closer again.

Using doubles we can get the precision we need, although we'll need to do hit detection on our own rather than to use the Unity colliders, which is something we already do for high-speed collisions. Here comes another problem, though - we do that via raycasts, which use single-precision vectors.

Gotta do some research on raycasts, methinks.
Anyone got some good ideas? ;)
: Re: Shrugger! Unity!
: Draco18s June 08, 2014, 08:37:24 PM
Gotta do some research on raycasts, methinks.
Anyone got some good ideas? ;)

http://rosettacode.org/wiki/Ray-casting_algorithm#C
: Re: Shrugger! Unity!
: NichG June 08, 2014, 10:55:58 PM
The raycasts should probably be fine with rounding off if you had to - you'd basically just do intersections with bounding volumes, and then if you intersect the bounding volume you create a random point of entry within the patch of the bounding volume you entered through and use that to figure out hit location/if there's a hit.

The bullets concern me a bit though. If you're just timestepping them to do collisions, they'll tunnel right through their targets (1/30 sec timestep means that the bullet can skip over a 160km range). So I assume that for individual timesteps you're using a collision algorithm that checks against the swept volume (conveniently, that would have a lot in common with raycasting, so you might be able to use the same code for both bullets and beams).

The real concern is aiming accuracy over the kinds of distances you've talked about. If you're trying to hit a 100m target 100km away, thats about a 20th of a degree of precision in aim (including things like leading the target, etc). Thats sort of why I was suggesting you might be able to round that off - a 0.1 meter feature at 100km away is going to be less than a pixel on the screen at that distance, so there's no way to really know whether or not the engine fudged the numbers a bit.
: Re: Shrugger! Unity!
: Aklyon June 08, 2014, 11:11:56 PM
Its starting to sound like Khan has too much complexity for the game to work with, which causes more problems the more things there are in the sim, from my (somewhat confused) point of view.
: Re: Shrugger! Unity!
: Draco18s June 09, 2014, 12:01:02 AM
The real concern is aiming accuracy over the kinds of distances you've talked about. If you're trying to hit a 100m target 100km away, thats about a 20th of a degree of precision in aim (including things like leading the target, etc). Thats sort of why I was suggesting you might be able to round that off - a 0.1 meter feature at 100km away is going to be less than a pixel on the screen at that distance, so there's no way to really know whether or not the engine fudged the numbers a bit.

He is well aware of the aiming difficulties at stupidly large distances.  I think that's part of the fun.  Mainly: having shots miss, fly off into space, and plink something seven light minutes away.  And possibly on your own side.

See also: http://365tomorrows.com/10/09/the-neodymium-accord/
: Re: Shrugger! Unity!
: Shrugging Khan June 09, 2014, 04:10:37 AM
Its starting to sound like Khan has too much complexity for the game to work with, which causes more problems the more things there are in the sim, from my (somewhat confused) point of view.
That's always been the case  :P
I'm trying to break and fix only one thing at a time, though, only moving on to the next once everything else more or less works.
And really, what choice do I have? The whole point of the game is "Multiple complex systems, inspired by reality, interacting to form the whole". So sure, I *could* just make things move at arbitrary speeds rather than by newtonian physics, and I *could* make all weapons hitscan and be done with it, and I *could* scrap the procedurally-generated-human--crew-for-every-task approach in favour of just using fully automated ships...and then I might even be done with the game one day. *But* where'd be the point?

: Draco18s
He is well aware of the aiming difficulties at stupidly large distances.  I think that's part of the fun.  Mainly: having shots miss, fly off into space, and plink something seven light minutes away.  And possibly on your own side.
Which is why I've tweaked the procedural weapon generation to favour lower rates of fire - fewer shots in the air (space), but every one of them matters to someone, sooner or later  ;)

: NichG
The raycasts should probably be fine with rounding off if you had to - you'd basically just do intersections with bounding volumes, and then if you intersect the bounding volume you create a random point of entry within the patch of the bounding volume you entered through and use that to figure out hit location/if there's a hit.
I'll have to actually write and test that system, I guess. If luck prevails, Unity's raycasts will work out fine out there. Otherwise I'll have to take the approach from the link Draco posted and translate it to C#.

: Draco18s
http://rosettacode.org/wiki/Ray-casting_algorithm#C
Which, coincidentally, is a pretty interesting site. They've even got it in Haskell, those crazy bastards!

: NichG
The bullets concern me a bit though. If you're just timestepping them to do collisions, they'll tunnel right through their targets (1/30 sec timestep means that the bullet can skip over a 160km range). So I assume that for individual timesteps you're using a collision algorithm that checks against the swept volume (conveniently, that would have a lot in common with raycasting, so you might be able to use the same code for both bullets and beams).
That's exactly the case. Right now we're using two different systems to check for collisions - Unity's built-in collision detection by collider intersection and a homemade raycast-ahead system - so we're not actually checking the swept volume but only a straight line; although I'll admit that that's a cop-out. Gotta change that someday. Oh, and I think we're also giving the bullets colliders so long that they're exactly as long as the distance they cover in one frame...heh, so if you somehow slowed it down or stopped time you'd see a 20-metre-rod tumbling around. Alright, gotta change that, too.

: NichG
The real concern is aiming accuracy over the kinds of distances you've talked about. If you're trying to hit a 100m target 100km away, thats about a 20th of a degree of precision in aim (including things like leading the target, etc). Thats sort of why I was suggesting you might be able to round that off - a 0.1 meter feature at 100km away is going to be less than a pixel on the screen at that distance, so there's no way to really know whether or not the engine fudged the numbers a bit.
Yeah, that's already a problem at ranges shorter than 5km. Spinal guns are aimed by rotating the entire ship, that rotating working through newtonian physics. The reaction wheels used for rotations are working A-OK, but the AI tends to oversteer a little, which leads to very slight errors in pointing the ship...which in turn means that at 5km of distance, a perfectly accurate gun can no longer  hit a target that's maybe 5m in size. Gotta either improve that bit of AI, or add some precision functionality to the reaction wheels that allows them to do adjustments of less than 0.1°/frame without newtonian physics (but at a higher energy cost, for example).
Guns on turrets don't have that problem, since they're allowed to rotate without having to go through physics.

Then again, shooting at a target that's 100km away, even with a very powerful gun, gives said target a window of well over 20 seconds from seeing the muzzle flash to impact. Plenty of time to point your armour the right way, or to just dodge away, so shooting small or fast targets at that distance isn't really something the AI should be doing a lot. That's missile range, really, and those can obviously adjust their trajectory in flight. Add to that that most guns are not actually perfectly accurate, and that you generally don't have 0 relative velocity to potential targets (so all targets are moving targets, more or less), and that intercept calculations at long range are generally not promising much if the target can accelerate in any way...and I don't think anyone will complain about a few missed shots at long range  ;D
: Re: Shrugger! Unity!
: NichG June 09, 2014, 01:37:19 PM
So my point is kinda, if bullets are only for shorter ranges then you should focus on making their physics optimized for accuracy at those ranges, and then if errors occur when you're trying for 100km away miracle shots then, well, would anyone actually notice? Essentially I'm trying to figure out where you can drop some orders of magnitude of required precision by looking at how you can segment your scene into near-field versus far-field effects.

For example, every 30 frames you could recompute 'zones', which are rectangular bounding boxes surrounding sets of ships/objects such that every object is within say 10km of another object in the zone. Then you'd use different physics for effects crossing between zones versus objects within the same zone. That means that within a zone you have 7 orders of resolution: [1cm .. 10km], and between zones you have a different 7 orders of resolution [100m ... 1 million km], lets say. The way you then cross between those resolutions is that you fill the remaining detail in with a random number - so if you're firing a shot from another zone, it rounds to the nearest 100m but then when it enters the other zone it adds a random number between -50m and +50m to the position to get rid of any banding artifacts.

I don't know whether it'll end up being practical to do so (especially within Unity, which basically has a black box for a physics engine), since this kind of scene segmentation approach tends to be tricky to implement even if its very effective when done right, and it feels like you may be fighting Unity to make it happen...
: Re: Shrugger! Unity!
: Shrugging Khan June 09, 2014, 05:30:44 PM
That's reasonable for general ship movements and sensor raycasts, but how would a gunfight between faraway ships work out? Imagine that the distance between them is small, say 5km or less, but their distance from the origin is rather large - 10,000km for example. Could those still play out according to standard rules?
: Re: Shrugger! Unity!
: NichG June 09, 2014, 08:48:07 PM
That's reasonable for general ship movements and sensor raycasts, but how would a gunfight between faraway ships work out? Imagine that the distance between them is small, say 5km or less, but their distance from the origin is rather large - 10,000km for example. Could those still play out according to standard rules?

I believe this would put them all in the same zone, so they'd be using the fine-grained physics. Essentially you'd use coordinates local to the zone, so the largest coordinate value you'd have to deal with would be 5km, not 10000km.

You'd basically then use the distance between the center of the zone and the origin in the coarse-grained coordinates to determine things like the effects of gravity. Essentially, the math would look something like this:

r_z: coordinate of zone center with respect to the origin in the coarse coordinates
r_i: coordinate of object 'i' with respect to the zone center in the fine coordinates

The fully correct calculation for the acceleration due to gravity on object 'i' would be:

a_i = -GM (r_z + r_i)/|r_z+r_i|^3

However, r_z is much larger than r_i, so we may be able to separate this into two contributions (one coarse-scale, one fine-scale). To do that, lets use an accelerating frame for the zone - that means that the zone itself is accelerating:

a_z = -GM r_z/|r_z|^3

So we'll subtract that acceleration out, meaning that now we're left with:

a_i = -GM [ (r_z + r_i)/|r_z + r_i|^3 - r_z/|r_z|^3 ]

Basically the next gimmick is to approximate this with a Taylor expansion and keep only terms of up to order r_i/r_z. It turns out this gives you:

a_i ~= -GM [ r_i/|r_z|^3 - 3 r_i dot r_z / |r_z|^4 ]

So you might try running a simulation using that kind of rule and having the zone itself orbit, and see whether the results look good to you or not.
: Re: Shrugger! Unity!
: Shrugging Khan June 10, 2014, 03:56:25 AM
Fascinating idea, the more I think about it...but I'm seeing one problem (either with the concept, or more likely with my understanding of it):

I thought the zones were meant to be Axis-Aligned Bounding boxes covering the entire playing field without gaps or overlaps?
How then could they be made to orbit in a circular//elliptic fashion without throwing the whole 3D grid into disarray?
: Re: Shrugger! Unity!
: NichG June 10, 2014, 02:45:23 PM
Well, they're not a grid so much as a coordinate system combined with a bounding box. The bounding box evolves along with the motion of the things in it anyhow, so it naturally 'orbits' as everything inside the zone orbits. The thing that requires more finesse is the evolution of things within the new coordinate system, since its not an inertial frame of reference.

Zones wouldn't cover the entire playing field, just the areas where there are dense clusters of objects.

Think of it sort of like this. The exterior coordinate of an object within the zone would be 'r_e'. The interior coordinate is 'r_i = r_e - r_z'.

Now, lets say you have some evolution of the coordinate system, e.g. dr_z/dt != 0 and more importantly d^2 r_z / dt^2 != 0. You need to take this into account in the evolution equation for r_i, so that dr_e/dt and d^2r_e/dt^2 are their true values. That is what modifies the gravitational force in the calculation I did above - taking that motion into account.

What might be nice is to actually properly take into account the fact that orbiting looks like rotation, so not only do you change r_z but you change the effective x,y,z axes as the thing orbits. That makes the math much messier, so I avoided it, but I suspect it would increase the separation between the coarse-grained coordinate system and the fine-grained coordinate system, so it might reduce the errors further at the cost of a lot of messy math.
: Re: Shrugger! Unity!
: Shrugging Khan June 29, 2014, 08:52:45 AM
No progress on the orbits or the long-distance coordinate system, but some other small fry:



-------------------------

Alright, so much for the good news.
We've also hit a pretty big snag with the resource system. Resources have various pointers to to non-monobehaviour objects representing the materials they're made of, the things they can be used for and so on. So when transferring resources or equipment from one place to another, we'd need to make a deep copy, creating new instances of those material or equipment ability objects.

Gents, what's a good way to do deep copying in C#?
Do we need to copy every field by hand, should we tinker with serialisation? Is slapping [System.Serializable] on every class a bad idea? What other ways are there?
: Re: Shrugger! Unity!
: Draco18s June 29, 2014, 09:10:48 AM
There...is not a good way to do that.

You can try writing the object to a byte array and reading it back out again, but there's no guarantee that that will work (copying everything in the manner you desire).

It'd be better to just write your own clone method for each object.
: Re: Shrugger! Unity!
: keith.lamothe June 29, 2014, 12:19:45 PM
Sounds like awesome progress :)

We've also hit a pretty big snag with the resource system. Resources have various pointers to to non-monobehaviour objects representing the materials they're made of, the things they can be used for and so on. So when transferring resources or equipment from one place to another, we'd need to make a deep copy, creating new instances of those material or equipment ability objects.
First question: why, exactly, do you need to create a copy rather than simply disassociate the object(s) from their previous owner/container/whatever and re-associate them with the next one?


Gents, what's a good way to do deep copying in C#?
There are good ways, actually, but no ways that are good and easy and quick.

What precisely are you trying to do? 

If you're saving to disk and loading from disk (or sending across a network and then re-creating from the network on the other side, which is remarkably similar to the disk save/load case) then I'd suggest writing it all out as a sequence of characters (I'm happy to provide more specific advice on how and how not to do that, and implementation examples).

If you're creating a copy in memory to be used by the same process, without any trips to or from the disk or network, then you'll basically want to write your own deep-copy method for each class.  Which is fairly straightforward (except for cyclical cases, but those can be handled with moderate care).  You don't want to write it all out as characters and then read it back in in this case.  That actually works just fine, but it's horrendously worse CPU wise (which hasn't stopped me from using it in some limited cases, but certainly not for a whole data model).

None of the "automatic" ways, like the serializable flag, are something I'd advise for a complex data model.
: Re: Shrugger! Unity!
: Shrugging Khan September 21, 2014, 01:51:08 PM
So, while the spaceship project doesn't see much progress lately (because all the problems and features that are next in line to be worked on require *concentration*, which is in short supply during exam season), I've off-handedly made a little terrain generator. It just generates a semi-reasonable heightmap, does some erosion on it, then generates some meshes to display it, and finally adds some simple structures (houses, bridges, ziggurats) made from primitives for flavour. No big deal.

Now, some of you might remember one or two discussions within this thread on the subject of moving the coordinate system's origin to the main camera's position - while the spaceship game doesn't have such a system yet (because the AI can't handle it yet), this little terrain generator does have it, generating new terrain as the camera moves on and destroying the meshes it leaves behind - the geographic data on which the terrain was based is still stored though, so it can be faithfully recreated when revisiting previously deconstructed areas.

Works decently well, if I may say so. But the obvious problem comes when, after wandering around for a while, a whole lot of unused terrain accumulates in RAM. So I'd like to just dump chunks of that onto the hard drive, if there's a decently simple way of doing it. There's some smart guys who've written serialize-it-all plugins for Unity - available free of charge - but I'd rather cook up something of my own. Problem is, I've never done it before.

Any good ideas?
: Re: Shrugger! Unity!
: Hearteater September 21, 2014, 03:44:19 PM
I'm not sure if your issue is doing it in Unity, or doing it in general. Below is some code for testing whether the serialization of a custom generic collection class is working. The collection class itself is [Serializable] and implement ISerializable along with IDictionary. I have a constructor that takes "(SerializationInfo info, StreamingContext context)" which builds a new collection from the incoming stream. The TestClass is just [Serializable]. Really it's that simple. Ignore the xml extension, this serialization is binary (controlled by the formatter). I switched from XML to binary at some point apparently. There is a lot more you can do, this is just basic serialization (for the TestClass) and custom serialization (for the collection), using the BinaryFormatter which is part of C#. XML serialization is a touch different. Really, googling c# serialization gives you a lot of really useful info.

Variable c below is an instance of the collection in question.

:
            /*
             * Optional testing of ISerializable interface
             */
            if (c.GetType().IsSerializable)
            {
                Console.WriteLine("\n--- ISerializable ---");
                IDictionary<int, TestClass> c2;
                BinaryFormatter formatter = new BinaryFormatter();

                for (int id = 0; id <= range + 1; id += 10) c.Add(id, new TestClass(id));

                //Serialize
                using (FileStream fs = new FileStream("CollectionTest_ISerializable.xml", FileMode.Create))
                {
                    formatter.Serialize(fs, c);
                }

                //Deserialize
                using (FileStream fs = new FileStream("CollectionTest_ISerializable.xml", FileMode.Open))
                {
                    c2 = (IDictionary<int, TestClass>)formatter.Deserialize(fs);
                }
                File.Delete("CollectionTest_ISerializable.xml");

                Console.WriteLine("  Count comparison: {0}", c.Count == c2.Count ? "Ok" : "Failed");
                Console.Write("  Item comparison: ");
                result = true;
                foreach (KeyValuePair<int, TestClass> item in c)
                    if (!c2.ContainsKey(item.Key)) { result = false; break; }
                Console.WriteLine(result ? "Ok" : "Failed");
            }
: Re: Shrugger! Unity!
: Draco18s September 21, 2014, 04:02:48 PM
Serialization followed by FileIO.

Write the data to the file in any format you care to (raw XML, compressed XML, binary data, whatever floats your boat), the computer doesn't give two shits what the data is or what file extension you give it.
: Re: Shrugger! Unity!
: keith.lamothe September 21, 2014, 07:08:34 PM
We did the "huge world, at most X (1 per player) in RAM at once" thing with AVWW.  Well, sometimes more than X because the server could hold onto a chunk for a bit after it was empty in case it was re-entered very quickly, but not significantly more than X.

Basically each chunk got its own file on the server.  It was never stored on disk on the clients (outside the pagefile, anyhow, but that's outside our concern).

As for the actual serialization, as with other things we did our own custom string-based serialization.  Writing a series of primitive values (where everything non-primitive is expressed in terms of its own series of primitives) has continued to be the simplest and most efficient (in dev terms, at least) way for us.
: Re: Shrugger! Unity!
: Shrugging Khan December 18, 2014, 09:47:15 AM
I've spent the last two or three months sluggishly working on my UI. And then came Unity and released their latest Update, with free UI components for everyone. Well, crap!

My code is nowhere near operational, so it seems that by just picking up the new Unity UI goodies, I can take a major shortcut. The new Unity UI seems to have pretty much anything that's necessary, apart from some gimmicks I was working on (3D UI elements, mostly). Unsurprisingly, it's also way prettier.

So I'm wondering right now - Should I put some more weeks to months into getting my UI to work, or just grab the Unity stuff and run with that?

What do youse think?
: Re: Shrugger! Unity!
: keith.lamothe December 18, 2014, 09:57:21 AM
You can probably guess my approach: tell them to get their newfangled black-box-components off my lawn and make my own stupid GUI ;)

Mainly because in my experience I inevitably, inevitably, wind up having to make my own anyway because the provided ones don't allow sufficient flexibility, or have weird bugs, or some combination thereof.

On the other hand, there's a lot to be said for rapid prototyping and getting to a playable game without spending unnecessary amounts of time on the incidentalia like exactly how the interface is implemented.  That probably means having to go back and overhaul the UI later, but it can be a worthwhile tradeoff.

So on balance I'd suggest keeping your UI stuff in a safe place so you can get back to it later, but then spend a day or two trying to get your game working with the provided components and see if it really is a shortcut.  If it takes longer than that then you may be better off just forging ahead with the PanzerUI or whatever you'd call such a thing ;)
: Re: Shrugger! Unity!
: Draco18s December 18, 2014, 10:13:02 AM
The GUI tools for 4.6 are massively improved from what I hear.
: Re: Shrugger! Unity!
: Shrugging Khan December 19, 2014, 04:53:56 AM
Well, now it is called the PanzerUI alright  :D

When I first touched the Unity UI stuff, I dropped it again because it wasn't obvious to me which components I would have to generate to get it running (since I do everything from code, refusing to go through the editor). But I guess I'll be doing some science after all, and see how quickly I can get it to work.

Thanks for your advice, gents!
: Re: Shrugger! Unity!
: Shrugging Khan December 28, 2014, 08:17:01 AM
So I told them to get their newfangled black-box-components off my lawn and made my own stupid GUI. PUI. It is called the Panzer User Interface now.

Not pretty, not optimal, and using quite a few workarounds. But it works! Displays text and simple rectangular shapes, reacts to clicks, activates, deactivates, hides, unhides, destroys and constructs nicely, all without being much of a performance drain. Key combos also work now, with any combination of Shift, Alt and Control and any key being detected correctly.

Still needs drag'n'drop, mouseover, text entry, grouping and other more or less important features, but the basic UI is functional.
I'll also have to learn a few things about working with text and making procedural textures, so I can stop using Unity's 2D-only GUIText class and slap my strings straight onto the UI's 3D meshes.

Anyways, things are finally ready for interactivity. May the user input and data output commence!  :D
: Re: Shrugger! Unity!
: keith.lamothe December 28, 2014, 10:29:25 AM
Congratulations!  May your UI flatten the enemy ;)
: Re: Shrugger! Unity!
: Shrugging Khan January 27, 2015, 04:45:43 AM
Quick'un: How much of a performance-hog are things like Mathf.Log10 / System.Math.Log10?

As per the usual, I'm pretty bad at maths, so I can't really judge it.

Oh, and for when I'm just trying to figure out how many digits a number has - is there a faster way?
: Re: Shrugger! Unity!
: Draco18s January 27, 2015, 09:14:17 AM
Oh, and for when I'm just trying to figure out how many digits a number has - is there a faster way?

Couple of options I see, if you're only interested in the whole number value (ie. 900 -> 3)

1) For-loop that divides by 10 and checks for > 1 and a counter.
2) Convert to a string and check for string length.
: Re: Shrugger! Unity!
: keith.lamothe January 27, 2015, 09:52:05 AM
Quick'un: How much of a performance-hog are things like Mathf.Log10 / System.Math.Log10?
I didn't know a number (before the later experiment, at least), but a few thoughts:


1) Off the cuff, raising x to y where y is not an integer is simply bound to be painful cpu-wise.  And taking the log of an arbitrary number is likely to involve something similar: i.e. no simple conversion to multiplication or division.


2) If all you want is the number of digits (of an integer, or the integer part of a real number, right?  Not talking places after the decimal?), realize that Log10 is doing a lot more work than telling you that (note that its result is a floating point value).  Doing more work = taking more time.  Generally, at least.  So it's a matter of asking "how do I answer only the question I'm actually asking?"  In which case the for-loop-dividing-by-10 that Draco18s suggested is pretty much your go-to method.  I wouldn't suggest the ToString() method as that involves heap allocation and, again, doing a lot more work than is actually necessary.


3) On the other hand, depending on how often you're doing this, it may not matter _at all_ how inefficient you make this particular computation.  Is it just for, say, 20 numbers on the GUI, once per frame?  Probably not going to notice the difference, and it's not going to get worse in more-intense gamestates (a key point).  But if it's multiple times per ship per frame and there could be thousands of ships in the more-intense gamestates, then some attention may be worthwhile.


4) If you really want to know the answer to "how fast is method XYZ" one of the best ways is simply to measure it yourself, by putting something like this in your program's startup code:

:
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        int iterations = 100000000;
        stopwatch.Start();
        for ( int i = 0; i < iterations; i++ )
            Mathf.Log10( i );
        stopwatch.Stop();
        Debug.Log( "stopwatch reported " + stopwatch.ElapsedMilliseconds + "ms for " + iterations + " iterations, average of " +
            ( (float)stopwatch.ElapsedMilliseconds / (float)iterations ) + "ms per iteration" );

In my case, the result was:

stopwatch reported 4932ms for 100000000 iterations, average of 4.932E-05ms per iteration

Of course, if your compiler is feeling cheeky it may simply optimize out those Log10 calls since the result is not used.  So I tried an alternate version:

:
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        int iterations = 100000000;
        double dummyResult = 0;
        stopwatch.Start();
        for ( int i = 0; i < iterations; i++ )
        {
            float thisResult = Mathf.Log10( i );
            dummyResult += thisResult;
        }
        stopwatch.Stop();
        Debug.Log( "stopwatch reported " + stopwatch.ElapsedMilliseconds + "ms for " + iterations + " iterations, average of " +
            ( (float)stopwatch.ElapsedMilliseconds / (float)iterations ) + "ms per iteration (dummyResult=" + dummyResult + ")" );

Which should force the computation of Log10 since the compiler can't say "well, he doesn't really need to see that value in the console log".

And that gave:

stopwatch reported 5426ms for 100000000 iterations, average of 5.426E-05ms per iteration (dummyResult=-Infinity)

So the first result looks pretty accurate for the cost of the actual Log10 call (the cost went up from 4.9 somethings to 5.4 somethings when I added in that += nonsense).  Unless it was feeling really cheeky and put something in like "if it's infinity, then we don't need thisResult for this iteration, which means we don't need the Log10 call from here on out", but I think that's kind of unlikely.

So 0.00004932ms, or 0.04932 microseconds, or 49.32 nanoseconds per call.  50ns is a fairly good chunk for a single mathematical operation.  Even Sqrt, which is semi-mythical in how long it can take, only came up as about 20ns per call in a similar test on my machine.  That said, it's all a question of how many calls we're talking.

I also tried a version that made sure the parameter to Log10 was a non-integer (by replacing it with "(float)i + ( (float)i * 0.001f )") but the result was very similar.  Just checking to see if maybe Log10 was using a more efficient branch for integer cases.

Amusingly, however, I found that the for-loop-dividing-by-10 situation took 90ns per iteration on float inputs, and 56ns on int inputs (fdiv being much worse than div on an ALU level).

So it actually looks like Log10 isn't bad here :)


So to sum up:
- Ask yourself: "does it matter?"
- If it matters, then don't guess.  Measure.
: Re: Shrugger! Unity!
: Draco18s January 27, 2015, 11:03:15 AM
- If it matters, then don't guess.  Measure.

I was going to mention as such, then forgot.
(Speaking of x^y math, somewhere I had a version that was very fast as it only handled integer values).
Ah, thanks Google.

:
int ipow(int base, int exp)
{
    int result = 1;
    while (exp)
    {
        if (exp & 1)
            result *= base;
        exp >>= 1;
        base *= base;
    }

    return result;
}

It basically takes a shortcut due to a mathemagic.

:
x^15 = (x^7)*(x^7)*x
x^7 = (x^3)*(x^3)*x
x^3 = x*x*x

Basically, as long as the exponent is greater than 1 you can square the input and divide the exponent by 2.
: Re: Shrugger! Unity!
: Shrugging Khan January 27, 2015, 11:23:36 AM
Some additional info: I generally do need it to return valid results for values < 1, with a round integer return sufficing in most cases. It'll be called between maybe 30 and 300 time per frame, depending on which UI elements are being shown...at least that goes for that particular application.

- Ask yourself: "does it matter?"
- If it matters, then don't guess.  Measure.

I'll remember that one  :D
I already built a little profiler-esque thingy, and although it's a bit primitive right now, I guess I could improve it to the point where it'll be usable for answering such questions.

And thanks for all the other info, too!

mathemagic
I actually didn't get that. At all  :o
: Re: Shrugger! Unity!
: keith.lamothe January 27, 2015, 11:34:45 AM
Some additional info: I generally do need it to return valid results for values < 1, with a round integer return sufficing in most cases. It'll be called between maybe 30 and 300 time per frame, depending on which UI elements are being shown...at least that goes for that particular application.
Ok, so something like a max of 30,000ns, or 30 microseconds per frame.  100 microseconds would be a tenth of a millisecond (and you want your frames to take no more than 16ms if you're going for 60fps).  Not something to worry about speed on in this case, I'd say.

If you need it to work for places past the decimal too, then I'd say just use the ToString().Length approach since 300 small heap allocs per frame isn't a big deal.

But more to the point: why do you actually need to count the digits?  Are you computing the visual size of the number on the GUI, or are you checking whether it should switch to (value/1000)kilowhatevers or (value/1000000)megawhatevers, or what?  Depending on the actual use case there are often performance tricks you can do that have nothing to do with the actual work itself (and thus no make thog do math).  Not that there's really any point in optimizing this in this case, but just for kicks.
: Re: Shrugger! Unity!
: Draco18s January 27, 2015, 12:13:51 PM
mathemagic
I actually didn't get that. At all  :o

Basically:

Math.pow(x, 4) == Math.pow(x, 2) * Math.pow(x, 2)  == Math.pow(x*x, (4/2))

And because several multiplications are faster than Math.pow (and the bitwise divide by 2 even faster) it's a shortcut to just reduce the processor load.

x^8 // == x*x*x*x*x*x*x*x
Becomes:
x *= x //x^8 == (x*x)^4
x *= x //(x*x)^4 == ((x*x)*(x*x))^2
x *= x //((x*x)*(x*x))*((x*x)*(x*x))

But in loop form
: Re: Shrugger! Unity!
: keith.lamothe January 27, 2015, 12:31:10 PM
Velociraptor math: tear problem into pieces, consume individually (but rapidly).
: Re: Shrugger! Unity!
: Shrugging Khan January 27, 2015, 12:56:42 PM
Are you computing the visual size of the number on the GUI, or are you checking whether it should switch to (value/1000)kilowhatevers or (value/1000000)megawhatevers, or what?  Depending on the actual use case there are often performance tricks you can do that have nothing to do with the actual work itself (and thus no make thog do math).  Not that there's really any point in optimizing this in this case, but just for kicks.
I'm actually doing both; Getting the optimal SI unit and rounding the value to as many digits as there is space left in the UI.
So please do tell Thog about ways to rig it up with rocks and tree trunks, he's not good at math.

Velociraptor math
Gah...why don't Math.Log and so on do this already? It seems like a straight-up improvement to have that as an option in there!
: Re: Shrugger! Unity!
: Draco18s January 27, 2015, 01:18:18 PM
Velociraptor math
Gah...why don't Math.Log and so on do this already? It seems like a straight-up improvement to have that as an option in there!

Because it doesn't work for floating point exponents.  x^0.5 is square root, and so on.

A few plots (http://www.wolframalpha.com/input/?i=graph+x^0.5%2C+x^1%2C+x^1.5%2C+x^2%2C+x^2.5+from+-2+to+2).
: Re: Shrugger! Unity!
: keith.lamothe January 27, 2015, 01:32:55 PM
Getting the optimal SI unit
That's probably simpler than all this: presumably there's a relatively small set of possible SI scales you're going for, probably 1/K/M/G for a lot of things.  Are you often wanting to display more than 3 digits "under" the decimal place, on an in-units-of-one number?

Anyway, if all you're trying to do in a particular case is testing for 1/K/M/G then just: if ( amount >= 1000000000 ) then G, else if ( amount >= 1000000 ) then M, else if ( amount >= 1000) then K.


and rounding the value to as many digits as there is space left in the UI.
From a usability standpoint, do you want it to display more than a certain number of digits? 

One of the things that really threw people about the numbers in TLF was how many of them were only significant in units of 1 (or higher) but it would show two or more places past the decimal due to generic handling of the prediction/result display logic (there is a ridiculous amount of stuff to predict and resolve in that game, so a generic framework was necessary).

One of the most popular changes I've ever made to AI War was dividing all the HP and attack (and a few other) figures by 1000.

Overall my point is that the question of "how many figures do I show?" is not "how many will fit?" but "how many does the player want?".  And once you know that then it's probably more a matter of designing your GUI to provide the necessary space on the minimum supported resolution and just go with that (plus whatever left/right/center alignment is necessary to make it look right at smaller values) rather than measuring it every frame.


So please do tell Thog about ways to rig it up with rocks and tree trunks, he's not good at math.
If problem hard, make it a different problem until rocks and tree trunks work.


Gah...why don't Math.Log and so on do this already? It seems like a straight-up improvement to have that as an option in there!
The general answer to that sort of question with generic libraries is this: because they're generic libraries, they cannot make very many assumptions about what's actually expected of them.  That limits the crazy unshielded-12-foot-diameter-buzzsaw optimizations they can pull without breaking spec on some subset of allowed inputs.

So if you call Math.Pow(double,double), expect it to treat the inputs as doubles and not to try int-specific optimizations on it.  Even with ints it has to consider overflow/underflow problems with bitshifting operations.  I'm not sure if those are problems that could actually be encountered in the case of Draco18s's approach above, but there's probably at least some edge cases that could bite it.  A few erroneous edge cases like that in your own code isn't a big deal.  A few erroneous edge cases like that in a core math function in .NET or Mono makes people flip the fleep out.

Yet another reason to write stuff yourself if you really care about how well they do their job :)  Though that has its own host of potential problems, of course.
: Re: Shrugger! Unity!
: Shrugging Khan January 27, 2015, 01:52:23 PM
Getting the best SI unit is a bit more complicated than that, since there's square and cubic units as well, and the length differences between their steps are rather large.
*Sigh*...I guess I should stop trying to get the perfect result and just settle for something readable that works.

One of the most popular changes I've ever made to AI War was dividing all the HP and attack (and a few other) figures by 1000.
Yeah, I'm quite the fan of that change. There's still plenty of big numbers in the game, after all  :P

It's not feasible in my case though, and it's likely not a problem either. Since I'm trying to teach myself physics while I'm at it, I'm really just using somewhat realistic physical values for everything. So no damage values, hitpoints and fixed speeds - it's all mass, volume, energy density, acceleration and so on. Some of those are very small, some are very large, and I generally just want to write some code that ensure they're always displayed in reasonably readable units and roundings.

Yet another reason to write stuff yourself if you really care about how well they do their job :)  Though that has its own host of potential problems, of course.
Mostly just that it takes me months to get anything done  :D

Because it doesn't work for floating point exponents.  x^0.5 is square root, and so on.
Guess we can't have everything  ::)
: Re: Shrugger! Unity!
: keith.lamothe January 27, 2015, 02:05:06 PM
It's not feasible in my case though, and it's likely not a problem either. Since I'm trying to teach myself physics while I'm at it, I'm really just using somewhat realistic physical values for everything. So no damage values, hitpoints and fixed speeds - it's all mass, volume, energy density, acceleration and so on. Some of those are very small, some are very large, and I generally just want to write some code that ensure they're always displayed in reasonably readable units and roundings.
Ah, ok, I get it.  Basically this is developer information.  Unless the target audience is people who enjoy playing games that present them with numbers on the *10^11 scale and numbers on the *10^-11 scale at the same time ;)

In that case, yea: don't try to make it nice, make it work.  Then when you're sure what you want to show, make it nice.
: Re: Shrugger! Unity!
: Shrugging Khan April 04, 2015, 02:11:12 PM
Once more unto the breach, dear friends, once more!

I'm completely re-doing my procedural terrain generator. Yay for wanton destruction and reconstruction!

Right now I'm considering two options, both on a Model-View basis. For now, assume that I'm doing nothing but a heightmap.

1) A set of many data points describing elevation as model, with the view picking a subset of those and building a mesh around those picks by treating them as vertices. The problem here is that I haven't been able to cook up an algorithm that produces a usable, gap-less mesh of triangles. So far I have gaps, overlaps, crossing edges and similar troubles...

2) A set of few data points describing landscape features (hill here, lake there), with the view picking random coordinates and guessing the elevation by interpolating between the nearest data points. This has the advantage that the view can just slap down triangles in any way it likes, and get the relevant elevation data for the vertices wherever they may fall. Downside: I haven't figured out how I'm going to do this one, at all.

Any advice on how to do either or which to pick, or recommendations in general, are appreciated as always  :)
: Re: Shrugger! Unity!
: Shrugging Khan May 01, 2015, 08:46:03 AM
Doing further work on procedural terrain; I was wondering how I could calculate how much lower terrain that's further out would have to be in order to account for the planet's curvature. As always, I cannot work out the math. Any help?  :o
: Re: Shrugger! Unity!
: keith.lamothe May 01, 2015, 09:57:50 AM
Spherical terrain... ouch.

I'm not sure what the "right" answer is, but have you gotten to the point where you can generate a perfectly spherical (or near enough) ball of rock?  That seems like a good first step.  Then if you wanted you could deform it from there, and as long as each step was valid the result would be valid.
: Re: Shrugger! Unity!
: Shrugging Khan May 01, 2015, 11:24:41 AM
I've cobbled (i.e.: googled) together a temporary solution based on Pythagoras' funky right angles. It won't work for the whole planet, but it's fine for anything from the POV to the horizon and a little way further around the globe. So it won't result in a complete sphere, but it will curve things nicely for that visual effect. It essentially just drops the vertical level of the terrain based on the planet's radius and the distance to the POV.

For viewing the planet from space, I think I will indeed take a sphere and just deform it a bit to suit the terrain data.

Sooner or later, probably once I include planet-to-space transitions, I'll have to actually generate proper terrain spheres. My model-side terrain data is based on longitude and latitude rather than actual 3D positions - I thought it would be easier to work with that way - so maybe I can just generate proper 3D positions based on that. Half the necessary logic for procedural mesh generation is already in place, but the actual math for calculating positions (something I did some months ago in a physics course and already forgot about...damn my memory) and the logic for sewing together the last unconnected triangles still needs figuring out.

And yes, I have once again completely forgotten why I am doing all this. But I know I must do it.
: Re: Shrugger! Unity!
: keith.lamothe May 01, 2015, 11:37:19 AM
Yea, I think you're out of my depth on the math if you're converting 3D coordinates to/from lat-long.

To generate a basic spherical mesh my first try would be to generate a series of circles with their origin moving along one of the axes of the planet, sample N points per circle and make those vertices for the planet's surface and connect them to the previous and next circle's points.

For the "mostly flat plane" approximation of a relatively small area, if it's earthlike you could try a drop of 8 inches per mile.
: Re: Shrugger! Unity!
: Shrugging Khan June 27, 2015, 05:34:14 AM
Yet another geometry/physics question!

When I have an object comprising multiple parts, and it moves and spins, and one of them separates - how do I calculate the velocity and angular velocity of the now separate object?

Thanks for any hints :)
: Re: Shrugger! Unity!
: keith.lamothe June 27, 2015, 10:52:43 AM
When I have an object comprising multiple parts, and it moves and spins, and one of them separates - how do I calculate the velocity and angular velocity of the now separate object?
Oof. No idea in terms of the actual formulae. But here's what I'd do for a first try:

1) set velocity.magnitude and velocity.direction to the same values as the former parent object. They'll probably diverge quickly, with the former parent continuing to spin.

2) set spin.magnitude and spin.direction to... to... how do we figure out if it's perpendicular or parallel to the former parent spin and what do we do if it's somewhere inbetween... oh just forget about it and set them to zero ;) Or to low random values to simulate them "tumbling" away.
: Re: Shrugger! Unity!
: Shrugging Khan June 27, 2015, 11:22:15 AM
Oh just forget about it and set them to zero. Or to low random values.
That's the best advice I've ever recieved  :D
It's also how I'm placeholdering it until I figure it out. I know I've learned this stuff in my physics course last semester, but I don't remember how it's done and my notes are in another town.

Well, it's not all that important, I guess...until I have to build a catapult, at least.
: Re: Shrugger! Unity!
: keith.lamothe June 27, 2015, 11:25:35 AM
Well, it's not all that important, I guess...until I have to build a catapult, at least.
Oh, simulating a Space Trebuchet is easy.

Just give it a 100% chance of failing catastrophically.
: Re: Shrugger! Unity!
: Shrugging Khan June 27, 2015, 11:30:43 AM
Heh. I'm currently making good progress on my physical object management system (POMS!), which will allow me to have space AND planets! With gravity! It just took me a few months to figure out how to convert Cartesian to polar coordinates to orbital elements and vice versa. Now I just have to manage some floating origins, ignore relativity, trick unity into doing my bidding and add some actual content...

...actually an older version of my space game already had space trebuchets. They might have been based on linear magnetic acceleration. The AI also had a 100% chance of utilising them incorrectly  :P
: Re: Shrugger! Unity!
: Draco18s June 27, 2015, 01:46:26 PM
As for the broken part's velocity:

http://www.dummies.com/how-to/content/calculating-tangential-velocity-on-a-curve.html

Figure out the magnitude and direction as if the parent object wasn't moving (just spinning) then add the result to the parent object's non-spin velocity.

Then yeah, add some random spin for tumble, will be close enough.
: Re: Shrugger! Unity!
: kasnavada June 29, 2015, 03:30:51 AM
If I understand well, if "object 1" is the base object, object 2 being the one separated... I'd consider the center of gravity of "object 2" as being a "point" on a circle centered on the center of gravity of "object 1" (and make both shapes irrelevant). Then this model applies:

https://en.wikipedia.org/wiki/Circular_motion
: Re: Shrugger! Unity!
: Shrugging Khan June 29, 2015, 04:22:26 AM
Thanks for the links, gents. I'm just horrible with Math, so it'll take me some time to figure out how it all works for 3D (all examples I can find are 2D only).

Unrelated: I'm currently encountering some potential performance problems with the POMS!. Since an object will recalculate its mass, center of mass and other stats when a subobject is attached or removed from it, and all objects are attached to the planet in one way or another, the planet has to iterate through every object there is every time something gets chopped off of or welded to something. I was hoping my POMS! would be able to work without exceptions, but this one has me stumped a bit. I suppose this would've been a problem for any sufficiently complex object...maybe some sort of bucketing is in order. Does anyone know a good algorithm to determine what the ideal bucket size is? I know one has been mentioned in a lecture, but that was a fair while ago...   :-\
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 08:16:04 AM
Does anyone here know their Lambda expressions?
I'm getting NullRef Exceptions at the following line:

:
List<TLO> tlos = abstractablesThisTurn.Select(item => item.objekt as TLO).Where(item => item.GetType() == typeof(TLO)).ToList();Where abstractablesThisTurn is a List<Abstractitem>, AbstractItem.objekt being the interface Abstractable, and TLO implementing said interface.

The error reads as following:
:
POMS.AbstractionHandler.<Update>m__17 (POMS.TLO item) (at Assets/SKRIPTE/Physical Objects/Physical Object Management System/AbstractionHandler.cs:152)
System.Linq.Enumerable+<CreateWhereIterator>c__Iterator1D`1[POMS.TLO].MoveNext ()
System.Collections.Generic.List`1[POMS.TLO].AddEnumerable (IEnumerable`1 enumerable) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:128)
System.Collections.Generic.List`1[POMS.TLO]..ctor (IEnumerable`1 collection) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:65)
System.Linq.Enumerable.ToList[TLO] (IEnumerable`1 source)

Now, this won't be a hassle to rewrite without Lambda trappings, but they're just so damn elegant when they do work.
So if anyone knows their way around them, please do tell me what I borked here  :)
: Re: Shrugger! Unity!
: keith.lamothe July 28, 2015, 08:51:07 AM
Does anyone here know their Lambda expressions?
Enough to avoid them :) They should be fine in general, but it's an additional layer of indirection where I may or may not understand what the compiler actually does with it. Kind of like the difference between for(int i = 0; i < Length; i++) and foreach; similar semantics but very different performance implications in some circumstances. But with lambdas having much higher potential for that kind of gotcha.

That said, I don't think the nulls here are due to the lambdas. Maybe it's a cast that it can't actually perform at runtime, though that seems odd. Best to just strip away the extra complexities and debug the logic itself, with something like:

:
List<TLO> result = new List<TLO>();
Type tloType = typeof(TLO);
for(int i = 0; i < abstractablesThisTurn.Count; i++)
{
  Abstractable item = abstractablesThisTurn[i];
  if(item == null)
  {
    Debug.Log("see the violence inherent in the system!");
    continue;
  }

  if(item.GetType() != tloType)
    continue;

  TLO itemAsType = (TLO)item;
  if(itemAsType == null)
  {
    Debug.Log("bwuh?");
    continue;
  }
  result.Add(itemAsType);
}

And if that works, then investigate the lambda-specific parts.
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 09:44:34 AM
There's a performance difference between for and foreach!? D:
*googles*
: http://www.dotnetperls.com/for-foreach
The for-loop is faster than the foreach-loop if the array must only be accessed once per iteration.
Alright, so nothing unexped!

So back to the Lamdbas: I guess you're right, in that I shouldn't try to optimise. Especially when all I stand to gain is concise code. I suspect I sometimes mistake concise code for fast code, to be honest.

Having switched to Non-Lambda, it works. Once again readability saves the day. So thanks for reminding me of that  :P
: Re: Shrugger! Unity!
: keith.lamothe July 28, 2015, 10:04:55 AM
There's a performance difference between for and foreach!? D:
*googles*
: http://www.dotnetperls.com/for-foreach
The for-loop is faster than the foreach-loop if the array must only be accessed once per iteration.
Alright, so nothing unexped!
I didn't mean that at all. That kind of overhead is fine.

What I mean is that entering a foreach involves allocating an iterator object, at least in mono. And if you have a heavily nested section that involves a foreach, such that the section can get hit thousands of time per frame, and you're going for 60fps, you're going to pile up an awful lot of temporary allocation. That's not a semantic problem, but it can lead to frequent garbage collection, which can be quite a bane. We ran into it in a serious way when porting AIW to unity, because the GC was happening so often it was chopping the music playback to pieces, nor was it great for general responsiveness.

When we converted some of the most frequently hit foreach's to for's, that problem mostly went away. There are other things like List<T>.Contains() where T is a value-type that cause similar problems, or anonymous delegates that involve local parameters from the calling scope, but step one was "stop using foreach" :)


So back to the Lamdbas: I guess you're right, in that I shouldn't try to optimise. Especially when all I stand to gain is concise code.
I think the optimization is fine, as long as you understand (and are willing to accept) what it's actually doing. And remember that the biggest optimization is from "not working" to "working".

Are you sure the problem was actually in the lambda, or was the list being iterated containing some nulls or whatever?
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 10:28:48 AM
the biggest optimization is from "not working" to "working".
I have to pin that to my bathroom mirror or something. It really should have stuck by now, but I keep wasting time on everything but that.

Well, the new code is simply
:
List<TLO> tlos = new List<TLO>();
foreach (AbstractItem ai in abstractItemsThisTurn) {
Abstractable a = ai.objekt;
if (a.GetType() == typeof(TLO)) {
tlos.Add((TLO) a);
}
}
And it runs fine. I really don't know what to blame if not the Lambda thingy.

When we converted some of the most frequently hit foreach's to for's, that problem mostly went away. There are other things like List<T>.Contains() where T is a value-type that cause similar problems, or anonymous delegates that involve local parameters from the calling scope, but step one was "stop using foreach" :)
Gah, GC! That, and memory leaks, is things that I really try to pay attention to, but without really knowing what I'm doing...sometimes I wish I were using C++, where everything is a huge hassle but at least I know roughly what's happening to memory :P

: Re: Shrugger! Unity!
: keith.lamothe July 28, 2015, 10:36:45 AM
Memory in C# isn't all that mysterious, once you know what it's doing. Though with the higher-level-abstraction stuff like lambdas and LINQ and whatnot it probably gets pretty crazy. I use anonymous delegates a lot (passed into our own functions) but nothing fancier. Even that has unintended consequences, it just saves so much code duplication when doing stuff like "for each building owned by this race that's fully constructed and not shut down, do X".

Conciseness, I can take or leave. Avoiding tons of code-duplication, on the other hand, is really important.
: Re: Shrugger! Unity!
: Draco18s July 28, 2015, 11:48:15 AM
Having recently dived headfirst into contravariance,* I discovered that the .NET version used by Unity (yes, even Unity 5) is .NET 2, so its possible that what you're trying to do is fine....in a newer version of .NET, but not in 2.0

*I wanted to write my own event system where I could make a call like this:

:
... {
    someObject.attachEvent(someFunc);
}

public void someFunc(SomeEventType event) { }

But I couldn't 'cause .NET 2 doesn't support the contravariance required to figure out what Type the attachEvent function's parameter is supposed to have.
: Re: Shrugger! Unity!
: keith.lamothe July 28, 2015, 11:50:20 AM
But .NET 2.0 supports plenty of contrariness! ;)
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 12:47:50 PM
New Issue: I have to handle a large number of objects, each at a specific point in time.

Essentially, every time I'm done handling an object, I estimate when I'll need it again and toss it into some collection with a note saying "take a look at this again at (UnityEngine.Time.time > 418.012)" or somesuch.

But I've no idea what kind of Collection to use. List? SortedList? Some sort of Set? Since this has to handle pretty much every object in the game world, of which there may be many, it has to be as performant as possible - both when inserting new elements, when I get at them again, and when I eventually throw some out. And I have to be able to either cheaply remove and re-add elements, or it has to support changing their assigned date when I reexamine them.

Any ideas?
: Re: Shrugger! Unity!
: keith.lamothe July 28, 2015, 12:55:11 PM
New Issue: I have to handle a large number of objects, each at a specific point in time.

Essentially, every time I'm done handling an object, I estimate when I'll need it again and toss it into some collection with a note saying "take a look at this again at (UnityEngine.Time.time > 418.012)" or somesuch.

But I've no idea what kind of Collection to use. List? SortedList? Some sort of Set?
Try a List, get it working, optimize later if needed.

To clarify, does this collection have to have the items sorted in order of when they next need to be checked?
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 01:15:39 PM
Well, I only have to get a small of number of them per frame, so if they aren't ordered and I have to iterate over all of them to find out the ones with the correct dates, that might be a whole lot of iterating.

But yes, I'm optimising again...gah!  :'(
: Re: Shrugger! Unity!
: keith.lamothe July 28, 2015, 02:57:11 PM
Do all these objects have a spatial location? Does that location ever change between time-of-scheduling and time-they-should-be-processed?
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 03:03:07 PM
Yes they do and...well, it changes on being processed. What are you thinking of? Are we going to weird places now?

I also need a separate system that will function similarly; to be used for the AI. There'll be no spatial locations to use there; How would that change things?
: Re: Shrugger! Unity!
: Draco18s July 28, 2015, 04:23:43 PM
Binary tree.  Done.

Insertion is very fast, and unity has a special IndexOf(...) operator that returns a value indicating where in a sorted array an element would be, if it was already in the array (said function requires the array be sorted and takes advantage of binary-tree search properties).

So as long as the array starts sorted (this is easy, an empty array is sorted) you can rapidly insert new items at the point at which they would normally be.  Then in order to do your scheduling, look at the first element (this one will have the smallest time) and say "is this greater than the current time?" and if so, you're done.

You'll need a wrapper object that holds the [thing your interested in] and the [time to check].  Override Equals() and GetHashCode() and return the values of checkTime.Equals() and checkTime.GetHashCode() for each.
: Re: Shrugger! Unity!
: Shrugging Khan July 28, 2015, 04:41:48 PM
You do make it sound easy  :D

It's a mite late here by now, so I'll be trying it tomorrow. Already have that wrapper from my previous attempts, so expect horrifying results in about 10 hours. Thanks for the tip!

Wait, what exactly are you referring to here?
: Draco
checkTime.Equals() and checkTime.GetHashCode()
: Re: Shrugger! Unity!
: Draco18s July 28, 2015, 08:43:16 PM
http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden
: Re: Shrugger! Unity!
: Shrugging Khan July 29, 2015, 03:14:15 AM
Nonono, I meant *which* .Equals and .GetHashCode. Those of the wrapper?
: Re: Shrugger! Unity!
: Draco18s July 29, 2015, 11:28:47 AM
Nonono, I meant *which* .Equals and .GetHashCode. Those of the wrapper?

Oh, oh yes.  The wrapper should override Equals and GetHashCode.  You will need to implement the IComparable interface as well (although Lists can be sorted without it, it makes it much easier).  Those will make it so your wrapper can be the Key in a HashTable and such, which is important for storing and retrieving stuff from collections. ;)

You could probably pass on Equals and GetHashCode and just implement IComparable for the suggested a binary tree; it was late last night when I wrote that post, so I wasn't thinking straight.
: Re: Shrugger! Unity!
: Shrugging Khan September 12, 2015, 11:22:53 AM
Garbage Collection! Any good advice, resources or things-to-keep-in-mind about it? :)
: Re: Shrugger! Unity!
: keith.lamothe September 12, 2015, 11:34:26 AM
Garbage Collection! Any good advice, resources or things-to-keep-in-mind about it? :)
Frequent GC's cause problems, notably music skipping, making the UI feel rough (mouse jumping around when GC happens mid-motion, etc). Really frequent GC's tank your framerate.

Frequent GC's come from a ton of transient heap allocation, meaning stuff that doesn't go on the stack (generally speaking, anything in a function's parameter list is on the stack, though params[] stuff may get put on the heap sometimes, not sure) that is allocated via new and then goes out of scope quickly after that allocation.

Obviously, the solution isn't simply to hold onto everything you ever allocate, or you'll run out of RAM.

Nor is the solution to put everything on the stack, which is technically difficult to accomplish and leads to lots of bugs because the copy-by-value behavior of structs can be non-intuitive with complex stuff (it's also impossible with recursive data structures).

But it does sometimes mean holding onto allocated space longer than you might otherwise, and sometimes putting stuff on the stack you wouldn't otherwise.

The first things to check for if you're seeing frequent GC's, though, are things like List<T>.Contains() where T is a value type (int, enum, struct, etc), if that happens in a section that's hit a lot it leads to a ton of boxing that thrashes the heap with transient allocation.

That doesn't mean doing a find-all on Contains and just hitting whatever you find, though, but rather running the unity profiler with judicious use of Profiler.BeginSample() and Profiler.EndSample() (we use wrappers around those), and looking at the memory column of the profiler to see what sections are causing the most allocation during your normal frames. Then narrow down the sections with more begin-sample and end-sample (best not to nest them too much, though, to keep overhead down). Generally speaking allocation for idle-state can be kept to zero bytes, or close enough for government work.
: Re: Shrugger! Unity!
: Shrugging Khan September 13, 2015, 04:09:23 PM
Holy what!? The Profiler is now included in the free version!  :o

Thanks for that information, it kinda passed me by so far. I now have a lot of things to do, all at once!
: Re: Shrugger! Unity!
: keith.lamothe September 13, 2015, 05:17:08 PM
Holy what!? The Profiler is now included in the free version!  :o
Is it? I'd forgotten you were on the free version. The profiler is... not nearly as good as ANTS or whatever like we were able to use in .NET itself. But it's better than nothing, once you learn how to use it (and how to not use it).
: Re: Shrugger! Unity!
: Draco18s September 13, 2015, 08:13:13 PM
You on 5?  Pretty much everything is free in 5.  The stuff that isn't is stuff that either takes manpower or cloud resources.
: Re: Shrugger! Unity!
: Shrugging Khan September 14, 2015, 03:54:30 AM
Yeah, we switched to 5 on a "more stuff can't hurt (too much)" basis, but I kinda assumed the profiler was still restricted to pro because...I dunno. Because they'd never give away something that important for free? I considered buying Unity Pro pretty much just for the profiler, a while ago, but I don't have that much money to spend.
I had even written my own pseudo-profiler based on Time.realtimesincestartup comparisons, flawed as that was.

Now I can actually see that our recent spikes in delta-time were caused not just by this-and-that, but even by which method call exactly. This will greatly simplify optimisation - but with great optimisation potential comes an opportunity to waste all my time on that, so better not go overboard...

...also, I still don't understand how to read the Profiler's information on GC. Guess I have some more delving into the Unity Docs to do  :o
: Re: Shrugger! Unity!
: keith.lamothe September 14, 2015, 08:46:56 AM
This will greatly simplify optimisation - but with great optimisation potential comes an opportunity to waste all my time on that, so better not go overboard...
Premature optimization is the root of all evil (or at least most of it) in programming. -Donald Knuth (https://en.wikiquote.org/wiki/Donald_Knuth)

...also, I still don't understand how to read the Profiler's information on GC. Guess I have some more delving into the Unity Docs to do  :o
On the CPU Usage mode (modes are along the left side of the profiler window, on the top part), the bottom grid in my display has the following columns:

Overview (which code section it's talking about)
Total (% CPU for that frame in that section and all subsections under it)
Self (% CPU for that frame in just that section, not including anything in a subsection under it)
Calls (# of times that section was entered during that frame)
GC Alloc (# of bytes allocated on the heap in that section during that frame)
Time ms (# of milliseconds spent in that section during that frame and all subsections under it)
Self ms (# of milliseconds spent in just that section during that frame, not including anything in a subsection under it)

If you don't get all those, try right-clicking one of the column headers you do have, and see if GC Alloc is in the list, and click it.
: Re: Shrugger! Unity!
: Shrugging Khan September 15, 2015, 04:51:46 AM
Alright, we did some good stuff to performance. Turns out the main hog (apart from complicated mathematics. Hello, Orbital Mechanics!) was all the debugging we did, and how it was displayed in the interface. Debugging UI Windows and UI elements in general now update at much more reasonable occasions. Yay. Now, so much for the stuff that was obvious with the profiler.

Is there any way to have it display averages rather than per-frame data?
: Re: Shrugger! Unity!
: keith.lamothe September 15, 2015, 08:52:55 AM
If it just averaged in a generic sense the results would be pretty meaningless. There may be some averaging you can do yourself, by measuring a given section every frame for a few seconds and so on. But why would you want the averages? General speed-up is mostly a matter of seeing what hits it the hardest and chopping it down, rinse, repeat.
: Re: Shrugger! Unity!
: Draco18s September 15, 2015, 12:33:44 PM
Alright, we did some good stuff to performance. Turns out the main hog (apart from complicated mathematics. Hello, Orbital Mechanics!) was all the debugging we did, and how it was displayed in the interface.

Oh yeah.  Debug.Log() is so ridiculously expensive its not even funny.
: Re: Shrugger! Unity!
: keith.lamothe September 15, 2015, 12:46:42 PM
Generally you want any remotely-frequent debugging to not be on by default unless you're specifically hunting something down. We use F3 as the debug mode toggle for most of our common debugging info.
: Re: Shrugger! Unity!
: Shrugging Khan September 16, 2015, 03:32:17 AM
If it just averaged in a generic sense the results would be pretty meaningless. There may be some averaging you can do yourself, by measuring a given section every frame for a few seconds and so on. But why would you want the averages? General speed-up is mostly a matter of seeing what hits it the hardest and chopping it down, rinse, repeat.
I guess that's true.
Imagine some sighing here, please, as I adjust to the reality of not being able to solve all my problems at once  :(

Oh yeah.  Debug.Log() is so ridiculously expensive its not even funny.
Truth! But we threw most of those out a fair while ago and moved every non-critical debug logging to the ingame interface. The problem in this case was some string formatting the homebrew interface did - inserting line breaks into overly-long strings. I haven't yet figured out why that specifically took so long, but it led me to some old and performance-owwie faults in the UI that I managed to fix.

Generally you want any remotely-frequent debugging to not be on by default unless you're specifically hunting something down. We use F3 as the debug mode toggle for most of our common debugging info.
How does that toggle work, if I may ask? Does it disable logging at runtime, or from the editor?
: Re: Shrugger! Unity!
: keith.lamothe September 16, 2015, 08:58:11 AM
The problem in this case was some string formatting the homebrew interface did - inserting line breaks into overly-long strings. I haven't yet figured out why that specifically took so long, but it led me to some old and performance-owwie faults in the UI that I managed to fix.
strings are often a source of unexpected performance problems. Remember that strings are immutable, and that adding a 1-character string onto the end of a 1000-character string results in the allocation of another 1001-character string. Similarly, adding a 1-character ('\n') string into the middle of a 1000-character string does at least creates another 1001-character string, but it may actually also create an intermediate string that's 501 characters long (if you were putting the \n smack in the middle of the old string), depending on how you wrote it.

For situations where you're building a string out of a lot of pieces, StringBuilder is a good just-get-it-done class. If you're doing a _huge_ amount of string building (as we do when serializing data to disk), it's a good idea to write your own buffer class that wrappers a char[] or something like that, and carefully think through the allocations and how to avoid them (for instance, you don't have to use Int32.ToString(), the code for translating an int to a sequence of characters isn't all that complex and doesn't have to involve any heap allocation).

Though I think I've already mentioned the above and you're talking about string formatting, so perhaps there's something else going on that this doesn't cover. Do you mean actually using string.Format?

: Shrugging Khan
Generally you want any remotely-frequent debugging to not be on by default unless you're specifically hunting something down. We use F3 as the debug mode toggle for most of our common debugging info.
How does that toggle work, if I may ask? Does it disable logging at runtime, or from the editor?
It's just a bool that our code toggles when it detects F3, and that bool is checked a bunch of places in our code to see whether it should do whatever kind of debugging. Not all debugging is under that toggle, just the "diagnostic stuff we frequently want to be able to get at without having to recompile or even restart the app".
: Re: Shrugger! Unity!
: Shrugging Khan September 25, 2015, 07:35:06 AM
Alright, we've discovered that yes, we have a shit-ton of GC happening due to List.Contains().
Now that it's diagnosed, what can be done about it?  ???
: Re: Shrugger! Unity!
: Draco18s September 25, 2015, 09:14:06 AM
I'm not sure why that would require GC, and a little of googling around didn't provide any insight either.
: Re: Shrugger! Unity!
: keith.lamothe September 25, 2015, 09:29:40 AM
Now that it's diagnosed, what can be done about it?  ???
A variety of things. Which one is best depends on your situation.


1) Simply converting:
:
bool inTheList = someList.Contains(foo);
to:

:
bool inTheList = false;
for(int i = 0; i < someList.Count;i++)
{
  if(someList[i] == foo)
  {
    inTheList = true;
    break;
  }
}

(all this assuming that foo is a value type, NOT a reference type, and that someList is a List<foo>)

Will solve the problem for that particular call, but if you're doing it in a lot of places that's a lot of code expansion and is somewhat error prone, etc.


2) Avoiding having lists of value types is another approach, as often you can just have it be a list of reference types instead, but that's very specific to your codebase.


3) You could write your own non-generic collection for each value type you need to have a list of. This can be very simple, like:
:
public class ListOfInts : List<int>
{
    public new bool Contains( int Item )
    {
        for ( int i = 0; i < this.Count; i++ )
            if ( this[i] == Item )
                return true;
        return false;
    }
}
I haven't tested the memory performance of that approach, but I suspect it's basically the same as approach 1.
: Re: Shrugger! Unity!
: Shrugging Khan September 25, 2015, 09:40:38 AM
Thanks! I've already started working on approach 1, but I was unsure if it would even help. Will finish it immediately  :D

Converting everything to reference types isn't really something I want to do; too many problems at other ends of the thing.
Approach 3 might be worth doing if we end up running into a lot of these. Will keep it in mind.

Edit: Hello there! Using approach three for just one List type, I was able to speed things up by 20%, cut GC by 60%, and reduce the GC trouble caused by Contains() by...100%? Seriously? I'll be off to make non-generic List classes for EVERYTHING now!

Or is that a bad idea?  :o

Edit2: I don't suppose using the same approach for IndexOf() would work to the same effect?
: Re: Shrugger! Unity!
: keith.lamothe September 25, 2015, 11:24:41 AM
I'll be off to make non-generic List classes for EVERYTHING now!

Or is that a bad idea?  :o
Premature optimization is the root of all evil. Just wrapper the ones you actually need to and focus on writing the game :) We still use tons of lists of value types that need none of these treatments, because we never use Contains() or whatever on them.


Edit2: I don't suppose using the same approach for IndexOf() would work to the same effect?
We don't use IndexOf() often enough for me to know for sure, but I suspect it's the same deal there if you're seeing allocation from that method.


The general principle is that List<T>, where T is a struct (includes int, enums, etc), has to "box" a T before it can test it for equality to another T. Both Contains() and IndexOf() necessarily involve O(n) "does T1 equal T2?" operations, hence O(n) boxing operations. Boxing means allocating a reference type on the heap which contains a T (that may not be exactly what happens, but it allocates something on the heap).

Boxing is often not a problem, and you don't have to make it public enemy number one, but if it's something that gets hit a _ton_, like thousands of time per frame for sixty frames per second, then... ow.
: Re: Shrugger! Unity!
: Shrugging Khan September 25, 2015, 12:33:40 PM
Yep, IndexOf() was another one this approach fixed.

I'll stop optimising now; everything seems to run pretty smooth as is  :D
: Re: Shrugger! Unity!
: Draco18s September 25, 2015, 12:45:29 PM
IndexOf() can be optimized....if the list is already sorted.  Then there's a binary-search shortcut version (https://msdn.microsoft.com/en-us/library/w4e7fxsh%28v=vs.110%29.aspx) that you can utilize.

Again, assuming the list is already sorted.  Which is easy if you start with an empty array, use BinaryIndexOf() and then Insert().

Probably best for large, but typically unchanging, collections.  Smaller and more mutable ones will likely benefit most from the manual search.

Another alternative is to use Dictionaries, which have O(1) lookup times (and O(1) insertion), but operate on key-value pairs.
: Re: Shrugger! Unity!
: Shrugging Khan September 25, 2015, 01:05:25 PM
I think I really should look into that, because Insertion is shaping up to be the next-biggest performance problem.

But no more optimising for now, I have to play with all the pretty shapes colours I can finally afford (performance-wise) :D
: Re: Shrugger! Unity!
: Draco18s September 25, 2015, 01:30:01 PM
http://bigocheatsheet.com/
: Re: Shrugger! Unity!
: Shrugging Khan September 25, 2015, 06:37:50 PM
Neato! Thanks  :D

I don't get the column headers à la "Average - Worst - Worst" though. What's the deal here? Are those average/worst-case scenarios?
: Re: Shrugger! Unity!
: Draco18s September 25, 2015, 11:16:35 PM
Neato! Thanks  :D

I don't get the column headers à la "Average - Worst - Worst" though. What's the deal here? Are those average/worst-case scenarios?

Yes. It should be noted that "best case" under spring is essentially "sorting a sorted array" which tells you nothing. Average and space complexity are the important factots. Less space means less GC. Better average case, less CPU (you'll now that there are trade offs there: faster often means more memory).

n is a stand in for the size of the list, k is a constant of some indeterminant value, and 1 is 1. I forget what m is.
For big-o notation, exact values are irrelevant: O(2n) isn't much different than O(n) or O(100+n). The first one is slower, but it isn't more complex. The last has some overhead, but has the same complexity.
That is: O(1) takes the same amount of time, regardless of the size of the list. O(n) takes the same amount of time as there are elements (think a loop that oates over each element once: each item takes the same amount of time, but the longer the list, the more time the whole loop takes). This is why the "best case" of sorting is always O(n), that's how long it takes to verify that the list is sorted.
And so on up the complexity tree.

What isn't there is the big-o for insertion into the middle of an array list (or at least, I didn't recognize it). Which I think is O(n) CPU and O(1) memory.
: Re: Shrugger! Unity!
: Shrugging Khan September 26, 2015, 03:46:28 AM
Aaah, yes, O-Notation. I'll probably write yet another exam about it in a few months. Algorithms and Data Structures...I slept through that lecture a year ago, but by now I know better  ::)

Time Complexity, I'll guess, is just a fancy term for how long it takes?
: Re: Shrugger! Unity!
: Draco18s September 26, 2015, 12:20:23 PM
Time Complexity, I'll guess, is just a fancy term for how long it takes?

Yes, in the general sense.  It's a relationship between "how many items" and "how long it will take" but makes no guarantees that a lower complexity algorithm will perform better under any given circumstance, just that as the number of items grows, the higher complexity one's time will grow more quickly.

Have a neat little video that will give you an idea of how things work in practice.  There's a couple of them.
https://www.youtube.com/watch?v=es2T6KY45cA
: Re: Shrugger! Unity!
: Shrugging Khan February 16, 2016, 03:09:39 PM
We're currently trying to implement Chemistry, and it's a bit tricky on the programming side.

So far we've gone with one abstract class Substance from which a variety of substances like Hydrogen : Substance, Graphite : Substance and Water : Substance inherit. These substances have a number of static properties like Density, Conductivity, Composition and potential Reactions.

But we've problems with the specifics of how to use those classes. Approaches tried so far:


Does anyone have a good idea of what's best done in such a situation?
: Re: Shrugger! Unity!
: keith.lamothe February 16, 2016, 03:15:40 PM
Have an enum SubstanceType and a class SubstanceTypeData which has one of those enums, and then whatever fields (which are set in the constructor based on a switch on the enum, and the constructor is called for each enum by a static SubstanceTypeData.Initialize() call) ?

That's what we do for most of our "lookup table" data, though lately we've done some where the records are defined by xml rather than by enum/ctor-logic.
: Re: Shrugger! Unity!
: Shrugging Khan February 16, 2016, 03:27:37 PM
Thanks!

So it'd look like:
:
public enum SubstanceType { Hydrogen, Helium, ... }
public class SubstanceTypeData {
 private SubstanceType substanceType;
 public SubstanceTypeData (SubstanceType substanceType) {
  this.substanceType = substanceType;
 }
}
How would I reference a Substance elsewhere, though?
Keep one instance each in a static table class and refer to that?
: Re: Shrugger! Unity!
: keith.lamothe February 16, 2016, 03:31:39 PM
Here's an example, from the Starward Rogue codebase:

:
public enum InventoryItemType
{
    None,
    Energy,
    Keycard,
    Missile,
    Credit,
    HealthShard,
    ExperiencePoint,
    Length
}

public static class InventoryItemTypeExtensionMethods
{
    public static InventoryItemTypeData GetData( this InventoryItemType Type )
    {
        return InventoryItemTypeData.Lookup[(int)Type];
    }
}

public class ArcenEnumIndexedArray_InventoryItemType<T>
{
    #region Instance Fields
    private readonly T[] internalArray = null;
    #endregion

    #region ctor
    public ArcenEnumIndexedArray_InventoryItemType()
    {
        this.internalArray = new T[(int)InventoryItemType.Length];
    }
    #endregion

    public T this[InventoryItemType key]
    {
        get
        {
            return this.internalArray[(int)key];
        }
        set
        {
            this.internalArray[(int)key] = value;
        }
    }
}

public class InventoryItemTypeData
{
    public readonly InventoryItemType Type;

    public string Name = string.Empty;
    public IGameImage CannotPickUpBecauseFullIcon;
    public IGameImage RecentTransactionListIcon;

    public int Max = -1;
    public int Default;
    public bool UsesSimpleHUDDisplay;
    public bool ShouldTrackPositiveChangesInTransactionLog;
    public bool ShouldTrackNegativeChangesInTransactionLog;

    public InventoryItemTypeData( InventoryItemType Type )
    {
        this.Type = Type;

        string cannotPickUpBecauseFullIconName= string.Empty;
        string recentTransactionListIconName = string.Empty;
        string recentTransactionListAnimatorName = string.Empty;
        int animDictWidth = 0;
        int animSpriteWidth = 0;
        int animFrames = 0;
        switch ( this.Type )
        {
            case InventoryItemType.None:
            case InventoryItemType.Length:
                return;
            case InventoryItemType.Energy:
                this.Max = 100;
                this.Default = 100;
                this.UsesSimpleHUDDisplay = true;
                break;
            case InventoryItemType.Keycard:
                cannotPickUpBecauseFullIconName = "FullIconKeyCard";
                recentTransactionListIconName = "Items/PickupKeycard";
                this.UsesSimpleHUDDisplay = true;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            case InventoryItemType.Missile:
                this.Max = 10;
                this.Default = 5;
                cannotPickUpBecauseFullIconName = "FullIconMissiles";
                recentTransactionListIconName = "Items/PickupMissile1";
                this.UsesSimpleHUDDisplay = true;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                break;
            case InventoryItemType.Credit:
                this.Max = 255;
                cannotPickUpBecauseFullIconName = "FullIconCredit";
                recentTransactionListAnimatorName = "Items/PickupCredits1";
                this.UsesSimpleHUDDisplay = true;
                animDictWidth = 160;
                animSpriteWidth = 32;
                animFrames = 19;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            case InventoryItemType.HealthShard:
                this.Max = 10000;
                animDictWidth = 370;
                animSpriteWidth = 74;
                animFrames = 18;
                recentTransactionListAnimatorName = "Items/PickupHealthShard";
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            case InventoryItemType.ExperiencePoint:
                recentTransactionListAnimatorName = "Items/PickupExperiencePoint";
                animDictWidth = 96;
                animSpriteWidth = 24;
                animFrames = 12;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            default:
                throw new Exception( "InventoryItemTypeData.ctor: no switch case defined for InventoryItemType '" + this.Type.ToString() + "'!" );
        }

        if ( cannotPickUpBecauseFullIconName.Length > 0 )
            this.CannotPickUpBecauseFullIcon = Game.Instance.LoadImage( "Misc/GameUnitPopups/" + cannotPickUpBecauseFullIconName, 58, CompressionType.None, TextureWrapMode.Clamp, false );
        if ( recentTransactionListIconName.Length > 0 )
            this.RecentTransactionListIcon = Game.Instance.LoadImage( recentTransactionListIconName, 52, CompressionType.None, TextureWrapMode.Clamp, false );
        else if ( recentTransactionListAnimatorName.Length > 0 )
        {
            OtherAnimator animator = OtherAnimator.Create( recentTransactionListAnimatorName, animFrames, CompressionType.None, TextureWrapMode.Clamp, animSpriteWidth, animDictWidth, 1, true );
            this.RecentTransactionListIcon = animator.Images[0];
        }
    }

    public static InventoryItemTypeData[] Lookup = new InventoryItemTypeData[(int)InventoryItemType.Length];
    private static bool HasInitialized = false;

    public static void Initialize()
    {
        if ( HasInitialized )
            return;
        HasInitialized = true;

        for ( InventoryItemType i = InventoryItemType.None; i < InventoryItemType.Length; i++ )
        {
            InventoryItemTypeData typeData = Lookup[(int)i] = new InventoryItemTypeData( i );
        }

        LoadLoca();
    }

    public static void LoadLoca()
    {
        for ( InventoryItemType i = InventoryItemType.None + 1; i < InventoryItemType.Length; i++ )
            i.GetData().InstanceLoadLoca();
    }

    private void InstanceLoadLoca()
    {
        this.Name = Language.Current.GetValue( "InventoryItemType_Name_" + this.Type );
    }
}

Initialize is called during application startup logic, and individual references are serialized/deserialized as Int32 casts of the enum itself, and if you have a reference and want the data you do item.GetData().whatever .
: Re: Shrugger! Unity!
: Draco18s February 17, 2016, 12:13:30 AM
Here's an example, from the Starward Rogue Arcen Engine codebase:

FTFY :P

TLF has codeblocks like that too for various things.
: Re: Shrugger! Unity!
: keith.lamothe February 17, 2016, 03:18:02 AM
It is a common pattern, yes. And more than one game has had an InventoryItemType, though generally it gets ripped out at the beginning of each new project (along with most stuff) and then added back in when actually called for :)
: Re: Shrugger! Unity!
: Draco18s February 17, 2016, 04:21:53 AM
Mhm ;)
: Re: Shrugger! Unity!
: Mad Rubicant February 17, 2016, 05:29:00 PM
XNA hijack!

So I'm working on my own project, using Monogame, and I'm not really sure how to load all my sprites in a non-blocking way. So say I have 8 million images to load, obviously I can't do
:
foreach sprite in sprites {
Content.Load(sprite)
}
since that will block for however long it takes to load the images. How can I get around this? As far as I know my options are async or threading, and I have no idea how to use either.
: Re: Shrugger! Unity!
: Hearteater February 17, 2016, 06:26:49 PM
Check out Content Tracker (https://contenttracker.codeplex.com/). Even if you don't use it directly, the code should help you get the right idea.
: Re: Shrugger! Unity!
: Mad Rubicant February 22, 2016, 04:42:12 AM
Well, I managed to throw something together that seems to work. We'll see whether have threading I errors in a few months.
: Re: Shrugger! Unity!
: Mad Rubicant June 20, 2016, 04:47:46 PM
So I have a question about Entity Component Systems. I decided that it wasn't worth the trouble rolling my own physics engine, and am in the process of integrating Farseer Physics, but now I've got a weird duplication problem. Before I started using it, I had a PositionableComponent that was combined with a DrawableComponent to be used by the rendering system, but with Farseer handling distances for me, it's a little redundant. But requiring a PhysicsComponent for anything that can be drawn is overkill. Should I keep the PositionableComponent and redundancy, or just fold that stuff into the DrawableComponent? This is all 2d, of course.

Also, the forums are being weird as hell; my reply box isn't wrapping the text and instead extending all the way to the right
: Re: Shrugger! Unity!
: Hearteater June 24, 2016, 07:51:31 PM
Are you experiencing problems with the redundancy (performance, code maintenance, usability, etc)? If not, leave it alone. You can always remove it later. Making progress is more important overall.
: Re: Shrugger! Unity!
: Shrugging Khan February 26, 2019, 02:37:21 PM
Hello, gents!

I just wanted to thank everyone for their help, and report that I have by now a B.Sc. in Computer Science (did my thesis project in Unity) and am working as a Junior Enterprise Software Developer working with C++.
My academic career has been a series of pretty close shaves with complete failure, but I'm now on a very good trajectory. I probably would have failed for want of a nail, but you all gave me lots of nails when I started out, so what success I have now is thanks to you all in some sense.

So, several hundreds of thousands of lines of code, multiple hobby projects (nothing publishable though) and several professional projects (one in Unity, even), many books read and discussions had, multiple programming languages learned (but C# still preferred), I have today written my worst class declaration ever, and I wanted to share it with you:

:
public class Mesh<MeshType, VertexType, EdgeType, TriangleType> : AbstractMesh where MeshType : Mesh<MeshType, VertexType, EdgeType, TriangleType>, new() where VertexType : Vertex<MeshType, VertexType, EdgeType, TriangleType>, new() where EdgeType : Edge<MeshType, VertexType, EdgeType, TriangleType>, new() where TriangleType : Triangle<MeshType, VertexType, EdgeType, TriangleType>, new() {
So as a PSA to everyone else who wants to go into software development or hobby programming: Never be afraid to ask dumb questions of transatlantic strangers on pseudonymous internet boards, never give up on a career you chose if it lines up with your personal interests, and also never hesitate to write the stupidest-looking code you've ever seen if it gets the job done.

And sorry for the necroposting. Lock this thread if it seems appropriate.
: Re: Shrugger! Unity!
: keith.lamothe February 26, 2019, 02:40:50 PM
I just wanted to thank everyone for their help, and report that I have by now a B.Sc. in Computer Science
My condolences!

I mean, congratulations :)

It may be a necroposting, but only in the best Frankensteinian sense.

"It's alive!"
: Re: Shrugger! Unity!
: Draco18s February 26, 2019, 04:19:15 PM
and I wanted to share it with you:

:
public class Mesh<MeshType, VertexType, EdgeType, TriangleType> : AbstractMesh where MeshType : Mesh<MeshType, VertexType, EdgeType, TriangleType>, new() where VertexType : Vertex<MeshType, VertexType, EdgeType, TriangleType>, new() where EdgeType : Edge<MeshType, VertexType, EdgeType, TriangleType>, new() where TriangleType : Triangle<MeshType, VertexType, EdgeType, TriangleType>, new() {

How utterly horrific.
: Re: Shrugger! Unity!
: x4000 February 26, 2019, 08:06:52 PM
Congratulations from me, as well!  That's fantastic news, and I'm so glad to hear that you're already off and doing wonderfully horrible things like the rest of us. ;)
: Re: Shrugger! Unity!
: Draco18s February 26, 2019, 11:04:59 PM
Congratulations from me, as well!  That's fantastic news, and I'm so glad to hear that you're already off and doing wonderfully horrible things like the rest of us. ;)

Oh, some of us do really terrible things.

Like invent our own esolangs and (https://codegolf.stackexchange.com/a/179916/47990) then (https://codegolf.stackexchange.com/a/179734/47990) doing (https://codegolf.stackexchange.com/a/179717/47990) codegolf (https://codegolf.stackexchange.com/a/177753/47990) with (https://codegolf.stackexchange.com/a/177057/47990) it (https://codegolf.stackexchange.com/a/180332/47990). Including IDE support (https://github.com/Timwi/EsotericIDE/pull/10).
: Re: Shrugger! Unity!
: x4000 February 26, 2019, 11:13:51 PM
Good grief!