It’s been a while, so time for a quick progress update
It’s been a while, so time for a quick progress update! I’ve moved into a new place now and I’m back up and running, so that distraction is out of the way thankfully. I’ve been continuing work on trying to improve the building system. Part multi-select is now pretty much done, and I’ve been trying out some ideas for selection rotation, check out the latest dev diary video for more details.
These changes are in the demo pre-release branch on Steam, so give that a try and let me know what you think!
Hey everyone! Things have been kinda hectic lately, I’m currently in the process of finding a new place to live, which has been quite disruptive to getting work done on the game. But, I’m still slowly making progress, and it's time for a long overdue update I think.
As you may know, in the past I’ve gone back and forth on whether to change the building system in the game to make it more user friendly. Although many people have gotten used to the current controls, I still think that quite a few (especially new players) find them a bit awkward and off-putting. I really should have dealt with this a long time ago, but I just couldn’t think of a design that I was happy with, so to be honest I just kept putting it off. Anyway, lately I’ve been having another go at prototyping some new ideas to try and address these problems once and for all.
I’ve made a dev diary video on all this, that way it’s a bit easier to explain what I’ve been working on!
GearBlocks on Steam
Hey all, I've just put out another minor demo update, just a few tweaks and bug fixes in this one.
Release notes:-Added check to prevent too many parts from being spawned.Increased camera far clip distance and shadow draw distance.Bug fixes.Upgraded to Unity 2019.4.21.
GearBlocks on Steam
Just released a minor demo update with the help screen improvements and quick / auto save!
Release notes:-Improved help UI screen, now lists links to tutorial videos, and has a quick reference guide.Implemented basic quick save / load world functionality (using F5 / F9 keys respectively by default).Implemented basic auto save world functionality with a configurable time interval between saves (see “gameplay” options menu).Bug fixes.
Tutorials, and quick / auto save
Time for a quick update on what I’ve been up to over the past couple of weeks.
The first thing to mention, in case you missed “tutorial week” last week, I released a series of tutorial videos for GearBlocks beginners, so do check those out if you haven’t already. Click here for the playlist.
I’ve been working on improving the help screen in game. There’s now a section that lists all of those tutorial videos, and clicking on a link will open up the Steam overlay and play the video.
I also added a quick reference guide to the main screen UI:
The last section has a list of controls for the tools, but I’m planning on improving this by changing it to be more of a step-by-step “how to build” guide.
Currently there’s no undo functionality in the game, and it’ll be a while until I can get to this, so in the meantime I’ve implemented an auto save feature. At least this way there’s less chance of people losing all their progress from an accidental deletion for example. In the gameplay options menu the time interval between saves can be configured, or auto save turned off altogether.
Right now there’s only one auto save “slot”, but I’d like to add multiple save slots (e.g. two or three) that it cycles through.
Quick save / load
I’ve also implemented quick save and load. Pressing F5 saves the world (again, there’s currently only one save slot). Holding F9 for half a second will load the last saved world (whether it be from an auto, quick, or regular save).
Hopefully all of these improvements will make life easier for both new and experienced players!
The seventh and final episode of the beginner's tutorial series, introducing the world tool, and wrapping things up
The seventh and final episode of the beginner's tutorial series, introducing the world tool, and wrapping things up!
Episode six of the tutorial series, introducing some more tools, for changing materials and painting your creations
Episode six of the tutorial series, introducing some more tools, for changing materials and painting your creations.
Five episodes into the tutorial series, and we finally get to try out some gears
Five episodes into the tutorial series, and we finally get to try out some gears!
Part four of the tutorial series, this time focusing on parts with controllable behaviours, such as motors and lights
Part four of the tutorial series, this time focusing on parts with controllable behaviours, such as motors and lights.
Episode three of the tutorial series, talking about how to use the different attachment types to make things move
Episode three of the tutorial series, talking about how to use the different attachment types to make things move!
Here's episode two of the GearBlocks tutorial series
Here's episode two of the GearBlocks tutorial series!
Here's the first episode of a new GearBlocks tutorial series for beginners
Here's the first episode of a new GearBlocks tutorial series for beginners. I'll be releasing a new episode every day this week!
GearBlocks Demo 0.6.7686
A new demo update is now live, with the new builder tool model, part attachment options, and more!
Release notes:-Replaced the old placeholder tool models with a single new shared model used by all tools.Implemented a display screen on the tool model to show the currently selected tool and its status.Improved the tool particle effects.Added an “advanced options” panel to the builder tool UI:-Allows attachment types to be optionally disallowed during part attachment.Has an option to disable the part interpenetration test during part attachment.Improved painter tool UI.Saved games now referred to as “saved worlds”.Added “invert direction” option to all controllable part behaviours.Gears are now paintable.Bug fixes.Upgraded to Unity 2019.4.18.
Part attachment improvements
Hey everyone, here’s a brief update on some of the things I’ve done over the past couple of weeks.
Attachment type filtering
Sometimes when attaching a part, other unwanted attachments might be created between that part and other adjacent parts, which the player then has to go and delete afterwards. It would be more convenient if these attachments weren’t created in the first place.
Here’s an example where we’re aligning a beam to an axle, but additional unwanted attachments are being created between the beams:
As an attempt at a solution to this, I’ve implemented a way to filter out attachment types during part alignment. There’s now an “advanced options” panel in the builder tool UI, which allows each attachment type to enabled or disabled for part attachment.
Here the fixed attachment type has been disabled in the advanced options panel:
Any disabled attachment types won’t be considered when determining if parts can align together, and any newly created attachments won’t be initialised to a disabled type (and will fall back to the next available allowed type).
So in the example with the beam and axle, disabling the fixed attachment type will prevent attachments from being created to the adjacent beams, but will still allow a rotary bearing attachment to be created between the beam and axle.
Here a rotary bearing attachment is about to be created between the beam and axle, but no other attachments between the beams:
I’ve also modified the builder tool display screen to show which attachment types are currently allowed, as you can see in the images above.
There was a bug where, by quickly dragging a selected part while clicking to attach it, it was sometimes possible to attach it such that it interpenetrated another part.
To solve this I now use the attachment’s position and orientation to calculate each part’s new local position and orientation when merging composites together.
However, I think there is value in allowing part interpenetration, as it opens up creative possibilities for advanced users! So, I’ve added an option to the builder tool UI advanced options panel to turn off the part interpenetration test.
I’ll be releasing a demo update very soon with these changes, plus the new builder tool model, and more, so watch out for that!
Player tool model
As I mentioned in the previous post, I’d started to mock up some ideas for the player character’s tool model. To keep things simple I decided to just have a single “universal” tool, and over the past couple of weeks I’ve been developing this idea further.
I wanted something relatively compact that wouldn’t get in the way, but still could provide useful feedback to the player. I settled on an appearance that references VR controllers and the like, and also takes inspiration from some great ideas from the GearBlocks community!
First step was to model it in Blender. My modelling skills are rudimentary at best, so I like to keep things pretty simple, but I think it turned out OK.
By the way, the handle has the same radius as an axle in the game, and is designed to fit into the player character’s hand!
Then after dropping the model into the game, I got to work implementing a status display for it. This uses the Unity UI system with a world space canvas positioned just behind the tool’s transparent screen. I customised the UI shader slightly so that the UI elements are emissive with an HDR colour, making the display glow brighter than its surroundings (looks pretty cool at night!)
Builder tool display, mostly empty right now, but in the future will show the status of some options that I’m planning on adding:
Material tool display, shows the currently selected material:
Linker tool display, shows which link types are currently selected to be edited:
Painter tool display, shows the currently selected paint colour:
Lastly, I worked on improving the builder tool “energy beam” effect a bit, and added another effect (a glowy sparks thing) to represent the source of the beam.
I also trigger the glowy sparks effect when the material or painter tool are changing things (I’ve removed the old paint spray effect). I’ll probably have to revisit these effects (improve their appearance, maybe add sounds etc.) but for now they’re a decent step in the right direction.
This video shows everything in action:
OK, that’s it for this update. Thanks for following along this year, for your invaluable feedback, and as always, thanks for your patience with my slow pace of development! 🙂
Happy holidays to you and all the best for the new year (here’s hoping it will be an improvement on 2020!)
Beginnings of the scenario mode
Hey everyone, time for a quick update on what I’ve been working on over the past month or so.
If you’ve been following the development of GearBlocks for a while, you’ll know that my plan for a long time has been to build something on top of the current open ended “creative mode” game-play. This is something I’ve been wanting to work on for ages, and now I’ve finally made a start on it! I’m calling it the “scenario mode”, but you could equally refer to it as “campaign mode”, “challenge mode”, or “tutorial mode”. The idea being that it’ll be flexible enough to cater to all of these use cases and more.
My plan is to create a series of scenarios of increasing complexity to gradually introduce new players to the concepts in the game and act as a tutorial mode. Beyond that I’d like to include an additional series of scenarios for experienced builders to challenge them further, but that will come later.
Each scenario may have a limited selection of tools and / or parts to build with, and certain objectives to achieve. Once the objectives are achieved, the scenario is complete, and it may then unlock more scenarios.
The process for creating a scenario is pretty simple. You set it up in creative mode, save the game tagged as scenario, and then it’ll be available to launch as a new game in scenario mode. This way players can create their own scenarios and upload them to the workshop!
So far I have done the following:-Changed the UI and code to now refer to a saved “game” as a saved “world”, I felt this made more sense because a saved “game” from creative mode can now serve as a template for a new game in scenario mode.Modified the UI and code so that a new scenario mode game can be launched from any saved world that’s tagged with scenario (this includes built-in, locally saved, and workshop downloads).Implemented code support for parameters to specify which game features are allowed when a scenario is active (such as which tools are available, whether new constructions or parts can be spawned, etc.)Added a scenario editor panel in the world tool UI for editing these parameters while in creative mode.
Here’s what the scenario editor UI looks like right now.
There’s still plenty more to do, for example:-Add the ability to test a scenario from within creative mode without having to exit first and start a new game in scenario mode.Implement an option to reset / restart a scenario while playing it.Add support to save / load in-progress scenarios (not sure if this will be strictly necessary, but could be good for scenarios that take a long time to play through).
Beyond that I need to build out some features to facilitate creating objectives (e.g. special parts for start / end trigger zones, gates, etc.) but this is something I’ll discuss in more detail in a future update.
Player tool model
I’ve also been mocking up some ideas for the player character’s tool model, I’m sick of the crappy “box on a stick” placeholder that’s in the game currently!
Originally I was thinking of having a separate model for each tool (builder, linker, painter, etc.), but to reduce scope and simplify things I’ve now decided to have a single universal tool model. However, when the player switches between tools, I still want it to visually represent this somehow, e.g. with a display, visual effects and so on.
I think I know the direction to go in now, and soon I’ll be firing up Blender and getting to work on it.
GearBlocks on SteamGearBlocks Demo 0.6.7603
Hey all, another demo update is just out, with UI and part behaviour improvements, plus a few bug fixes.
Release notes:-Improved and added in-game UI overlays to show what actions are available to the player, and the keys bound to them.Various other tweaks and improvements to UI textures and elements.Implemented a gear engagement indicator.Part behaviour actions now have primary and secondary key binding slots (and can use modifier keys).Added configurable part behaviour settings for input smoothing and motor direction.Controllable part behaviours can now be configured so that their bound keys either toggle activation on and off, or have to be held down to keep activated.Enabled linear bearing attachments on gears.Double clicking on a construction in the world tool UI will now select it.Bug fixes.Upgraded to Unity 2019.4.13.
UI and part behaviour improvements
Hey all, here’s an update on what I’ve been up to over the past several weeks. I’ve mostly been focused on providing more UI feedback for players in game, and improving part behaviour control.
I’ve overhauled the in-game UI overlays to show the player what actions are available to them depending on the current context. These overlays show which keys are bound to these actions, so that they can always see what can be done at any given moment. I’m thinking this will replace the current text based hints, as it pretty much renders those redundant.
Below you can see the player overlay on the bottom left, the toolbar overlay in the middle, and the part overlay on the right. Each of these overlays have been modified to show various available actions and their key bindings.
The player overlay now shows the current camera mode and whether free flight is enabled. The toolbar overlay shows which keys to press for the tool and construction menus, and the part overlay now shows whether the part behaviour is active and which key to press for the part behaviour UI.
I’ve also added new overlays in the top left corner to show the available actions depending on which tool is active:-
Selection overlay (for select, delete, attach, detach, etc.) and transform overlay (for translate, rotate, resize, etc.):
Material overlay (apply and pick):
Link overlay (add / remove, and delete all):
Paint overlay (apply, remove and pick):
My plan is that eventually the tool models themselves will also show additional status information, for example the painter tool will show the currently selected paint colour.
Gear engagement indicator
While attaching gears and trying to align them so that they’re engaged, it’s not always totally clear whether the game thinks they’re actually engaged or not, at least until the construction is unfrozen and the player perhaps finds that things aren’t working the way they expected.
So I’ve implemented a gear engagement indicator - when a gear is highlighted, arrows point to the other gear(s) it’s currently engaged with. Here's an example where the idler bevel gear in a differential is highlighted, showing the other two bevel gears it's engaged with:
It also works while aligning a gear during construction, so that the player knows what to expect once they attach it:
Part behaviour improvements
I’ve unified the way key bindings work between the actions you can configure in the controls options screen and those in the part behaviour UI. This allows part behaviours to now use modifier keys, and to have a secondary key binding.
Controllable part behaviours can now be configured so that their bound keys either toggle activation on and off, or have to be held down to keep the behaviour activated.
I added a parameter to controllable part behaviours to configure input smoothing. When smoothing is set to a higher value, input is less responsive but it’s easier to hold it at a roughly constant value by tapping the key. Conversely, when smoothing is set to a lower value, control is more immediate and responsive.
This can be really useful when using servos for vehicle steering for example. Increasing the servo’s maximum RPM while also increasing input smoothing provides responsive but still nicely controllable steering:
Finally, I also added a parameter to the electric motor part behaviour to invert the motor’s direction. This works regardless of whether keys are bound to control the motor or not, but obviously is particularly useful when they’re not.
I’m planning on releasing a demo update with these changes soon, so keep an eye out for that!
Discord build contest Aug 22nd - Sept 6th Theme
Discord build contest Aug 22nd - Sept 6th
Theme: Build a construction vehicle.
Thanks for your awesome builds everyone, and congrats to the winners!
GearBlocks on SteamGearBlocks Demo 0.6.7560
Hey everyone, I've just released a minor update to the demo. Here are the release notes:-Saved game / construction format changed to support part attachment improvements, old saves are converted when loaded.Parts can now slide along multiple slider rails that are placed end-to-end.Constructions are now spawned frozen and positioned in front of the player, rather than being immediately selected.Player free flight movement now has a different acceleration and a higher top speed when holding shift.Bug fixes.Upgraded to Unity 2019.4.10.
Part alignments and slider rails
Greetings all, I think it’s time for an update on what’s been happening for the past few weeks! I got back up and running on a newly built PC after the old one gave up the ghost, and I’ve been working on task management stuff, making various improvements to the game, and fixing bugs.
During the down time while waiting for parts to arrive for my new PC, I couldn’t make much development progress, so I took the opportunity to get set up on Trello for task tracking. All of my tasks are on there now, as well as feature requests and suggestions from the GearBlocks community. Many of the tasks still need fleshing out more and perhaps breaking up into sub-tasks, but it’s a decent start.
The great thing about Trello is that it gives people the opportunity to comment and vote on tasks. Currently it’s set up as invite only, so if you’d like access, email me at: firstname.lastname@example.org
I’ve been making improvements to how part alignment works, specifically how alignment positions & orientations are defined and processed.
Previously, a part’s alignment grids could be specified from a local origin + width & depth values, saving the need to specify each alignment point individually. Now, these grids have been extended to optionally have a height value, allowing for alignment “columns” to be more compactly represented (useful for axles for example).
Also, the alignment grid setup and search code has now been refactored to be simpler, easier to debug, and easier to extend.
All this was a prelude to the main change, which was to make part attachments (fixed, rotary bearing, etc.) refer to the alignment grids that they were created from. An attachment now gets its orientation and allowed attachment types directly from the alignment grid, saving the need to store them separately. The main reason for doing all this though was to address a problem with linear bearings which I’ll come to in a moment, but having access to the alignment grids this way has other advantages too, for example it allows for retrieving the alignment type when displaying attachment indicators (e.g. surface vs. interior could be shown differently). This is something I’ll hopefully get to make use of in the future.
As attachments now index into their source alignment grids, I had to change the save format to store these indices. I’ve implemented code to convert old saved games / constructions upon load so that their attachments reference valid alignment grids.
When setting up the physics constraint for a linear bearing attachment, a sliding distance and anchor offset need to be calculated. Previously this was done by simply using the bounds of the part, i.e. its outer dimension along the sliding direction. However this only works for simple “convex” parts (e.g. blocks and axles), for anything more complex, the sliding distance may need to be less than the size of its bounds.
So to solve this, the sliding distance and offset for a linear bearing attachment is now calculated based on the dimensions of its source alignment grids, which it has access to due to the changes I mentioned earlier.
The slider rail parts are limited to 25 units in length, I don’t want to make them any bigger than this as I think it would be rather unmanageable to build with. However, it seems reasonable to be able to create effectively longer slider rails by placing them end-to-end, so I made some modifications to allow parts to appear to slide from one rail to another. To do this, I implemented code in the slider rail part behaviour to find its adjacent neighbours, and then calculate a new total sliding distance and offset for any linear bearing attachments associated with it.
Here’s an example of this in action:-
I’ve also been working on some other improvements. For example, constructions are now spawned frozen and positioned on the ground in front of the player. Previously one of the parts in the construction would have been selected by the player after spawning, resulting in the construction potentially being oriented weirdly, poking through the ground, player, etc. This made spawning constructions awkward and confusing, and I think the new way is a lot better.
Player character free flight movement has been modified to have different acceleration and a higher top speed when holding shift. This helps to quickly navigate larger distances around the map.
All of this, plus various bug fixes will be in the next demo update, which I’m hoping to release very soon!
GearBlocks on SteamGearBlocks Demo 0.6.7518
Hey everyone, I’ve just released a demo update with all the UI and workshop improvements that I discussed in the previous blog post, along with several bug fixes, enjoy!
Release notes:-Improved UI textures, colours, and elements to make the UI more legible and easier to use. Improved the general appearance and layout of all the UI menus and screens. Selection lists of saved games / constructions are no longer refreshed every time UI screens are opened, only when something has changed. Improved Workshop browser screen, including search functionality, various sorting & filtering options, and voting. In saved game / construction UI screens, shown saves can now be filtered by their tags. Added UI support for publishing saved games to the Workshop, and for loading downloaded games. Saved game / construction tags are now forced to be all lowercase, in order to match Steam Workshop. Double clicking on a saved game / construction will now load / spawn it. User now asked to confirm before overwriting an existing saved game / construction. Esc. key now backs out of in-game GUIs. Added a “Steam Workshop agreement” popup UI that is shown after publishing an item when the player needs to agree to it. Increased LOD transition / draw distances for parts. Bug fixes. Upgraded to Unity 2019.4.5.
UI and Workshop improvements
Hey everyone, it’s been a while, so here’s a brief update on what I’ve been working on over the past month or so!
Save / load UI improvements
I’ve made quite a few improvements to the UI screens used for saving / loading games or constructions.
Now, rather than repopulating the list of saves whenever the screen is opened, they are only updated if something has actually changed (e.g. file saved or deleted). This makes it more responsive and means the scroll position doesn't keep getting reset.
I’ve also implemented some features to help manage and organise a larger number of saves more easily. Each save screen now has a list of tags (populated from those currently in all the saves), which can be selected from to filter out which saves are shown. In addition, locally saved, Workshop downloaded, and built-in example saves are now separated into their own panels that can be switched between.
The player now has to confirm before saving over an already existing saved game or construction (just like when deleting a save).
Double clicking on a saved game or construction now loads / spawns it, without having to click on a button. Similarly, double clicking on a map in the “creative mode” screen will start a new game with that map.
I also spent a lot of time tweaking the layout of the UI screens and improving the various UI elements. My aim was to improve the overall UI appearance, make better use of space, and (most importantly) improve legibility.
The UI could still be way better of course, and there are many more things I would like to do, but I think it has been a good step in the right direction.
Finally, the other area I’ve been working on is extending and improving the Steam Workshop support in the game.
In the Workshop browser screen, there are now a whole host of searching, sorting, and filtering options. The player can search with a text string (matches against the text in item names and descriptions), or they can search using tags (matching against any or all specified). Results can be sorted by popularity, recently added, etc. and filtered by items subscribed to, published, etc. Speaking of popularity, I also added buttons for voting items up and down.
This was all implemented using Steamworks functionality, so it was pretty easy to do really, the main challenge was more on the UI side of things.
Lastly, I’ve also added support to the load game screen for publishing saved games, and for loading games downloaded from the Workshop!
On Monday my PC completely died (reboots every few seconds), narrowed it down to either the CPU or motherboard. It’s a fairly old machine, so at this point it probably makes most sense to build a new PC.
Anyway, I’m currently resorting to using my old laptop, which is a major setback to progress as it makes development painfully slow. I was hoping to release a demo update soon with all the UI and Workshop improvements, but this will probably be delayed for a while now unfortunately.
Discord build contest for the Steam Game Festival week
Discord build contest for the Steam Game Festival week: June 16th - 22nd
Theme: Build a walking vehicle.
The creations for this one were amazing, well done to everyone who entered!
GearBlocks on Steam
The Steam store page is now live, with the latest demo available to download with Workshop integration and more. Check it out, and don't forget to add the game to your wishlist!
NOTE: To load your old saved games / constructions in the new Steam demo, first make sure you load them in the previous demo version (0.5.7362) and save them back out to convert them to the new save format.
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…
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!
More gear improvements
Over the past few weeks I’ve been working on the gears and a few other random bits and pieces.
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!
Discord Build Contest
Discord Build Contest: March 21st - April 5th
Theme: Build an amusement park ride.
Thank you to all those that took part, and congrats to the 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!
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!
An update all about the latest demo, showing the physics performance improvements, a tutorial on the new debug console, and more
An update all about the latest demo, showing the physics performance improvements, a tutorial on the new debug console, and more.
GearBlocks Demo 0.5.7362
Sorry everyone, the latest build (0.5.7361) had a bug where slider rails would not attach to anything, so I'm releasing another build with a fix for this.
The problem was due to an issue in the Unity editor with multi-select editing (i.e. selecting multiple gameobjects and editing common serialized properties). This can mess up serialized enum properties, I've been bitten by this before, and that's what happened here. The slider rail part was inadvertently set to have the same alignment and attachment flags as the axle part. An easy fix to set it back to the correct enum flags, but such a stupid and annoying problem.
I also found another bug that was a silly error on my part that messed up switching between first / third person mode, so I've fixed that too.
GearBlocks Demo 0.5.7361
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.
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.
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).
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.
First I upgraded from 2017.4 to Unity 2018.4, this brought some significant improvements:-PhysX upgraded to 3.4, I found this to 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.
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.
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.
One of you talented folks 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 the 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.
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!
Photon PUN and building UI feedback
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, so thank you for that! 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.
GearBlocks building UI - need your feedbackGearBlocks building UI - need your feedback!
One of the main core elements of GearBlocks is the building game mechanic, and it’s an area I’m still not really happy with. I think the builder tool user interface is too clunky and awkward to use, and it presents too steep a learning curve to new players. However I’ve struggled to think of how to simplify the UI without losing the flexibility of the current system.
So I decided to go back to basics and just look at the way that parts are positioned and orientated to be aligned together. For now I’m ignoring part resizing, which I think it might be best to separate out into another tool anyway.
In this video I show what I think are some of the problems with the current system, and demo a quick and dirty prototype of a possible alternative.
I’d love to know what you guys think.How hard was it for you to learn how to build stuff in the game when you first started?Do think the current builder tool is basically OK as it is, should I just leave things as they are and get on with finishing the rest of the game?Or do you find the current building user interface difficult to use?Do you think the approach that I’ve shown here in this prototype is worth pursuing?
Let me know in the video comments, or on the GearBlocks discord. Thank you, and happy holidays!
A quick run through what’s new in the latest demo, a better player character model, improved animations, and player physics interaction
A quick run through what’s new in the latest demo, a better player character model, improved animations, and player physics interaction.
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!
GearBlocks Demo 0.5.7273
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.
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.
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!
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.
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.
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.
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!
The janky placeholder player animations that have been in the game for ages were long overdue for replacement with something better. Over the past couple of months I've been working on sourcing better animations, setting up the animation blending and transitions, and then driving that based on game state.
I worked out that I needed animations for:-Standing idle.Standing jump.Turn left / right in place.Locomotion (forward, backward, strafe left, strafe right) at various speeds from walking to sprinting.Walking and running forward jumps (for jumping while moving backwards or strafing I just use the standing jump animation, as I couldn’t find anything more suitable).Seated.Tool holding (right arm held out) in up, forward, and down directions, blended based on the camera view direction.
I don’t have the budget to pay for an animator, so it was quite challenging to find suitable animation content to meet these requirements. In the end I was able to get by with a combination of a paid animation pack from the Unity asset store, some free animations from https://www.mixamo.com/, and creating some animations from scratch.
It was a fiddly process to set up the animation state machine in Unity to get all these motions blending and transitioning nicely, but I’m happy with the final outcome:-
First person mode
I've now enabled the animated player character in first person mode, the downside being that this can cause problems with bits of the body poking through the camera near clip plane, not the easiest thing to avoid especially if the camera is set to have a wide field of view.
To solve this I had to do a few tricks to offset the character and camera based on the view direction. It also imposed restrictions on the range of motion of the upper torso and arms and therefore what animations I could use. The end result is well worth it though:-
In first person mode the camera is now attached to the character’s animated head position, this adds a lot of life to the camera movement (e.g. “dipping” after landing from a jump), and makes a big difference to the feel of the game:-
Once I had the player character animations working well in both first and third person modes, I moved on to the task of adding some tool models and attaching them to the player’s hand. Now, as the player selects between the different tools (e.g. builder, painter, etc.), the transition between them is animated, and the models are swapped. Right now I just have simple placeholder models for the tools, and I plan on adding some transition sound effects, but here’s what it looks like so far:-
Time for a long overdue update! I’ve done a lot over the past two months so I’ll have to split this into a couple of blog posts. In this first one we’ll look at the character models I’ve been working on.
Crash test dummy
A while ago I added knuckle joint connectors which, along with the ball and socket connectors, can be used to construct simple rag-doll characters. This got me thinking, it would be cool to have some proper body parts with the connectors built in to them, which could be assembled in the game to make more convincing humanoid rag-dolls. I figured a crash test dummy would best fit with the idea of being made up of rigid body parts with exposed joints.
The first thing I had to decide was what body parts would be needed. I wanted to allow for flexibility of movement, but not have so many parts that building a character in the game would be unmanageable. I settled on the following 11 parts:-Upper and lower torso (initially I had a single torso part, but in the end I had to split it to allow for animation - see “Player character” below).Head.Upper and lower left arm.Upper and lower right arm.Upper and lower left leg.Upper and lower right leg.
The second problem to solve was the joint connector locations and body proportions, this was tricky as I wanted to keep all the connectors on unit boundaries (or failing that, half unit) relative to one another, while keeping the dimensions of all the body parts in proportion.
After these decisions were resolved it was time to fire up Blender and make some parts, here’s what I ended up with:-
…and once assembled together:-
I added attachment points on the hands so that other parts such as axles can be connected to them:-
…and because the body parts are compatible with everything else in the game, you can create all sorts of nightmarish stuff!
One of the longest unresolved design problems in GearBlocks has been the player character model, the skinned models in the game at the moment are just placeholders and were well overdue to be replaced. The trouble is, I couldn’t decide what the player model should look like, or how to have it fit in aesthetically with the rest of the “GearBlocks world”.
Then I thought, now that a humanoid character can be built in the game from body parts, why not utilise this for the player too? This will require implementing a way for a character built in game to be selected and used as the player model.
To explore this idea, I decided a crash test dummy wasn’t good enough, I wanted to have a proper human. Inspired by action figurines, I tried to make the body parts so that their joints, although exposed, are not overly obvious. I went with a stylised appearance for the face and hair, this was partly due to the limitations of my modelling skills, but I also think this look fits the visual style of the game quite well. Here’s what I have so far:-
Note that this is all still a work in progress, in particular the clothing and feet need some more refinement, as do the skin and hair shading. At some point I’d also like to add a female variant, and other skin tones. Plus it would be cool to have accessories (such as crash helmets). I did make the clothing paintable however, which allows for creating somewhat unique looking characters:-
…and of course you can mix and match with the crash test dummy parts!
I haven’t yet implemented the system to make a built character “become the player”, this will need to hook up the body parts to the appropriate animated bones (replacing the old skinned mesh altogether). For now I’ve hacked something together so I can test these character models out with the player animation system to make sure they work properly:-
The animations you see here are all new, in fact most of my time over last two months has actually been spent on the player animations, and this will be the topic of the next post…
Text decals, data links, and electronics
I’ve been wiped out with a nasty bug over the last couple of weeks which slowed productivity somewhat, still got quite a few things done though!
I implemented a decal shader that can modify material properties in the g-buffer independently of normals. This allows for rendering over the top of objects already rendered in the scene, modifying albedo, smoothness, etc. while leaving the underlying normals as they are, which gives a “painted over” look. I wrote this shader specifically to work with rendering font text from the Unity UI.
Then, I added a Canvas in World Space mode and a UI Text component to the resizable plate part, and implemented a new text label part behaviour to configure the text string to be shown.
With a "painterly" font, it’s quite a nice effect, here’s an example of what it looks like:-
And here’s the part behaviour UI the player can use to configure the text string:-
This will be handy for labelling things on constructions, and I'm thinking I might make use of it in future challenge game mode scenarios / tutorials.
I refactored the part behaviour linking code using various interfaces to better decouple the code and make it easier to add new link types. I also made some minor fixes and improvements to the linker tool.
I then implemented a new data link type, which allows part behaviours to expose “data channels” that can be accessed by other linked part behaviours. Where appropriate, I added data channels to all the part behaviours already in the game, for example the electric motor now exposes its current RPM, torque, and power values.
Now the dawn of a whole new category of parts, electronics! I hope to expand on this a lot more in the future but here's what I've done so far.
Putting the text decal shader and the data links together, along with a LCD display font, I implemented some text display screen parts that show the data channels of the part they're linked to.
Here you can see the new data link type being used as we link a display to a motor:-
The display screen showing the motor's data channel values while it runs:-
These displays have a part behaviour that lets the player assign a data channel to each text line on the display. Here’s the UI for this, it needs some improvement but is functional for now at least:-
I also added some “sensor” parts which are little modules that calculate their own speed, acceleration, or attitude (i.e. orientation in the world) and report these values via data channels. These can then be linked to from the LCD displays to show their current values.
The speed sensor in action, as well as speed it also reports its altitude and rate of climb (RoC):-
The accelerometer sensor, reporting longitudinal, lateral, and vertical acceleration separately, as well as overall acceleration:-
Finally, the attitude sensor, which reports heading, pitch, and roll in degrees:-
I have loads of ideas for more sensor modules I could add in the future, e.g. for reporting angle, angular velocity, proximity (think radar / lidar) and so on. Let me know if you have any ideas too! Combining these with the control links I have planned will really open things up to some very cool possibilities I think.
Anyway, for now I've just been enjoying messing playing around with these parts, like adding some sensors and LCD screens to the Mosquito flyer for flight instruments!
Linker tool, power, and more
Here’s a quick update on what I’ve been working on over the last month or so!
After a long hiatus from working on it, I finally went back and completed the linker tool. The first attempt at this tool that I did a while back was hard-coded to work with the pulleys, so I had to generalise the implementation to support different link types. A part can now have one or more link nodes that are associated with its part behaviour(s). When the linker tool is active these link nodes can be highlighted by the player, which they can then click on and drag to another link node to create a link between them.
These are the different link types that I’ve done, or am planning to do:-Pulley - used to route belt between pulleys, implementation now complete.Power - used to link motors, batteries, solar panels, this is also now done (see “Electric Power” below).Data - allows one part behaviour to query data from another linked part behaviour, an example could be a screen that can be linked to a motor to display its current RPM.Control - allows one part behaviour to control another part behaviour, an simple example being a switch that can be linked to several motors, lights, etc. to turn them on / off together.
In this example you can see some pulley links and a power link being added between a motor and battery:-
As there are now different link types, I’ve made a few tweaks to make it easier to manipulate them. The indicators for each link type are colour coded so that they can easily be distinguished from one another, and there is now a linker tool UI that allows links of different types to be shown or hidden.
As I mentioned, I’ve now implemented “power” links so that motors, lights, and so on can be linked to batteries. I implemented code in the motor and light part behaviours to calculate a power value that is then used to discharge energy from the linked battery / batteries. Also, when braking, a motor will now regenerate energy back into its linked battery / batteries.
The battery part behaviour itself does very little other than tracking the battery’s current state of charge.
I’ve also added solar panels, these have a simple part behaviour that calculates a power value based on the panel’s surface area and its current angle relative to the sun. This is then used to charge energy into its linked battery / batteries.
It’s fun to play around with this stuff in conjunction with the day / night cycle in the game, using solar panels to charge a battery during the day which then powers your lights at night:-
I’ve also just added a new type of hinge connector, what I’m calling a “knuckle joint”, where the parts connect in line with one another like this:-
I made two versions of the knuckle joint connector, one that can rotate through 180 degrees and another that is limited to 90 degrees. Here’s an example of using the 90 degree version, as well as the ball and socket connectors I added ages ago, to make a ragdoll in the game:-
GearBlocks Demo 0.5.7019
New demo build is up. A lot of code "under the hood" has changed since the last one, so I'm really hoping I haven’t broken anything!
Better building for multi-player
Most of my time over the past few weeks has been spent on a major reworking of the code for all of the tools in the game (builder, material, painter, etc.) in order to improve the building experience for networked client players in multi-player games.
Previously the tool code that responded to player inputs in order to perform various actions (such as attaching a part, breaking an attachment, applying paint, and so on) would always run on the server for all players, with each client simply sending their inputs to the server for it to deal with. This setup made it relatively easy for the server to handle things like arbitration between players, seeing as they were effectively all running locally as far it was concerned.
However this approach was flawed, the most significant problem being the latency between client player input and an action happening, which made building really awkward to say the least.
So I’ve now re-implemented every tool so that player input is processed locally on each client. In some cases the client must still request the server to complete certain actions, so that the server can validate and arbitrate where needed (for example, while one player is attaching one part to a second one, at the same time another player could be deleting that second part; the server needs to have the final say on the outcome in this scenario). In many situations however, it is not necessary for the client to check with the server first (e.g. moving or resizing a selected part, painting a part, etc.), instead the client just informs the server of the change made so that it can be broadcast out to the rest of the clients.
The result is that the building experience for networked clients is now basically the same as it is in single player games. The other benefit of these changes is that because input is processed locally for each player, it simplifies the code and makes it a bit easier to modify and improve the tools.
Builder tool tweaks
On which subject, I’ve made a couple of minor improvements to the builder tool thanks to some suggestions I’ve received.Remove actions (delete part, destroy construction, etc.) are now delayed, during which time the action key has to be held down. This should hopefully prevent annoying accidental deletions from mis-clicks!I changed the default key binding for duplication from “Q” to “Left Alt + LMB”, by default “Q” is now dedicated just to opening the tool menu.
The usability of the builder tool controls is still an ongoing concern, and something I’ll have to keep plugging away at over time, but at least now it’ll be easier to implement any further improvements I need to make.
New demo coming soon
Finally, I’m getting close to releasing another demo build, and I’ve been fixing a bunch of bugs in preparation for this. There have been a ton of changes to the code since the last demo, so I’m slightly paranoid that some as yet undiscovered bugs might have been introduced. Time to do some more testing I think, hopefully I don’t encounter any last minute issues!