Announcement

Collapse
No announcement yet.

Getting Started With SLIC

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Getting Started With SLIC

    Step 0:

    It's probably about time we made it a bit easier for people to get started with SLIC. For absolute beginners, the first thing you need is a ModPack. I've appended a ZIP that contains a template structure, all you have to do is unzip it to

    ...\Call To Power 2\Scenarios.

    Write your new SLIC code in

    MyModPack\scen000\default\gamedata\scenario.slc

    and use

    MyModPack\scen000\english\gamedata\scen_str.txt

    for the text ('strings') in your messages. Any modified files that you want to use need to go in the appropriate place: e.g., if you want to use a modified strategies.txt you need to put it in ...\Scenarios\MyModPack\scen0000\default\aidata.

    To use this zip again, rename the folder 'MyModPack' to whatever you want, and then unzip again.

    More information about this file structure can be obtained from Hexagonian's Mod guide available from http://www.geocities.com/hexagonia/

    This provides the basic file structure. Modswapper, again from Hexagonian's site, provides a more advanced system.

    (Thanks to Martin Guehmann for the Beaver tga, used to represent the busy and hard working modmaker. )

  • #2
    Here's that Zip:

    [Edit: fixed the path so you don't have to make a new folder when you unzip]
    Attached Files

    Comment


    • #3
      Step 1. Although not necessary, the editor Editplus makes life a lot easier. It's available from http://www.editplus.com . Next pick up the attached zip which contains the files you need to use SLIC in EditPlus2. (These were originally from Locutus's site <http://home.student.utwente.nl/w.snijders>, but the ones here have a few little add ons in the autocomplete and cliptext files.)
      Attached Files

      Comment


      • #4
        Step 2. Here's some instructions for configuring Editplus2 to use the above files. (These are based on some instructions that Angelo Scotto included with his CSPL system for Civ2. Thanks, Angelo.)
        Attached Files

        Comment


        • #5
          Step 3. Finally, when Locutus finishes his Introduction to SLIC, it will be the definitive work. Until then, learning SLIC will remain a bit like doing a jigsaw puzzle.

          Edit: I originally posted some links to C documentation here, but now that both Immortal Wombat and Locutus have provided their SLIC documentation (see below), they were irrelevent.

          Also: The stuff about MyModPack is also largely outdated because everybody uses ModSwapper now.

          Combining the above with the Activision documentation should allow you to get started on writing your own SLIC programs.
          It's a real programming language so it takes a bit of practice before you get the hang of it. But don't get discouraged by all the crashes you'll get, and have fun!

          PS: One last very important point. While you are writing and testing your code make sure that in ...\ctp2_program\ctp\userprofile.txt you have "DebugSlic=Yes". This uses a bit more memory but it gives you better error messages and you can't properly debug your code without it. Once you're satisfied that your program's working perfectly, you could set "DebugSlic=No", but personally, I never bother. (That's how I gathered my expertise on Error Messages, I make a lot of errors. )

          Comment


          • #6
            dp
            Concrete, Abstract, or Squoingy?
            "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

            Comment


            • #7
              Fantastic. I think. Maybe. If you intend to learn C afterwards. Or know C already.

              I learnt SLIC with no grounding in C at all, and with no intention of learning C afterwards (at least yet...)
              From what I have seen, C is based around int and void functions? It is very possible to start using SLIC without adding int or void functions at all, using just handlers. This is how I (and I think Martin) began, maybe that would be simpler. It makes more sense having functions that are called based on logically named events.

              I found it easier to look at how the handlers worked, and piece it together logically. As all the functions are documented (all be in poorly, with many many bugs) these are a good place to start from.

              Btw, there aer some broken links amongst that lot...
              Concrete, Abstract, or Squoingy?
              "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

              Comment


              • #8
                Btw, there aer some broken links amongst that lot...
                Thanks, I removed one; the ones left seem to work.

                All those C-links are really meant to be just a stopgap until Locutus finishes his introduction, or at least puts something online (hint, hint ). The bits I "yes"d just cover basic overlapping syntax, but admittedly it's not the best solution because for one thing the examples used in these tutorials tend to have C-features that aren't in SLIC. And C is a much more powerful language: it's said that you can program anything in C.

                It is very possible to start using SLIC without adding int or void functions at all, using just handlers.
                I did a search on "Event Driven Programming" but didn't find anything useful. I'd like to find out more about this, it's something that, IMO, was just left out of the Activision docs.

                Comment


                • #9
                  Originally posted by Peter Triggs
                  All those C-links are really meant to be just a stopgap until Locutus finishes his introduction, or at least puts something online (hint, hint ).
                  Okay, I'll byte What I have written until now has been available on my website for quite some time now, I guess I simply forgot to give anyone the URL before You can download it from here but I must warn it's pretty rough and incomplete.

                  That is, the subjects covered are (more or less) complete but not all subjects are covered. The example code is all untested, all sorts of new stuff that I found out in the last 9 or so months not updated. It will probably be of great value to people who want to get into SLIC programming but you'll need other resources for info on the subjects not (yet) covered. It IMHO also severely lacks good (more complicated) examples.

                  I did a search on "Event Driven Programming" but didn't find anything useful. I'd like to find out more about this, it's something that, IMO, was just left out of the Activision docs.
                  Hmm, SQL3 tutorials perhaps?
                  Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                  Comment


                  • #10
                    rtf document??

                    Ah well, at least its out Thanks a million Locutus.
                    Concrete, Abstract, or Squoingy?
                    "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

                    Comment


                    • #11
                      I Am just learning slic myself and again with no grounding in c

                      Now who said it was like a jigsaw puzzle yes it is kind of problem is you need a sledge hammer half the time and the other a couple of years to spear.

                      You get us to it after a while and it becomes easier. the only help I can give to a new slicer is to look at the pre done scenarios and the bit of the apolyton website. it may take a bit but you should get there


                      well that's it

                      THE BIG MC
                      "Every time I learn something new it pushes some old stuff out of my brain" Homer Jay Simpson
                      The BIG MC making ctp2 a much unsafer place.
                      Visit the big mc’s website

                      Comment


                      • #12
                        I am alright with the general C programming variables, functions, flow controls etc. but I just don't have any reference about this SLIC in CTPII, I mean the meaning of variables, functions, to be more precisly, where is the connection between SLIC language and CTPII and how it is structured.

                        Comment


                        • #13
                          All the functiopns, events, and built-in variables are documented (basically) by Activision. You can get the infohere on Apolyton
                          Concrete, Abstract, or Squoingy?
                          "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

                          Comment


                          • #14
                            That's fantastic, thanks Wombat!

                            Comment


                            • #15
                              Event-Based Scripting for CtP2

                              ////////////////////////////////////////
                              // SLIC as an events-driven language. //
                              ////////////////////////////////////////

                              A quick guide by Ben Weaver, aka The Immortal Wombat.
                              email: weaver1@tinyworld.co.uk

                              TURN WORD-WRAP ON

                              This guide is probably only useful to some people, others will find it positivly unhelpful. Some parts are less well explained. I think these are the bits that Locutus has already done, so check out his SLIC guide here: http://home.student.utwente.nl/w.snijders/Slicdoc2.rtf

                              ---------------------------------------------------------------

                              1.0 Intro
                              1.1 Stuff
                              2.0 Handlers
                              2.1 Events as Handler Triggers
                              2.2 Structure of Handlers
                              2.3 Example Code
                              3.0 Variables
                              3.1 Defining variables
                              3.2 Built-in variables
                              3.3 Use of variables in functions
                              4.0 if, for, while
                              4.1 Boolean Logic
                              4.2 If, Elseif, and Else Statements
                              4.3 For Loops
                              4.4 While Loops
                              5.0 Functions
                              5.1 Example Function Code
                              5.2 Nested functions
                              5.3 User-made functions
                              5.4 Function-Based Coding
                              5.5 Events as Functions
                              6.0 Messageboxes
                              7.0 mod_ functions
                              8.0 End Note

                              ---------------------------------------------------------------

                              1.0 Intro

                              SLIC is a scripting language for CtP2. This means basically that it is a simplified programming language designed for use in CtP2. This allows you to make subtle, or not-so-subtle changes to the way the game plays, how some of the game rules act, and other such interesting things. It is based on a C-like syntax, but I see it very differently from C, because primarily it is events-driven language. Basically, think of SLIC as a reaction-language ie When x happens, SLIC makes y happen.
                              This guide should help you learn the basics of SLIC from the point of view as making y happen when x does, for many different and increasingly complex types of x and y.
                              Very important when SLICing: Have a goal in mind, and know how you are going to acheive this. This may mean getting very well aquainted with all the functions and events, or at least having a list of them available at any time.

                              Notes:
                              Most examples of SLIC coding in this guide do not come from Activision scenarios, as the SLIC in those is fairly complicated, and better examples are available. Consequently, if I refer to "SLIC files", I mean SLIC files other than Actision's *_func.slc and *_msg.slc files.

                              () - parentheses
                              [] - square brackets
                              {} - brackets

                              I am essentially very lazy, so a lot of the stuff in Locutus' SLIC guide, about Boolean logic, if, for, while, loops and number crunching is not included. It would probably be easier to read Locutus' guide first.

                              Also, I have put the events and handlers section first. This is a dubious idea, as an understanding of variables is needed for almost all other SLICing, but variables are essentially boring, so flick to section 3 as much as you like whilst reading section two, and you will still feel like you're learning how to do it, rather than the whole dull understanding it first.

                              1.1 - Stuff

                              At this stage I will make some comments about the C structure of SLIC, as you shouldn't need to go delving in C tutorials to learn SLIC. Every bracket that is opened '{' opens a new block of code. This will be dealt with more fully in chapter 4 with the if, for and while loops, but for now, every handler and loop that is opened, needs to be closed, so the game does not give you an error when it goes onto the next handler.
                              Note that when the bracket is opened, the next line is tabbed forward. This is so that the code is easier to follow. These two examples work eactly the same as ech other:
                              PHP Code:
                              HandleEvent(MoveUnits'kill_the_unit' pre {
                                  
                              KillUnit(unit[0]);

                              PHP Code:
                              HandleEvent(MoveUnits'kill_the_unit' pre {
                              KillUnit(unit[0]);

                              but when you get into really complicated code with 20 or 30 different loops and brackets, then getting the right thing closed at the right time is very important.

                              Also, every line that does not end in '{' should end with a semi-colon; this is a marker to SLIC that the line has ended.

                              Oh yeah, and a double forward slash acts to signify a comment:
                              PHP Code:
                              // everything beyond those slashes isn't read by SLIC.
                              KillUnit(unit[0]);   // this also works after lines of code have been ended with a semi-colon 
                              This may seem like a lot to remember, but when you're writing the code, it becomes second-nature mostly, and most of the time its easier to remember than forget.

                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~

                              2.0 Handlers

                              Open any SLIC file, and somewhere in it will be an event handler. Event handlers are what 'see' the event happening, and trigger the code that you want to react to that event (They recognise a specific x and trigger your code for y.

                              2.1 - Events as Handler Triggers

                              Events are things that happen in the game. Most are fairly self-explanatory. BeginTurn 'fires' every time a turn begins (once for each player, not once for every human turn). MoveUnit fires every time a unit is moved. Activision provided a list of the events that SLIC recognises. http://apolyton.net/ctp2/modificatio...icevents.shtml
                              Note that for each event, there are one or two (and occasionally three) variables listed after the event. for example:
                              GetExpelledOrder(army_t, location_t, int_t)
                              This is an event that will trigger a handler for example, you want to make it so that whenever an army is expelled, the player who owns the army will be told about it.
                              The variables after the event are automatically generated into the built-in arrays so that when you trigger a handler on the GetExpelledOrder event, army[0] will be the "name" for that army in context, location[0] will be the army's location in context, and player[0] will be the army's owner (I think).

                              In diplomacy events in particular, you often get 2 players listed. These will be stored as player[0] (the person making the proposal for instance) and player[1] (the recipient). This is different from player 0 (barbarians) and player 1 (Usually the human. Almost always the civ in blue)

                              2.2 - Structure of Handlers

                              Event Handlers will all look something like this:
                              PHP Code:
                              HandleEvent(BeginTurn'handler_name' post 

                              • The first bit 'HandleEvent' is always there. It defines the next block of code as an event handler.
                              • Then the parentheses open, and you have to fill in an event that you want the code to fire on. (ie. define your x)
                              • Between the ' ' marks, fill in a handler name. To avoid confusion (for yourself and the game) this shoud be named differently to every other handler, and not have the same name as any variables you are using.
                              • Then comes the pre/post bit. Most of the time it doesn't matter whether the code fires before or after the in-game stuff has been taken care of, but occasionally if you want one trigger to fire before the other, then set one to pre (before) and one to post (after).
                              • Finally, the brackets open, to signify that everything inside them is part of the event handler.


                              If you are using EditPlus2 with the SLIC addon, you should get a colourful line of blue-red-pink-blue, and then you know you didn't make any typos or whatever.

                              2.3 - Example

                              PHP Code:
                              HandleEvent(MoveUnits'kill_the_unit' pre {
                                  
                              KillUnit(unit[0]);

                              This is a very simple event handler. It consists of one event (the MoveUnit event), and one reaction, a function. It kills the unit that has just moved.

                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~

                              3.0 Variables

                              Variables in algebraic mathematics are numbers assigned a name, because their actual values change. In SLIC, this is much the same, only as well as integer variables (NB not decimals, SLIC can't use them), SLIC also uses unit variables, army variables, location variables and city variables. Player variables are treated as integers.

                              In the above example of an event, the event stores three variables, and these are denoted by army_t, location_t, int_t<player> The <player> bit is irrelevant, the player is just a number to the game. In functions, to get them to work properly, you have to fill into them the correct variables that you want the functions to work on (see chapter 5).

                              3.1 - Defining Variables

                              To make SLIC recognise the variables for what they are, so that it doesn't start treating a unit as a city, or a location for an integer, you have to define what each variable that you use is. This can be done inside the handler, or outside the code, on its own. The former is a local variable. It applies only to that handler. If you use it in another handler, you must redefine it. The latter is a global variable, it applies to all functions and handlers in the code, and can be used in messagebox text (see chapter 6).
                              NB. If you are mixing your SLIC with that of other peoples, chances are you may have used the same variables somewhere, so it is recommended to define variables locally, unless you need them global for some reason, in which case name them with really obscure names.

                              To define a variable, you need a new line, to tell the game what each variable is.
                              eg.
                              Code:
                              int_t	tmpNum;			// tmpNum (temporary number) will be treated as an integer
                              unit_t	tmpUnit;		// tmpUnit (temporary unit) will be treated as a unit
                              location_t	tmpLoc;		// tmpLoc will be treated as a location
                              army_t		tmpArmy;	// tmpArmy will be treated as an army
                              city_t	tmpCity;		// tmpCity will be treated as a city
                              			// note semicolons at the end of each line
                              Once they are defined, variables can be used below that point. Most SLIC files keep global variables at the very top, so they apply to the whole code.

                              3.2 - Built-in Variables

                              Activision Listing - http://apolyton.net/ctp2/modificatio...cbuiltin.shtml

                              As mentioned in section 2.1, and in Locutus' guide, SLIC comes with built-in variables that are already defined. They can be used as a suffix to any other defined variable eg. if tmpPlayer is defined as a player, tmpPlayer.cities will automatically be the number of cities that tmpPlayer owns.

                              These built-in variables are very useful to save time doing a CityCount(tmpPlayer) and similar functions all the time.

                              For some reason, these variables seem to work better (for me at least) if the player (or city, location, army, unit etc) is stored into the context array of player[0] (or city[0], location[0]...). If it isn't, then you can easily just do:
                              PHP Code:
                              player[0] = tmpPlayer
                              Which puts tmpPlayer into the player[0] array.

                              3.3 - Using Variables in Functions

                              Really related to chapter 5, but functions need to have the correct variables put into them.
                              Code:
                              HandleEvent(MoveUnits) 'kill_the_unit' pre {
                              	unit_t tmpUnit;		// define variable
                              	tmpUnit = unit[0];	// define what it actually is
                              	KillUnit(tmpUnit);	// the KillUnit function needs to have a unit_t in it.
                              }
                              Using the Activision function reference http://apolyton.net/ctp2/modificatio...ic2func.shtml, you can see which functions need which variables, and make sure you have the right ones available and defined.

                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~

                              4.0 Boolean Logic and if, for and while loops

                              4.1 - Boolean Logic

                              For me to do a guide to Boolean logic and calculations in SLIC would be foolish, when Locutus did such a comprehensive write-up here:


                              Reminder:
                              = make equal to
                              == is equal to
                              != is not equal to
                              > is greater than
                              < is less than
                              >= greater than or equal to
                              <= less than or equal to

                              4.2 - If, Elseif, and Else Statements

                              Pretty much the same as if statements in any programming language, and even in any spoken language.

                              Code:
                              HandleEvent(MoveUnits) 'kill_the_unit' pre {
                              	unit_t tmpUnit;				// define variable
                              	tmpUnit = unit[0];			// define what it actually is
                              	player[0] = unit[0].owner;		// name the unit's owner (it is not implicit in the event)
                              	if(player[0].cities > 10){	// if statement. IF the unit's owner has 10 cities...
                              		KillUnit(tmpUnit);		// if 'yes', then do function. Kill the unit.
                              	}				// close if statement
                              }						// close handler
                              If Statements return 1 or 0 , true or false. If the if statement is true (1) then the code inside inside the brackets is executed, otherwise it is skipped over.

                              This leads to elseif and else statements.

                              Code:
                              HandleEvent(MoveUnits) 'kill_the_unit' pre {
                              	unit_t tmpUnit;				// define variable
                              	tmpUnit = unit[0];			// define what it actually is
                              	player[0] = unit[0].owner;		// name the unit's owner (it is not implicit in the event)
                              	if(player[0].cities > 10){		// if statement. IF the unit's owner has 10 cities...
                              		KillUnit(tmpUnit);		// if 'yes', then do function. Kill the unit.
                              	}					// close if statement
                              	elseif(player[0].cities < 3){		// ELSE, IF (elseif) the unit's owner has less than 3 cities...
                              		KillUnit(tmpUnit);		// if 'yes', then do function. Kill the unit.
                              	}					// close elseif statement
                              	else{					// ELSE. (none of the above)...
                              		Heal(tmpUnit);			// if you haven't killed it in an if loop above, then heal the unit.
                              	}				// close else loop
                              }						// close handler
                              4.2 - For Loops

                              This is a way of executing a bit of code many times, without having to write it out many times.
                              Usually, this is done by having a counter which counts the number of times the loop has been done, and when it reaches the upper boundary you set, it stops.


                              The basic structure of a for loop is:
                              Code:
                              // define counter, usually i for integer
                              int_t	i;
                              // for statement ( starting value-semicolon-value is less than value-incremental increase) bracket {
                              for(i = 0; i < 8; i = i + 1){
                              	// code
                              //close loop
                              }
                              Note, for loops can run in reverse, starting high, and decreasing to 0. See some of Martin Guehmann's code, as he uses it far more frequently that anyone else.
                              eg.

                              Code:
                              HandleEvent(MoveUnits) 'kill_the_unit' pre {
                              	unit_t tmpUnit;						// define variable
                              	tmpUnit = unit[0];					// define what it actually is
                              	player[0] = unit[0].owner;				// name the unit's owner (it is not implicit in the event)
                              	if(player[0].cities > 10){				// if statement. IF the unit's owner has 10 cities...
                              		KillUnit(tmpUnit);				// if 'yes', then do function. Kill the unit.
                              	}							// close if statement
                              	elseif(player[0].cities < 3){				// ELSE, IF (elseif) the unit's owner has less than 3 cities...
                              		KillUnit(tmpUnit);				// if 'yes', then do function. Kill the unit.
                              		int_t	i;				// define counter variable
                              		for(i = 0; i < player[0].cities; i = i + 1){	// for each of player[0]'s cities...
                              			AddGold(player[0], 5000);		// give 5000 compensation 
                              		}						// close for loop
                              	}							// close elseif statement
                              	else{							// ELSE. (none of the above)...
                              		Heal(tmpUnit);					// if you haven't killed it in an if loop above, then heal the unit.
                              	}							// close else loop
                              }								// close handler
                              4.3 - While Loops

                              Can run similar to for loops, so that you run some code a certain number of times. eg.
                              Code:
                              HandleEvent(BeginTurn) 'while_loop' pre {
                              
                              	int_t	i;				// define counter variable
                              	i = 0;						// starting value
                              	while(i < player[0].cities){			// upper boundary
                              		AddGold(player[0], 5000);		// give 5000 gold 
                              		i = i + 1;				// incremental increase to i
                              	}						// close while loop						
                              }							// close handler
                              Another way while loops can work is when you want to identify one thing from many. This is equivalent to running a for loop until you find the one you want, and then breaking the cycle.

                              This code is taken and adapted from Locutus' piracy code:
                              (I should mention, random(xxx) gets a random number between 0 and xxx)
                              Code:
                              HandleEvent(BeginTurn) 'while_loop' pre {
                              int_t	xcoord;
                              int_t	ycoord;
                              location_t	tmpLoc;
                              
                              	xcoord = Random(GetMapWidth());				//	
                              	ycoord = Random(GetMapHeight());			// Initiate the numbers
                              	MakeLocation(tmpLoc, xcoord, ycoord);			// and the location
                              	while (TerrainType(tmpLoc) < 10) {			// IF the terrain at tmpLoc is below 10 (plains -> mountains)
                              		xcoord = Random(GetMapWidth());			// reinitiate
                              		ycoord = Random(GetMapHeight());		// the numbers, 
                              		MakeLocation(tmpLoc, xcoord, ycoord);		// and keep going, until the logic statement does not hold true
                              								// then you end up with the location you want
                              	}						// close while loop						
                              }							// close handler
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~
                              end of part one
                              Concrete, Abstract, or Squoingy?
                              "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

                              Comment

                              Working...
                              X