Enemy Coding Concepts in Multiplayer

  • GenkiGenga - I have a feeling there's going to have to be a LITTLE compromise with a MP game. I'm okay with the host dictating that. I'll let you know how the rest turns out!

  • Sorry to reprise this, but I'm now getting some interesting issues with Syncing the enemies.

    On start of the game, it has a single event that syncs the enemy family. Once you're in the game, you can connect to a room via menus, and join in. Once you start a new game, the enemies seem fine. As you continue on through new layouts, the enemies start having weird behaviors (ie some of the positions overlap each other on the peer machine until the peer attacks an enemy). Then the enemies created weren't being created on an exact X and Y, so when I call an "on created" event for the enemies, I set an "instance" variable so I can call each enemy on both machines. However, due to the nature of the enemies being created, the X and Y start to differ the more the game goes on.

    So I thought I'd sync the instance "instance" variable for the enemy family. Then on enemy created, I set the "instance variable" to the X and Y position if you're the host. However, that's not syncing to the peer player, and the instance is just forever "".

    Am I using sync variable incorrectly? And more importantly, why are some of the enemies being created on each other instead of their original position?

  • GenkiGenga - sorry to bring you back into this, but I can't find any appropriate documentation on syncing variables. Any idea on the best way to do this?

    Sorry for the shameful bump

  • Hey mate sorry for the slow reply.

    What you need to do is, before switching a layout have the host destroy all instances of synced objects (this means the peer has to wait a little bit for the update to get through as well once it is destroyed on the host). Otherwise they can carry over and at times you will have 2 of the same object (I'm guessing this is the cause of your x,y issues but couldn't be sure without looking at your project).

    If you refer to the ghost shooter multiplayer demo, you see you have 3 variables synced - health, kills and deaths. Once synced As long as you are only manipulating those variables on the host side it should be working. Remember you can always bring up the debug and find your zombie objects and check the individual variables for each when dealing with problems like this (will let you know if you have duplicates).

    I'm not sure that you can sync variables for the family object itself (I think i remember reading something a while back, its not something I have tried anyway). If you are doing the above correctly then syncing the zombie object instead may solve the problem.

    Let me know how you go.

  • GenkiGenga - no problem at all.

    I'm a bit confused, though. Doesn't the objects get destroyed on layout change?

    Basically, the way I'm creating my enemies is by using "spawner" objects that then create the enemy on the start of the layout (I do this strictly to disable enemy groups that aren't being used, and in case I change something, I can change the single sprite on my main spritesheet and it will change for everyone that's spawned). For the peer, I do the same thing but instead of creating an enemy I delete the spawner.

    I am, however, trying to sync a variable for a family. That could be why it's not working.

    So here's a possible better question (because this would save the syncing bandwidth if I could figure out a better way to do this) - Instead of setting an instance to the X and Y position of an enemy, what is something I could set a text variable for each enemy on both the Host and Peer sides that would be 100% fool proof?

    And if there is none, I'll try syncing every enemy individually with the instance variable and see how that goes.

  • The host will destroy all objects on the end of layout, but say the peer switches to a new one before the update from the host to destroy is received. In that case the synced objects can carry over into the new layout at the position they were in. In my experience it is a bit random so best practice is to wait a little bit to make sure it goes through by manually destroying them first.

    Any easy way to number your enemies would be with an instanced variable "EnemyNumber" and a global variable (number). Call it "EnemyCount".

    On the host side whenever you create a zombie, add one to EnemyCount and then set the EnemyNumber variable to the global variable.

    On the peer side (if you dont want to sync the variable) you could use the "On Created" system option and use the same technique. Might need to double check this works every time, not sure if there is potential variance with the order objects are spawned using the sync method with a large number.

  • GenkiGenga

    Thanks for the quick response!

    Okay, I've confirmed that changing the family to a sprite does not sync the variable. It must be a bug, then. I'll probably have to try it on a blank session and report it.

    I like the idea of the enemy count, but yeah, I'm not sure in what order the enemies are created. It might be worth a try since nothing else seems to be working...

  • No worries Steve.

    I think Ashley mentioned it was by design (families not being able to sync variables but I could be wrong).

    If you tried syncing the sprite itself and the instanced variable (not the family variable) and still no go then that is weird. I just double checked the ghost shooter demo to be sure, there is more than 3 synced variables actually - and it is working properly there.

    Recreating the problem in a minimised cap.x and then seeing how your project code is different once the issue is resolved is an awesome way to squash bugs though.

  • GenkiGenga - thanks for the help. I'll try that and see if it tells me anything.

    I wonder if you can only sync an object if the object is on-screen?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Any time,

    Shouldn't affect the sync whether the object is on screen or not. I am guessing you have an event that isn't triggering because the pick condition fails for whatever reason. It's always frustrating dealing with bugs like this but it is good experience in the long run. Stay determined

  • Ashley - I'm wondering if you could shed some light on this?

    TLDR version:

    I'm syncing the position of a family (which is working perfectly for each individual enemy), and then syncing an "instance" instance variable on the start of the first layout. On enemy created, I'm setting the instance var to str(X) & str(Y) on ONLY the host machine. But the instance is never being set on the peer machine (it's always "").

  • GenkiGenga - I figured it out! I made a test cap3 file and tried everything. It all worked - synced absolutely fine until....I changed the variable to a string. Apparently (doesn't say this in the manual, it seems) you cannot sync a string variable, only a number variable.

    Makes my job a bit harder having to redesign, but at least it works.

    UPDATE - Wow, this is even more limiting than I thought...you can only sync numbers below 255 (anything above will just return 255). Just curious, is there a reason for this, Ashley?

  • Huh! Ah ok, yeah I had no idea about that. Definitely seems like a bug. Nice work with that, I'm sure you just saved me some trouble down the line.

    Edit: I just went back and checked the manual again and it does say at the end of sync variables that it doesn't work for text instance variables. So I guess it's working as intended. Still good to know.

    Re the 255 limit, I tested this as well and it worked for me (just had the host sync a number variable and increase it as time went on). Was able to exceed 255 in chrome. What browser are you using to test?

  • https://strawberrypunchonline.com/

    When you sync a variable, you pick a "precision"

    Very Low means 0 to 255 integers (integers means no decimals)

    Low means -32768 to 32767 integers

    Normal is a Float which means you can get decimals but the higher the number the less decimals and precise it is and can use 7 characters to compose the number or something

    Double is like a float but it can use more number slots so it's more precise

    IF you can't go over 255 it means your variable is very low.

    None of these are bugs. String data would be very bad to sync 30 or 60 times a second and you don't really have any reason to. For example in my game if i want to change character apperance I send a String with the Send Message action with Reliable unordered and every other player know what the new character apperance is. (press the letter O to change apperance) There is no reason for every single player to sync appearance 30 times a second

  • - ah that makes sense, thank you!

    GenkiGenga - Nor did I! And you're right, it does say that in the manual. That is definitely something that should be bold

    Thanks for all your help!

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)