Gifting mechanics

Describe your experience with the latest version of FreeOrion to help us improve it.

Moderators: Oberlus, Oberlus

Forum rules
Always mention the exact version of FreeOrion you are testing.

When reporting an issue regarding the AI, if possible provide the relevant AI log file and a save game file that demonstrates the issue.
Message
Author
User avatar
swaq
Space Kraken
Posts: 190
Joined: Tue Aug 20, 2019 1:56 pm

Gifting mechanics

#1 Post by swaq » Mon Oct 07, 2019 10:33 pm

I am experimenting with the gifting mechanics and have been having trouble getting them to work. If I am in an alliance with the player the menu doesn't pop up at all. If I am at peace I get the menu to gift the fleet or planet to the other player but when I click it nothing happens.

Version: 2019-10-01.2681499
Attachments
save-20191007_152459.zip
(36.38 KiB) Downloaded 42 times

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 12529
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Gifting mechanics

#2 Post by Geoff the Medio » Tue Oct 08, 2019 5:52 am

Gifting is an order that works like scrapping; you have to end turn for it to take effect.

The issue with peace but not alliance allowing it is a good point, though.

Edit: hopefully fixed: https://github.com/freeorion/freeorion/ ... ac14a48995

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Gifting mechanics

#3 Post by alleryn » Tue Oct 08, 2019 12:22 pm

Geoff the Medio wrote:
Tue Oct 08, 2019 5:52 am
Gifting is an order that works like scrapping; you have to end turn for it to take effect.
I was testing with swaq.
Ending turn didn't cause the gifting to process. Also i believe there is supposed to be an icon (like with scrapping/colonization/invading) that appears when you intially order the gift. We weren't seeing any icons. Note that all our testing was done locally, each of us "playing against ourself".

User avatar
swaq
Space Kraken
Posts: 190
Joined: Tue Aug 20, 2019 1:56 pm

Re: Gifting mechanics

#4 Post by swaq » Sat Oct 12, 2019 10:43 pm

I went ahead and did more extensive debugging and found the culprit to be a sanity check that was incorrect. Something like "if any of the objects in the system are owned by recipient then return error" when it should be NOT that condition. After fixing that I found a crash when trying to cancel gifting of a fleet. Not entirely sure on the cause but mimicking the code for ungifting a planet made it not crash.

[My very first] pull request: https://github.com/freeorion/freeorion/pull/2590

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 12529
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Gifting mechanics

#5 Post by Geoff the Medio » Sun Oct 13, 2019 9:18 am

swaq wrote:
Sat Oct 12, 2019 10:43 pm
After fixing that I found a crash when trying to cancel gifting of a fleet. Not entirely sure on the cause but mimicking the code for ungifting a planet made it not crash.
That code was looping through a container (of orders), examining them and then removing the current item (by rescinding the order), which invalidates iterators to the removed item, which causes the looping to fail. By making a copy of the orders and iterating through that, but removing (rescinding) orders from the original container of orders, the iterators don't get invalidated.

Do you have a "real" name you want to be credited as, other than "swaq" or "swaqvalley"?

User avatar
swaq
Space Kraken
Posts: 190
Joined: Tue Aug 20, 2019 1:56 pm

Re: Gifting mechanics

#6 Post by swaq » Sun Oct 13, 2019 12:53 pm

Ahh, that makes sense.

I will PM you my real name.

JonCST
Space Kraken
Posts: 157
Joined: Sat Dec 15, 2018 4:28 am

Re: Gifting mechanics: how to designate a gift?

#7 Post by JonCST » Tue Oct 15, 2019 12:57 am

Hi all. I am currently running 0.4.8 build 2019-10-08.

I'm trying to give a planet and a ship to an ally, and cannot figure out how.

I have tried right and left clicking on everything i can think which might make sense, and a bunch which don't make sense: Planets, ships, empire names, pedia entries...

Does it just not work in this build? Or have i not used the correct sacred herbs and magic words yet?

A screen-shot might do wonders, if you have a version in which it works.

Thanks

Jon

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Gifting mechanics: how to designate a gift?

#8 Post by alleryn » Tue Oct 15, 2019 1:03 am

