1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

RFC: The Western World vision

Discussion in 'Rhye's and Fall Modmods' started by JediClemente, Aug 3, 2010.

  1. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    Hello everyone. Had some ideas for RFC for some time, but never saw the time to try them until now. I'd like to touch as less as possible (that's why Baldyr's PyScenario framework looked like a good idea, but unfortunately it's better for very specific little things, which I'll also try to think of).

    So, my point is to make RFC slightly more... eurocentric. Don't take this the wrong way if you're not european. I wish the game was a bit more close to reality. Just not in a strict sense.

    Some examples of what I'd like to try:

    Spoiler :
    - Make the euro civs more likely to be powerful/advanced, instead of seeing an score-leading 5-cities Japan packed with wonders in 1600. Tech rates should change dinamically through the game, never liked how they worked anyway (including the "static" extra 10% cost for each city above 10).

    - Allow it so that great empires can exist in Antiquity, just very unlikely to survive.

    - Adapt the game to rationalize picking a medieval civ with a 3000 BC start. No Jerusalem and catholic holy city razed by barbarians. No insanely huge barbarian hordes through Europe switching to you.

    - China and Persia should be able to respawn before Nationalism. They have the longest tradition of "local rule", they were also areas very difficult to maintain for foreign powers.

    - Try to ensure the whole world is populated. Right now colonization isn't really working in RFC. Africa is an empty spot. Very little is achieved in Australia. But this shouldn't be deterministic (see next point).

    - And this takes me to another point: settlermaps were a great achievement by Rhye, but after playing a lot, they just make the game so predictable. You know England will build New York, Spain Buenos Aires and so on.

    - You should received less stability penalty from controlling another civ's core area if it's distant and Nationalism hasn't been discovered yet. In fact stability should be more based in your number of cities, tech level and civics than in where they are.


    I look for ideas, extending this points or adding another ones. And of course, I think I'll need some help, as I don't know exactly where it is all located (I suppose stability is dispersed through the DLL).

    Anyway, took a look to the Congresses.py file and it seems not that difficult, only a bit large. (should have a spoiler-alert message, until now I didn't know the exact mechanics for the AI to vote against you :mischief: )

    And this is the first thing I'll work in:

    Scramble for Africa.

    Once again, Congresses were great when Rhye added them, they make the game more interesting.

    But:
    - They were between european powers, not ever you'd see China asking for a city in Mongolia.
    - Most of them arbitrated european interests in territories abroad, especially in the case of the aforementioned african partition. So no England asking for Brest. I know the Vienna Congress served as some inspiration also, but that's not really the same concept as I see it.

    Add to that a new special Congress, or Conference. This is my initial draft:

    After the discovery of Biology, the european civs still alive will divide the continent between them, save for Ethiopian territory (if the civ is alive) or a reduced part of its core area (if it's dead).

    This division should depend on whether each euro civ already had at least a city in Africa or not, its power (game points, these can be compared in python right?), our previous historical knowledge (settlermaps, but not literally, as pointed before; some variation is appreciated), the existence of other african civs (Mali, Carthage) or non-europeans (Arabs, Turks) whose cities would not be taken right away but had to be conquered (declaration of war + units spawned).

    Also this Conference, and Congresses in general, should only take place in an scenario of total peace (between the participants).

    Now, I don't know if the euro civ with the least points should not be counted, what to do in special cases (three or less euro civs alive), and so on. Anyway, to this respect, Russia should not be counted as an Euro civ (sorry друзья, I hope you understand).

    So, any thoughts?

    And for starters, is there a way to count the cities a civ has in a continent? :lol:
     
  2. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    (reserved for -I hope- not that far into the future when some files will be posted)
     
  3. Science Rules

    Science Rules Prince

    Joined:
    Nov 26, 2004
    Messages:
    358
    Location:
    Massachusetts
    Is your new Congress solely for dividing Africa up?

    One other idea would be to add another Congress to divide China up to represent the Unequal treaties.
     
  4. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Oh, this sounds great! :goodjob:

    Start learning Python right away, as most of what you plan on doing will rely on you being able to do quite a bit with this language. Trust me, you could spend the next two months unsuccessfully trying to get these things done, only actually learning some of the very basics in the process by trial and error. Or you could spend two weeks actually reading up on Python - and you'd learn as much as you otherwise would in the first two days!

    At a glance, the "dynamic" Tech rate features would probably be done in the DLL however (while everything involving stability is Python only - and can be found in the Stability.py file) but I'm not even sure its doable. But you could probably figure out some way to work around this by penalizing the non-Euros.

    I have no idea how you're gonna achieve non-deterministic colonization, but perhaps spawning historical cities randomly on a game-to-game basis would work? Because trying to make the AI do what you want it to do on its own might prove very difficult! (And also would have to be done in C++.)

    About counting cities per continent, this can of course be done in a variety of different ways. You could specify a continent by its map coordinates, then loop through these tiles and add +1 to a counter for any valid city encountered. But there are also something called map areas already in the game, but I'm not quite sure about those. I suppose they divide the world into continents and such - and I know Rhye uses them to make Constantinople/Istanbul change from European to Asian, and Siberia to become "European". This might also be a way forward.

    What you need right now is a good textbook, someone to get you started :king: and some basic task to work at while learning. You probably shouldn't start by trying to rebuild the Congresses feature, but rather find some other pet peewee that you want to tackle anyways eventually. Once you learn the basics and understand how CivIV modding with Python works, it would be pretty easy to do just about anything.

    Also, you probably don't wanna look too closely on what Rhye has done with Python, because not all of it is optimal by no means... :rolleyes: I've come to realize the Rhye is first and foremost a game designer - and a wonderful one at that - but probably hasn't taken the time to learn all of the basics of something like Python. So you will encounter some odd things you probably wont be able to figure out by yourself. And also, RFC is an old project and I understand how the basic framework - no matter how flawed - would have to have remained largely unchanged though-out the development process. So I'm not trying to put Rhye down - the mod works fine, after all, and that is what counts! :king:

    So you will be doing yourself a favor by learning the basics first, and then applying that to the mod. I trust you will use RFC Epic/Marathon as your framework for this?
     
  5. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    Yes, Africa only, that would be the initial idea.

    I also thought about something similar for Asia, if certain conditions were met (for example, China/Khmer should be dead, on the verge of collapse or too technologically backwards).

    But before that let's see if I can make the first thing.
     
  6. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    Yes Baldyr, thank you, I'm reading it. Fortunately Python doesn't sound like klingon to me.

    I suppose the new RFC Epic/Marathon doesn't affect Congresses as they are now, does it?
     
  7. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Just let me know once you get stuck.

    RFC:E/M doesn't change any rules, it only adds two difficulty levels. And adds speed to the game.
     
  8. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Some thought on Python mod-modding (with RFC:E/M in mind):

    You might wanna start you project by making your own Python module for the mod. Try to localize as much as you own code you can there, so that Rhye's/embryodead's code stays intact. This will help you to keep track of what you've done, as you only leave references to your Eurocentric (or whatever) module scattered all over the place. If you add a comment every time you do that you will also be able to find these calls at a later date.

    The basic things you'd wanna add to your Eurocentric.py file is probably some import statements:
    Code:
    from CvPythonExtensions import *
    This gives you module access to the entire CivIV Python API.
    Code:
    from PyHelpers import *
    This is a very handy alternative API created by the programmers at Firaxis as wrapper for the most useful methods found in Boost Python (as the original one is also known as - it adds a Python API to the C++ function library).

    You really wanna get into PyHelpers as soon as possible. And if you manage to get to chapters 12-16 in the textbook this will also start to make real sense to you.
    Code:
    from Consts import *
    This imports all the constants in the Consts module - and you don't even have to use the con. prefix found in every one of Rhye's modules. But if you wanna do it the way Rhye did it, you go:
    Code:
    import Consts as con
    Next up:
    Code:
    import RFCUtils
    This is where Rhye (and embryodead) has collected many of the helper functions (almost like an API of its own) for RFC. Since all these functions are defined as class methods, you need to have a RFCUtils instance to use them with. This all makes no difference to you (and it makes little sense anyway), but you also wanna add this line to avoid creating new RFCUtils objects all of the time:
    Code:
    utils = RFCUtils()
    Because then you only use the one instance with the utils. prefix. You can see examples of use all over the RFC code.

    There are many more modules - both part of the Python programming language, the CivIV game and the RFC mod as such that could be imported - but the above would be sufficient for starters.

    Also, you wanna give your module its very own CyGlobalContext instance. This is the class in CivIV Python that grants access to all the information about the game, so its essential. Its both convenient and kosher to only create one instance of this class:
    Code:
    gc = CyGlobalContext()
    Now you can access all the class methods with only the gc. prefix. You could consider doing the same thing with CyGame and CyMap:
    Code:
    game = CyGame()
    map = CyMap()
    Next, you could define some of the most common functions found in all or most of the RFC modules. Like checkTurn():
    Code:
    def checkTurn(iGameTurn):
            pass
    You probably already know what this is and does - and that you're supposed to replace the pass statement with some block of code eventually.

    Note however that you don't need - and really shouldn't - define a class for all of your functions. So there will be none of the self. nonsense in your module. (If you wanna make your own RFC concepts with Object-Oriented Programming using classes, you would probably wanna put that in another module anyway. Just like Rhye has divided the mod after content.)

    Now, what you do with these "standard" functions is call on them from the CvRFCEventHandler module - the engine that drives the mod. You simply add a function call inside the content of the onBeginGameTurn() method (found on line #428):
    Code:
            def onBeginGameTurn(self, argsList):
                    Eurocentric.checkTurn(argsList)
    Now the code in checkTurn() will be run once every game turn. But note that you also have to include a import statement in the Event Handler (and in every other module accessing your custom module):
    Code:
    import Eurocentric
    This concludes my getting-started tutorial. Now you are ready to start programming for RFC. Any questions? :p
     
  9. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    Thank you, now I understand completely the file I was editing, which was Congresses.py, BTW.

    For the moment for this changes it's better to edit that file than creating a new one.

    I've made a lot of progress, successfully changing the current congresses, and in a few days I'll have the African event properly running.
     
  10. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Nice! :goodjob:

    That'll show anyone who thinks that this programming business is impossible to learn... :rolleyes:
     
  11. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    I have a problem. Regular congresses work with the changes, but the special event for Africa (ScAfrica) never starts, even though the code to do so is almost identical to the one for regular Congresses.

    There's a variable iScAfricaEnabled, which is initialized to 0 in StoredData.py. It's changed to 1 when two or more euro civs have Biology (enabling the event, which is looked for in checkTurn), and to 2 when startScAfrica() ends.

    I've tried several games as the Americans, giving Nationalism and Biology to other civs from the editor. As I said, congresses work, but the african event doesn't.

    :cry: :confused:

    Here are the changed files if anyone know what can it be. The changes are marked by comments with my nickname.
     

    Attached Files:

  12. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    The code really doens't make much sense to me so I'd have to analyze it in more detail to be able to spot anything.

    Firstly: Have you enabled Python exceptions? Because one single error would cause the whole Python callback to derail. So there must be no exceptions running the code.

    You might consider adding print statements and enabling debug logging. That way you can follow what code is actually activated - if any. If you add key variables and values you can also see what actually happens at each juncture.

    Look into the Civilization4.ini to enable exceptions and logging.
     
  13. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    Where are the logs saved?
     
  14. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    \My Documents\My Games\Beyond the Sword\Logs\

    You need to keep an eye on PythonDbg.log, PythonErr.log and PythonErr2.log.

    Also, I noticed something completely awry in your code. The Barbs.foundCity() function is used for founding cities (building them) - not looking for them. So the if statement invoking it is basically flawed.

    And you would have access it like:
    bar.Barbs().foundCity()
    Which in itself is not good. But I wont go into it because you don't need it anyway.

    So there should definitely be exceptions - and this would make the code not work.

    You have some work ahead of you, that is for sure.

    I'd still recommend that you start with something simpler that this, as your first programming project. Also, you should probably make your own module for the code. And skip having a class for the code, unless you really know why you want one. It simplifies things to not use Object-Oriented Programming where it is not needed. :rolleyes:

    Take some time to learn more about Python in general before you try this again, and you end up saving a lot of time!
     
  15. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    I'm using that function to found a city each time, not to find it.

    It's inside an if because it returns true or false depending on if it was founded or not.

    (well, the original Rhye function didn't always return a boolean, so I changed it)
     
  16. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Change the import statement to:
    Code:
    import Barbs
    Then add this assigment:
    Code:
    bar = Barbs.Barbs()
    Now you can access the method with
    Code:
    bar.foundCity()
    This is all because Rhye added a class to the Barbs code, making all functions class methods. :p Don't do that in your own modules.

    Thats one exception less.
     
  17. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    You were right, problems come from that foundCity() function.

    I need another way to found cities.

    Good news is apparently the rest works. :goodjob:
     
  18. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Congratulations! :king:

    You found cities with either CyPlayer.initCity() or CyPlayer.found() - they are similar but do somewhat different things.

    But I don't see why you can't use the function in Barbs?
     
  19. JediClemente

    JediClemente Prince

    Joined:
    Jan 21, 2004
    Messages:
    446
    Location:
    Madrid, Spain
    Hm. I think I'll leave it without city founding. It's fine as it is anyway.

    So basically I have setup an event that, under the proper conditions, splits Africa between the european powers.

    Regular congresses are also changed. Now only euro civs vote, and the way candidate cities are selected is a bit different.

    I'll upload it when my other changes are done, if anyone's interested.
     
  20. Baldyr

    Baldyr "Hit It"

    Joined:
    Dec 5, 2009
    Messages:
    5,530
    Location:
    Sweden
    Of course you wanna share your mod-mod!
     

Share This Page