• Civ7 is already available! Happy playing :).

How to make a Python mod

i am confused how do you get the window to appear? do you press Shift +~ or one at a time?
 
I'm not sure what you mean, but it might be difficult - if not impossible - to open the Python console on some keyboard layouts. If all else fails - get an American keyboard at it should work.

But using the Python console isn't critical or necessary. Its just a tool and you can do without it. So you can complete the lessons without actually testing things in the console. It really doesn't matter.
 
You know about short-keys? Like ctrl + S for quick-save? Or ctrl + T to toggle the map grid on/off.

What you do is you hold down the shift/alt/ctrl key and press the letter/key. So with the Python console you need to hold the shift key down while you press the ~ key.

With a US keyboard you should be able to access it - but its not a problem if you can't. The console isn't used for Python modding - its rather used for testing various things - like your finished Python mod. But its still not necessary.
 
LOL :stupid:i though you had to press the + key insted of pressing shift ~:lol:.
 
how can i test it if i can't get the window to pop up?
 
You don't have to test your mod with the Python console. That is just something I made up so that the reader can have some fun playing around with the code and seeing the results on screen. But it really only takes time and effort to do.

The real testing is actually playing the finished mod. It will all become clear once you read through the tutorial. :D
 
Ah, are you gonna mod Vanilla? I have never even tried to mod Vanilla - I've only ever worked with BTS. Is the Python console even present in Vanilla? (It should be, but I wouldn't bet on it.)
 
Apparently, the Firaxis definition of "moddability" means "making players learn a whole programming language just to do the things that Fantastic Worlds offered from a built-in game menu"

:sad:

Ah, are you gonna mod Vanilla? I have never even tried to mod Vanilla - I've only ever worked with BTS. Is the Python console even present in Vanilla? (It should be, but I wouldn't bet on it.)

Ironically, I first tried opening the console in Warlords, and it didn't work. So, on a hunch, I fired up core (I refuse to call it "vanilla") Civ4 and sure enough, the console magically appeared as if from nowhere.
 
You're not quite right about that, but sure. If this is your outlook on things you could just keep modding Civ2.

I'm planning on making my PyScenario application BUG compatible in the future - then all those things you were able to do with Fantastic Worlds will be also available for Civ4. But you'd still need to learn programming and XML to mod the game.
 
Well, I'm vaguely familiar enough with XML that I can edit those files without rendering them non-functional... I had to learn that in order to tinker with Tiberium Wars.
 
XML is the basic level of modding. The XML portion of the game is actually available to make the game easily customizable. If you wanna script stuff for a scenario, basically, you use Python. And if you wanna add your own game concepts - or radically alter the way the game is played - then you use C++. It is possible to learn any and all of these skills, so its basically just about how motivated you are as a scenario maker or modder. No one is keeping any of this from you, so I don't think whining about having to learn how to do these amazing things is warranted.
 
Oh, I'm not whining. I'm the kind of person who would rather code HTML manually than use Dreamweaver. I'm just saying that computer companies seem to have forgotten the concept of "user-friendly" modding. Have you compared the original Starcraft campaign editor to the Starcraft II editor? It's insane!

Anyway, different question... do you happen to have any older versions of PyScenario stashed somewhere? The newest version requires your Epic/Marathon mod, which in turn requires BtS...
 
The first version of PyScenario was made for the Rhye's and Fall of Civilization (RFC) mod. The current version can only be used with the RFC Epic/Marathon mod-mod. These are both beta versions, meaning that development is still going on.

A future final version would probably be independent from any other mod, sans BUG of course.

If you know Python it would be possible to port PyScenario to your own or any other mod. But on the other hand - if you know how to do that, then you don't need PyScenario to begin with...

So you could just take the plunge and learn how to do proper Python instead. Its not anywhere as hard as you probably think it is.
 
do you have a link to the python code list? or atleast one for civ so i can see it practical
 
