Multiship gameplay

edited August 2016 in EmptyEpsilon
I would have called the post "multiplayer", but it's always the case with 6 players per ship..!

More and more people get to know Empty Espilon, and a few larps and conventions appear looking for activities with many players and many ships. This post is a wish to open the discussion about questions, problems and suggestions for the features of the game in a multiship environment.

I'll start by making a few list of the topics that could be discussed here :

1. - player compared to playerS in the code.
2. - Customizable ships
3. - player vs player... and the factions
4. - multiplayer scenarios
5. - Communication across players and factions.
6. - Game stability
7. -

----

1. "Player" in the code.
I've had some issues working with many ships in the code. Since i'm quite new to all this, I tired to start from parts of the code of other scenarios to create new ones. Since all current scenarios are meant for 1 player (or 2 in one scenario), the player is always identified as "player" in the code.

When working with 3 to 7 ships, I had to create different names for every ship. ex :

GuerrillaRadio = PlayerSpaceship():setFaction("Arianne"):setTemplate("Camelot")
GuerrillaRadio:setTypeName("GuerrillaRadio"):setCallSign("TGR")


Then if I wanted to create an event when any player pass in an area, it became complicated... I though maybe to call for something like "if PlayerSpacship() then", or repeat the function for all ship names.

- Am'I doing this right ?
- Is there a way to affect all players ship's at once ? like by sending a message or tweaking the ship.
- Have you had some toughts or ideas about this ?

:)