JonCST wrote:
Tue Oct 15, 2019 12:57 am
Hi all. I am currently running 0.4.8 build 2019-10-08.

I'm trying to give a planet and a ship to an ally, and cannot figure out how.

I have tried right and left clicking on everything i can think which might make sense, and a bunch which don't make sense: Planets, ships, empire names, pedia entries...

Does it just not work in this build? Or have i not used the correct sacred herbs and magic words yet?

A screen-shot might do wonders, if you have a version in which it works.

Thanks

Jon
This thread is about how gifting was broken. It isn't fixed until geoff's (10/8) and swaq's (10/12) commits, so your 10/8 version probably won't work...

Also the empire you're gifting to has to have a presence in the same system as the object you are trying to gift. Then right click the planet or fleet (not ship) you want to gift and the context menu will display an option to gift.

JonCST
Space Kraken
Posts: 157
Joined: Sat Dec 15, 2018 4:28 am

Re: Gifting mechanics: how to designate a gift?

#9 Post by JonCST » Tue Oct 15, 2019 2:13 am

alleryn wrote:
Tue Oct 15, 2019 1:03 am
JonCST wrote:
Tue Oct 15, 2019 12:57 am
Hi all. I am currently running 0.4.8 build 2019-10-08.
This thread is about how gifting was broken. It isn't fixed until geoff's (10/8) and swaq's (10/12) commits, so your 10/8 version probably won't work...
That's what i wasn't sure of, thanks for the update.
alleryn wrote: Also the empire you're gifting to has to have a presence in the same system as the object you are trying to gift.
Hmm. Definitely didn't know that.
alleryn wrote: Then right click the planet or fleet (not ship) you want to gift and the context menu will display an option to gift.
That's what i was hoping to see. Of course, with the wrong version, it won't display the option.

Thanks for all the info.

Dumb question: is there somewhere i could have read the mechanics? I looked moderately hard, and didn't find it, but maybe it is in one of the places i haven't looked yet?

Thanks again.

Jon

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Gifting mechanics: how to designate a gift?

#10 Post by alleryn » Tue Oct 15, 2019 2:25 am

JonCST wrote:
Tue Oct 15, 2019 2:13 am
Dumb question: is there somewhere i could have read the mechanics? I looked moderately hard, and didn't find it, but maybe it is in one of the places i haven't looked yet?

Thanks again.

