1. Captain of Industry
  2. News

Captain of Industry News

CD #33: New map, revamped tutorials, and bricks!

Hi Captains, Zuff here and I am thrilled to tell you about our biggest patch yet, the almighty v0.4.13! I have also prepared a TL;DR version of this post in a video form. The full hundred-lines-long patch notes are at the end of this post as always. Let’s get started!

[previewyoutube][/previewyoutube]

Thanks for translations!

Before we jump in the new features and changes, I have a quick announcement. We appreciate the extra work some players put into translating the game. Captain of Industry is currently translated to XX languages and the latest addition is Turkish!

To show our gratitude we will be giving out Steam gift cards to the most active translators! If you translated a significant amount of strings please expect an email in coming days (the one you registered on Weblate)! Many thanks! And if you’d like to help us with translations, see https://translate.captain-of-industry.com/projects/captain-of-industry/game/

What’s new in patch v0.4.13

[h2]New map: Insula mortis[/h2]
The works on a new map editor are well underway but we wanted to give you one more map to enjoy before the editor is ready. The new map is called Insula mortis and it is a beautiful group of islands rich in raw resources. To get access to nearby islands you will have to make land bridges by dumping material to the ocean. There are rumors that this island is cursed but our scouts found no evidence of this so it's probably just a legend.



[h2]New mass upgrade tool[/h2]
It’s finally here! With this new tool you will be able to select an area of buildings to upgrade. It works for all upgrade entities, including machines, conveyor belts, or pipes. By the way, this tool was implemented solely by our new team member Jeremy who joined our team in November. If you enjoy this tool in particular (or if you’d like to see it improved), feel free to drop him a line on our Discord!



[h2]New and reworked tutorials[/h2]
Since the game's release back in May, we have been receiving lots of feedback about a steep learning curve and lack of guidance at the beginning of the game. We spent a lot of time and care analyzing the feedback and our solution is two-fold.

First, we implemented a new checklist-based tutorial that will help new players to learn the basic mechanics and progress through the game. This feature is optional and it was designed to be as non-intrusive as possible. Progress in the game is not locked behind any goals, there are no time limits, and every goal can be individually skipped. However, you will get rewards by completing the goals so think twice before skipping them!



Second, we have revamped our existing non-interactive tutorials. Tutorials now use less text and more images to make them easier to read and understand (there are over 170 new images!). Longer tutorials were split to smaller chunks and many new ones were written to cover even more topics. We put an extra effort to focus tutorials on explaining mechanics and features that are otherwise harder to discover by just playing the game.



These tutorial changes were a lot of work but we wanted to get it done before fully switching to the work on Update 1 so that players can have a better experience now, not later.



Pages from a 90-page working document that we used for collaborating on tutorial revamp.

[h2]New chain: Bricks[/h2]
Addition of bricks was actually indirectly caused by the tutorials revamp. When we were writing goals and tutorials for the early game, concrete production seemed like too complex of a chain to set up. Concrete production requires the establishment of two new mines (limestone, and sand), limestone has to be processed to cement, dry ingredients have to be pre-mixed, and then combined with water – what a process!

Another issue with concrete was dependency on slag. It seemed advantageous to make concrete from crushed slag, as opposed to crushed rocks, because slag was just a by-product of iron ore smelting and rock would require a third mine to be set up. However, in that stage players were often still making iron from scrap that is not producing slag. This also made players reluctant to dump slag on the ground, stalling their iron smelting lines by lack of demand for concrete.

To fix these issues, bricks were introduced. Bricks are made using dirt, water, and coal and they are used in Construction parts recipe instead of concrete. The nice thing is that dirt often comes from your other mines so you might not need to even set up a new mine for it.

Concrete can be still used in construction parts as an alternative when it is unlocked later in the game. Note that some buildings require concrete for construction explicitly so it is not possible to progress through the entire game without making it.



[h2]New mods configurator[/h2]
A common feedback from players who are using mods was that it was not possible to add or remove mods from existing games. While the modding community is still very young, we decided to invest in supporting this feature. Note that this will not work with all mods.

Additionally, you can pick mods when starting a new game. This means that you can have many mods installed but only choose ones that you want during a game start. Loaded games will automatically load mods present in those games.



[h2]Further optimizations of transport pillars rendering[/h2]
Our eternal fight for more frames per second was focused this time on transport pillars rendering. The biggest difference was the introduction of LODs (level of detail) so that pillars further from the camera are using simpler models. When the camera is too far away, pillars are not even rendered at all!

We tested this on Neet Engineer's factory where the number of triangles rendered by pillars alone decreased by more than 50% from 5.7 to 3.2 million (his factories are huge!). This did not result in a huge FPS gain on our hardware but players with weaker GPUs, especially laptops, could see some nice boost. Memory consumption was also lowered slightly.


Animation showing three levels of details of transport pillars. Level 0 is the normal model, level 1 has significantly reduced polygon count which is shown when looking from a distance, and level 2 completely turns off pillars rendering when the camera is too far away.

[h2]Refugees balancing[/h2]
This patch brings many balance changes but the most important one is that the world map no longer gives refugees from explorations. This change was made to prevent frustration from bringing new people from explorations while your settlement was already full, making people homeless. To balance this, Beacon is now infinite with diminishing returns.
Key behavior changes
Here are the most important behavior changes from this patch.

