Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1377385 Posts in 65399 Topics- by 57685 Members - Latest Member: PetterK

May 25, 2020, 06:13:02 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsGearBlocks - Build working physics based machines and mechanisms [DEMO]
Pages: 1 ... 7 8 [9]
Print
Author Topic: GearBlocks - Build working physics based machines and mechanisms [DEMO]  (Read 25564 times)
dangersam
Level 1
*



View Profile WWW
« Reply #160 on: October 07, 2019, 10:58:08 AM »

Saved game serialization

Well, seems like another two months has gone by in a flash!  I was away visiting family for some of this time, and the work I've been doing on the game has resulted in a frustrating lack of progress to show for it, but here's an update on what I've been up to anyway.

Saved game serialization

Up until now, saved games and constructions have been serialized via a binary stream, with no formatting, just using BinaryReader and BinaryWriter directly.  This is fast and results in a compact file size, but has one huge disadvantage, a lack of version tolerance.  In other words, if I add or remove any variables to be saved, or reorder them, then old saved game files will no longer load correctly.  To work around this I wrote code to check a version number in the saved file, and then convert things over for each added or removed variable.  This is a hack really, and has resulted in rather messy and hard to maintain code.

This situation is bad enough with just the demo version of the game out there, with a cut down feature set.  Maintaining saved game backwards compatibility will only get harder once the full version is released.

Ideally, I need a properly structured save file format, with some kind of key value pairing that would allow for version tolerance, but wouldn't bloat the file size too much.

BinaryFormatter

First I investigated using BinaryFormatter, because it allows for version tolerance via optional fields, but I couldn't get it to work when deserializing MonoBehaviour classes.  I need to be able to instantiate the MonoBehaviour and then populate serialized values into it, not have the deserialization process itself try and allocate a new MonoBehaviour (which is not allowed by Unity).  I thought maybe using a serialization surrogate might allow for this, but couldn't figure out a way to make it work.  The other downside of BinaryFormatter is all the assembly and type data it saves out adds quite a bit to the file size.

Json serialization

So after looking around for other possible solutions, I decided to try Json.  This provides the key value pairs I need in a fairly compact structured format.  I used Json.NET from Newtonsoft (provided via a Unity asset store package for ease of integration) which seemed really promising, it's very easy to use and highly configurable.  In most cases there's very little additional code to write, you can just use the JsonProperty attribute to specify which class properties to serialize, and configure how they're serialized.  Also, it allows for populating properties of a MonoBehaviour that has already been allocated, by using JsonSerializer.Populate() inside a JsonConverter.

Still, it took me several weeks to get Json serialization working for both saved constructions and full saved games, there were a few stumbling blocks along the way which took time to work around, as did just learning how to best use the Json.NET API.  The end result seemed great though, it solved the version tolerance problem, and the code was so much simpler and cleaner.

One issue was that the resulting file sizes of the text based Json format were huge.  Given that the game uses the same serialization code path to send construction data between networked players, this was a problem.  So, I switched over to using Bson (the binary equivalent to Json), and also compressed the data via a DeflateStream.  This worked well, the resulting file sizes actually ending up smaller than my original binary stream format.

Performance and memory problems

At this point I thought I was good to go, but then I started profiling the Json serialization with large saved game files (more than a thousand parts), and realized I was in trouble.  Firstly, deserializing the saved game was more than twice as slow using Json vs. the old binary stream method.  This wasn't a complete disaster as the load times weren't terribly long in the first place.  The other more serious issue was that the Json deserialization did an enormous number of tiny GC allocations (as in millions of allocs, totalling hundreds of MB!).

I found that reducing the JsonProperty name lengths helped slightly with this but not to any significant degree.  I spent quite a lot of time restructuring the code that loads the various modules in the game (player, constructions, time of day, etc.) to try and deserialize from the file stream more efficiently, but this made very little difference to performance or memory usage unfortunately (the resulting code was cleaner than before though so I guess the refactoring was worth doing anyway).

I'm annoyed with myself that I didn't do enough tests to pick up on these problems before putting all the effort in to convert the game over to use Json.  If I'd known ahead of time, I probably wouldn't have bothered.