Comments

  • 2. Customizable Ships

    Players love the idea of improving their ships and make a choice in how to tweak it in a way that best fits their type of gameplay. It differentiate them from all the other similar ships in the same game and is an important part of the multiship experience. For Dussel-3, we had a system of credits and store to buy ship improvements that taht made players quite ecstatic.

    Before starting the scenario, we could then tweak the ships with the DM screen. But it gets long for 7+ ships. I tried to simplify this process by regrouping the ships stats in one document. It worked well at first, then we had crashes and we tougth it might be one of the reasons.

    I had all playerships stats in one script : "playership_dussel.lua" with info like :
    DIVX = PlayerSpaceship():setFaction("Vindh"):setTemplate("Artheurge")
    DIVX:setTypeName("Camarade DIVX"):setCallSign("DIVX")


    Then in the scenario, I would call the script : require("dussel/playership_dussel.lua")

    and then put it in play with a position : DIVX:setPosition(-357000, 15000)

    ----

    The idea was that I could only alter the "playership_dussel.lua" script to tweak the ships, and when the scenario would prompt it, all changes would be made. Ex :

    DIVX:setBeam(3,100, 0, 1000.0, 6.0, 10)

    ----

    I wondered if it was something you thought about. If it is something you were looking for and/or had ideas of how to implement in the game.

    Also, I noticed that many players would've like the ability to chance the model or color of their ship (some model include a few different colors scheme). Actually I understand it is impossible by how the model are called. Is there a way (and will) to change that ?
  • The "player" link is just used in the single ship scenarios. The actual "engine" of the game has no concept of a single player ship. The PvP scenario is the best example of this.
    Writting multi-ship scenarios is more complex, not just because you have more ships to track, also because you have way more things that could happen in/out of order.


    Calling "PlayerSpacship()" will create a new ship. So "if PlayerSpaceship() then" does not do what you want. It creates a new ship...

    As already explained, you can create multiple player ships just fine, and assign them to different names (actually, variables)
    
    ship_alpha = PlayerSpaceship():setTemplate("Atlantis"):setPosition(0, 0)
    ship_beta = PlayerSpaceship():setTemplate("Atlantis"):setPosition(1000, 0)
    ship_gamma = PlayerSpaceship():setTemplate("Atlantis"):setPosition(1000, 1000)
    
    Now, this allows you to use ship_alpha, ship_beta and ship_gamma troughout the code, just like "player" is used in most scenarios.

    This does make it tedious if you want to do the same thing on all 3 ships. And there are 3 "main" things you might want to do on all ships. You might want to apply something on all ships (for example a modification, or a message).
    You might want to check if all ships have a condition (for example, all ships are are near location X)
    Or you might want to check if ANY of the ships has a condition.

    This is where more advanced programming constructs are useful. Note that the scripts are written in lua. While slightly dated, the Lua PIL 1.0 is a useful read: https://www.lua.org/pil/contents.html
    (Up to chapter 7, after that it becomes less relevant and goes into more advanced things that are not all available in EE)

    Some example code that might help.
    
    --Create our 3 ships
    ship_alpha = PlayerSpaceship():setTemplate("Atlantis"):setPosition(0, 0)
    ship_beta = PlayerSpaceship():setTemplate("Atlantis"):setPosition(1000, 0)
    ship_gamma = PlayerSpaceship():setTemplate("Atlantis"):setPosition(1000, 1000)
    
    --Create a table to store all player ships, and put the ships in this table.
    all_player_ships = {}
    table.insert(all_player_ships, ship_alpha)
    table.insert(all_player_ships, ship_beta)
    table.insert(all_player_ships, ship_gamma)
    
    Now we have a table called "all_player_ships" which is actually a list of all the player ships that we created. This is useful. Because, for example, if we want to send a message to all players, we can do:
    
    --Assumes that main_command is a ship/station created earlier.
    for number, ship in ipairs(all_player_ships) do
      main_command:sendCommsMessage(ship, "Message for you sir")
    end
    
    Checking for conditions is a bit more complex. The easiest way to follow would be to do this:
    
    --Check if all ships are within a distance of a point.
    all_in_range = true
    for number, ship in ipairs(all_player_ships) do
      if distance(ship, 5000, 5000) > 1000 then
        all_in_range = false
      end
    end
    if all_in_range then
      --Do something when all ships are in range.
    end
    
    This also works for checking a single ship condition, but then a bit the other way around.
    
    --Check if all ships are within a distance of a point.
    one_in_range = false
    for number, ship in ipairs(all_player_ships) do
      if distance(ship, 5000, 5000) < 1000 then
        one_in_range = true
      end
    end
    if one_in_range then
      --Do something when one of the player ships is in range.
    end
    

    This is the simplest way I could think of how to make things happen with multiple player ships. Note that it does not really matter if it's player ships, cpu-ships, or any other thing. If you want to keep track of a 100 asteroids, it works exactly the same. Example, the "waves" scenario is using code like this to keep track of all the enemy ships.
  • Wow...
    That is quite a course ! Thanks Daid ! I'll keep that as a good reminder.

    I tried to use tables to generate reputation to those of a certain table when certain criteria was met but I must've made something wrong somewhere.

    Another situation that happens is the fact that it means I would've to plan all ships to put in the game, then delete those that wont be used. In our next event, we would like to give the choice to the players of which scenario they will do.

    I would also have to make sure to have an update script for respawn that would put the new ship in the table again. In pvp, death is a common thing... Something like this I suppose ? (taken from the pvp scenario).

    if (not ship_alpha:isValid()) then ship_alpha = PlayerSpaceship():setFaction("Human Navy"):setTemplate("Atlantis"):setPosition(-8500, 15000) table.insert(all_player_ships, ship_alpha) end

    I also tried a new function to add a new playership from the GM screen (if i wanted to choose the moment to respawn a ship)
    addGMFunction ("Respawn playeship", function()
    				
    			if not DIVX:isValid() then
    				DIVX:setPosition(532600, -38600):setCallSign("DIV X2")
    			end
    
    (( then I would repeat for each other ship)) 
    
    end)

    ---

    note : I don't know if you see it in the same way as me, but the "code" function on this forum shows a yellow box with white text. It's mostly unreadable... baybe we could use a dark grey instead of yellow.
  • edited August 2016

    note : I don't know if you see it in the same way as me, but the "code" function on this forum shows a yellow box with white text. It's mostly unreadable... baybe we could use a dark grey instead of yellow.

    Yeah, that looks bad. Will try to fix tomorrow.
  • Setting the background of code,pre to #222 seems like a quick fix.
  • edited August 2016
    The color should be fixed now. It was picking up on the default theme's color scheme.
  • The Shoreline scenario is set up for single ship or multiple ships. I've tested a bit with two ships, but I'd love to hear from anyone else that tries it out. The scenario is in a pull request that has not yet been reviewed. You can try it yourself before it gets included in a release:

    https://drive.google.com/open?id=1_-grLPUXl_wvp_XGysDsKlD1n-t1Wbj3
  • Certainly going to try it with my group! Thanks for sharing that!!
Sign In or Register to comment.