Excavators no longer return to the mine tower when mining finishes, unless they are outside of the mine area. This should make mining more efficient, especially when resuming mining after all designations were fulfilled.

Dumping designations are searched based on proximity to the vehicle, not the mine tower. This makes dumping more efficient since vehicles usually drive shorter distances. Placement of the mine tower also makes no impact on dumping operations.

Transport connector now attempts to accept inputs evenly from all connected ports. This means that a connector has an equivalent behavior to a balancer without any priorities or ratio enforcement settings on. This can for example ensure that all products are being conveyed evenly through a congestion.



Transports construction tool now places a connector in places where it makes sense (e.g. two output ports facing the same tile). This simplifies connecting entities that have ports facing each other.



Statue of maintenance now provides maintenance reduction based on the number of operational statues instead of a flat bonus for any number of statues. The maintenance reduction of a single statue was reduced from 5% to 4%, but each additional statue gives an additional reduction which is a half of the previous one. For example, 3 statues give 4% + 2% + 1% = 7% total maintenance reduction now.

It is now possible to flip entities with mechanical shaft such as turbines and generators. This enables more designs when making power plants.



It is now possible to queue any research node and all required parent nodes will be queued before it automatically.

Improved ship surrender logic so that your ship will not surrender if the enemy has much lower HP. This should never happen how:


[h2]Significant bug fixes[/h2]
This patch brings so many fixes, here are the most important ones.

Fixed recycling of gold which was incorrectly returning only 1/3 of the expected value. Are you ready for the extra gold?

Fixed contracts that were in some cases charging more Unity than they should have. More Unity for you!

Transport connectors now return products to the shipyard when destroyed instead of destroying them. No more lost products!

Fixed buried pipes that are no longer destroyed when another transport is built on top of them. Yes, you can bury pipes. No, it is not a good idea.

Thanks for the incredible reviews!

One last thing. We are completely blown away by all the positive reviews posted on our Steam page recently. During the last 30 days we have received all positive reviews except one! Thanks everyone for this wonderful gift! We read every single review carefully and take notes on what to improve.



And that’s all for today. The entire MaFi Games team wishes you happy holidays and a wonderful New year 2023!

Full patch notes


New map: Insula mortis

Improved experience
* Added mass upgrade tool. When an area is selected for upgrade, a popup window can be used to select what entities in that area should be upgraded.
* Added comprehensive checklist-based tutorial that will guide new players though the early game (can be disabled).
* Reworked and restructured tutorials to better explain game mechanics, be more simple to read, and be less verbose.
* Added mods configuration options when starting or loading a game. This also allows you to add/remove mods before a game is loaded. Note that not all mods can be safely added/removed from a save.
* Introduced a new bricks production chain into the game. Bricks can be used as an alternative for Concrete in Construction parts. Bricks are designed to make early game a bit easier.

Performance
* Further optimized transport pillars rendering and added LODs, saving many millions of drawn triangles in large factories.

Balance changes
* World map no longer gives refugees from explorations.
* Beacon is now infinite with diminishing returns.
* Reduced early research difficulties.
* Removed electronics from collapsed radio tower.
* Research labs no longer consume Unity when idle.
* Reduced connector buffer size significantly (size is still based on transporting speeds of connected entities).
* Increased water requirements to make 8 acid from 4 to 6.
* Reduced water yield from cleaning of 24 toxic slurry from 20 to 18.

Behavior changes
* When assigning a vehicle to a building (e.g. mine tower), assign the closest one.
* Excavators no longer return to the mine tower when mining finishes, unless they are outside of the mine area.
* Dumping designations are no longer searched based on proximity to the mine tower but on proximity to the vehicle.
* Refueling trucks now don’t leave fuel stations while the station keeps loading them with more fuel.
* Trucks and excavators now prefer to refuel at the fuel station that is assigned to their mine tower.
* Improved logistics jobs priority system.
* Transport connector now attempts to accept inputs evenly from all connected ports (outputs were already even). This means that a connector has an equivalent behavior to a balancer without any priorities or ratio enforcement settings on.
* Transports construction tool now places a connector in places where it makes sense (e.g. two output ports facing the same tile).
* Statue of maintenance now provides maintenance reduction based on the number of operational statues. The maintenance reduction of a single statue was reduced from 5% to 4%, but each additional statue gives an additional reduction which is a half of the previous one. For example, 3 statues give 4% + 2% + 1% = 7% total maintenance reduction now!
* It is now possible to flip entities with mechanical shaft such as turbines and generators.
* It is now possible to queue any research node and all required parent nodes will be queued before it automatically.
* Improved ship surrender logic so that your ship will not surrender if the enemy has much lower HP.