Jon
I suppose the snarky answer would be "in the code". Honestly, swaq and i were chatting the other day and trying to figure out if he could invade that one native colony where the maintenance ship was. I was looking through to figure out whether invasion happened before or after combat (it's before). Anyhow, as i'm looking through i stumbled across something called HandleGifting(), which led me to remember how you were talking about giving planets to allies in our multiplayer game (readers: Jon, swaq, and I are on the same team in slow server multiplayer game).

Anywho, this is how i came to know that gifting was a thing, and led to us finding some of the errors in gifting. If it's better documented somewhere, i'm unaware of it.

The *Game Concepts*/Diplomacy category in the Pedia could use some work. Right now the only things is it are "AI Aggression Levels", which i don't even know what it has to do with diplomacy, and "Peace", which admittedly is a pretty nice concise informative article. "Alliances" and "Gifting" could certainly be added if someone had the motivation.

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 12529
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Gifting mechanics: how to designate a gift?

#11 Post by Geoff the Medio » Tue Oct 15, 2019 6:08 am

alleryn wrote:
Tue Oct 15, 2019 2:25 am
"Alliances" and "Gifting" could certainly be added if someone had the motivation.
That would be appreciated.

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Gifting mechanics

#12 Post by alleryn » Tue Oct 15, 2019 12:14 pm

I started looking through the code to figure out the mechanical effects of the various diplomacy levels for pedia documentation.

It looks like this is another place where the code wasn't updated when alliances were added? (Along with the gifting mechanics geoff fixed above):

Code: Select all

void GenerateSitRepMessage::Execute(const ScriptingContext& context) const {
    int recipient_id = ALL_EMPIRES;
    if (m_recipient_empire_id)
        recipient_id = m_recipient_empire_id->Eval(context);

    // track any ship designs used in message, which any recipients must be
    // made aware of so sitrep won't have errors
    std::set<int> ship_design_ids_to_inform_receipits_of;

    // TODO: should any referenced object IDs being made known at basic visibility?


    // evaluate all parameter valuerefs so they can be substituted into sitrep template
    std::vector<std::pair<std::string, std::string>> parameter_tag_values;
    for (const auto& entry : m_message_parameters) {
        parameter_tag_values.push_back({entry.first, entry.second->Eval(context)});

        // special case for ship designs: make sure sitrep recipient knows about the design
        // so the sitrep won't have errors about unknown designs being referenced
        if (entry.first == VarText::PREDEFINED_DESIGN_TAG) {
            if (const ShipDesign* design = GetPredefinedShipDesign(entry.second->Eval(context))) {
                ship_design_ids_to_inform_receipits_of.insert(design->ID());
            }
        }
    }

    // whom to send to?
    std::set<int> recipient_empire_ids;
    switch (m_affiliation) {
    case AFFIL_SELF: {
        // add just specified empire
        if (recipient_id != ALL_EMPIRES)
            recipient_empire_ids.insert(recipient_id);
        break;
    }

    case AFFIL_ALLY: {
        // add allies of specified empire
        for (auto& empire_id : Empires()) {
            if (empire_id.first == recipient_id || recipient_id == ALL_EMPIRES)
                continue;

            DiplomaticStatus status = Empires().GetDiplomaticStatus(recipient_id, empire_id.first);
            if (status == DIPLO_PEACE)
                recipient_empire_ids.insert(empire_id.first);
        }
        break;
    }

    case AFFIL_ENEMY: {
        // add enemies of specified empire
        for (auto& empire_id : Empires()) {
            if (empire_id.first == recipient_id || recipient_id == ALL_EMPIRES)
                continue;

            DiplomaticStatus status = Empires().GetDiplomaticStatus(recipient_id, empire_id.first);
            if (status == DIPLO_WAR)
                recipient_empire_ids.insert(empire_id.first);
        }
        break;
    }

    case AFFIL_CAN_SEE: {
        // evaluate condition
        Condition::ObjectSet condition_matches;
        if (m_condition)
            m_condition->Eval(context, condition_matches);

        // add empires that can see any condition-matching object
        for (auto& empire_entry : Empires()) {
            int empire_id = empire_entry.first;
            for (auto& object : condition_matches) {
                if (object->GetVisibility(empire_id) >= VIS_BASIC_VISIBILITY) {
                    recipient_empire_ids.insert(empire_id);
                    break;
                }
            }
        }
        break;
    }

    case AFFIL_NONE:
        // add no empires
        break;

    case AFFIL_HUMAN:
        // todo: implement this separately, though not high priority since it
        // probably doesn't matter if AIs get an extra sitrep message meant for
        // human eyes
    case AFFIL_ANY:
    default: {
        // add all empires
        for (auto& empire_entry : Empires())
            recipient_empire_ids.insert(empire_entry.first);
        break;
    }
    }
https://github.com/freeorion/freeorion/ ... 3237-L3248

Line 3244 which is testing for peace should probably be changed to test for peace/ally?

Code: Select all

if (status == DIPLO_PEACE)
-->

Code: Select all

if (status >= DIPLO_PEACE)
in the case

Code: Select all

 case AFFIL_ALLY: {
        // add allies of specified empire
Does that seem right?

EDIT:
And also here:

https://github.com/freeorion/freeorion/ ... 1190-L1198

Code: Select all

            case AFFIL_ALLY: {
                if (m_empire_id == ALL_EMPIRES)
                    return false;
                if (m_empire_id == candidate->Owner())
                    return false;
                DiplomaticStatus status = Empires().GetDiplomaticStatus(m_empire_id, candidate->Owner());
                return (status == DIPLO_PEACE);
                break;
            }
For this "affiliation" code, do we need a separate case statement for allied affiliation, or should peace and allied be grouped together?
/EDIT

Edit2:
There is another instance of this same affiliation type code. The relevant line is 3510 in Effect.cpp SetVisibility::Execute
https://github.com/freeorion/freeorion/ ... .cpp#L3510

I believe this may pertain to a bug we observed (but haven't reported) from our current multiplayer game, where players weren't able to see planet specials uncovered by allies.
/Edit2

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Gifting mechanics

#13 Post by alleryn » Tue Oct 15, 2019 3:02 pm

I finished searching the code for DIPLO_ and its dependents, which hopefully gave me an understanding of how diplomacy works. Here's what i have:

allies:
share visibility
share supply
humans can share victory (depends on game rules)

peace:
can gift

war:
default
can invade
can bombard
ships block supply
ships attack each other
armed ships prevent colonization
can blockade

gifting:
at peace
owned object in system

Based on that, here are my proposals for the Pedia (changes are underlined, note that i probably have the syntax wrong for linking other articles, but it should be close enough to convey the idea until i nail down that detail):
  • DIPLOMACY:
    • \default\scripting\encyclopedia\game_concepts\diplomacy\DIPLOMACY.focs.txt (unchanged)
    • name = DIPLOMACY_TITLE = "Diplomacy" (unchanged)
    • short desc = DIPLOMACY_ARTICLE_SHORT_DESC = "Diplomacy" (unchanged)
    • desc = DIPLOMACY_TEXT = "Non-exhaustive list of Diplomacy features:" --> "List of Diplomacy features:"
  • WAR:
    • \default\scripting\encyclopedia\game_concepts\diplomacy\WAR.focs.txt (new)
    • name = WAR_TITLE = "War"
    • short desc = WAR_TITLE
    • desc = WAR_TEXT = "War is the default diplomatic state between empires. Armed ships will enforce a [SYSTEM_BLOCKADE_TITLE] on enemy ships, obstruct enemy [[metertype METER_SUPPLY]] lines, impede enemy colonization, and engage in combat with enemy ships. Enemy planets may be subjected to invasion or bombardment."
  • PEACE:
    • \default\scripting\encyclopedia\game_concepts\diplomacy\PEACE.focs.txt (unchanged)
    • name = PEACE_TITLE = "Peace" (unchanged)
    • short desc = PEACE_TITLE (unchanged)
    • desc = PEACE_TEXT = "Peace is the diplomatic state between empires in which they mutually agree not to attack each other's ships or planets, not to enforce a [SYSTEM_BLOCKADE_TITLE] on each other's ships, not to allow ships to obstruct each other's [[metertype METER_SUPPLY]] lines, and not to impede colonization. Peace is the minimum level of diplomacy at which [GIFTING_TITLE] between empires is allowed."
      As far as i can tell War and Peace are the same as far as supply propagation goes (planetary supply can still obstruct a peaceful opponent's supply). Colonization can still be "impeded" if two colony ships are attempting to colonize at once. Really this statement means that armed ships don't impede colonization of a peaceful opponent, but i can't think of a way to word that without making it overly-complicated.
  • ALLIANCE:
    • \default\scripting\encyclopedia\game_concepts\diplomacy\ALLIANCE.focs.txt (new)
    • name = ALLIANCE_TITLE = "Alliance"
    • short desc = ALLIANCE_TITLE
    • desc = ALLIANCE_TEXT = "Alliance is the closest diplomatic state between empires. Allied empires share visibility and [[metertype METER_SUPPLY]] lines. Allied empires may share victory when the relevant Game Rule is set accordingly."
  • GIFTING:
    • \default\scripting\encyclopedia\game_concepts\diplomacy\GIFTING.focs.txt (new)
    • name = GIFTING_TITLE = "Gifting"
    • short desc = GIFTING_TITLE
    • desc = GIFTING_TEXT = "Empires with sufficiently close dipomatic relations ([PEACE_TITLE] or closer), may gift planets or fleets to one another, provided the target empire has a presence (ship or planet) in the same system as the object being gifted."
      Note: As far as the code is concerned the other empire's presence may be any object, but in practical terms i think this really amounts to an outpost, colony, or ship (there's no way, for example, for an empire to control a building a system without controlling an outpost or colony there).
  • SUPPLY:
    • desc = METER_SUPPLY_VALUE_DESC =
      '''The supply meter on a planet represents the number of star-lanes supply can extend through. Smaller planets can supply greater distances, large planets reduced distances.

      Supply lines are shown by coloring star-lanes with an empire's color. Planets connected by supply lines form a 'Resource Group' and can share physical resources. Production Points created on one planet can be used on any connected planet to build ships or structures.

      A set of core supply starlanes for an empire (the set of least-jump starlanes connecting the resource-producing systems of each Resource Group) will have greater thickness than the non-core starlanes. If PP is currently being wasted within a Resource Group, the outer bands of the core starlanes will be a contrasting color.

      Supply lines can also be used to refill the [[metertype METER_FUEL]] supply of ships.

      Supply lines will be obstructed by armed enemy ships belonging to empires with which an empire is at [WAR_TITLE]. At the opposite end of the spectrum, empires in an [ALLIANCE_TITLE] will share supply lines and all their associated benefits.'''
  • AI_LEVELS:
    • category = "DIPLOMACY_TITLE" --> "CATEGORY_GAME_CONCEPTS"
Edit:
System Blockade: war --> [[encyclopedia war]]
/Edit

Please submit any and all criticisms and suggestions for improvement, typos, etc. Thank you!

Note: At some point in the future i would advocate for standardizing the symbols used for name, short desc, etc and separating out the ones that are categories, e.g.
  • name = DIPLOMACY_TITLE --> CATEGORY_DIPLOMACY_TITLE
  • short desc = DIPLOMACY_ARTICLE_SHORT_DESC --> CATEGORY_DIPLOMACY_SHORT_DESC
  • name = PEACE_TITLE (unchanged)
  • short desc = PEACE_TITLE --> PEACE_SHORT_DESC
Last edited by alleryn on Wed Oct 16, 2019 2:55 pm, edited 1 time in total.

User avatar
Geoff the Medio
Programming, Design, Admin
Posts: 12529
Joined: Wed Oct 08, 2003 1:33 am
Location: Munich

Re: Gifting mechanics

#14 Post by Geoff the Medio » Tue Oct 15, 2019 6:10 pm

alleryn wrote:
Tue Oct 15, 2019 12:14 pm
For this "affiliation" code, do we need a separate case statement for allied affiliation, or should peace and allied be grouped together?
There should probably be a separate AFFIL_PEACE and associated parsers and handlers. For now, a pull request to change those == DIPLO_PEACE to >= DIPLO_PEACE would be a good fix.

User avatar
alleryn
Space Dragon
Posts: 259
Joined: Sun Nov 19, 2017 6:32 pm

Re: Gifting mechanics

#15 Post by alleryn » Tue Oct 15, 2019 6:16 pm

Geoff the Medio wrote:
Tue Oct 15, 2019 6:10 pm
alleryn wrote:
Tue Oct 15, 2019 12:14 pm
For this "affiliation" code, do we need a separate case statement for allied affiliation, or should peace and allied be grouped together?
There should probably be a separate AFFIL_PEACE and associated parsers and handlers. For now, a pull request to change those == DIPLO_PEACE to >= DIPLO_PEACE would be a good fix.
Will do. Edit2: Done. https://github.com/freeorion/freeorion/pull/2595 I tested briefly in both multiplayer and singleplayer. /Edit2

Minutes ago i encountered a serious bug, which hopefully will be fixed by those changes. I have formed an alliance between two empires. Empire 1's visibility is shared with Empire 2, but Empire 2's visibility is not shared to Empire 1.

Edit:
Those changes didn't seem to affect visibility in the way i had hoped.

After further testing, this bug is not so serious as i first thought. The vision sharing does seem to be symmetrical.

The bug seems to be that vision is only granted when fleets move, or something like that. In the save, moving a ship off of the green homeworld exposes vision both of that ship, and of the homeworld itself.

/Edit

Edit3:
I went back to test again, and i'm not sure what i was seeing before.

Current visibility does seem to be shared correctly. Data about "known unknowns" (e.g. planets previously explored but not currently visible) is not shared. This feels a little unintuitive but may or may not constitute a bug. In any case, i don't think it should be considered high priority. I will include a screenshot below to illustrate the situation a bit better:
Image
Save:
MultiplayerVisionAssymetry.zip
(161.01 KiB) Downloaded 23 times
Last edited by alleryn on Wed Oct 16, 2019 11:54 am, edited 5 times in total.

Post Reply