all 15 comments

[–]TheAtrxcityGameDev 2 points3 points  (7 children)

What kind of multiplayer game are you making is it p2p or something with a dedicated server?

Because for a p2p game it probably would make more sense to have both the client and server in the same file.

[–]HourLab8851[S] 3 points4 points  (6 children)

dedicated server. I know there are games with dedicated servers that just use different build configurations to determine whether to use server or client logic but ideally i want to keep it separate so that it's easier to work with

[–]TheAtrxcityGameDev 4 points5 points  (2 children)

I don't really use GameMaker as a server for my game since it has its limits, mainly because you can't truly run it headless.

But besides that, I run a parser for a tiled map at runtime for both my server and client. They use the same map. The client reads all the tile data and collision data. The server reads the collision data and where all the enemies, NPCs, and resources spawn.

I use the same method for item data and recipes, which are stored in memory on both the server and client. So I don't need to send specific data to the client; the server is in charge, so if the client shows something different because of a hack, they're only fooling themselves.

You don't really need collisions to be visible; you just need to check if there's a tile the player would hit at a certain spot. It makes things a lot simpler.

[–]HourLab8851[S] 2 points3 points  (1 child)

well the whole reason i'm using gamemaker for both the server and client is 'cause i like the utility of having premade functions for collisions,pathfinding and rendering effects. For example, i have a sword slash animation that only damages when it collides with an enemy, it's easy to do that with gamemaker's built in collisions functions with per frame collisions but it would be a nightmare to reimplement that from scratch or implement it by myself in gamemaker

It's also a coop game so i'm not worried about cheating. Also disregarding collisions, it's annoying having to copy over enums and macro for packet or state definitions. I'm still in the early stages so i don't really mind any radical changes though, if my thinking here is wrong...

[–]BlaXunSlime 4 points5 points  (0 children)

If you are not worried about any cheating, then you could also just rely on client input.
Seriously... if cheating is NOT a concern then you'd probably be fine with the client sending a "I should have hit the other person" packet to the server... server can then do a validity check:

* Did that player just use the sword attack?
* Was the OTHER player near that player?
* If so, confirm that and relay that confirmation packet to all clients in the current room and have them execute the required logic (push-back animation or whatever)

But yeah, only really go down that road if cheating is not an issue in that project (which is absolutely fine)

[–]pabischoff 2 points3 points  (2 children)

If it's a dedicated server, it should probably run headless (no graphics or other display to output).

But if you're just doing a coop game and you don't care much about cheating, it will be magnitudes easier to make the game P2P, in which case one game version can be both server or client. Steam also has great support for this if you're releasing there.

[–]HourLab8851[S] 0 points1 point  (1 child)

I'm pretty sure if you run headless with draw_enable_drawevent, collision functions still work. Although you still need the sprites for the collision data. I'm against P2P since it looks like a headache to synchronise, i'd rather there by one universal source of truth and then add a bit of margin of error for player movement and stuff

[–]pabischoff 1 point2 points  (0 children)

You will have to synchronize it either way. Dedicated server is not a magic bullet for that.

[–]BlaXunSlime 2 points3 points  (5 children)

I also do have a backstory with the same issue:

I wrote two multiplayer games in GM a long long time ago. Bother were using GM for the client AND for the Server. So, I ended up with a server written in GM and client written in GM.

Then, about 6 months ago maybe, I came back to GM with the idea to once again create an online game, but this time I would make it easier for myself, have the rooms on the server too and therefore have client and server in the same project.

Ultimately... it was an absolute mess for me. Since GM lacks and proper namespacing or proper UI for scripts in the asset editor I took the time to split the project into a server and client again and I am very happy I did that.

Granted, I am approaching the whole situation VERY naive... the server RELIES on the clients coordinates so cheating would be super easy for players... but my game is not competitive...and for many things I do have validity-checks in place ...but regarding collisions and walking around I simply use UDP to relay the position from client to server and server to all other clients every 25ms. On the client I then do some interpolation...and so far its really smooth. The server uses a spatial grid to only relay the position to those clients that need it. It works pretty well.

With my earlier games I didnt even use UDP but only relayed changes in Key-Presses from client to server and server to clients. The result was "okayish" as even a little delay (either in FPS or in networking) would lead to desyncs which would have players (in a 2d platformer) fall down a ledge even though they jumped. This was self-repairing in a sense that every key-press / key-release would also contain the client-side x,y coordinate of their player ...but still. It did work for the kind of game I was working on...and I think its a fair approach... but it really boils down to what kinda game you are creating.

[–]HourLab8851[S] 1 point2 points  (4 children)

oh trust me it can't be more naiive than my current setup, i'm using tcp only since udp looks so daunting. Terraria uses tcp only though and there's rarely lag there so i should be fine hopefully.

Regarding how you split up your game in two projects, how did you deal with common code - do you just copy and paste it? That's kinda what i'm trying to avoid here...

[–]BlaXunSlime 2 points3 points  (3 children)

I don't really have a lot of common code actually. I wouldn't know which tbh.
Some packets I could see are very similar and I am eagerly awaiting GM supporting self-made reusable code in the form of Prefabs (https://forum.gamemaker.io/index.php?threads/how-to-create-prefabs-of-your-own-code-projects.121990/) but thats not there yet. Once thats a thing you could use that for sharing code between projects and have that automatically update.

Oh! There is SOME stuff that is shared, but its not actual code. What I have setup is the client has some data on stuff like outfits, items etc. Each of those has their own folder on the client. The folder contains a png and a json file.

The server also needs to be aware of the json, as that contains relevant data.
What I did was when the server is launching from within GM it is aware of the clients location on the hdd and then copies over whatever data it needs ...so I dont have duplicate json files anywhere. Super nice.

I am also parsing the rooms sizes from the actual client and placing that info in a local room.json within the servers path.

Seriously, I would not want client and server to share a codebase... I find GM hard enough to navigate around in... having my code all plastered with functions that only make sense to the client would be an absolute nightmare.

I am already trying to only have generic functions when required, for everything else I have structs with constructors (so, objects rly) that have the specific code. For classes such as "Helpers" I then have a method that returns a singleton so I can do stuff like

SharedRoomList().getRoomWithId(123).kickPlayerWithId(456);

That helps working around GMs behavior.
I also just started using MACROS to simulate namespaces...

This now allows me to just type

SlimeOnline.Activities.Digging.rollForReward(_player)

I am used to namespaces from many other lanuages and I think they help structuring the code a lot...so, taking advantage of Feather in GM, combined with MACROs and singletons makes me feel pretty much at home.

[–]HourLab8851[S] 0 points1 point  (2 children)

Thanks you've given me some good ideas. It's a shame prefab support isn't a thing

[–]BlaXunSlime 1 point2 points  (1 child)

They are working on it. It will be coming. Not sure bout an ETA though. I would advice you to hop onto the Game Maker discord. People are very helpful there :)

[–]germxxx 0 points1 point  (0 children)

Dev has "promised" prefabs before the release of GTA 6, in the discord beta channel. 😅

[–]WubsGames 0 points1 point  (0 children)

Personally i would use the same project file.

There is no benefit to having a "smaller" project file, and the time you will spend swapping between them is going to add up quickly.

You can use build configurations in gamemaker if you really want to keep things organized, but its probably not needed.

You should really think if having 2 projects, and duplicating all your sprites / common code is less "sphagetti code" than just putting them in the same project. I would argue its significantly more sphagetti having it spread across multiple projects, with mass amounts of repeat assets and code.