UniverCity - Change log
I didn’t end up keeping to my plan of releasing this month due to a few issues. The main issue it is took me a few tries to get through the build review process, one issue was a crash on steamOS that seemed to be caused by webrender and the other issues were all multiplayer related. I managed to get it approved in the end. The other issue was between all of this I was ill making working on the game hard. Given the event happening on steam soon I’ve decided its best to delay the launch until after that finishes. On the brightside I have more time to work on content now.
UniverCity is a university management game being programmed in the Rust programming language.
Gameplay⌗
Extensions are now automatic⌗
Joining buildings as always been a bit of pain point with trying to keep it usable and bug free at the same time. Its been a few iterations and hopefully this one is the last. Previously to join two buildings you had to edit both and place the extension object where you wanted the join to happen. This was a pain to do as it required two object placements and had to be repeated for every tile along the edge. Along with this it was possible to cause breakages with removing extensions or the other building whilst something was placed along the join.
The new system is now automatic using a new update script system that
was implemented. Simply placing a building near to another one
will cause it to join up. In order to handle this across the network
I used serde_transcode
to convert a lua table to CBOR bytes and
back again, this may get used in a few more places later as its really
useful.
Steam Multiplayer⌗
I was planning on implementing this later but I decided it may help me pass the multiplayer issues in the review (no port forwarding required). I took this time to redo the multiplayer user interface. In the multiplayer menu you’ll see a list of open lobbies hosted by your friends, from that screen you can either host your own lobby or connect to a dedicated server via an IP address. The lobby now shows players with their icons and gives you an option (in steam lobbies) to send invites. This should making playing with other easier.
New Objects and texture swapping⌗
To ease creating variants of objects I’ve added a way to swap the texture of a model at runtime.
I also improved the handling of objects for professors, they will now randomly walk over and spin the globe every now and again.
Internal⌗
Crash dumps⌗
One issue I was having when having people test my game was trying to
figure out crashes. As mentioned in a previous blog post I replaced
all usages of unwrap
with a assume!
macro that included file
and line number information as well as logging to a file. This didn’t
always help due to the fact not all crashes were on unwrap
or even
in my code (e.g. a library) and on Windows it seems like the log from
assume!
didn’t always make it in to the log file.
So I set out to build a crash dump system that would save backtraces into
a file that I could read and debug, this sadly required going back to
panic=unwind
however. Using the backtrace
crate inside a panic
hook made getting the backtrace pretty easy however without debug information
the backtrace was mostly useless. I initially thought about just shipping
with debug=true
as I really don’t care about protecting the code that
much however this wasn’t going to work due to the increase in binary size,
on linux the binary went from 12MB to 170MB. To try and work around this
I stripped the binaries before uploading them keeping a copy of the unstripped
binary as well, due to the backtraces including pointers as well I was
hoping to just pass them to addr2line
and get the function name and line number
back. The issue was that the pointers in backtrace
didn’t match up to the
pointers in the symbols due to them being based on their memory location
that was randomized each run. Whilst I’m not sure if this is a good solution
I created a function called base_anchor
.
#[no_mangle]
#[inline(never)]
pub extern fn base_anchor() {
}
This function had its pointer included in the backtraces so that I could
use the difference from its memory location and its symbol location
(obtained with nm
to find it via its unmangled name). This difference
could be used to shift all other pointers in the backtrace into something
that could be passed into addr2line
.
For windows it was pretty much the same except instead of using command
tools I had to use the Windows API to lookup the symbols from the .pdb
files. I used winapi
plus some custom bindings to functions that winapi
was missing.
So far these crash dumps have been pretty useful, hopefully if I ever get the time to clean up the code I could try and make this into a crate that can used for other applications too.
Steamworks⌗
As part of the multiplayer work I had to improve my Steamworks
bindings where I encountered an issue with the way steamworks handles structs.
They actually use packed structs but the packing depends on if its on linux
or Windows. I’ve implemented a work around via proxy methods for now until
the packed(val)
attribute becomes stable.
Minor things⌗
- Staff variants now can have their own icons
- The default resolution is no longer 800x480 and instead defaults to your desktop resolution
- The show required button now includes the number of required objects left
- Clicking the show required now scrolls up to fix being left with a blank list when scrolled down the list
- Scripting clean ups and optimizations. Removed a large number of allocations
converting from
&str
->CString
- The delta encoding of floats has been improved to reduce/remove the error build up that was happening over time. Should fix a lot of pathfinding issues.
Twitch⌗
I haven’t been streaming my work on twitch here lately but sometimes I will pop up and stream for a bit. Feel free to stop by and watch if I’m streaming.
Subreddit⌗
I’ve opened a subreddit for the game as per someones suggestion. It’s mostly empty currently but hopefully that’ll change once I get some time to put some work into it. Here