Cargo Space - devlog #0
I started working on a new project, again, but this time, I really feel like it’s something I’d like to finish. So I’ll do something I rarely do, I’ll talk about my plans and goals for the project before I start. I’m hoping this will help me feel accountable for what I do, stay focused, and avoid excessive amounts of yak shaving.
I seem to have this recurring idea/hangup on a game where you build a spaceship out of the parts you find lying around, and you go and explore space with your friends (co-op) and fight against environmental hazards and space pirates.
10 Years of gamedev
A not particularly brief history about the origins of this project.
2012: 10 years ago
I’ve already made one jam game in this genre (though single player), called Lego Scavengers. In fact, this game was one of the first jam games I ever made, and also one of the most successful ones, we won the 3rd place and an actual cash prize of around $750.
This was a game we made during the final weeks of the university semester. After the deadline we had to get back and read for our neglected exams… then work and life happened, and though we intended to, we never picked up the project again and then I didn’t even touch gamedev for years as I started working in consulting and then on Qt Wayland for four years.
2018: Reboot attempt #1
When I started getting back into gamedev, the first non-jam project I started on was that I wanted to make a non-lego multiplayer version of Lego Scavengers with battle-royale like combat.
I started in Unity, and attempted to get an MVP running with ships and 2d physics working across the network. I quickly discovered that the networking situation in Unity was horrible, and the physics engine was non-deterministic, which made some approaches to low-latency networking more or less impossible. And the resulting prototype was horribly laggy and unpleasant to use.
Making a game in Unity where significant multiplayer gameplay depended on physics just seemed not to be worth all the trouble at the time.
2018-2022: Completely forgetting about the idea again
I got my hopes up when I watched Unity’s talks about DOTS and Unity physics and the new DOTS multiplayer stack, though… unfortunately. As time has shown: the Unity multiplayer situation basically just got worse and turned into the choice of either “deprecated” or “unfinished”. Even though DOTS kind of works, it integrates really poorly with the rest of the engine and tooling, and it doesn’t really seem to be prioritized that highly by Unity anymore.
However, this meant I just shelved the project for a couple of years, waiting for DOTS to mature. However since that didn’t really happen, I just forgot about the idea.
In the meantime I made countless small jam games, with the hope that I would “fall in love” with one of them enough to make a complete game out of it. However, that didn’t really happen either. I seem to get bored with projects once the jam deadline has passed.
Discovering the Bevy game engine
Even though I was disappointed by Unity DOTS, I was still fascinated by the idea of the ECS architecture, so when I stumbled upon Bevy it seemed like it was made just for me:
- Permissive open source license
- Written in rust
- ECS-first architecture with minimal boiler-plate
- Highly modular (bring your own physics engine)
This renewed my faith that it would be feasible to implement rollback-based multiplayer physics in an ECS game engine. I found GGRS, a rollback networking library for it, but was disappointed that it didn’t support web browsers, so I made matchbox_socket
to address that, and then I made a couple simple test games with it.
One of those games ended up taking way more time than I planned, and I ended up getting so frustrated and fed up with it that I just dropped it and never really showed it to anyone. I was so annoyed with networking that I didn’t really want to touch that either for several months.
2022/Today: 3rd time’s the charm?
So that’s the gist of my last 10 years in gamedev, grossly simplified. However, I think that now I finally may have both the tools and the experience to actually pull off my old co-op space scavenger dream. My hope is that since co-op space scavenging seems to be a recurring theme for me, it will be a project I’ll manage to stick with through the hard, boring and frustrating parts of development.
It also definitively helps that Bevy is an open-source game engine, and as I discover bugs and make patches and plugins for it, I get to feel proud about making valuable contributions to the community.
Challenges and failure strategies
Networked multiplayer is hard (really)
I used to be annoyed by people telling me not to make a multiplayer game. Now I don’t. I get where it’s coming from. You get all sorts of headaches you wouldn’t otherwise run into. Especially if, like me, what you find interesting about game development is design and gameplay.
My plan now is therefore to make a game where I can scrap the networked part, and just make a split-screen multiplayer game instead. I’ll focus the game around 1-4 player player vs. environment combat, resource gathering and ship building.
As I make the game in Bevy, I’ll write all the gameplay logic in simple deterministic systems, just operating on inputs, entities and components. I have to take some care to make sure the systems stay rollback safe, but if I fail at networking, it won’t radically different, I’ll just disable rollback and everything else will stay the same.
I also think focusing on 4 players max will increase my chances of success, especially with respect to peer-to-peer networking.
I also intend this to mainly be a game you play with your friends, which means it isn’t the end of the world if I don’t get ELO-based matchmaking working, or anti-cheat, and latency is probably less of an issue most of the time (since friends tend to usually be in the same country).
I mean, don’t take me wrong 10+ players, matchmaking and PVP would be awesome, but I don’t want my project to be a failure without it.
So what this boils down to is really keeping the scope down.
Networked physics is harder
Synchronizing a physics engine over the network is probably something gamedev parents warn their children about.
I’m going to attempt it anyway.
While taking a break from my space game endeavors, this is actually an area where I gained a lot of experience.
I spent quite a bit of my indie-time reading up on engineering math I’d forgotten, I read a few papers about XPBD and implemented a proof-of-concept and tutorial series about how to implement a physics engine directly with the Bevy ECS.
So I did yet another thing people have told me not to do, and discovered that it was hard. I struggled a lot with friction, subtle bugs and explosions. However, what I also discovered is that if you leave out friction, and you leave out 3d, and you stick to simple shapes and position-based dynamics, it’s actually quite manageable.
At least, this approach worked out quite nicely for A Janitor’s Nightmare.
I guess these are famous last words, but I’m planning to use a custom-built (X)PBD physics engine for this project as well. I’ll probably leave out regular friction and just use simple linear damping for most objects. I’m rolling my own instead of going with bevy_rapier_2d
, since I hope it will make it simpler and more efficient to implement rollback for physics, and also easier to write stable constraints when building a ship out of lots of small parts.
It also feels safe to know how everything works down to the smallest detail, and not have physics be this black box that either works or doesn’t.
Again, keeping the scope down is probably key here.
How to do player movement inside spaceships (which are also moving)?
Each player will control their own character. The plan is to use 2D platformer controls while inside spaceships (where there are “gravity” fields), and jet-pack-flying while outside, in open space.
I have no idea how hard this will turn out to be to implement. I’ve made some platformers before, but not inside moving objects that can rotate and accelerate themselves.
I have very little experience making 2D assets
So I’m a programmer by education and during my day job, and I have spent the last 20 or so years honing this one skill. I’ve also done a fair bit of game design, but with limited time on jams, I’ve usually skipped making proper assets in favor of focusing on gameplay and making a working game.
Consequently, most of my game characters are boxes or squares. Actually, counting my games on itch.io, only 9 out of 18 have a non-box character in them.
I’ve focused more on art lately, even spent a fair bit of time with a drawing tablet. But for actual game assets, most of what I’ve made is in 3D, so I don’t really know how to go about making 2D character animations for instance.
That said, I do own a pen tablet, and I’m able to make things that at least I think look decent, but it takes me a really long time, and if I’m being honest it’s probably not that great compared to what other people would be able to do in much less time.
However, I do really enjoy making assets myself, and I like the feeling of ownership I get of making everything myself. On top of that, I often feel like I’m going insane if I do too much coding, so doing some drawing once in a while would probably be a welcome respite when I’m stuck with some hard coding problem
So I’m not completely sure what to do here. Perhaps I should look for a mentor or some other way of getting guidance on how to be more effective and also improve the quality of my work. Perhaps I’ll have a go at making an initial version of the art myself then pair up with a real artist later once I have a working game…
The plan
My first goal is to have something playable with the absolute minimal amount of features, but still reduce risk in each of the areas I just identified.
2-player p2p networking
Networking is hard, so starting off I’ve decided to make it as easy for myself as humanly possible… but still qualify as networked multiplayer. 2 players will pair up using my Matchbox project. I’ll need to write deterministic gameplay code, but I won’t worry about disconnections, additional players, save games and so on just yet.
Simple physics without rotation or contact friction
I’ll make a very basic physics engine, it will support collision detection and frictionless collision resolution. Nothing will rotate. All dynamic (moving) objects will be circles. I will have to deal with how to collide with tilemaps since I will use them for planets/asteroids and in order to do platforming inside space ship modules.
Basic 2D platforming that feels good, even on a moving ship
I expect I’ll have to solve a few problems with jittering and perhaps (but hopefully not) run into issues with floating point precision.
When adding rotation to the mix it will probably get even harder.
But even with simple axis-aligned physics, I expect I’ll run into things that are good to discover early and hopefully fix early.
In order to properly test this, I’ll have to let one player be able to control and fly the ship, while the other is allowed to run around inside it.
Make the prototype look good
Since I also want to find out if I’ll be able to make all the assets myself, I will force myself not to cut corners and use boxes for everything.
I will actually make an idle animation, a run animation and a jump and fall pose, and don’t use any placeholder assets. It won’t have to be perfect, but I want to go through the motions of how it is to actually make everything so I get an idea of how much work it will be, and whether it’s really something that I will enjoy working on or not.
What’s next?
I’ve already started working on this prototype. And I’m going to finish it, then test it with someone online. If all goes well I’ll take it from there and write another post about it and decide where to go next.
My biggest worry is whether it will be too hard to make rotation work, so that’s one candidate for what to pick up next. Another is to get some actual gameplay working, crafting, building, mining, ship destruction etc… we’ll see. I’m trying not to get too far ahead of myself.
If it doesn’t go well, I’ll probably write a post-mortem about it, then scrap the project again. Or maybe I’ll pivot and make a completely different game based on the parts that actually turned out well.
In any case, I’m feeling good about this project, I’m excited to see where it will take me.