endless-sky / endless-sky

Space exploration, trading, and combat game.
https://endless-sky.github.io/
GNU General Public License v3.0
5.78k stars 1.02k forks source link

Variants within variants: an easier way to implement new ship variants into fleets #4668

Open Amazinite opened 4 years ago

Amazinite commented 4 years ago

Is your feature request related to a problem? Please describe. This is basically resurrecting #2143, but with a new suggested syntax. The core problem is that creating new ship variants and adding them to fleets is somewhat cumbersome, especially if you want a high variety of possible fleet combinations. This was brought up in #2143 in that if you have 3 ships with 3 variants each, there are 27 possible combinations of these three ships. It would be unreasonable to create 27 different fleet variants, so we end up losing out in fleet variant diversity for the sake of our sanity.

Related Issue Links

2143

Describe the solution you'd like Here is an example syntax of my idea of how we could make it easier to add variants.

variants "Leviathan"
    "Leviathan" 5
    "Leviathan (Laser)" 3
    "Leviathan (Hai Weapons)"
    "Leviathan (Hai Engines)"

fleet "Large Northern Pirates"
    ...
    variant 4
        variants "Leviathan" 2
        "Headhunter" 2
    ...

variants "<name>" is a list of ships similar to how fleet is a list of variants. The numbers following the ship names are their weight, functioning the same way as a fleet's variants. WIthin the fleet variant, the line variants "Leviathan" 2 means to pull a ship from the variants "Leviathan" list twice (not the same ship twice, but roll for a ship twice). The name of the variants does not need to match the name of the ship, and the ships in the variants don't even need to be the same ship. For example, one could create the following variants list.

variants "Republic Warships"
    "Cruiser" 2
    "Cruiser (Heavy)" 2
    "Cruiser (Mark II)"
    "Carrier" 4
    "Carrier (Mark II)"

variants could be modified by events in the same way as fleets, either being completely overwritten or simply added to or removed from. This means that whenever we create a new ship variant, instead of having to come up with a bunch of fleet variants for it to fit into, we could simply add it to a variants list that the fleets pull from.

Describe alternatives you've considered An alternative implementation could be that which @Lorantine described in #2143, which would also allow for a greater variety in the number of ships that appear instead of just the variant of ships that appear, but it doesn't seem like that would be as modular as this one, unless we combined the ideas and implement a similar notation for the variants (or even just all ship) described here, e.g.

fleet "Large Northern Pirates"
    ...
    variant 4
        variants "Leviathan" 1-3 10 5 2 # pull 1 to 3 ships from this variants list
                          # with a 10/17 chance of 1, 5/17 chance 
                          # of 2, and 2/17 chance of 3.
        "Headhunter" 2 # could also use that notation here if desired.
    ...

Although at this point that sounds like a separate issue.

As per #2143 as well though, it might not be a bad idea to allow unnamed variants definitions within a fleet variant.

# Yields the exact same results as the first example, but this `variants` list
# can't be used elsewhere
fleet "Large Northern Pirates"
    ...
    variant 4
        variants 2
            "Leviathan" 5
            "Leviathan (Laser)" 3
            "Leviathan (Hai Weapons)"
            "Leviathan (Hai Engines)"
        "Headhunter" 2
    ...
Amazinite commented 4 years ago

Slapping the milestone on this because #2143 was milestoned, and this really seems to me like a necessary feature to have at some point now that I've requested it.

Zitchas commented 4 years ago

I think this would go a long way to encouraging a larger variety of ships for the placer to encounter without massively magnifying the size of our fleets file. I would like to see this implemented.

tehhowch commented 4 years ago

How does one handle specifying accompanying ships? With a variant variant system, we lose the ability to exactly specify that a fleet has all bays occupied, because the number of bays is now possibly variable

Zitchas commented 4 years ago

Would it be possible to have the ship file itself contain references to carried ships, so that we could specify that, for example, when purchasing an ibis it comes pre-loaded with two petrels and 4 terns? Then everytime an Ibis is used in a fleet, it automatically comes with the appropriate fighter/drone count. That's probably a subject for a different discussion, though.

In terns of this variant list, could ships be given their own nested variant list? Then when one pulls a "Republic Carrier A" from the list of options, it goes and finds the Republic Carrier A variant list, which notes that it comes with 3 ships picked from the following list of B,C,D,E,F...

This would mean that each ship (and possibly each variant) with bays could have its own list of possible carried ships.

Amazinite commented 4 years ago

How does one handle specifying accompanying ships? With a variant variant system, we lose the ability to exactly specify that a fleet has all bays occupied, because the number of bays is now possibly variable

It could simply be that there's no guarantee for all bays to be filed should it be the case that someone fills a variants list with ships of differing bays. I'd imagine that in normal use, variants lists would only contain variants of a single ship instead of mixing ships, which means that you could guarantee the number of fighter and drone bays that need filled. If we want to have variants lists of multiple ship types though, perhaps we could have a new keyword fill for carried ships. The following would fill the two chosen ships with however many Lances and Combat Drones are needed.

variants "Republic Warships"
    "Cruiser" 2
    "Cruiser (Heavy)" 2
    "Cruiser (Mark II)"
    "Carrier" 4
    "Carrier (Mark II)"

fleet "Large Republic
    ...
    variant
        variants "Republic Warships" 2
        fill "Lance"
        fill "Combat Drone"
    ...

And if you want to fill the bays with differing ship types, you'd give each fill a weight. In this case, the Lance is 3 times more likely to get chosen for a bay than the Dagger, as with the Combat Drone vs the Surveillance Drone.

fleet "Large Republic
    ...
    variant
        variants "Republic Warships" 2
        fill "Lance" 3
        fill "Dagger"
        fill "Combat Drone" 3
        fill "Surveillance Drone"
    ...

Or to be more explicit with exactly which category is being filled, the keywords could be fighters and drones.

fleet "Large Republic
    ...
    variant
        variants "Republic Warships" 2
        fighters "Lance" 3
        fighters "Dagger"
        drones "Combat Drone" 3
        drones "Surveillance Drone"
    ...

Should the specified ship not match the category (e.g. put fighters "Falcon" or something), it'd be ignored.

Amazinite commented 4 years ago

How does one handle specifying accompanying ships? With a variant variant system, we lose the ability to exactly specify that a fleet has all bays occupied, because the number of bays is now possibly variable

I think that this might actually be solved by the formation idea mentioned in #4704.

variant "Cruiser"
    "Cruiser" 3
    "Cruiser (Mark II)

variant "Carrier"
    "Carrier" 3
    "Carrier (Mark II)"

fleet
    variant # Top level variant
        variant # A variant for choosing which capital ship we use, 66% Cruiser, 33% Carrier
            formation 2
                variant "Cruiser" 2 # Choose 2 ships from the Cruiser variant, plus 8 combat drones
                "Combat Drone" 8
            formation
                variant "Carrier" 2
                "Combat Drone" 12
                "Dagger" 8
        "Frigate"
        "Gunboat" 2
    variant
        variant # 50/50 choose a Cruiser and their drones or a Carrier and their drones/fighters
            formation "Cruiser with complement"
            formation "Carrier with complement"

variant "Cruiser with complement"
    variant "Cruiser"
    "Combat Drone" 4

variant "Carrier with complement"
    variant "Carrier"
    "Combat Drone" 6
    "Dagger" 4
petervdmeer commented 4 years ago

I see the keyword variant being used for 2 different things here:

How about using a different keyword (versions) for the different types of ships (and the relative occurence of the type within the version)?

For your example:

versions "Navy Cruiser"
    "Cruiser" 3
    "Cruiser (Mark II)

versions "Navy Carrier"
    "Carrier" 3
    "Carrier (Mark II)"

fleet
    variant 20 # A variant for choosing which capital ship we use, 66% Cruiser, 33% Carrier
        "Navy Cruiser" 2 # Choose 2 ships from the Cruiser versions, plus 8 drones and fighters
        "Combat Drone" 8
        "Frigate"
        "Gunboat" 2
    variant 10
        "Navy Carrier" 2  # Choose 2 ships from the Navy Carrier versions, plus drones and fighters
        "Combat Drone" 12
        "Dagger" 8
petervdmeer commented 4 years ago

I also like Zitchas idea to have carried ships specified as part of the ship definition (and maybe refer to versions there as well).

A way to represent that (example based on fleet "Large Southern Merchants"):

versions "Southern Armed Transport"
    "Argosy" 30
    "Argosy (Laser)" 20
    "Argosy (Missile)" 15
    "Argosy (Blaster)" 25
    "Argosy (Turret)" 15
    "Bactrian" 2
        carry "Dagger" 3 #This can be an exact ship type, but also a reference to a version

The fleet would then look something like:

fleet "Large Southern Merchants"
    government "Merchant"
    names "civilian"
    cargo 4
    personality
        confusion 30
        timid frugal appeasing
    variant 20
        "Southern Transport"
        "Southern Interceptor"
    variant 30
        "Southern Transport"
        "Southern Interceptor" 2
    variant 30
        "Southern Armed Transport"
    variant 10
        "Southern Medium Warship"
        "Southern Transport" 3
    variant 10
        "Southern Medium Warship"
        "Southern Transport" 3
        "Southern Interceptor" 3
    variant 10
        "Southern Medium Warship"
        "Southern Transport" 3
        "Southern Light Transport" 4
        "Southern Interceptor" 3
    variant 12
        "Southern Transport" 3
tehhowch commented 4 years ago

Regardless of the keyword used to denote the "variant ship" definition, I believe it will be necessary to specify the keyword when using the functionality in a fleet variant node, unless remove load-time content sanity checks or defer them until after all nodes have been loaded. Otherwise, there is no way for the game to determine that the child token is a named version/variant or a named ship, as Set#Get will return a pointer no matter what, and Set#Find may return one (if it was loaded already) or nullptr (if it is not yet loaded, or if it is actually not present).

petervdmeer commented 4 years ago

I would like to keep the load-time sanity checks (where they are), so I agree with tehhowch on the keyword in the fleet-variant section (to differentiate between ships and ship-versions.

Hurleveur commented 1 year ago

If we want more flexibility on ships we should definitely have a way to do add or remove outfits, and then variants in variants would make a lot more sense, I think.