User interface
* Replaced toggle buttons with checkboxes.
* Improved several dialogs to properly respect the Esc key.
* Total population view moved from the big top left tiles to the main top toolbar.
* Removed custom starving notifications and moved them to the regular notifications.
* Notification dismissal status is now persistent (loads from a save).
* Collapse warning icon on affected building disappears when its notification is dismissed. Notification reappears when more terrain under the affected building is modified.
* Custom warning notifications on storages don't go away until the contents are more than 5% off the target to prevent flickering.
* Message notifications now auto-collapse when there are more than 5 of them.
* Add "delete entire transport" action into the construction toolbox for better discoverability.
* Transport height now shows the correct height when connecting to other transports.
* Remove the top title bar from the bottom toolbar and use tooltips for the items instead.
* When selecting an entity, prefer a vehicle if there are two entities to choose from. This allows selecting trucks clipped inside of buildings.
* Fixed idle non-assigned vehicles that were not properly updated in the UI.
* Fixed an incorrect estimate of water yield in the rainwater harvester.
* Fixed Recipe book that did not show some recipes as locked if the owning entity was locked.
* Fixed hotkey for price tooltip did not work if transport editor was activated via copy tool.
* Fixed missing tooltips in settlement overview, added a link for tutorial about health.
* Product stats titles are now ordered by name.
* Made key-binging tooltips translatable.
* Mining overlay can be now toggled without canceling current selection for building.
* Games can be loaded/saved by double-clicking on existing file names.
* Updated translations, thanks to everyone who is contributing!

Significant bug fixes
* Fixed recycling of gold which was incorrectly returning only 1/3 of the expected value.
* Fixed issue with free maintenance when global maintenance amount exceeded capacity.
* Fixed contracts that were in some cases charging more Unity than they should have.
* Fixed game crash when clicking "continue" for a save file that was deleted in the meantime.
* Fixed terrain rendering that was showing lighter stripes on steep slopes.
* Fixed shipyard collapse that was not properly destroying products, potentially causing the permanent radiation issues.
* Fixed incorrect sun brightness and shadows intensity when a game was loaded during rainy weather.

Transport related bug fixes
* Transport connectors now return products to the shipyard when destroyed (instead of destroying them).
* Fixed buried pipes that are no longer destroyed when another transport is built on top of them.
* Fixed pipe attachment to the pillar that was sometimes incorrectly oriented.
* Fixed spontaneous transport collapse that sometimes happened during flip, connection, or upgrade.
* Fixed transport pillars that were sometimes stuck as a blueprint.
* Construction state of a transport (e.g. ongoing upgrade or construction pause) is now properly preserved when joining it with other transports.
* Fixed construction cubes visualization when transport under construction was connected to other transports.
* Paused transports no longer accept products.
* Transports in clearing mode are no longer moving products and are no longer accepting products.
* Fixed destroy tool that was incorrectly selecting the entire transport when the cursor was previously on any other non-transport building.
* Fixed transport destroy tool that was not showing destroy preview when repeatedly hovered over the same spot on a transport.

Other Bug fixes
* Server racks can no longer be added into non-constructed data centers.
* Fixed vehicle overlay that was sometimes shown for an incorrect vehicle class.
* Fixed wood disappearance when truck overload edict was active.
* Fixed inability to select tree harvesters sometimes.
* Fixed edict panel to correctly show effects of unity-positive edicts.
* Fixed excess consumption of lab equipment on research finish or change.
* Cargo depot modules now have an idle state.
* Fixed that the beacon was not losing progress when paused.
* Fixed buildings highlighting during route assignment.
* Fixed rendering of building ghosts particles below terrain designations.
* Upgrade of machines now properly prunes obsolete product buffers. This means that upgraded Blast furnace II will no longer accept iron ore since it cannot even process it.
* Trucks no longer exceed reservations of other trucks when delivering their cargo
* Fixed unity stats that did not contain items that went over the unity cap.
* Fixed some recipes that were unlocked too early or were not visible in research.
* Fixed that cutting and pasting of a building with vehicles assigned did not preserve the vehicles assignments.
* When people leave due to lack of food, any homeless will now get properly accommodated in their place.

CD#32: What's in store for our first major update

Ahoy sailors, Captain Zuff reporting for our next Diary post. Today we have lots of information about what we have been working on and about the next big update!

MaFi Games is growing

Before we get into the game updates, on behalf of the entire MaFi Games team, I would like to welcome Jeremy, our new senior software engineer from the UK. We are so happy to have you join us and help us accelerate progress on the game! Here are a few words from Jeremy:

“Hi everyone! I'm excited to be joining the team and am looking forward to getting stuck in. While I have a background in performance optimization, I'll be working on all parts of the game, from bug fixes to new features. I'll mostly be working in the background so you may not see me pop up in person too often, but hopefully, you enjoy the results of my work!”

And by the way, Jeremy has been recently working on the new upgrade tool.

Update 1 plans

Past weeks we have been busy planning the next big update as well as prototyping what is feasible to do so that we can deliver on the plan. The community feedback played a huge role in this process and we are thankful for everyone who is sharing it on Discord, Steam, feature requests site, Reddit, and elsewhere!

We have a lot of plans but in this post, I will share a smaller chunk that we are working on right now.