So now I'm not sure what to do.  If I stick with the old binary stream solution, then all the Json serialization effort will have been wasted and I'm still stuck with difficult to maintain code for backwards compatibility.  But the Json serialization option as it stands isn't acceptable, I'd need to do something to resolve the memory and performance issues.  One possibility would be to manually serialize everything (i.e. use JsonReader / JsonWriter directly rather than JsonSerializer), supposedly this is the fastest way as it avoids overhead from reflection and so on.

I've decided for now to put all this to one side, think about it some more, and come back to it later.  In the meantime I really need to get back to trying to make some positive progress with the rest of the game!
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #161 on: November 03, 2019, 06:12:24 PM »

Character customisation

Over the past few weeks I've been finishing up the player character work I started a while back, along with some code refactoring and other things.

Building a player character

I've now implemented functionality so that a construction built out of body parts can be treated as a player character model.  Such a "character construction" differs from a normal construction as follows:-

  • It doesn't get serialized out to saved games, because the player's character construction gets spawned separately (based on what was selected in the character screen, see below).
  • It doesn't collide with other non-character constructions or objects in the world (the player's CharacterController takes care of collisions).
  • It can't be selected, frozen, or destroyed.
  • Body parts in it don't move via physics, instead they are locked to the appropriate animated bone (e.g. head, upper arm, lower leg, etc.)

I added a new character screen accessible from the main menu.  This allows the user to select a character construction, which will then be spawned as the player character when entering a game.



To create a custom character, first the user assembles a construction as normal out of body parts, and then they save it via the save construction screen.  As shown below, I added a tab to this screen to allow a construction to be saved as a character so that it'll then appear in the character screen and be available for selection.



To switch to the new character, the user then has to exit back to the main menu, go into the character screen and select the one they just saved, before re-entering a game.

In game, the character construction can be seen in the world tool UI just like any other construction.  However there are some operations that can't be performed on it as mentioned before: select, freeze, or destroy.  This can be seen below, note that the character construction has an icon to identify it as such.



This pretty much completes the player character system although, as always, there are a few loose ends to tie up:-

  • I need to add checks to ensure that the construction is valid to be a character (e.g. has the correct body parts, and they are connected together appropriately).
  • Currently, to change the player character construction the user has to exit back to the main menu, I'd like to implement a way to swap it during game play.
  • The body part meshes need a bit more modelling work.
  • I'd like to add more attachment points to the body parts to allow for more customisation options.
  • I also want to add more body part variants and accessories.

Free flight mode

I've also finished working on a "free flight" mode for the player.  This turns off gravity for the player and changes the controls slightly so that the user can fly up and hover in the air, handy for when building large constructions!

Singleton squashing

Finally, I also did another code refactoring pass to eliminate the remaining singleton MonoBehaviours in the game (well nearly).  This primarily involved converting them to ScriptableObject assets, and replacing any public method calls with events and handlers.  I covered this topic in the ScriptableObjects For Fun and Profit blog post a while back, so I won't go into detail here.  Suffice to say I'm done with this refactoring process now, there are only a couple of singleton MonoBehaviours left, which are for my networking abstraction layer (something I also blogged about a while ago), and I think I'm just gonna leave these as they are.
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #162 on: November 27, 2019, 07:03:45 PM »

Player physics

Over the past few weeks I fixed a bunch of bugs, and then turned my attention to player physics and movement control.

Problems with using CharacterController

Since the very earliest days of the game's development I've been using a CharacterController for the player along with a "character motor" script (adapted from a Unity sample) to control it using the CharacterController's Move() function.  The character motor would apply forward / back, strafing, and jumping movement, acceleration due to gravity, and if the player was standing on a moving object it would make them move with it.

This setup worked reasonably well, but the CharacterController doesn't provide proper interactions with Rigidbodies in the world.  The player is treated as a static immovable object when things collide with them.  The player can't push objects around, and they can't be pushed by objects either.  It just looks wrong when for example a vehicle hits the player at high speed and they don't move at all.

Also, the character motor implementation had a bug where, if the player collided with a Rigidbody, they would occasionally get thrown across to the other side of the map.  Most often this happened when exiting a seat, very annoying!  I suspect this issue was related to the code that moved the player when standing on something, but I'm not 100% sure.

Despite all these problems, I didn't particularly want to add more work to my plate by throwing out this character motor code and starting again from scratch.  So I tried playing around in the OnControllerColliderHit() message to try and get the player to push stuff around, and in OnCollisionStay() I tried to make the player be pushed by objects that collide with them.  I couldn't get this to work nicely though, I think it really is necessary for the player to have a Rigidbody to give proper physical interactions, anything else is always going to be a bit of a hack at best.

At this point I realised I needed to ditch the CharacterController and start from scratch after all, using a Rigidbody instead.

A physics based player

So now instead of a CharacterController, the player has a CapsuleCollider and a Rigidbody.  I implemented new code that replicates the original forward / back, strafing, and jumping behaviour, by applying a force to the player's Rigidbody.  It uses a Physics.SphereCast() to detect contact with the ground and to find the Rigidbody that the player is standing on, if any.  If they are standing on a Rigidbody, its velocity is transferred to the player.  Also, the force used to move the player is applied in the opposite direction to the Rigidbody that they're standing on, thus obeying Newton's third law.

To sum up the features and benefits of this new approach:-

  • Correct player collisions with other Rigidbodies.
  • Player can push other Rigidbodies around.
  • Player can be pushed by other Rigidbodies.
  • Player can stand on a moving Rigidbody.
  • Obeys Newton's third law when player accelerates while standing on a Rigidbody, this results in really cool "conservation of momentum" behaviour.
  • Player falls due to gravity automatically from having a Rigidbody, but even better, the player's weight now pushes down on the Rigidbody that they're standing on.
  • Eliminates the old "player thrown across to the other side of the map" bug.
  • Code is simpler and cleaner than the old character motor implementation.

Here are some examples of all this in action:-

















As you can see this provides a level of interaction between the player and the constructions they build that simply wasn't possible before, so I'm happy I bit the bullet and re-implemented things this way!

However it's by no means perfect, and there are a few issues / missing features that will need addressing at some point, for example:-

  • I'd like to implement code to handle climbing steps, I think the player needs an extra force to push them up steps, as they tend to get stuck at the moment.
  • I also want to add something to make the player slide off ledges, as right now the player can stand more than half way off a ledge with their feet in the air, which looks weird.
  • The old character motor had code to make the player slide down steep slopes, not especially crucial but it would be good to get this working in the new implementation.
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #163 on: December 01, 2019, 02:30:38 PM »

A bit later than I was hoping, but here’s a new demo build!  This one includes a whole bunch of player character improvements and several bug fixes too.


Here's a quick run through what's new in the latest demo:-


« Last Edit: December 11, 2019, 03:06:49 PM by dangersam » Logged

Leadphalanx
Level 0
*


View Profile
« Reply #164 on: December 02, 2019, 03:17:32 PM »

Awesome stuff! Garry's mod always had frustrated me with the instability of mechanical construction and the general 'flimsiness' of a lot of the constraints.  I'll definitely be checking out the test build tonight. 
Logged
dangersam
Level 1
*



View Profile WWW
« Reply #165 on: December 05, 2019, 09:11:02 PM »

Join the GearBlocks Discord Server!

Hey everyone, I’ve finally gotten around to creating a Discord server for GearBlocks!

You can upload your save files there, so I think it will be a great place to share your creations, at least until I implement a proper way to do this from within the game itself.

It’s also a good place to discuss the game, share tips & tricks, give feedback, report bugs, and so on.

I’m still learning my way around the whole Discord thing, so let me know if you have any suggestions for the GearBlocks Discord.  Welcome aboard!
« Last Edit: December 05, 2019, 09:27:27 PM by dangersam » Logged

dangersam
Level 1
*



View Profile WWW
« Reply #166 on: January 16, 2020, 05:52:19 PM »

Happy new year everyone!  Time for a quick dev update for last week (meant to post this earlier, but ah well).

Networking abstraction and Photon PUN

About a year ago I implemented a networking abstraction layer to separate use of the deprecated Unity RakNet based API from the rest of the code.

Last week I made some improvements to its interface to finish it off, and then I added a new implementation under the hood using Photon PUN 2.  I went with PUN because it's easy to get up and running, it's well supported, and its API is very similar to the old Unity API.  Thankfully the PUN implementation was relatively easy to do, partly due to the API similarity, and partly because of the abstraction layer which meant I didn't have to touch the rest of the code.

I've no idea yet if I'll stick with PUN in the long run, but for now it at least means I can get rid of all references to the deprecated Unity networking API, while not breaking my prototype multiplayer implementation.  So now I'm finally free to move on past Unity 2017.4 and upgrade to a newer version, which I'll hopefully be doing soon!

Builder tool UI feedback

After the recent video I put out about the builder tool UI changes I was considering, I've had loads of amazing and really useful feedback, which was awesome!  I think the consensus is to leave things as they are and focus on the rest of the game, so that's what I'll be doing, at least for now.  I'll keep the prototype code around somewhere in case I need to come back to it in the future.

Saved game serialization

As for this week, I'm back to looking at Json.NET saved game serialization, a topic I covered a few months ago.  I'm trying to improve on the performance and GC alloc issues I had discussed in that blog post.  If this doesn't work out then Json isn't going to be viable for this purpose, and I'll have to think of another way to solve the inflexibility of the current binary stream based system.
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #167 on: January 25, 2020, 06:13:01 PM »

Saved game success with Json

A few months ago I re-implemented the saved game serialization using Json.NET, the idea being to replace the existing BinaryReader / BinaryWriter based approach.  I've already discussed the motivations for this before, so I won't go into it again, if you're interested you can read about it here.

Unfortunately, during testing I found serious performance problems and excessive GC allocations during (de)serialization.  Using JsonSerializer (along with the JsonObject and JsonProperty attributes, JsonConverters, and so on) keeps the code nice and simple, but the performance and memory overhead with large data sets is exorbitant, at least that's what I found.  I was worried the work I'd done would go to waste and I'd have to find some other alternative to the current save / load system.

Well, I have now reworked things again to (de)serialize everything manually with JsonReader / JsonWriter, avoiding JsonSerializer altogether.  Happily this seems to have eliminated the performance and memory issues, it comes at a cost of having more code to maintain and it's not as "clean", but I think this is a small price to pay.

So baring any unforeseen issues, I think using JsonReader and JsonWriter this way will do the job.  The version tolerance Json gives should allow me to move forward with new features without worrying so much about breaking old saves!
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #168 on: February 12, 2020, 09:37:38 PM »

Unity upgrade brings performance gains

Now that I've removed the old RakNet networking stuff, I've been unblocked from upgrading to later versions of Unity, and so that's what I've been working on over the past couple of weeks.

Unity 2018.4

First I upgraded from 2017.4 to Unity 2018.4, this brought some significant improvements:-

  • PhysX upgraded to 3.4, I found to this be a big performance improvement, especially for constructions with a large number of rigidbodies / constraints.
  • Non allocating collision contacts.  By enabling "Reuse Collision Callbacks", and using the new Collision.GetContacts() API in OnCollisionEnter / OnCollisionStay, this eliminates GC allocs and improves physics performance too.
  • Graphics jobs no longer marked as “experimental”, so I enabled this, it should take some load off the main render thread.
  • Terrain instanced rendering, fewer draw calls for rendering the terrain mesh.
  • .NET 4.x no longer experimental, so I switched over to this from version 3.5.
  • IL2CPP scripting back-end for standalone builds, compiles to native binary, should improve performance and is more secure than shipping IL assemblies.

Unity 2019.3

Then moving on to 2019.3, which included a PhysX upgrade to version 4.1, this didn't seem to provide any additional performance gains out of the box, but it does introduce some intriguing possibilities:-

  • New temporal Gauss Seidel solver (see below).
  • Automatic box broad-phase pruning, I tried this and didn't notice any performance improvement, but I need to do some more tests to be sure.

Temporal solver

This new solver is supposed to improve stability for jointed rigidbodies with large mass ratios.  I was hoping that it would eliminate or at least reduce the need for "fake" masses.  For example, the gears right now all have the same (quite large) mass regardless of their size, to prevent them slipping, and it would be nice to give them real masses instead.

Unfortunately in my experiments this didn't work out, in fact even leaving the gears with their fake masses, they wouldn't run smoothly at all.  It was almost as if the constraints between them were now too stiff, so instead of locking them together I tried using a limit with a small distance, to introduce some "backlash" to relax things slightly.  This definitely helped but was still not completely smooth.

Sadly though, there were many other problems too, such as CV joints glitching out like crazy under even small torque loads, and wheels sinking through the ground.  Not to mention spring dampers being way too strong (I guess everything would need re-tuning).

So I decided to leave this for now and stick with the old projected solver.  There is a potential massive performance gain to be had with the temporal solver however, due to its faster convergence.  I found that to achieve the same approximate constraint "stiffness", it seems to only need the number of solver steps to be scaled linearly with the sim fixed time step, rather than with the square of the time step like the old projected solver.

