1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. Photobucket has changed its policy concerning hotlinking images and now requires an account with a $399.00 annual fee to allow hotlink. More information is available at: this link.
    Dismiss Notice
  3. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  4. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  5. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  6. Dismiss Notice
  7. Forum account upgrades are available for ad-free browsing.
    Dismiss Notice

Dom Pedro's Mod Helper for Python Modders

Discussion in 'Civ4 - Mod Components' started by Dom Pedro II, Jul 21, 2009.

  1. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    Dom Pedro's Mod Helper
    or How I learned to stop worrying and love Python

    Anybody who has talked to me for any length of time about modding knows I have hated python for a long time. While I still don't like its form, I've come to realize that python has a number of important advantages over the SDK. I've started working on scenarios that require small, unique tweaks that don't really justify tinkering with C++, but I've still found python to either be too cumbersome or not powerful enough to do everything I want. This mod comp attempts to strengthen python by using the SDK and XML to work more effectively with it. I designed it for my own needs, but I figured I would share it with the world.

    Enclosed in the file and attached separately below is a quick and dirty tutorial for how to use this mod comp.

    I am currently accepting suggestions for other things they would like to see python able to do, so let me know.


    WHAT IT DOES:
    This mod component does not change gameplay. It is specifically to make the lives of modders who can use python easier, and give them greater power over the code. Hopefully, this simplified system will also encourage people to go a step further in their modding beyond XML and try their hand at python scripting.

    This code takes the system used for calling python methods for Events and expands it to other areas of the game. Modders can attach new python methods to units, promotions, specialists, buildings, civics, civilizations, leaders, religions and more in the XML that will be read from python. This allows players to create small, self-contained python methods that are executed at the appropriate time without complicated checks in python.

    With this mod component, you will be able to have specialists give the same benefits as buildings, allow Wonders all the effects of Civics, and virtually any other possible combination. You can have buildings that automatically spawn units in regular intervals, and much much more. Many of the SDK functions that were previously not exposed to python have now been exposed so modders can use the new system to its full potential.

    EDIT: I also forgot to mention, I threw in some code to the TechInfos that lets you give announcements to all players who have met the first discoverer of a tech. This has no gameplay consequences, I just liked the idea of having messages appearing like "A Sumerian inventor has become the first person to build a heavier-than-air aircraft!" or something like that.

    Changes in v 0.3:

    Added code to easily script new Action Buttons based in part on talchas's Action Buttons 2.0

    Added CIV4ActionButtonInfos.xml

    Updated the Tutorial

    Changes in v 0.2:

    PythonAIWeights:

    Added <PythonAIWeight> tag to UnitInfos, PromotionInfos, BuildingInfos, CivicInfos, ReligionInfos, SpecialistInfos.

    Added <iAIWeight> to PromotionInfos, ReligionInfos, and SpecialistInfos

    Added new tags to CIV4EventTriggerInfos.xml:

    <TriggerImages> - Allows for random, era-specific images be displayed with the event popup
    <TriggerSounds> - Allows for random, era-specific sounds to play with the event popup

    <PrereqOrEvents> - Prerequisite OR Events allows either/or event prerequisites

    <PythonProbability> - Allows modders to have the probability of
    <PythonCityTriggerValue> - Gives modders control over what criteria makes a city better or worse for a trigger... allows more fine tuning beyond the existing PythonCanDoCity tag
    <PythonPickBuilding> - Select a building based on any criteria rather than letting the computer randomly pick one.
    <PythonPickCivic> - Select a civic
    <PythonPickBonus> - Select a bonus based on any critiera
    <PythonPickReligion> - Select a religion based on any criteria
    <PythonPickCorporation> - Select a corporation based on any criteria
    <PythonPickCulture> - Select a particular culture (i.e. Player) in a particular city
    <PythonPickOtherPlayer> - Select other player based on any criteria rather than being randomly selected by the computer
    <PythonPickTech> - Select a tech
    <PythonText> - Can create display text dynamically.

    Added new tags to CIV4EventInfos.xml

    <PythonText> - Dynamic display text for the event popup buttons
    <PythonGold> - Dynamically set gold cost/reward
    <PythonBestTech> - Choose a tech to be awarded
    <PythonBestCivic> - Choose a civic to switch to
     

    Attached Files:

  2. davidlallen

    davidlallen Chieftain

    Joined:
    Apr 28, 2008
    Messages:
    4,743
    Location:
    California
    Holy smokes! This looks great! I have about a thousand lines of python into Dune Wars and about a thousand for Fury Road. This would make a lot of things simpler.

    There are a bunch of things which are possible to do by modifying CvGameUtils.py, such as AI_unitUpdate, AI_chooseProduction, etc. These would all be more convenient if they were controlled from xml tags as well, to allow mod merging without untangling a chain of if statements inside these functions.

    Also, there are some entry/exit routines that would be helpful. I was trying to do something when entering *or leaving* a civic. It looks like your PythonCallback is called upon entering the civic; could you define one for leaving a civic? Also something like canDoCivic would be helpful.

    I can probably go through my existing code and come up with a dozen more suggestions!

    How does this code interact with BUG? That is, merging your sdk source code changes with BUG seems like it would be a big undertaking; do you plan to premerge with some of the common modcomps like BUG?
     
  3. Agent327

    Agent327 Observer

    Joined:
    Oct 28, 2006
    Messages:
    16,046
    Location:
    In orbit
    Downloaded.:goodjob:
     
  4. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    Indeed, that's one of the reasons why I did this. I personally don't like coding in python, so anything that makes it less complicated is a plus in my book :) How would you suggest AI_unitUpdate and AI_chooseProduction being controlled from the XML though?

    The callback method for a particular civic is called both when it's being activated or deactivated (along with specialists, religions, promotions, etc.) One of the arguments passed to the python method is the integer "iChange", which is either a 1 or a -1 depending on whether you're switching to or switching from a particular civic. When you create a new python method, you're going to want to use this to determine what exactly is supposed to happen. Actually, if you're doing something simple like giving a happiness bonus, it's very simple. Just do something like:

    player.changeExtraHappiness((iChange * iCivicHappiness))

    That way when you activate the civic, it will add (1 * iCivicHappiness) to extra happiness, and when you deactive it, it will add (-1 * iCivicHappiness) which should subtract the exact same amount of happiness. That's how it's done in the SDK when processing civics, buildings, resources, etc.

    Also, isn't canDoCivic already a function? Is there a reason why there should be civic-specific canDo methods defined in the XML?

    Fire away. Worst I can say is no ;)

    I haven't tried to merge this with any other modcomps, but I think it should be fairly easy to do since it doesn't really add any new content. That's left to the modders.
     
  5. avain

    avain (key)

    Joined:
    Jul 29, 2006
    Messages:
    2,770
    Location:
    Budapest, EU
    Looks great! (although I think no amount of love would make me not hate python)

    Any ideas of the effect of merging this with WoC (Lite) modular XML loading?
     
  6. xienwolf

    xienwolf Chieftain

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
    You could attempt to control some AI decisions with tags along the lines of <AIPythonWeight> which will call out to python and check for any weight values early in the decision process, allowing you to prevent further processing with a return value. The main decision would be to have a return value of an array for all weight values being considered, or allow the check to process on each unit/building/project/whatever being checked. Could lead to considerable slowdown the second way, but be confusing for new modders the first way.

    UnitUpdate type of intercept can just be a simple <PythonPerTurn> function in which there is a check for isHuman() in the python which then leads to a series of orders being given for AI units that override normal control.
     
  7. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    I agree personally... but actually, that's what makes this cool. You'll have to do a lot less work with python to get the same effects. As a result, I'm hoping that it will get people who aren't good with python to give it a shot to make their mods better.

    Super awesomeness I would imagine... This mod comp is very useful, but it's not particularly complicated or revolutionary. The Events have used this technique from the beginning, so I doubt that there would be much of a conflict with most existing modcomps. I even created a separate python file just for the new methods so people wouldn't have to merge multiple python files.

    That's a very good idea. I had been trying to think of ways to have the AI use this as well as give people more control over the AI.

    Well, most of the info types have a <PythonDoTurn> tag if that's what you're saying. This would allow people to have particular buildings, civics, etc. perform per turn functions like spawning units and such. Of course, as the tutorial shows, if you add conditions to that method, you can make it so that they will perform the actions every X number of turns rather than every turn.
     
  8. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    I'm also thinking about some more stuff for the UnitInfos that can be called when initiating combat. In particular, I'm think about combat modifier, first strikes, and withdrawal scripts.


    Ok, I'm going to add the AI code xienwolf suggested right now.

    I also have code that I worked on for another project that involves modifying Events that I'm going to add into this because it's relevant to this and extremely powerful. This new code will hit event modding like an atomic bomb.
     
  9. The_J

    The_J Say No 2 Net Validations Retired Moderator Supporter

    Joined:
    Oct 22, 2008
    Messages:
    29,883
    Location:
    Germany / Netherlands
    :wow: holy...! :wow:
    That looks completly awesome.
    I can't imagine, how much work you must have put in this.


    :cry: but i don't want to break the compatibility of my mod.
    :cry: it's a shame.
     
  10. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    v0.2 uploaded ;)

    I've added in the python AI Weights and the new Random Events features... Let me know what you think.
     
  11. Agent327

    Agent327 Observer

    Joined:
    Oct 28, 2006
    Messages:
    16,046
    Location:
    In orbit
    :rolleyes: Haven't even tried out v. 0.1... Oh well.:thumbsup:
     
  12. deanej

    deanej Chieftain

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
  13. cybrxkhan

    cybrxkhan Asian Xwedodah

    Joined:
    Aug 10, 2006
    Messages:
    9,687
    Location:
    The Universe
    I've done lots of XML before, but I'm extremely inexperienced in python, so this question I'm pretty sure is kind of stupid, but I noticed that in this "mod" there are some XML files. Are this required for this thing to work, as in do I have to add in the new tags to every single XML file in an old mod? Or can I just use my old XML files with the python and sdk here?
     
  14. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    Please, ask all the questions you want. I need to know where people are getting stuck so I can include it in a more comprehensive tutorial.

    Alright, let's suppose for a moment, that you wanted to create a Wonder called Leonardo's Workshop that automatically upgraded your units ala Civ2.

    You would create a python method that cycles through all of your units every turn and then upgrades any units that have valid upgrade paths. Let's suppose you give it the rather inelegant name "doLeonardoWorkshopDoTurn". But how do you get the game to recognize this python method? That's where the XML comes in...

    In the CIV4BuildingInfos.xml, you put in the <PythonDoTurn> tag "doLeonardoWorkshopDoTurn". What you're essentially doing by adding that tag is telling the program, "Look for the doLeonardoWorkshopDoTurn method." When a player builds the Leonardo's Workshop, it will be processed in the SDK. If you leave this tag blank, the game will simply assume that you don't want this Wonder to do anything special in python and will move onto the next bit of code.

    But you only need to add these tags to the things that you actually want to use python. In other words, if you just want to make one Wonder that uses a python method, you don't have to copy all of the files from my modcomp into your mod. You just need to copy and paste my Buildings schema file into your Buildings folder, and you'll need to add the XML tag in the proper place for the Wonder you want. If your mod is using another modified DLL, you'll have to merge the two first, which gets a bit trickier.
     
  15. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    Yes, I forgot that I had been using the Debug DLL (which is quite a bit bigger than the normal DLL), and I'd zipped that along with the v0.1. v0.2 has the correct "Final Release" DLL.
     
  16. cybrxkhan

    cybrxkhan Asian Xwedodah

    Joined:
    Aug 10, 2006
    Messages:
    9,687
    Location:
    The Universe
    Alright, that's all I needed to know. So, just to make sure I understand, basically what you're saying is that this tag is optional.

    If so, then that sounds great. Thanks a lot!
     
  17. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    Yes, the XML tags are only necessary for the items that you want to make use of python code.
     
  18. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    I'm thinking that it might be a good idea to merge the Actions Button modcomp into this. I may do that tomorrow.
     
  19. davidlallen

    davidlallen Chieftain

    Joined:
    Apr 28, 2008
    Messages:
    4,743
    Location:
    California
    Having an efficient, easy to use way to add action buttons would be great. There are several existing modcomps which enable action buttons in pure python, but some of them add complexity rather than subtracting it. What is the design that you would propose for this?

    When I add action buttons in python, I have to make a bunch of changes in CvMainInterface and it is a little messy. I would like to have one callback to determine if the button should appear at all, another one to determine if the button should be greyed out *with a help message*, and then there is the linking you have to do through ModNetMessage to be called when the button is clicked.
     
  20. Dom Pedro II

    Dom Pedro II Modder For Life

    Joined:
    Apr 3, 2002
    Messages:
    6,811
    Location:
    Exit 16, New Jersey
    Well, I was just thinking of merging talchas's Action Buttons 2.0, which is done mostly in the SDK I believe.
     

Share This Page