[h2]Terrain graphics and simulation improvements[/h2]
A pivotal change of the terrain rendering tech is the extension of the maximal number of supported terrain textures. Players have been asking why they cannot dump various materials on the ground and one reason was that our terrain supports only 24 different textures. This has been a big limitation and we are working on rewriting the terrain rendering to support up to 256 different textures! This will allow us to add more textures to the game, increasing visual variety as well as allowing players to dump more different materials on the ground. Mods will be also able to take advantage of this by adding new custom dumpable materials.

Adding more textures is not the only terrain improvement. We feel that the terrain looks too plain and is missing visual richness and variety. Our artist Miroslav is hard at work improving existing terrain graphics as well as adding new models such as grass, rocks, bushes, branches, tree stumps, etc. Take a look at a mock scene below!

Comparison of current terrain in the game (top) and our new terrain prototype with new props and textures (bottom).

Close-up of the new terrain prototype including new props.

Close-up of the new terrain prototype with new textures of rock and iron ore.

Another important change we are hoping to implement is improved terrain physics simulation. One issue we are constantly dealing with is that the material collapse angle is the same for all states of a material. For example, a solid rock on a mountain will collapse at the same angle as a mined rock from that mountain. This often results in cascading collapse of entire mountains when they are disrupted by mining.

We plan to separate “solid” materials from “already mined” ones and have different collapse rules for them so that steeper mountains are possible. We are also thinking about mining changes so that tall mountains are not always possible/easy to be mined from the bottom. This will need more testing.

[h2]Rendering improvements[/h2]
This is a big topic, but a long story short is we want to make the game look better and one feature that makes a tremendous difference is anti-aliasing.

Currently, we use the “deferred” rendering pipeline in Unity. It has many advantages such as efficient rendering of lights, or powerful post-processing features. However, one thing that it cannot do well is anti-aliasing (smoothing out jagged edges). Unity implements a technique called “temporal anti-aliasing” that renders each frame slightly differently and averages consecutive frames in time. This technique helps but does not work very well. We were experimenting with a different rendering pipeline called “forward” that does support multi-sample anti-aliasing (MSAA).

The decision on the rendering pipeline is not easy and there are always trade-offs. From our initial testing, the MSAA is such a big visual improvement to the game that we are considering removing lights (currently only used on vehicles) and switching to the forward rendering pipeline. This is a relatively big undertaking since many of our custom rendering code was assuming deferred renderer, but we think it is worth the result.

Comparison of the deferred rendering with temporal anti-aliasing (currently used in the game) and the new forward rendering with 8x MSAA.

From the comparison above you can see that the MSAA does a much better job of smoothing out the jagged edges on the models, especially in the distance. Also, you can see that the grass on the terrain is visible much further since most of the grass blades have sub-pixel size which is not possible to be rendered with the deferred renderer.

Another benefit of MSAA is that it produces “stable” images that do not change over time. A big disadvantage of temporal AA used by the deferred pipeline is that small objects and edges tend to flicker. This is part of the algorithm that reduces aliasing, but it can be very distracting to see flickering, especially when the camera is not moving. This is especially visible on bright objects such as molten metals where the flicker can be much more apparent. This issue is not present when using MSAA.

Unwanted flicker caused by the temporal anti-aliasing of the deferred renderer. This issue is not present when using forward rendering with MSAA.

Models improvement
We are also working on improving some of our 3d assets. This is going to be a continuous effort but we hope we are up to a great start.

New tier II excavator model compared to the old one. You can hopefully tell which one is which!

[h2]Map editor[/h2]
Terrain and rendering improvements lead us to the biggest and most complex feature that we are working on – the map editor. While we have a simple editor that was used to make existing maps, we cannot simply make it available to all of you since it is using Unity Editor UI. It is also very hard to use, even for us, and we wanted to offer more powerful tools that are easy to use.

Another big issue is backwards/forwards compatibility. Currently, maps are represented via code (maps are procedurally generated) and the representation is relatively brittle. Sometimes we need to do manual changes to the existing maps source code to keep them compatible. This obviously would not scale to community-made maps. We would hate to do some changes to the game that would obsolete all maps made by the community.

The solution here is two-fold. First, design a new map representation that will be as robust to game changes as possible. Second, create a new editor that uses the in-game UI that handles editing of the new map representation.

Making a COI map editor has an additional complication that many other games do not have to deal with: What is under the terrain surface matters. COI has a fully dynamic layered terrain and resources are often underground. This means that the editor has to support this. We are still not completely sure how to implement this but we have ideas to try. We will definitely give you an update on this topic as we work on it.

Another close-up of the new terrain prototype.

[h2]More music[/h2]
We are also happy to announce that our artist Ondrej has been working on another 30 minutes of music for the soundtrack. We have nearly 80% done!

What else is planned for Update 1

We also plan to implement tree replanting, better product visualization on conveyor belts, improved unit storage visualization, and hopefully add a few more machines for more processing capabilities. We will cover these areas in more detail once we get closer to working on them.

When?

It is hard to predict exact dates as we are diving into significantly large areas. We aim to deliver the update in Q2 2023. We will also drop at least one medium-sized update this year that has some nice improvements and bug fixes.

Upcoming changes

We also have a few changes that are coming before any big update arrives. These are bug fixes but also a new tutorial system with goals and active tracking of player progress. We hope we will be able to improve the initial experience when folks are learning the game. This update should arrive in a couple of weeks.