Whow, this thread is pure gold when trying to learn the first steps into CIV4 mofifications. Thank You, Baldyr, you did really a great job with this!

Actually I love this rebel theme and want to use it in my further civ4 games. And with the help of this guide it is possible even to do some small improvements too. :) I have some experience in C, but to write the magic "Hello world" program is one thing (yeah, I know, programming is just debugging an empty file) and to get it compiled & linked & run another ... :D ... the part describing the EventManager entries helps so much!!!

Of course I have some questions:
1.) How would the popupMessage look like, if it transports a parameter?
modPopup.setBodyString(popupMessage, iNumRebels)
(with
popupMessage = "This city is threatened by %% rebels"
iNumRebels = 2)
--- just wild guessing.

2.) I suppose variables assigned outside of checkTurn() keep their value from one turn to the next?! So I can simply define a turncounter outside and handle it inside:

Code:
<TD class=code>
iturn_counter = 15 + cyGame.getSorenRandNum(10, "rebels tci")
def checkTurn():
  if iturn_counter > 0:		# no rebelion this turn
    iturn_counter -= 1
    return False
  else:
    iturn_counter = 15 + cyGame.getSorenRandNum(10, "rebels tc")
    """Checks if the CyCity instance is valid for the rebels event."""
    ...
</TD>

Would this work? I like it better to have those 20 turns just on average.

3.) I don't want to burden the AIplayers with additional fighting. How would I make the whole joy for the human player(s) only? something like:
pyHuman = PyPlayer(gc.getHUMAN_PLAYER())
??
 
Whow, this thread is pure gold when trying to learn the first steps into CIV4 mofifications. Thank You, Baldyr, you did really a great job with this!
Thanks! :D Python modding is actually not the most important stuff to know when it comes to CivIV modding. Knowing your WBS and XML is probably much more important - and the SDK is where the real power is at. But Python is still handy to know. :goodjob:

1.) How would the popupMessage look like, if it transports a parameter?
modPopup.setBodyString(popupMessage, iNumRebels)
(with
popupMessage = "This city is threatened by %% rebels"
iNumRebels = 2)
--- just wild guessing.
I'm not sure how your complete code would look like, but it would probably be something like this:
Code:
iNumRebels = 2
popupMessage =  "This city is threatened by %s rebels!"
modPopup.setBodyString(popupMessage % iNumRebels)
(The %s bit adds the integer value into the string after conversion to string type.)
2.) I suppose variables assigned outside of checkTurn() keep their value from one turn to the next?! So I can simply define a turncounter outside and handle it inside:
In theory yes, but there are two issues with this approach. Firstly the global variable iturn_counter won't be recognized inside checkTurn() as a global variable because you're assigning values to it (with the -= operator). This is why you need to use the global command to alias the local variable with the global variable before you assign or reference it inside the function:
Code:
global iturn_counter
You don't need to do this with constants, or read-only global variables. Those will be recognized anyway.

The other issue is that once you save and reload the game the Rebels module will be read anew and the iturn_counter will get the default value. In order to store a custom value inside the game so what it will be saved - and loaded - with it, is done with scriptData. Its basically just a field in some Cy object, like CyGame:
Code:
onPreSave(argsList):
    CyGame().setScriptData(str(iturn_counter))

onLoad(argsList):
    global iturn_counter
    iturn_counter = int(CyGame().getScriptData())
Note how scriptData must be a string value and therefore is converted into string type with the str() function. And once read it needs to be turned into a valid integer value again, with the int() function.
3.) I don't want to burden the AIplayers with additional fighting. How would I make the whole joy for the human player(s) only? something like:
pyHuman = PyPlayer(gc.getHUMAN_PLAYER())
??
I'm not sure if you need a PyPlayer instance for this, but the way to find the player ID of the human player is CyGame.getActivePlayer(). Put in a conditional statement:
Code:
eHuman = cyGame.getActivePlayer()
if ePlayer == eHuman:
 
Top Bottom