Pressing On
Trying something a bit new this week. Normally we structure patches around one-or-two significant new features that have been added to the game. Unfortunately nothing is quite ready to release, but we do have a large number of small improvements, bug fixes and quality of life additions that I think everyone playing on the stable branch will appreciate. So here they are!
Update on Trading
We're going through adding functionality to what you can already do with the Communications Motherboard. This is mostly based around finding storage devices on the same data network and collating their contents. This will determine which items are available to trade. The means to transfer goods between yourself and the trade vessel will be pretty 'magical' to start with, but the shuttle landing process will be added after that.
Major Architectural Work
At this point of development it becomes clear what big packages of existing work needs to be reconsidered, because you get a better idea of what is fun in the game, where your performance problems are, and what is actually realistic to achieve. We've identified four key areas that we need to redevelop and are starting work to finish these off. Once these are done, we will have the broad platform in place for the complete game - and then just need to focus on the stuff around it.
Remember these are only intended plans and we go into them considering if they are possible. Where they're not, we will have to change and adapt, dropping what we can't do or what isn't fun. Don't consider these absolutes!
Zero-point Shifting
Our game engine (Unity), like nearly all others, uses "float" precision for "vectors" - vectors are used to position things in the game world. This means that each "number" in the position (x,y,z) has a fixed number of bits in which it can be stored. For a float that number of bits is 32. Each number in the position is effectively stored as two values: the "significand" and the "exponent". The significand store the significant digits of the number up to a fixed amount, and the exponent stores the order of magnitude of the number, also up to a fixed amount. In a float these fixed amounts are 23 and 8 bits respectively. Because a high value of the exponent results in the gap between numbers that the computer can represent becoming larger, the further the number is from zero the less absolute precision it has. The practical result of this is the as you get further from the origin (0,0,0) the physics objects start "shaking" because you don't have enough precision for smooth movement.
The solution to this is to abstract the "meta" position of the object (i.e. the position of it in the game universe) from the "rendered" position of the object (i.e. the position of the object in the game scene). This means when the player gets a certain distance from the origin we move the character back to the origin and adjust the position of everything else so those things keep the same position relative to the player.
In essence, it's a pretty simply thing to do. In practice, because position is handled nearly everywhere, it's quite laborious and fraught with bugs to implement.
What does this allow us to do? This allows us to offer much, much bigger worlds to the players. Allowing them to explore beyond the current limit before things break, which is 5km³. We need this for vehicles such as rovers, drones, air vessels, etc…
Multiplayer Netcode / Object Virtualization
The game sends a lot of data to clients. We're using the early unity version of UNET for networking, with a mix of high level and low level network messaging. Sometimes we have our own serialization of network messages and sometimes we use Unity's helpers to have it do the heavy lifting. This means we have a lot of memory turnover (garbage) and cleaning this up is what causes game stutter every few seconds. Network messages aren't the only source of this, but they're a major contributor. Even when playing alone the game runs as a server and sends messages to itself, so it still contributes to the problem when playing alone.
Unity is releasing a new network package soon, and we'll be evaluating whether to use that, or to abstract out objects completely. This means that, like the zero point shifting above, we might have game objects existing "virtually" in a universe sense as pure data constructs, and only turn them into "game" objects when we need to render them. This means we can have a "pool" of such objects and when we need to draw one, we simply apply the "virtual" objects details to it and plop it in world. This would give tremendous performance improvements, both in memory and in CPU. The result would be quite remarkable. But it's worth considering this is, in fact, a huge amount of work and quite risky.
We can't 100% commit to which option we choose, but at the very least some level of multiplayer refactoring will occur.
What does this allow us to to? Potentially tremendous performance improvement, not just for multiplayer but also for single player if game objects are virtualized. This means better frame rate and order of magnitude amounts of game objects that could be supported.
Session Abstraction
Big words! What does this mean? Simply put, this means cleaning up our quite messy initialization procedures when you start a game. We need to abstract out elements of this and clean it up. By doing this we really open up the door for what "types" of games we can support. Want to replay the same save again and again as a round like SS13? Can do! Want to make a MP deathmatch arena? Sure can! Want to create a coop-mission challenge? Yep that too!
What does this allow us to do? In addition to cleaning up the game setup and removing many pesky connection bugs, this allows us to restart the game while clients are connected, as well as support advanced gameplay modes such as round-based play.
Game-world Migrations
Off the back of the previous work, we want to be able to migrate one game world to another. We actually already have this work mostly done, and we were actually going to support it via migrating to new sessions. This meant four players could migrate to a new session when they wanted to take a mothership somewhere, but the other players in the world could continue. It "mostly" works. But it's really, really complicated. Complicated is bad. If this wasn't a niche game, we'd probably go down this route. But it's a niche game and we have to embrace that. This means we need to go for safe options, ones that we know we can do without over committing and not delivering.
So we're going to dial back that system a bit. You'll be able to take everyone currently playing, get on a vessel, and go to a new world. Using the session abstraction this means:
- Save out what is going to the new world (players on ship, stuff on ship)
- Delete everything except player "brains"
- Make the new world
- Create the stuff we saved out
- Start the game
What does this allow us to do? Away missions, basically. It allows you to continue game sessions over many worlds. Build a ship, fly it somewhere new, fly back to your old place. The main caveat we're likely to make is requiring everyone in the play session to migrate at once, rather than splitting the session into instances.
So while not a complete road-map, this will hopefully give players a good idea of what we're looking at working towards over the next few months. If you have any questions, hop into Discord!
*Hotfix* Version 0.2.1833.8470
- Fixed bug that prevented second input on chips being set.
Version 0.2.1831.8467
- Added new uniform models for when they're un-equipped to replace the original flat box models that they've had since release.
- Added 'Appearance' button to the settings screen. This functions the same as the character creation screen that has always been accessible in-game, but sets a preset character that will be used when you create a new world. This will be extended later to work with joining multiplayer games.
- Added Localized text (translation) support to the New World screen.
- Added Atmospherics Tablet Cartridge can now be used to read the internal atmosphere of another Stationeer's suit. Good for diagnosing unconscious players! Thanks to Sim and Neouni for the suggestion.
- Added dimmed backgrounds to all windows and dialog boxes to better prompt the user on what's currently interactable.
- Added a define command to the IC that allows programmers to create constant values without using a register.
- Added more sounds to UI including the character creation menu.
- Added moustache facial hair variants for November.
- Added in-game sounds for task, mission and stage completion, adding an object to your hand slot and opening and closing inventory windows.
- Added some more missing interface sounds in the menus.
- Added Holding the smart-rotate key as a modifier (default: C) now lets you loop through logic device pin options backwards.
- Added Green as a new available hair colour.
- Adjusted Prompt, Alert and Confirm dialog boxes to be more consistent with each other and adjust their size to the content inside better.
- Adjusted IC Script Editor window layout to be more consistent with other windows in the game.
- Adjusted Text Input window layout to be more consistent.
- Adjusted max radius an many looping sounds to reduce sonic clutter. WIP.
- Adjusted IC help windows to be longer, showing more items.
- Changed Debug Log file entries to exclude some unnecessary data and replace it with some metrics that are more useful for troubleshooting, like server type and loaded mods. The game log file can be found in %userprofile%\AppData\LocalLow\Rocketwerkz\Stationeers\output_log.txt and is immensely useful if you're reporting a bug - particularly ones where an error was displayed in the lower-left corner of your screen.
- Improvement IC better supports coding with enum values.
- Improvement Devices on device pins are now sorted unibetically (= alphabetically, give or take).
- Updated Localization Files (Current 29th November)
- Fixed text jumping around when resizing the Stationpedia.
- Fixed a pretty major issue with a 'default active' sound that was causing it to use up all available sound voices, preventing any other sounds from playing. Complex stations should now sound much better, but there is still WIP on this.
- Fixed a bug where combining pipe networks wasn't calculating new combined total atmosphere properly.
- Fixed a bug where removing a pipe from the end of a network would clear the atmosphere contents.
- Fixed a bug where removal of a pipe from a network wouldn't divide up atmosphere properly.
- Fixed the documentation for lr on the IC.
- Fixed Dynamic Hydroponics attached to a Tank Connector not being removable, due to not having an animation controller.
- Fixed Prompt dialog boxes jumping in size occasionally.
- Fixed bug in which battery wall light would drain power even when off.
- Fixed bug in which battery wall light would remain on even after battery discharged.
- Fixed Digital Valves are no longer forced into an error state by being fully enclosed in a frame.
- Fixed Issue starting new worlds due to previous WorldSettings change and dependency on worlds names not being changed.
- Fixed sound clashes in the main menu.
- Fixed inventory sounds playing at once when you start a new game.
- Fixed issue with new moustache variant for third face style.
- Fixed error whenever destroying the Portable Solar, as it was trying to start generating power, despite it being in the process of being destroyed.
- Fixed the majority of misaligned and overflowing text within menus and on buttons. Text should now autosize and stay within their bounds. Especially noticeable when using a localized language.
- Fixed Error when trying to recycle the Portable Solar, as it was trying to run solar-charging code like whenever you drop it, despite it being in the process of being destroyed.
- Fixed instances where duplicate sounds were playing when navigating menus.
- Fixed Issue with the full beard on one of the face variants not displaying properly.
- Fixed issue on loading characters where organ creation could fail, resulting in immediate death.
- Fixed NullReferenceException error that could occur if the UI Audio Manager attempted to play audio before it had properly initialized.
- Fixed a bug in which the GasDisplay could show incorrect units if cycled through temperature (finders credit to EinBerliner).
- Fixed incorrect close tag in ChangeSettingToFor value.
- Fixed bug on IC where defines weren't storing hashes correctly.