Example of the new tutorial system that we are working on.

Conclusion

This is all we had for you for now but don’t forget, this is just the first wave. There are more features coming in Update 1 and we will keep you updated as we get to work on them.

Thank you for your continued interest and support and let us know your thoughts on Discord, Steam, or Reddit!

Patch notes for v0.4.12

The v0.4.12 has graduated from experimental and is now available on the main branch! To learn more about the patch, see our recent Captain's diary #31: https://www.captain-of-industry.com/post/cd-31

[h2]Performance[/h2]
* Optimized rendering of common buildings resulting in up to 3x more FPS.
* Optimized rendering of construction cubes that no longer cause any FPS drop.
* Optimized game loading which is 2-8x faster.
* Optimized save datastructures making save files 2-3x smaller.
* Fixed issues causing consecutive loads consuming more memory and being slower.

[h2]Other improvements and fixes[/h2]
* [Important] Added `ChangeConfigs` method to `IMod` interface allowing mods to change configs. This is not a backwards-compatible change.
* Building ghosts, construction cubes, and ports now have color based on construction state.
* Building ghosts now have subtle texture to make them more recognisable.
* Current weather is now shown as an icon.
* Fixed that the cargo depot would accept any fluid as fuel instead of just diesel.
* Fixed cargo depot that could give free fuel when adjusting sliders.
* Fixed loud sound when quitting the game.
* Fixed loading of files with special characters such as '['.
* Fixed a special case where cargo depot did not allow to assign a product
* Fixed top bar jumping between single and double row when a date length was changing.
* Clinic now prefers a higher tier of medical supplies if it has multiple types stored.

[h2]v0.4.12a[/h2]
* Fixed construction of transport pillars.

[h2]v0.4.12b[/h2]
* Fixed entity icons disappearing after upgrade.
* Fixed tile validation overlay for flipped/rotated entities.

[h2]v0.4.12c[/h2]
* Fixed incorrectly highlighted particles during (de)construction.
* Farm no longer simulates fertility when under initial construction.
* Fluid colors on storages and transports are now visible immediately after load.

[h2]v0.4.12d[/h2]
* Improved how mods are loaded, being able to reference and load dependent DLLs.
* Added command line arguments useful for modding such as --skip-assets-preload, use --help to list them all.
* Added XML documentation for all mafi DLLs. It should just show up in your IDE when using mafi APIs.

[h2]v0.4.12e[/h2]
* Fixed tree harvester UI that was not properly updating the line to goal.
* Fixed building (de)construction cancellation that could sometimes result in insta-built entities.
* Fixed hit-box of chicken farm to not contain an empty area next to it.
* Fixed issue with balancers when they were configured to have no power consumption.

CD#31: Up to 3x more FPS and 2x faster loading!

Hello Captains! Zuff here bringing you exciting news about the latest patch v0.4.12 that has just landed to the experimental branch!

TL;DR: The game now loads 2-8x faster, save files are 2-3x smaller, and FPS is 2-3x higher! This patch is without a doubt the largest performance update to Captain of Industry to date! And there are also some nice changes regarding construction visualization and minor fixes. Keep on reading to learn how these amazing speedups were achieved or skip to the end for full patch notes.

Before we dive into the technical details about speedups, I would like to announce a change in the schedule of Captain Diaries. Until now, we were doing CD posts every two weeks but going forward we won’t keep a strict schedule. These posts take a long time to prepare and sometimes we’d prefer to keep working on things and announce them when ready, not when a 2 week deadline ends. In fact, that’s precisely what happened with this post.

Here’s Marek and Filip with the technical details about the performance improvements.

Rendering performance improvements

Ahoy! Captain Marek speaking and I am thrilled to tell you about some serious performance improvements that we have done. The two techniques used to achieve this were GPU instancing and Level of Detail (LOD).

As you might recall, our previous performance improvements were also revolving around GPU instancing (batch-rendering) of many small entities, transport pillars mentioned in Captain's Diary #15 gave as 2-3x more FPS and building ports mentioned in Captain’s Diary #29 yielded 20-50% more FPS.

We have this handy tool that can selectively disable rendering of objects and based on this performance analysis, the biggest performance offenders were 1) buildings/machines, 2) transports, and 3) construction cubes (when present). We will skip transports for now and focus on buildings and construction cubes. Let me start with the cubes optimizations.

Chart showing what takes the longest time to render.

[h2]Construction cubes optimizations[/h2]
Construction cubes are these little boxes representing scaffolding that appear over a building when it is being constructed, upgraded, or deconstructed. They appear for each voxel of the built entity. For common entities that's 100-1000 cubes per building. But a single greenhouse needs over 10k cubes! You probably see where this is going. Tens of thousands of individual cubes updated every frame (since they are animated) and we have a perfect recipe for FPS disaster.

We thought about two ways of addressing this issue. One, use GPU instancing and don’t worry about the high counts of cubes. Alternatively, we could reduce the number of cubes and make them larger to avoid too many individual objects. Well, we decided to go all-the-way and do both optimizations!