I think this new solver will be worth revisiting again if I have time at some point in the future.

Performance results

A talented GearBlocks builder sent me this awesome snow groomer creation!  It's quite physics heavy due to the tank tracks (a large number of rigidbodies, constraints, and collision contacts), so I've been using it as a test case to do some before and after performance comparisons.



I also compared with "Continuous Contact Detection" (under gameplay settings) both on and off.  Turning this off disables OnCollisionStay, which makes a big performance difference when there are a large number of collision contacts (the only downside being you get no sliding sound effects).

Here are some results (running on my dev machine at 1920x1080 full-screen) with the snow groomer:-

  • 2017.4 / PhysX 3.3, OnCollisionStay enabled: <10 fps.
  • 2017.4 / PhysX 3.3, OnCollisionStay disabled: <10 to 23 fps.
  • 2019.3 / PhysX 4.1, OnCollisionStay enabled: 14 to 21 fps.
  • 2019.3 / PhysX 4.1, OnCollisionStay disabled: 30 to 40 fps.

Note that there's a range on these numbers because performance varies depending on how things are moving, how many collisions are happening, etc.
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #169 on: February 18, 2020, 12:56:14 PM »

Debug console

Over the weekend I implemented a debug console in the game, something I've been wanting to do for ages.  It shows logging output, and it can be used to inspect / modify variables, and trigger events in the game.

This was pretty simple to do, because the "global" variables and events were already implemented as ScriptableObject assets (see ScriptableObjects For Fun and Profit for details).  It was just a matter of making them automatically add themselves to a list to then be accessible in the console.  Almost as if I'd planned it that way from the beginning!

These existing variables and events are used by the various systems in the game, and don't all necessarily make sense to mess with in the console, but many can be useful for testing purposes, or simply for playing around under the hood.  I did add a couple of extra variables just for fun though, one to modify gravity, and another to change the time scale (slow-mo / fast forward).

The console itself has a simple UI, just scrolling text with a box to input commands at the bottom.



There are a few different available commands, for example to do things like listing the available variables or events, or to get help on using the console.

Typing a variable's name will shows its current value, or typing its name followed by a value will modify it.  Typing an event's name (followed by arguments if required) will raise that event, which can cause things to happen in the game (depending on the game's current state).
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #170 on: February 26, 2020, 01:27:53 PM »

Player physics improvements, rendering optimisations

In this update I'll briefly go over what I worked on last week.  This week so far has been focused on bug fixes and preparing for another demo release which should be coming very soon!

Take a seat

Previously, when a player activated a seat, they would be "locked" into the seat by their transform being re-parented to the seat part's transform, and their Collider / Rigidbody disabled.

This meant that the player would suddenly seem to have no mass, having no weight exerted on the seat.

So instead, I now keep the player's physics active, and lock them into the seat using a ConfigurableJoint between the player's Rigidbody and the seat part's parent Rigidbody.

This means that the player's mass now dynamically affects the construction they're seated in.  Also, by setting up the ConfigurableJoint appropriately it allows for some sprung-damped "give" between the seat and player, as you can see below.



It does of course mean however that constructions now have a little more overall mass and a slightly different CoG when players are riding in them, much as in real life.

Highlighting render optimisation

When a part (or a whole construction) is frozen, selected, etc. it is highlighted with a glowing outline.  To achieve this the part's meshes are drawn in a "mask" render pass that accumulates the outlines of all the highlighted objects.  However, up 'til now, even parts / constructions that weren't currently being highlighted would still be drawn in this pass (having no visual effect and not necessary).

So now I've modified things so that it no longer draws parts in the highlighting mask render pass unless they are actually currently being highlighted.

I also tweaked the mask render shader to fade the highlighting out over distance, and set the camera far clip plane to cull objects beyond the "fully faded out" distance.

These changes save on draw calls, and give a slight rendering performance improvement when viewing constructions with a large number of parts.
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #171 on: February 27, 2020, 10:35:58 AM »

Here’s the latest demo update with the new saved game format, all the physics and rendering performance optimisations, player physics improvements, debug console, etc.


Here's a update video all about the latest demo:-


« Last Edit: March 02, 2020, 08:48:19 PM by dangersam » Logged

dangersam
Level 1
*



View Profile WWW
« Reply #172 on: April 08, 2020, 04:56:49 PM »

Revisiting gear physics

Hey everyone, I hope you and your families are hanging in there during this crazy situation we're all in at the moment.  It seems like the whole world has been turned upside down over the past month or so.  It's hard to predict what the future will bring, or what the long term impacts will be, but I've been trying to stay focused as best I can by working on the game!

At some point soon I need to starting putting together trailer videos and other materials for GearBlocks, and for this I want to build some example creations to show off all the parts in the game.  So a while back I started building a 4WD off-road buggy with differentials, CV joints, suspension and so on, but that's when I ran into a problem.

Heavy gears and weird physics

It's an issue that someone pointed out to me quite a long time ago actually.  It's this: when you have a 4WD vehicle with a long axle connecting the front and rear differentials via gears, at high speed the vehicle wants to rotate in one direction (i.e. steer left or right) much more easily than the other.  Its preferred direction depends on the direction of rotation of the long axle.  This is a very odd and unnatural behaviour, almost like a kind of gyroscopic effect, and is even more noticeable in the air (during a jump for example).  The problem can be reduced slightly by increasing the simulation update rate (and therefore physics accuracy) but this isn't really practical as it slows performance too much.

It turns out that this weird behaviour is so noticeable because the gears all have really big masses (20kg each).  When you have a gear on each end of a long axle (e.g. running front to rear of a 4WD vehicle), it has a large polar moment of inertia.  I'm not entirely sure why, but this fact, combined with the high RPM of the axle is what seems to be making the problem so bad.  I found that if I give the gears smaller, more appropriate mass values, the unwanted behaviour is significantly reduced.

Why do the gears have such high masses in the first place?  Well, it's a workaround to prevent the gear teeth from slipping from one physics constraint to the next.  In the physics simulation, if you have two rigidbodies constrained together, generally speaking the more equal their masses, the better that constraint will solve (with less "stretchiness").  Giving the gears a large mass was a hack to try and balance them with the combined mass of all the parts in the rest of a typical construction.

I've always hated this hack, apart from anything else it makes constructions with a lot of gears weigh a huge amount!  So I've been working on a way to make the gear constraints more resilient, allowing the gears to have more reasonable masses, while still preventing gears slipping.

Searching for an anchor

Previously, when two gears were engaged, for each gear the closest constraint anchor position to the other gear would be found.  The problem is, on any particular gear each possible anchor position is quite close to its neighbours, making it easy to slip from one to the next if the constraint doesn't solve very well (i.e. if it "stretches").  However, I realised there's a better approach, here's how it works.

Starting with the simplest case - two gears with an equal number of teeth.  As before, for the first gear in an engaged pair, the closest anchor position to the second gear is found.  Then, taking the index of the first anchor and negating it will give the anchor index for the second gear, as it can be assumed to match only one possible anchor on that second gear, as shown below.



By directly mapping the first gear's anchor index onto the second gear makes it almost impossible for the gears to slip.  The physics constraint would have to stretch so much that the gears rotate one whole revolution opposite to one another, very unlikely to happen!

To make this work with a pair of gears with an unequal number of teeth is a little trickier.  The largest common factor of the two gear's numbers of teeth has to be considered when mapping the first gear's anchor index onto the second.  This means that there is no longer only one possible anchor on the second gear, for example here's a situation with three possibilities (a, b, or c).



It means that, of these three possible anchor positions, the closest to the first gear must be found.  However, they're still far enough apart that slipping from one to the next is highly unlikely.

Finally, I had to account for the relative orientation of two gears when they first become engaged.  So an anchor index offset is calculated at the point of engagement, that is subsequently applied when mapping an anchor index from one gear to another.

Other gears, and pulleys

Once I had this all working for gear wheels, I then applied the same principle to rack and worm gears.  Previously, if for example you crashed a vehicle with rack and pinion steering, it was very common for the rack gear to slip, causing the steering to be offset.  You'd have to freeze and unfreeze the construction to fix it.  Now this annoyance is much less likely to happen!

I also re-implemented the constraint anchor search code for pulleys to work in a similar way to the gears, bringing the same benefits to the pulleys.

Tuning the masses

I'm now in the process of tuning the gear masses.  For stability under high torque loads, I'm finding I still need to give them masses higher than they would naturally have (albeit not as high as before), particularly for the smaller gears.  It takes a lot of testing, but hopefully soon I'll be able to settle on some reasonable masses for the gears that work well in most situations.

All told, this has been a lot of work (that I wasn't planning to have to do), but I think the results are well worth it!
Logged

dangersam
Level 1
*



View Profile WWW
« Reply #173 on: April 18, 2020, 08:43:49 PM »

Discord build contest winners. I had a lot of fun messing around with these builds. Been meaning to make this video for a while, but better late than never I guess!


Logged

dangersam
Level 1
*



View Profile WWW
« Reply #174 on: April 25, 2020, 05:15:59 PM »

More gear improvements

Over the past few weeks I've been working on the gears and a few other random bits and pieces.

Gear masses

I've now finished tuning the gear masses to have more reasonable values.  They're no longer crazily heavy but still work well in the situations I tested.  Due to the lower mass values the gear's "teeth" physics constraints can no longer handle as much torque loading as before.  However I found this not to be such a problem because for example, vehicles are generally now much lighter (requiring less motor torque to accelerate them) so things tend to balance out OK.

Gear model improvements

I've also made some improvements to the gear models themselves and added additional axle attachment points to them, something I've been meaning to do for ages.  These modifications serve two purposes, firstly it makes it easier to actually see the gears rotating, and secondly it allows for greater flexibility with what you can do with the gears.



Here's an example, the red hand of this stopwatch (indicating seconds) is rigidly attached to an axle "passing through" the central gear via a rotary bearing, while the white hand (showing minutes) is attached to another short axle rigidly attached to one of the gear's new attachment points.



Other possibilities with these extra attachments include using the gear as a crank, attaching a structure such as a rotating platform to the gear, or even attaching other gears to the gear!

Other random non-gear related stuff

In order to try and improve performance for constructions with a large number of lights, I've made a first stab at a simple distance based culling for lights.  I also plan on adding a settings option to disable shadows cast from them (separate from sun shadows), as this helps performance dramatically when you have a lot of lights.

Another quick change was to make the seat fabrics be paintable to add a bit more variety to the seats!

Logged

dangersam
Level 1
*



View Profile WWW
« Reply #175 on: May 22, 2020, 05:19:38 PM »

Steam Game Festival



Phew, it's been a busy time lately!  I decided it would be a good opportunity to take part in the upcoming Steam Game Festival from June 9th to 14th.  So for the past few weeks I've been working towards getting ready for that, and there's still a lot more to do.

I'm excited that soon the GearBlocks store page will be live on Steam, and a new updated demo build will be playable there during the festival!

Saved game changes

The first thing to mention is that I've removed support for the legacy save format, which means that saved games / constructions from demo builds prior to the most recent version (0.5.7362) will no longer load.  You can still convert older saves into the new format by loading them into demo version 0.5.7362 and saving them back out.

I have also changed the saved game / construction folder structure slightly, so that all files for each save are now held in their own sub-folder (existing saves are converted over to this new folder structure).  Also, each save now has an additional meta data file (for name, description, and tags).

I've modified all the save / load UI screens to allow the name, description, etc. to be entered / viewed when saving or loading, for example:-



All this was necessary for the next step...

Steamworks integration

Given that the GearBlocks demo will soon be up on Steam, I really wanted to take advantage of the platform from the get go, and utilise Steam Workshop in some way.

The first step was to get Steamworks integrated and initialised.  I'm using the excellent Facepunch Steamworks .NET implementation (https://github.com/Facepunch/Facepunch.Steamworks), which seems to support everything I need, and I found it to be really easy to use!

Next I implemented code for publishing saved constructions to the Workshop, and spawning subscribed (and downloaded) constructions, also modifying the construction spawner UI to support these operations:-



Finally, I built a basic browser screen to query and view all items currently uploaded to Steam Workshop, and to allow you to subscribe / unsubscribe to them:-



There's a lot more work left to do for this screen, e.g. query sorting and filtering options, up / down voting of items, etc. but this has the bare bones functionality for now.

Also I plan on adding Workshop support for saved games, which should be relatively quick to do now, saved games already have meta data so they're basically good to go.

Steam store page

Before the festival starts, I also need to get my store page ready for prime time, as this will link to the demo and give people an opportunity to wish-list the game.  I still have plenty more work to do on this, but I've done most of the graphical assets now.  I'm not going to reveal any of these just yet, but you may have already noticed the new and improved logo!


Logged

Pages: 1 ... 7 8 [9]
Print
Jump to:  

Theme orange-lt created by panic