Author Topic: Shrugger! Unity!  (Read 151394 times)

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #240 on: 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? ;)
The beatings shall continue
until morale improves!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #241 on: 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

Offline NichG

  • Full Member
  • ***
  • Posts: 125
Re: Shrugger! Unity!
« Reply #242 on: 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.

Offline Aklyon

  • Core Member
  • *****
  • Posts: 2,089
Re: Shrugger! Unity!
« Reply #243 on: 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.

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #244 on: 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/

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #245 on: 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?

Quote from: 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  ;)

Quote from: 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#.

Quote from: 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!

Quote from: 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.

Quote from: 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
The beatings shall continue
until morale improves!

Offline NichG

  • Full Member
  • ***
  • Posts: 125
Re: Shrugger! Unity!
« Reply #246 on: 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...

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #247 on: 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?
The beatings shall continue
until morale improves!

Offline NichG

  • Full Member
  • ***
  • Posts: 125
Re: Shrugger! Unity!
« Reply #248 on: 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.

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #249 on: 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?
The beatings shall continue
until morale improves!

Offline NichG

  • Full Member
  • ***
  • Posts: 125
Re: Shrugger! Unity!
« Reply #250 on: 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.

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #251 on: June 29, 2014, 08:52:45 am »
No progress on the orbits or the long-distance coordinate system, but some other small fry:

  • Beam weapons updated to have a much nicer placeholder system. Much more BZZZZZT than PEW PEW now. I need more information on direct energy weapons to improve it further.
  • More realistic formulas to calculate ballistic projectile speed and cyclic rates of fire.
  • More realistic subcomponent densities, ship weights (with infinite, weightless fuel and oxygen) now range from 60 to about 1000 tons.
  • Rudimentary space weather system to dissolve unimportant debris (more aggressively so when performance is low) and turn it into dust, which can be scooped up for recycling.
  • Instead of using Unity's TrailRenderer, we now use a custom trail renderer that accurately reflects the effects of inertia and thruster output changes. Gotta keep them short and quick-dissolving for performance reasons, but they're way pretty, albeit a bit tattered.
  • New targeting HUD with intercept display, reticule and relevant information.
  • New ship and component destruction system, with potentially dangerous debris flying off.
  • More flexible ways for ship construction to deal with multiple turret or sensor arrays.
  • Improved background generation. Broken Dyson Spheres and debris belts ahoy!


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

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?
The beatings shall continue
until morale improves!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #252 on: 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.

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: Shrugger! Unity!
« Reply #253 on: 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?


Quote
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.
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #254 on: 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?
The beatings shall continue
until morale improves!