GPU instancing was already explained in the previous posts, basically it allows rendering of multiple instances of an object by the GPU given a list of data describing how each object is rendered. And you can probably imagine how four 1x1 cubes can be combined to one 2x2 cube reducing the total number of cubes. I will just note that to make this super efficient, cube position, size, color, and animation state are all handled in the GPU shader and cubes are no longer updated on the CPU every frame.

Test scene for construction cube benchmark.

For performance testing, we have set up an empty island where 5 greenhouses were being constructed at the same time. The game without construction cubes was running at 123 FPS, before optimizations this dropped to 7.4 FPS when all 50k construction cubes appeared. After our optimizations the FPS is back at 120! Suffice to say that construction cubes will no longer lag your game!!

Chart comparing rendering performance of baseline (no cubes) to 50k rendered cubes before and after our optimizations.

[h2]GPU instancing for buildings[/h2]
Building optimizations have a similar vibe as construction cubes or building ports, using GPU instancing to reduce the overhead of rendering many objects separately, but there is a problem. GPU instancing handles only rendering of 3D models, but buildings need much more than that. They need to be selectable by the player, have animations, sounds, particles, be able to collapse, and none of this can be “GPU-instanced”.

Based on our performance data shown below, we have decided to go after the low-hanging fruit and optimize only the buildings that have no animations, sounds, or particles. As a coincidence these ones are actually taking the majority of the frame time because there are so many of them. I am talking about retaining walls, connectors, balancers, solar panels, vehicle ramps, etc.

Approximate rendering times for top 14 buildings from factory by MaddProf. Blue marks static non-animated buildings that we decided to optimize, red are all unoptimized.

There were additional issues with GPU-instanced rendering of buildings. One of them is flipping. Most buildings can be flipped horizontally or vertically to aid with connection constraints. The issue is that when a 3D model is flipped, all triangles will change their winding order (whether the vertices are ordered clockwise or counterclockwise). Why does this matter? A typical optimization done by virtually any 3D game/engine is to do something called back-face culling. Basically, if the 3D models have all triangles with the same winding order, GPU can quickly detect whether a triangle is facing “towards” or “away” from the camera by checking its winding order and if it is facing away, it can skip drawing its pixels. Have you ever wondered why 3D models are “invisible” from inside when the camera clips inside? It is exactly thanks to this optimization. Triangles are visible only from one side.

So what is the issue with flipping again? GPU instancing can render all the instances of one 3D model at once, but the setting for back-face culling must be the same for all instances. So you either enable back-face culling and have all flipped buildings rendered “inside-out”, or disable it and draw twice as many triangles.

Two instances of Mine control tower rendered with the same setting of back-face culling. The right one was flipped along the horizontal axis and due to incorrect triangle winding order it looks “inside-out”.

Actually, there is a third option. Split buildings into two sets, flipped and non-flipped, and draw each set with a different setting of back-face culling. While this makes code infrastructure slightly more complicated and introduces a second draw-call for each building type, we went with this solution to avoid drawing unnecessary triangles.

Another issue was building selection and highlighting. We had to set up proxy elements in the scene that are invisible but allow us to select buildings with a cursor. Highlighting is done by rendering into a special buffer and this is handled by a separate draw call (a third one). Here, we do not distinguish between flipped and non-flipped buildings.

And a final issue that I’d like to touch on is the collapse mechanic. When a building is dug under it will collapse and this must work for buildings rendered with GPU instancing. We have actually borrowed a similar code that animates construction cubes and used it to animate a fall of a building. When collapse happens, the static building model is hidden and a same-looking but animated building model is displayed. We also add a proxy-object with dust particles.

A visualization of a frame as rendered by the GPU. On the left you can see the scene being rendered before GPU-instancing optimizations and the water collectors are rendered one by one. Compare this to the right half where instancing allows the GPU to render large chunks of buildings at once. Note that this comparison is not exact in the representation of time taken to render each entity.

[h2]Level of details for buildings[/h2]
GPU instancing is making triangle drawing more efficient for the GPU but it actually does not reduce the number of processed triangles. At some point, no matter how efficiently we feed the GPU with triangles, it won’t be able to keep up processing and rendering them. And we know that some of you will just keep building bigger and bigger so we’ve implemented another layer of optimization – Level of detail (LOD).

The idea behind LOD is simple. Models far from the camera can be replaced by simpler ones, reducing the number of rendered triangles. When done well, you can hardly tell the difference.


Example of LODs of the rainwater harvester. The original model (left) has 3734 triangles and the simplified model (right) has just 698.

The disadvantage of this technique is added code complexity and, more importantly, we need to make simplified models for each building which takes a lot of extra 3D modeling work. Because of the extra work, we are LOD-ing only the most important models for now and will be adding more as we go.

The kicker is that LOD and GPU instancing optimizations can go hand-in-hand. We group entities to 256x256 tile chunks and all entities on each chunk are rendered with respective LOD based on camera distance. This allows us to utilize both optimizations and also compute the LOD level only for each chunk, not for each entity.

Chart showing how LOD reduces the number of rendered triangles.

[h2]Final results for building rendering optimizations[/h2]
We will present the results on a rendering benchmark of several selected factories from the community, namely from MaddProf, Yandersen, and NeetEngineer – thanks for sharing your amazing factories with us!


