Results 1 to 2 of 2

Thread: Using the Script Replicator

  1. #1
    Augustus Lucifer's Avatar Life = Like a beanstalk
    Patrician Citizen

    Join Date
    Aug 2006
    Location
    Mote of Dust
    Posts
    10,725

    Default Using the Script Replicator

    If you're up on your Course Materials, you should have already found and downloaded the Script Replicator(not because you have to, but because you'd be insane not to!). If not, I recommend you check the Course Materials thread, follow the link, and DL it. Some of you may have toyed around with it, some may not have. The concept is very simple but it serves a fundamental time-saving purpose, allowing you to write thousands of lines of code in literally minutes, if you know what you're doing.

    This thread serves a few purposes:
    • Shows you how to use the Script Replicator to turn 3 lines of code into thousands of lines of code.
    • Shows you the work of nested if statements.
    • Shows you how there's more than one solution to doing something usually.
    • Shows you the faults of the scripting engine in its inability to use all-encompassing or self-referential commands.


    This is not part of the Lesson Plan. There is no homework. I hope that after reading this though you'll be able to use the Script Replicator in your scripting endeavors and understand a little bit more about building scripts in modular chunks. Before we get started I suggest you read the Five Steps to Scripting Success and complete Lesson 1 and Lesson 2 to get the basics down, since I won't belabor them here.

    First let's follow the steps laid out in the Five Steps to Scripting Success to flesh out the script being written. As a disclaimer, since this script is being written for AUH, the displayed factions/settlements are not vanilla, but if you follow the instructions it should be easy to make one for vanilla.

    Goal

    The goal of this script is to create an "AI Building" which appears in all AI-held settlement and not in any player-held settlements. The purpose of this is so that all EDB buildings which require "building_present_min_level" can use an or statement to require the AI building instead. This enables the AI to bypass the restrictions set on the player and let them build up their cities easily from the get-go, one of many things to help them make up for their inherent stupidity.


    Feasibility

    This script is definitely feasible, because we can create and destroy buildings based on who owns the settlement. One thing this script requires due to the way the "destroy_buildings" command works is for the AI Building to have its own building tree, otherwise this script will impact other buildings in that tree as well. Additionally, the player/AI should not be able to build it through normal means, so the building entry needs a requirement(such as and event_counter never_gonna_fire 1) which insures it can never be built except through script.

    Follow Along Note
    This thread does not go into how to add new buildings and the EDB. For the purposes of this thread a building tree called ai_building with one building also called ai_building already exist. If you don't know how to add buildings, I recommend you read A Guide to the Export_Descr_Buildings.txt File and A Guide to Guilds(ignore the parts pertaining only to guilds).

    If you plan to follow along you will need to create that building tree and building or your script won't function. If you want my EDB code to insert ask in the thread and I'll provide it, though you still need to know where to put it and to add the strings.


    Concept

    When conceptualizing a script there are often various ways to achieve the same end. Some are more efficient, some are just more compact, some are fairly interchangeable. For this script there will be shown two separate methods, one that utilizes a slew of monitors and one that uses nested if statements. Here is a mockup(these are pseudocode, not actual code):
    Spoiler Alert, click show to read: 

    ;Destroy buildings
    monitor_event local faction turn end
    if local faction = x
    destroy ai_buildings for x
    etc etc for each faction
    end_monitor

    ;If Statement Method - Create Buildings
    monitor_event settlement turn end not local
    if faction x is not local faction
    __if settlement x owned by faction x
    __create ai building in settlement x
    etc etc for each faction for each building
    end_monitor

    ;Monitor Method - Create Buildings
    monitor_event settlement turn end not local
    and settlement is x
    create ai building in settlement x
    end_monitor

    copy monitor for each settlement

    Actualize

    Okay so now we have our concepts. We know what we want it to do, we know how we're going to do it, now all we need is to do it. That's going to be a lot of code though, the if statement method we're using requires 7600 lines of code for 14 factions and 182 settlements, or roughly 3 lines of code per faction per settlement(so significantly more with 30 factions and 199 settlements). The monitor version uses significantly less lines of code as it doesn't contain redundancy, but as a result it needs to be present in separate monitors. The reason for this is to use if statements you need conditions with I_ in front of them, as they don't require exports from the event. The I_SettlementOwner command fits this bill, but it requires you to also specify a faction, meaning you have to create redundant code for every faction that could possibly own it. The only other I_ command that fits requires a siege to take place(as shown in Tsarsies' Garrison Script).

    So now let's start with the destroying of buildings in player-owned settlements, because this is the smallest bit of code that works the same for all methods of creating them. Here's the code for one faction:
    Code:
    monitor_event PreFactionTurnStart FactionIsLocal
    	if I_LocalFaction champa
    		destroy_buildings champa ai_building false
    	end_if
    end_monitor
    A few things to keep in mind. Both destroy_buildings and PreFactionTurnStart are to my knowledge kingdoms-only commands. If you aren't building your mod on kingdoms and you plan to do scripting, go buy kingdoms right now and convert it; you have a computer and internet access so you probably aren't dirt poor, you really have no excuse not to shell out the $20 or whatever it is now for Kingdoms to boost your game. As well, when you see false after the destroy_buildings, it doesn't mean don't destroy them; if you check the docudemons you'll see that true/false there specifies if the faction is refunded the cost of the building, which we don't want to happen since the building is intended to be intangible.

    What this code does is say: Before the turn start of the player faction, run this monitor. If the local faction is champa, destroy all buildings in the AI Building chain in champa-owned settlements. The monitor is not terminated so it runs every turn start. Now if you're astute you might observe this leaves a window between capturing a settlement and the next turn where the player can exploit the AI building. Well you'd be right, but as scripters it isn't our job to shore up every possible way the player can exploit our scripts, you simply point out ways that people who want to use house rules should not exploit them where exploits exist, and leave those who want to game the system to their debauchery. If you're really anal about that sort of thing though you could take measures to stop it from happening, but it may require more intensive scripting in some cases so it's often best just to leave things to TurnStart/End and let bygones be bygones within the turn period.

    So now for our mod we have 14 factions that use scripts(non-playable/etc. factions are not included or supported as being playable). For your mod you might have less or more, and they're likely called different names. What we need is an if statement for each one, it'd only take us a minute to copy-paste and replace by hand, but let's use the Script Replicator just to get a hang of it.

    Follow Along Note
    If you're following along and trying to do this yourself, good, doing is always better than watching to learn something. For those of you who want to try this yourselves, follow these steps:

    1) Install the Script Replicator if you haven't already.

    2) Navigate to the folder where you see "ScriptReplicator.exe". In this folder create a sub-folder and call it "Replicator Pre-Mades". When you start the replicator it first opens its own directory, so the best place to keep replacement variables you plan to use often is in a sub-directory.

    3) In this folder create a new file called factions.txt. Open the file and enter the name of all of your factions in your mod or vanilla separated by a line break and save it, like so:
    Spoiler Alert, click show to read: 

    Code:
    champa
    daiviet
    dali
    goryeo
    jin
    khitans
    khmer
    minamoto
    mongols
    pagan
    song
    taira
    tibet
    xixia

    We will use this file for the next part. It's always a good idea to have pre-made files for common variables you might replicate a script for, most notably factions and settlements.


    Okay so now it's time to take our above script and look at it in what I call modular sections. That is to say figure out which parts of the script are likely to be replicates of other parts of the script with one or two variables changed. For our destroy buildings script, the only difference between the if statement for champa and the if statement for song is the name of the faction in two places. So what we do is run the script replicator to replace that variable with the other variables we need. Here is a look at a modular section of the code, using {param} to indicate the part that will differ each time.
    Code:
    	if I_LocalFaction {param}
    		destroy_buildings {param} ai_building false
    	end_if
    Follow Along Note
    If you're following along you should have DLed the Script Replicator, created a sub-directory to hold your code snippets and variable replacer files, and create a file called factions.txt with the names of all the factions you want the script to work for.

    1) Take the code snippet provided above showing the modular code, and copy it into a new file in the Pre-Made folder called code.txt then save.

    2) Open the Script Replicator by clicking on ScriptReplicator.exe

    3) On the left you will see a directory tree "Select File to Replicate From". Double-Click on the Pre-Mades folder and select code.txt. If you selected it properly and installed the replicator properly, the code snippet shown above should appear in the top box labeled "Original Script".

    4) On the right you will see a directory tree "Select File to Copy From". Double-Click on the Pre-Mades folder and select factions.txt. You should now see your factions in the "Words to be Imported" window.

    5) Now it's time to tell the replicator which word in the original script you want to replicate with the words in the variable file. Enter {param} into the "Set Parameters" input field. (Note: You can use any word, but I recommend first find-replacing for {param} in your code snippet to insure another word you might choose doesn't occur in-line.)

    6) Click Replicate. If you did it correctly in the lower window you should see the code snippet replicated with {param} replaced by each subsequent variable provided in the variables file, resulting in code that looks something like this(it will initially have two line breaks between each replication but I generally remove those if the overall code is small):
    Spoiler Alert, click show to read: 

    Code:
    	if I_LocalFaction champa
    		destroy_buildings champa ai_building false
    	end_if
    	if I_LocalFaction daiviet
    		destroy_buildings daiviet ai_building false
    	end_if
    	if I_LocalFaction dali
    		destroy_buildings dali ai_building false
    	end_if
    	if I_LocalFaction goryeo
    		destroy_buildings goryeo ai_building false
    	end_if
    	if I_LocalFaction jin
    		destroy_buildings jin ai_building false
    	end_if
    	if I_LocalFaction khitans
    		destroy_buildings khitans ai_building false
    	end_if
    	if I_LocalFaction khmer
    		destroy_buildings khmer ai_building false
    	end_if
    	if I_LocalFaction minamoto
    		destroy_buildings minamoto ai_building false
    	end_if
    	if I_LocalFaction mongols
    		destroy_buildings mongols ai_building false
    	end_if
    	if I_LocalFaction pagan
    		destroy_buildings pagan ai_building false
    	end_if
    	if I_LocalFaction song
    		destroy_buildings song ai_building false
    	end_if
    	if I_LocalFaction taira
    		destroy_buildings taira ai_building false
    	end_if
    	if I_LocalFaction tibet
    		destroy_buildings tibet ai_building false
    	end_if
    	if I_LocalFaction xixia
    		destroy_buildings xixia ai_building false
    	end_if


    7) That will be output to a file called new_campaign_script.txt on your Desktop, so you don't need to try and copy the window, just go open that file. Now you can copy the contents of that file into the monitor and voila, you just wrote 3 lines of code and got 10x that with little effort.

    Note: Keep in mind that the new_campaign_script.txt is overwritten each time you run the script replicator. If you want to save the contents of it save them elsewhere to a different file name, and try not to have a file with that name on your desktop that you're using for other purposes.


    Once we've replicated it and inserted it into our monitor, here's what the code looks like:
    Spoiler Alert, click show to read: 

    Code:
    monitor_event PreFactionTurnStart FactionIsLocal
    	if I_LocalFaction champa
    		destroy_buildings champa ai_building false
    	end_if
    	if I_LocalFaction daiviet
    		destroy_buildings daiviet ai_building false
    	end_if
    	if I_LocalFaction dali
    		destroy_buildings dali ai_building false
    	end_if
    	if I_LocalFaction goryeo
    		destroy_buildings goryeo ai_building false
    	end_if
    	if I_LocalFaction jin
    		destroy_buildings jin ai_building false
    	end_if
    	if I_LocalFaction khitans
    		destroy_buildings khitans ai_building false
    	end_if
    	if I_LocalFaction khmer
    		destroy_buildings khmer ai_building false
    	end_if
    	if I_LocalFaction minamoto
    		destroy_buildings minamoto ai_building false
    	end_if
    	if I_LocalFaction mongols
    		destroy_buildings mongols ai_building false
    	end_if
    	if I_LocalFaction pagan
    		destroy_buildings pagan ai_building false
    	end_if
    	if I_LocalFaction song
    		destroy_buildings song ai_building false
    	end_if
    	if I_LocalFaction taira
    		destroy_buildings taira ai_building false
    	end_if
    	if I_LocalFaction tibet
    		destroy_buildings tibet ai_building false
    	end_if
    	if I_LocalFaction xixia
    		destroy_buildings xixia ai_building false
    	end_if
    end_monitor

    Now I can comment it to remind myself and others what it's supposed to do, save it, and test to make sure it works. Keep in mind that I started with champa in there, and it was also replicated, so you can usually remove the one you wrote for the purposes of replicating it after inserting the replicated code(as it will be redundant).

    That's all for the first part of this, in the next part I'll show you the two different kinds of code for the creating building half, how nested if statements work, how to replicate a script using two variables to produce roughly 2,000x the code you actually wrote, and how you can later refine and test your script.
    Last edited by Augustus Lucifer; July 06, 2009 at 09:17 PM.

  2. #2
    Augustus Lucifer's Avatar Life = Like a beanstalk
    Patrician Citizen

    Join Date
    Aug 2006
    Location
    Mote of Dust
    Posts
    10,725

    Default Re: Using the Script Replicator

    Reserved for Second Part

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •