sschmid / Entitas

Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
MIT License
7.18k stars 1.11k forks source link

Is it feasible to use Entitas in the backend? #1078

Open alex-moonlitgames opened 1 year ago

alex-moonlitgames commented 1 year ago

Context We currently have a singleplayer game. Diablo perspective but guns as weapons (for both player and enemy), goal is to clear each room out of X max and get loot at the end.

Old gameplay: https://youtu.be/ck-nqOgGjXo?t=79

Apart from guns & bullets, player characters have abilities, 3 active and 1 passive. We have / want typical RPG spells and special attacks, distilled to just "abilities" that have a wide range of unique effects, such as: life drain, mind control, hp / damage / speed / etc. boosts, as well as the opposite effect to debuff enemies.

Problem Since we are using Entitas for the client, but we want to introduce PvP and Coop, the need to move Entitas to a C# backend solution arises.

Option 1 (Ideal, clean): I would assume that for each match, we would create a micro-instance with a separate Entitas running in order to isolate Entities and Systems from other matches, then either recycling or destroying / recreating them on demand.

Option 2 (Risky): I don't think, at any point, did our entity count within a game level surpass or came close to 100 Entities, so if 1000 matches are running, and somehow we do have EVERYBODY AND EVERYTHING in the same 1 Entitas instance and we isolate them by matches, it might work but that means 100,000 Entities, a few dozen Systems operating on them. Don't know about thisone.

Option 3 (Unlikely): Some sort of P2P but since there's a certain amount of Physics involved, I can literally feel my soul leaving my body having to deal with any of this. Plus, the game is mobile first, so any lag, disconnect will be / feel unfair. Also client authoritative is cumbersome to check for cheating.

alex-moonlitgames commented 1 year ago

Bump

mchamplain commented 1 year ago

To me Option 2 means rewriting everything, you need to think differently when you want to handle multiple matches. there's a risk of interference between matchs... scaling is a pain also.

Option 1 is probably your best bet will offer a more stable gameplay experience, any issue or crash would technically affect a single game. it's easier to predict ressource usage and easier to scale by just spawning more game servers. but being server-authoritative you might need to implement lag compensation and client prediction... but with movement and bullet speed seems slow enough that you might not need it at first... coop can probably work fine without it, but PvP will prolly need it.

WeslomPo commented 1 year ago

Entitas works fine in console application and don't need unity. Also, you can have as many copies of context in one instance as you want. In our project we have two copies of contexts in one game at same time for local and global data. You just need to manage that copies by hand or dependency container.

If I have to make a multiplayer game, I will choose 1 option.

alex-moonlitgames commented 1 year ago

Thank you for your thoughts! My second issue is physics, as it's a shooter game with collisions. It's got to be server authoritative but also I have to move core gameplay there as well, while at the same time having it in singleplayer game modes too.

Should I have a pure C# collision library both backend and frontend? Or use a UI-less Unity instance for each match?

SidiaDevelopment commented 1 year ago

You can use a UI-less Unity instance as a server, handling multiple games at once, tag each networked entity with an id what game it belongs to and only broadcast those that belong to the game the current player is in. You can load multiple maps, aslong as you offset them by a generous value so their physics objects do not collide

mchamplain commented 1 year ago

you can use Unity in headless-mode I think, my understanding is that it will simply work without rendering anything. a very simple implementation would be to have clients only send input to the server, process physics on the server, and sync position and stuff back to the clients. But lag will probably feel bad for players so you also run the physic on the client to control the 'local' player, but then you always take what the server say the position is so that clients can't cheat. on slow-ish movement it should work pretty well

alex-moonlitgames commented 1 year ago

@mchamplain Ha, I remember rubberbanding in shooters. Due to large amounts of physics layers, I probably would have to create a new instance for each match, rather than all games in the same instance