Testing factory from MaddProf with a sea of retaining walls.

The overall results are impressive! We saw 2-3x more FPS on very large factories. The more buildings the greater speedups. MaddProf’s sea of retaining walls (over 4k walls to be specific) saw an improvement from 17 to 25 FPS. A factory from Yandersen with over 1700 solar panels and 480 rainwater collectors saw a FPS increase from 10 to 25 (when the gigantic solar farm was in the view). Finally, Neet Engineer's factory is something else. With nearly 4k solar panels and 5k transport connectors, it is the largest factory that we have ever loaded and due to the insane amount of buildings, we saw FPS improving from 7 to 23 (depending on the camera view). With these improvements we are looking forward to seeing what else you can build!



That was a lot of info, but wait, there is more! Filip has detailed info regarding optimizations of loading and save files!

Load Times

Captain Filip here. We have heard your feedback on long load duration times and we have been noticing them as well. It has become our priority to understand what is going on and reduce it. The good news is that we managed to shave off a lot.

Game init consists of several phases:
  • Game init + load
  • UI build
  • Rendering initialization

First critical one was game load. It turned out that for large factories it became crazily slow. I have actually received a save file from JDPlays from his YouTube series. You can check out his video here showcasing his island, it’s really impressive. We also used a couple more save files provided by folks from our community - JoneY and Manuel de Heer, thanks for that!

One of my theories was that the game simply decided to punish JD for trying to break it all the time which would make sense 🤣. But after a few technical investigations it turned out that several things were more expensive than we expected. If you recall how Marek previously improved game rendering by focusing on ports, well guess what, ports did strike again. Each port is represented by a class which turned out to be a bit too heavy as ports supported Events, however given there can be 4-6 times more ports than entities and it quickly adds up. Also, our Events are a bit special as they are automatically saveable, however their callback compilation was taking way too big of a slice of our load time, so simplifying ports by removing these Events entirely helped a ton. We have also simplified terrain designations and their backing data structures for mine towers and assigned jobs as players typically have lots of designations. With all this, the improvement got quite substantial.

First of all, the save size got reduced quite a bit. On large factories the save files are now 3 times smaller. However, it has been also reduced due to us fixing one leak in stats that not everyone was hitting.

Chart showcasing the size of save files before (red) and after (green).

The game load is now 6.5 times faster, however even for more compact factories we are still hitting 1.7 times improvement.

Chart showcasing how long it takes to load the game in seconds before (red) and after (green).

As a side effect of this effort, the save & auto save now became faster as well. Which is great because no one likes slow auto save.

Chart showcasing how long it takes to save the game in seconds before (red) and after (green).

When investigating the game load we noticed that there is actually another phase that decided to cause troubles - UI initialization. It was eating 12 sec from the start of the game. Now this one is interesting, because it does not depend on the size of a factory. So reducing this would reduce the waiting time for everyone. It turned out that Unity had few footguns in their API, and we were paying hard for re-parenting during UI build.

For Unity fans out there, we build UI via code using Unity’s API. When you want to create a new UI element you need a GameObject. The most obvious API for that is “new GameObject()”, however what happens is that Unity creates a new separate root hierarchy for it and once you place that object into a new parent, it throws the old parent hierarchy away and updates the entire sub-hierarchy about the new parent. The solution was to use Object.Instantiate which (unlike GameObject constructor) accepts a parent to create that object in the right place. Sometimes we would build an entire window UI (such as research) before we put it into Unity’s Canvas. At that point we would pay for re-parenting of every single element of that window, almost the same as creating each of those elements again. When this happened on multiple levels of the UI it added up very quickly. In total, the re-parenting was eating half of our UI build duration.

Another observation we made was that our bottom toolbar panels, that contain all the machines, were taking up significant time to build as for each category we had a separate panel. So we merged all of these into one UI view which is shared by all the categories.

And final improvement was that we added Unity Sprites caching to avoid duplicates when building the UI which saves not just time but also the memory.

At the end all the improvements got us from 12 seconds to 2 seconds. Not too shabby! When we add the load duration improvement + ui init improvement into one chart, here are our new game load + ui build improvements:

Chart showcasing how long it takes to load + init UI of the game in seconds. This is basically the major portion of time spent waiting for the game to start.

Now it becomes a bit more clear while JDs island got so well thought through. Whilst waiting for the game to load, he had so much time thinking about his next steps! 😉

[h2]Subsequent game load[/h2]
We had several reports that subsequent load takes longer (loading while already in a loaded save). It was because of a memory leak. Well, not necessarily a memory leak but a misunderstanding between us and how Unity expects us to dispose of their native objects. Also we learned that running GC right before we load a new game might be a good call to prevent C# allocating an even bigger heap. Obviously systems with smaller RAMs had to have a hard time because at that point it might have ended up page swapping the memory. So we fixed all of that and based on our experiments, subsequent load is no longer slower.

Improved buildings blueprint visualization

Part of the performance improvements was a partial rewrite of entities construction and visualization. While at it, we have improved construction visualization in two ways.

First, building blueprints now show the entity texture in a subtle way. This makes recognising blueprints slightly easier. Take a look at the following comparison.

