Hello everyone, it’s been a long time coming, but it’s finally time for another update!
There’s too much to cover in technical detail here really, so I’ll just give a brief summary…
Combustion Engines
As I mentioned in my last post, I tried using physics forces applied to physical piston and con-rod parts to drive the engine. After prototyping this, I found it not be a viable solution, due to phantom forces (from rapidly moving piston and con-rod parts), performance cost, and other issues.
Mean Value Modelling
I looked into other possible methods for simulating internal combustion engine. The basic requirements being: a model that takes current engine RPM and throttle amount as inputs, and calculates output torque. Ideally it should be parameterised to allow for tweakable engine characteristics (giving different torque curves etc.)
Some possibilities included (in order of complexity): lookup tables, mean value modelling (MVM), 1D or multi-D fluid dynamic modelling. After investigation, I chose a basic MVM approach for relative simplicity (for performance and implementation), while still providing more flexibility and realism than a simple lookup table based solution.
This required implementing code for:-
- Gas (air) physics – flow rate calculation (choked flow), pressure state equation, etc.
- Engine physics – calculations for: throttle air flow rate, fuel flow rate, volumetric efficiency, thermal efficiency, indicated torque, friction loss torque, and pumping loss torque.
- A “sim updater” to update the simulation multiple times per fixed update (giving a smaller time step per update). I found this was necessary to improve simulation stability of the throttle air flow and intake manifold pressure.
- Part behaviours for the engine crank, head, throttle, etc. to calculate their various parts of the simulation.
Parts
I’ve made a selection of new parts (cranks, cylinders, heads, throttle, etc.) that you can use to build combustion engines.
There are three crank parts (rear, middle, front) that can be assembled together to make a crankshaft. An engine must at least have a rear crank part, as it is the “driven crank” – i.e. it has the part behaviour that actually calculates and applies torque to the crankshaft.
The piston and con-rod are not separate parts in of themselves, but are shown automatically when a cylinder and crank are linked together. They have no associated physics rigidbodies, they’re just animated based on the crank angle relative to the cylinder.
You can make pretty much any engine configuration you like!
Sound
I wanted the engine sound to be derived from and recognisable to any given engine configuration. For simplicity, the approach I went with is to play a looped “single cylinder” sound for each of an engine’s cylinders, with pitch and volume varied based on RPM and engine load. The audio playback is then synchronised across all the cylinders, with a precise timing offset for each cylinder.
I developed a method for determining timing angle from firing order and crank angle, and then used this to calculate the offset for audio synchronisation. I found the ear is very sensitive to small changes in audio timing, but when the playback is synchronised with the correct offsets, out pops the characteristic sound of a V6, V8, V10, and so on!
The resulting sounds aren’t perfect by any means. For example, the sound sample I used could be better, and there are phasing issues with certain engine configurations which can cause the overall sound to be a bit “weak” in lower frequencies. However, I’m generally quite happy with the results, given the low implementation and performance costs.
Lua Script Mods
To assist the player when building and tweaking combustion engines, I figured some additional tools would be useful. These were implemented as Lua script mods.
The EngineTool shows an engine’s firing order, provides a choice of predefined firing orders, and allows firing order to be individually adjusted per cylinder head.
The PartBehaviourGraph script mod displays real-time graphs of part behaviour data channels. It will work with any part behaviour, but will be especially useful for monitoring combustion engine torque, power, etc.
More Parts and Materials
There are a bunch of other parts in the game too, torsion springs, pipes, more gear & pulley sizes, new wheels, and more.
Linear actuators now have new “stepper” and “auto centre” operating modes, configurable in the part behaviour menu.
The materials have tweaked density & strength values, and there are new material types such as lead, teflon, and rubber.
Example Constructions
There are some new examples in the kit building scenario you can try out, to get a feel for putting engines together.
Okay that’s it for this update, I hope you enjoy it!
Full release notes:-
- New parts for building combustion engines:-
- Cranks.
- Cylinders.
- Heads.
- Throttle.
- Starter motor.
- Alternator (generator).
- Fuel tanks.
- Fans.
- Added new engine and fuel link types (for use when building engines).
- Other new parts:-
- Racing wheels 4×8 and 5×8.
- Torsion springs (axle-to-axle & block-to-axle).
- Centrifugal clutch ring gear x3.
- Spur gears 10T, 14T, 18T and 22T.
- Pulleys x1.5 and x2.5.
- Pipe sections.
- “V” and “W” angled blocks.
- Gusset x1.
- Racing helmet for characters.
- Materials:-
- Density and strength values tweaked to try and better match real world values.
- New materials added: glass, glass fibre, lead, rubber, teflon, and tungsten.
- Linear actuators now have tweakable min / max extension and new “auto centre” and “stepper” modes.
- New constructions added to the kit building scenario:-
- Go-kart (1 Cylinder).
- Sports Car (4 Cylinder).
- V12 Formula Racer.
- Flat 6 Endurance Racer.
- Lua scripting changes and new features:-
- Added methods to IDataSource interface to get a part behaviour’s individual data channels (old methods for getting data now deprecated).
- Each data channel can now be a different type (float or boolean), and is accessible via a new IDataChannel interface.
- New “shapes” UI element (use IElementFactory.CreateShapes() to create from Lua) for adding custom quads, primitives, and lines within a UI canvas.
- New “time series graph” UI element (use IElementFactory.CreateTimeSeriesGraph() to create from Lua).
- New “text objects” – UI text that can be located in 3D space, created in Lua via the TextObjects global (see ITextObjects interface).
- Added support for resizable UI windows (see IsResizable and other new properties in IWindow interface).
- Added support for rotating UI elements (see IRotatable interface).
- Added Vector2 type.
- New script mods:-
- UIShapesTest – Demonstrates UI shapes.
- TimeSeriesGraphTest – Demonstrates UI time series graphs.
- PartBehaviourGraph – Displays real-time graphs of part behaviour data channels (such as torque, power, etc.)
- EngineTool – Shows an engine’s firing order, provides choice of predefined firing order, or for individual adjustment per cylinder head.
- MiniMap – Displays a map showing construction locations in the scene.
- Improved debug console (window background, command history length).
- Bug fixes.
- Upgraded to Unity 2021.3.40.