Example of blueprint of mining tower. Left is how it looked until now, right is the new version. Notice the subtle details of the constructed building.

Second, blueprint color as well as colors of construction cubes are now matching the construction state. Blueprints for buildings under construction are blue, paused construction is marked as gray, and deconstruction is red.

New construction coloring for buildings. Blue (left) is a furnace under construction, gray (middle) is paused construction, and red (right) is a furnace under deconstruction.

This new color scheme also eliminates the need for icons marking paused construction as they were sometimes in the way, visually cluttering the scene. All this and more is also described in a new game tutorial that is triggered when the first building construction is paused.

Old rendering with construction pause icons (left) and new rendering with gray ghosts representing buildings with paused construction (right)

Changelog for v0.4.12
v0.4.12
Performance
* Optimized rendering of common buildings resulting in up to 3x more FPS.
* Optimized rendering of construction cubes that no longer cause any FPS drop.
* Optimized game loading which is 2-8x faster.
* Optimized save datastructures making save files 2-3x smaller.
* Fixed issues causing consecutive loads consuming more memory and being slower.

Other improvements and fixes
* [Important] Added `ChangeConfigs` method to `IMod` interface allowing mods to change configs. This is not a backwards-compatible change.
* Building ghosts, construction cubes, and ports now have color based on construction state.
* Building ghosts now have subtle texture to make them more recognisable.
* Fixed that the cargo depot would accept any fluid as fuel instead of just diesel.
* Fixed cargo depot that could give free fuel when adjusting sliders.
* Fixed loud sound when quitting the game.
* Fixed loading of files with special characters such as '['.
* Fixed a special case where cargo depot did not allow to assign a product
* Fixed top bar jumping between single and double row when a date length was changing.
* Clinic now prefers a higher tier of medical supplies if it has multiple types stored.

Patch notes for v0.4.11

The v0.4.11 has graduated from experimental and is now available on the main branch! To learn more about the patch, see our recent Captain's diary #30: https://www.captain-of-industry.com/post/diary-30

[h2]New Features[/h2]
* Unlocked buildings are now highlighted in menus until they are selected for the first time.
* Added an option to auto-return the main ship after exploration when there are no more reachable locations to explore.
* Added a new edict that reduces ship fuel consumption by 10%.
* Added an option to make ships 50% slower to save 30% of fuel per trip.

[h2]Cargo ships and contracts balancing[/h2]
* Increased cargo ship capacity by 2x, fuel consumption by almost 2x. World mines buffers were also increased to accommodate.
* Larger cargo ships are now more fuel efficient per trip.
* Decreased total travel duration of cargo ships from 3.3 to 3 months.
* Increased cargo depot modules unloading speed, the highest tier now unloads the ship in just one month.
* Increased profit on copper, iron and quartz contracts.
* Increased profit on contracts selling coal and vehicle parts 2.
* Added new contract: consumer electronics -> quartz.

[h2]Other balancing[/h2]
* IMPORTANT: Gas rotary kiln changed to return CO2 instead of Exhaust.
* Reduced coal consumption of the silicon recipe in the Arc furnace II by 50%.
* Reduced computing consumption of Arc furnace II from 6 to 4.
* Increased the throughput of Chemical plant for graphite production from CO2 by 2x.
* Reduced transports building duration by 80%.

[h2]Other fixes and improvements[/h2]
* Retaining walls are no longer buildable on terrain designations and vice versa. This should prevent issues with mining/dumping over the walls. A new console command `toggle_terrain_designations_over_entities` can revert this change for power users.
* Renamed "Liquid nitrogen" to "Nitrogen tank" as it is a unit product.
* Fixed UI that was not clickable in some cases in windowed mode.
* Transport snapping is always enabled when no transport is selected. This allows snapping to ports and other transports when starting transport construction.
* Fixed that entities with reserved ocean area such as ocean pump/dump could block ship access of the cargo depot/shipyard indefinitely.
* Fixed the "Recover ocean access" action. Note that all ocean areas will be recomputed after loading this game version which may cause entities being newly blocked or unblocked.
* Improved ocean area recovery action that now shows what is blocking the ocean area if the recovery fails.
* Fixed vehicle dust particles that were not emitted properly in some circumstances.
* Increased vehicle dust particles visibility distance and optimized their rendering.
* Fixed buffers clearing to only clear buffers of unassigned recipes that are not used by any assigned recipe.
* Toggling of planning mode no longer cancels the current building session (e.g. cut & paste).
* Fixed that toggling prod. level on world mine did not reduce workers when it had full buffer
* Fixed a rare case where a settlement transformer would not work for settlements with low population.
* Fixed internal buffers in the Maintenance depot that could accumulate large amounts of maintenance.
* Fixed a rare issue with terrain data serialization that could lead to corrupted save files.
* Fixed incorrect shortcuts shown when insta-copying transports.
* Partial execution for recipes was changed to kick in only when no other recipe can be satisfied fully.
* Added UI showing the state of supply of fuel rods in the nuclear reactor.
* Improved error tooltips and other places for colorblind accessibility.
* Excavators no longer forcibly turn on their lights during game pause.
* Updated translations, thanks to everyone who is contributing!