Announcement

Collapse
No announcement yet.

Events and Scenarios

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

  • Events and Scenarios

    We want to provide scenarios to the players. Currently, these scenarios are hard-coded as java classes, and referenced by a java file, so that is not open at all.
    This thread is to define a design to allow for more openness.
    We want something like a xml definition for scenarios. It means we need a set of files describing unit types, techs, etc. (we already have some of that). We also have to be able to save the map, units on field, economy (this is underway).
    When we have all this completed, it will be possible to generate a scenario without compiling anything IF:

    -We change the resources/ directory. Currently we have a resources directory in the jar. All files are read from there (except settings). We should probably have one subdirectory per scenario.

    -We are able to identify a list of available scenarios: Probably add a scenarios.xml file in /resources, which a modder could edit, or propose a file open (which may be a pain in java).

    Additionnally, I want to add some events capabilities so that you can check a condition and do something at the beginning of each turn. For example, to implement Mark's example government scenario, the condition would be turnId = 20, the action being: set ai civ#2 behaviour to aggressive.
    This means we will also need a xml file for events in the scenario subdirectory.
    The syntax could be {event}
    {if}turnId=20{/if}
    {then}
    {affect}(same tags to set ai attitude as in save file){/affect}
    {/then}
    {/event}
    A list of possible actions would include: affect values, increase/decrease values, show events (text, images, sounds) to the player.

    Remarks upon the whole scheme are welcome. In particular, Gary, if you have any ideas on how things should/could be done, or plans of doing some of the scenario stuff.

    Once we get a design, I will be able to know how much time this requires so we can decide when to do it (soon, later, much later, much much later).
    Clash of Civilization team member
    (a civ-like game whose goal is low micromanagement and good AI)
    web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

  • #2
    We change the resources/ directory. Currently we have a resources directory in the jar. All files are read from there (except settings). We should probably have one subdirectory per scenario.
    I had been thinking in terms of a scenarios subdirectory of the resources directory, with one file per scenario in that subdirectory. The code to select and load from that directory is pretty straightforward.
    -We are able to identify a list of available scenarios: Probably add a scenarios.xml file in /resources, which a modder could edit, or propose a file open (which may be a pain in java).
    I would think that a scenario editor will not be far away.
    Additionnally, I want to add some events capabilities so that you can check a condition and do something at the beginning of each turn. For example, to implement Mark's example government scenario, the condition would be turnId = 20, the action being: set ai civ#2 behaviour to aggressive.
    This means we will also need a xml file for events in the scenario subdirectory.
    The syntax could be {event}
    {if}turnId=20{/if}
    {then}
    {affect}(same tags to set ai attitude as in save file){/affect}
    {/then}
    {/event}
    A generic event interface would be needed. Within that, I see no problem with having a possibly large number of potential events provided. In particular, I don't much like the prospect of having to parse "turnId=20" and perhaps many similar expressions, when:
    &ltevent&gt
    &ltturn&gt20&lt/turn&gt
    ...and possibly other conditions...
    &lttrue&gt...some effect...&lt/true&gt
    &ltfalse&gt...some effect...&lt/false&gt
    &lt/event&gt
    will achieve the same result.
    I want, if at all possible, to avoid creating another programming language. If we find ourselves writing program like constructs, it is probably better to put it in Java code, which can then be parsed by the JVM to produce a class. This is not too difficult.
    A list of possible actions would include: affect values, increase/decrease values, show events (text, images, sounds) to the player.
    In line with my whole philosophy of programming, I would add events and effects only when they are used. Adding a possible list at the start could waste a great deal of time.
    Remarks upon the whole scheme are welcome. In particular, Gary, if you have any ideas on how things should/could be done, or plans of doing some of the scenario stuff.
    I was about to start this. I ties in with my intention of tidying up the whole XML scene. The new XML code I have does away with all the intermediate classes, all we need is to match the internal variable or subclass names to the tags in the XML file, and provide an interface to give the element name for the main element (which need not be the same as the class name), to create an instance, and to store it.
    Once we get a design, I will be able to know how much time this requires so we can decide when to do it (soon, later, much later, much much later).
    I had intended (hoped?) to do it in the next two to three weeks.

    Cheers

    Comment


    • #3
      Some discussion on this general topic went on in the thread XML macro language? way back when. Just skim it if you look at it, since some thoughts are a bit overboard. I think Kull's comment about what the needs of the scenario community are is an important one to keep in mind for the long run.

      Other links on the topic can be found off the "Macro Language" page on the web site, and may be worth a quick look to see what general opinions were on what features are needed. Of course a lot of it is irrelevant now. If anyone find a jewel post amongst all the old stuff please feel free to pull it forward into this thread.

      As Gary said, if we're going to have a really complete macro language it might as well be java! And I echo the point that we should just implement what we're going to use in the immediate future.
      Project Lead for The Clash of Civilizations
      A Unique civ-like game that will feature low micromanagement, great AI, and a Detailed Government model including internal power struggles. Demo 8 available Now! (go to D8 thread at top of forum).
      Check it out at the Clash Web Site and Forum right here at Apolyton!

      Comment


      • #4
        Neither do I want to create another language.
        The turnId=20 I left there but I didn't like it the moment I wrote it...
        Sticking to my example, it could go:
        {if}{turn}20{/turn}{/if}
        {true}{playerCiv}
        {technology name = "Military Tactics"}
        {multiply} 2 {/multiply}
        {add} 1 {/add}
        {/technology}{/playerCiv}{/true}
        or, for Mark's scenario:
        {true}
        {civ name="X2"}
        {attitude civ="Player"}ennemy
        {/attitude}
        {/civ}
        {/true}
        I don't think we want to compile code if that can be avoided. I don't think the compiler comes with the jre.

        I am also pretty sure even "simple" statements like the above are too complicated for a mod-maker, so we will need an editor or feedback from someone like Kull to create events files. Note Richard's tech editor was good, but here the list of tags you can imbed varies.

        To have one file per scenario seems difficult to me. I imagine scenarios where you change unit values. Since there is a military xml file and dedicated parser, do you want to include that in the file or modify the file itself?
        Clash of Civilization team member
        (a civ-like game whose goal is low micromanagement and good AI)
        web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

        Comment


        • #5
          To have one file per scenario seems difficult to me. I imagine scenarios where you change unit values. Since there is a military xml file and dedicated parser, do you want to include that in the file or modify the file itself?
          The XML parser I have (in game.libraries.parser, it is currently being used for the layout settings data) doesn't care what file it gets the data from. So the game would read in the standard military file, and the scenario could override specific units, or add new ones. The same would apply to any other segment, such as technology.

          Cheers

          Comment


          • #6
            The XML parser I have (in game.libraries.parser, it is currently being used for the layout settings data) doesn't care what file it gets the data from. So the game would read in the standard military file, and the scenario could override specific units, or add new ones. The same would apply to any other segment, such as technology.
            I still don't like it: You cannot delete things with that approach, or totally replace things. I am currently playing a civ2 scenario (by Kull) and checking the events, units etc. files: The tech tree was totally rewritten so it would start earlier and finish around 0AD. Reading all techs like gunpowder because they are in the default file seems wrong. Same with military units. The figures are so different from standardciv2 values that the warrior with no prerequisite is ridiculous in the scenario. I think the scenario has to be able to say it overrides in whole a given xml file.
            Clash of Civilization team member
            (a civ-like game whose goal is low micromanagement and good AI)
            web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

            Comment


            • #7
              I think the scenario has to be able to say it overrides in whole a given xml file.
              I don't see any problem with that at all. In fact, I suspect that the scenario will specifiy the external files it will use.

              One thing we haven't really moved on yet is the subject of random scenarios. In Civ, I do not ever play any other kind of scenario, going right back to Civ1. In that case it needs a standard set of data.

              Cheers

              Comment


              • #8
                suspect that the scenario will specifiy the external files it will use.
                If you mean to have some sort of #include or java import in the file, then it's OK for me.

                Of course, we need a standard set of data for random maps. Note that even civ1 asks a few options like difficulty and number of civs at the beginning, which may be meaningless in a scenario, so the scenario must be able to display these questions. That means it probably needs a setup flag or something like that.
                Clash of Civilization team member
                (a civ-like game whose goal is low micromanagement and good AI)
                web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

                Comment


                • #9
                  Given that JavaCC makes "making your own language" actually quite straight forward, I wouldn't totally rule out a simple language which is alot like Java but not nearly so strict. Here's what I would suggest:

                  The event-handling language would need to allow 3 main things: check(value), set(value), do(action). It would use end of line (\n) as a terminator to avoid people forgetting that darn semicolon, would not be case sensitive, and would not require "==" for evaluation (an extremely common mistake that comes up in programming).

                  Starting with a simple scenario, let's say you want to see if the player has accomplished the goal of capturing Rome. To do that you would do this in the event file:

                  if (city.Rome.controlledBy = Player)
                  {
                  do( gameOver(Success) )
                  }


                  The gameOver() function would be set by the game itself, but could be over-ridden by the mod-maker in some fashion.

                  Now, see if you can guess what this would do:

                  if (Rome.controlledBy = Barbarian)
                  {
                  do( sack(Rome) )
                  do( removeAllUnits(Rome) )
                  set( Rome.controlledBy to Rome.previousOwner )
                  }


                  Now compare that readability of that to a non-programmer to the following:

                  if (city.rome.controlledBy() == civ.barbarian)
                  {
                  sack(city.rome);
                  removeAllUnits(city.rome);
                  city.rome.setController(city.rome.previousOwner);
                  }


                  And if they capitalized something incorrectly or forgot a trailing semicolon at best they'd get a modified compiler debugger message. I think we all know how helpful THOSE messages are, so that's not good at all.

                  It would also basically require the creator of the event to not only have previous programming skill, but they would have to learn the basics of Java (a strictly typed language, of all things). We java programmers must remember how bewildering java looks to those not familiar with it, and a language that is simple as possible is a must.

                  In other words, there won't be many events made for the game of Clash if they're done purely in java.


                  When it comes down to it either an event language is needed or it somehow must be handled in .xml.

                  A language as the one I propose above would be easily extensible and forgiving to non-programmers, as well as allowing the maximum amount of possibilitys.

                  Using .xml for events wouldn't really reduce the overhead in making such a language, I believe, yet it would be even more complicated than a simple event language. XML is good for descriptively storing human readable data, but it's not so good for anything else (after all, XML stands for eXtensible Markup Language, not eXtensible Programming Language).
                  Better to be wise for a second than stupid for an entire lifetime.

                  Creator of the LWC Mod for Civ3.

                  Comment


                  • #10
                    I am looking at how scenarios are made in civ2 to compare with what we can provide.

                    The original xmls I proposed are not, in my opinion, usable by non programmers. Here is another try, Gary, tell me if the xml parser can handle that:

                    The example
                    if (city.Rome.controlledBy = Player) {
                    do( gameOver(Success) )
                    }
                    would be in pseudo-xml:
                    {condition}
                    {city name="Rome" civ="Player"/}
                    {/condition}
                    {true}{Victory/}{/true}
                    This is much simpler than:
                    {city}Rome{Controller}Player{/Controller}{/City}
                    In fact, enclosing tags should not be used if possible as they tend to make writing big and double the chance of mistyping.

                    The other example:
                    if (Rome.controlledBy = Barbarian){
                    do( sack(Rome) )
                    do( removeAllUnits(Rome) )
                    set( Rome.controlledBy to Rome.previousOwner )
                    }
                    could be:
                    {condition}
                    {city name="Rome" civ="Barbarian"/}
                    {/condition}
                    {true}
                    {sack city="Rome"/}
                    {RemoveAllUnits city="Rome"/} (could be {x="12" y="13"})
                    {city name="Rome" civ="previous"/} **
                    {/true}

                    ** Here the city xml element must be interpreted differently depending on whether the element is in a condition or an action.

                    Opinions?
                    Last edited by LDiCesare; January 31, 2002, 09:59.
                    Clash of Civilization team member
                    (a civ-like game whose goal is low micromanagement and good AI)
                    web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

                    Comment


                    • #11
                      I've been playing around with my idea for CEL (Clash Event Language), and I figured I'd go ahead and post a little example of it to see what everyone thinks. Does it seem simple enough to use by someone who isn't a programmer?

                      No worrys about actual implementation of it, just wondering about how it looks so far.

                      Here is the basic example I have so far:

                      CELVersion = 0.1

                      # This is a comment. Comments begin with the number (#) character, and end at the end of the line (when you hit the enter key).
                      # There are no multi-line comments at this time.

                      # The first line of this file assigns a value to a variable. At this time there is no such thing as a "static variable" that can be user-defined,
                      # however variables provided by the game are considered static and cannot be directly manipulated in the above way (you have to use set() to alter those, if they are alterable).
                      # The CELVersion variable should always be defined, and should not be "customized" by the writer of this file.
                      # The only reason to change it is to tell the CEL parser what version of CEL this is. So if a file is version 0.2, but the parser only supports 0.1,
                      # the parser will simply be able to return a "version not supported" error message. In clearer words: don't screw with the version number, because it could cause this file to break.

                      # This file is only read once when a scenario starts/when a saved game is loaded. Sections are evaluated many times, but this file is only read once.
                      # So if you make any changes to the events file while playing the game you must exit the game you are playing (but you don't have to close the whole Clash game itself),
                      # then reload the saved game/start a new game.

                      # Just about everything in CEL is case insensitive, so "var" is the same as "Var" is the same as "vAr". But you should try to stick to the same case rules throughout the file,
                      # to avoid confusing the heck out of yourself and everyone else. The case used by default is the reccommended style, and you are encouraged to adopt it as your own.



                      :START TURN:
                      # This section is evaluated at the begining of every turn.


                      :END TURN:
                      # This section is evaluated at the end of every turn, but before the movement phase.


                      :START BATTLE:
                      # This section is evaluated when a battle begins, before any other events - including rolls for retreating/surrendering, et al.


                      :END BATTLE:
                      # This section is evaluated at the end of a battle, before any units are removed from the game (which occurs after the battle has ended).


                      :CITY CAPTURED:
                      # This section is evaluated whenever a city has been captured. A "capture" is whenever a unit owned by someone other than the current controller of the city
                      # is unopposed in the city before the begining of the next turn (at the end of the movement phase). Control of the city does not automatically go to the invader;
                      # that's handled here, in the events file.

                      # SPECIAL VARIABLES:
                      # City.CityCaptured = This is the city that was captured that caused this section to be evaluated. It is available exclusively in this section.

                      # TIP: To find the name of the city that was captured, use City.CapturedCity.cityName


                      # This simply gives control of the captured city to the civilization that captured it.
                      set( City.CityCaptured.controlledBy to City.CityCaptured.capturedBy )


                      :FUNCTIONS:
                      # This section is only "evaluated" once, because this is simply a section that holds function declarations. All functions must be declared/defined (they are the same thing in CEL)
                      # here and no where else.

                      # SPECIAL FUNCTIONS:
                      # gameQuit() = This function is provided by Clash and cannot be over-ridden or changed at this time. It's the equivalent of choosing the Quit option from the file menu.


                      gameWon()
                      {
                      do( popupMessage("Congratulations, you have won the game!") )
                      do( gameOver() )
                      }

                      gameLost()
                      {
                      do( popupMessage("Oh no, you lost the game!") )
                      do( gameOver() )
                      }

                      gameOver()
                      {
                      do( gameQuit() )
                      }
                      Last edited by Plutarck; February 2, 2002, 02:47.
                      Better to be wise for a second than stupid for an entire lifetime.

                      Creator of the LWC Mod for Civ3.

                      Comment


                      • #12
                        There are 2 things I don't like in your language, Plutarck:
                        One is:
                        set( City.CityCaptured.controlledBy to City.CityCaptured.capturedBy )
                        Parsing and understanding the . is messy. (Also, it should just be CityCaptured.controlledBy). That requires javaCC or something like that, which I'd rather avoid if I can make do with xml. I'd rather not have many tokenizers.
                        Second:
                        As for the {} as delimiters, they are usually not easy to understand to non programmers.
                        Having variable definition as x=1, then changing it not thru = seems funny to me.
                        I'd much rather have blocks like xml (although the <> are boring), and single lines.
                        Much like civ2 (from memory):
                        @coordinates
                        12,24
                        13,23
                        @endcoordinates
                        rather than { }.
                        The same text/endtext instead of popUpMessage("ten lines later I forget the closing parenthesis")
                        Going xml just replaces
                        @text by <text>
                        and @endtext by </text>

                        As for events, as Gary said, we'll put them in when the need arises. Indeed new turn, end turn are good ones. I am not sure about start/end battle, unless you explain me for a specific mod why you need that.

                        The way civ handles things is quit good IMO, as many events are actually conditions that you may check everytime or just once. This could translate by a <justonce/> flag in a condition.

                        I will try to look for CTP2 scenarios as there is a script language therein, and look at what is used in it and whether we need a slic-like thing like you propose.
                        Clash of Civilization team member
                        (a civ-like game whose goal is low micromanagement and good AI)
                        web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

                        Comment


                        • #13
                          You know now that you mention it, I realized - why would so many parens be needed anyway? And on set vs =, clearly the simplest thing would be to have it only handled one way, and set is probably easier to figure out for non-programmers than "=" or "==".

                          So this:

                          CELVersion = 0.1

                          Becomes this:

                          set CELVersion to 0.1

                          "to" would be equivalent to "=" or "==" (depending on the language you use as a comparison). This all makes it feel a bit "Basic" to me, and I can't say I'm a big fan of the windows-style of language, but it would seem that a simple middle ground could be struck.


                          Now, about "City.CityCaptured". The reason for the "City." on the begining is to remove ambiguety. I realised after my first post the problems of not having it.

                          For instance, consider this:

                          Rome.population

                          Now, what does this refer to? Does this refer to the population of the city of Rome, or to the population of the Civilization of Rome? And what if their is a unit someone wants to name Rome, or a leader, or any other thing for that matter?

                          Now, instead if you use City.Rome.population, it's obvious what is being refered to. The same would go for Civilization.Rome.population (or maybe Civ.Rome.population instead, if prefered).

                          Rather than using dots the alternative would be "->", like that used in PHP (and I believe also in C), but I'm really not a fan of that at all, and for many reasons. For one thing it's at least 3 times as hard to type


                          Now for popupMessage, it was this:

                          do( popupMessage("Congratulations, you have won the game!") )

                          But instead, consider this:

                          do popupMessage "Congratulations, you have won the game!"

                          Now that seems to look a whole lot better.


                          Thus there would be no extra parens to forget, which really can be a hassle.

                          But should parens still be kept for functions? What would look better/be more functional, this:

                          do gameOver

                          Or this:

                          do gameOver()

                          Both have alot going for them, but I'd think that keeping the parens would remove ambiguety and make it easier to pass variables, such as coordinates (which is probably the main use for such a feature).

                          We'll assume the parens can stay.


                          So now the gameWon() function would look like this:

                          gameWon()
                          {
                          popupMessage "Congratulations, you have won the game!"
                          do gameOver()
                          }


                          Now, the question is if brackets are better than the "something" and "endsomething" constructs. Personally, I find the following:

                          if
                          ...
                          endif

                          To be really rather...fugly and annoying. This may just be personal preference, but I really like the C-style method such as:

                          if (true)
                          {
                          ...
                          }

                          True, it isn't as obvious or easy to learn, but once learned it is easily adapted to many uses. Such as !(), where the if is only executed if the internal statement is false, the addition of elseif and else (though it's probably just as easy with the method I'm arguiing against), while and foreach, and other similar such things.


                          But as the key is simplicity in this case, and the goal is to have the greatest percentage of potential modmakers to be able to make any mod they like, whatever would meet such conditions would be preferable.


                          Oh, and about the start/end battle sections, I haven't thought up a use for those yet either. I was just trying to think up any possible use for sections so I could write them down and try to think up some way they'd be used. They certainly wouldn't be needed any time soon, and obviously something shouldn't be implemented unless there is some real use for it.


                          And on "just once" items, that is a good point. It could just be done with a variable in a loop. So you'd set the control variable to true so it would be executed every time it came up, but when you didn't want it to be anymore you'd just set the variable to false.

                          But that might be a bit too complicated for just a simple "do this once" statement.

                          Hm...something to think about. Perhaps a "doonce" keyword, or "do-once". Or a bit more cryptic but easy once learned would be "do(1)" to do something one time, or "do(10)" to do something 10 times, etc.

                          But then, would that just do the same thing 10 times all in a row, or just once per execution up to a maximum of 10 executions?


                          Always something new to ponder
                          Better to be wise for a second than stupid for an entire lifetime.

                          Creator of the LWC Mod for Civ3.

                          Comment


                          • #14
                            Example of Event/Trigger useage

                            Mark asked me to add this to the thread.

                            I've attached two files that could be of help for whomever is coming up with the event language. The first one is slic.xls, a spreadsheet with every CTP2 event/variable/trigger, that we in the CTP2 community were able to get out of the AI programmer (Joe Rumsey) at Activision. It is extremely extensive, and also gives the parameters required to use these events/triggers. The reason some variables are open to MOD useage, is for things like:

                            - g.player = the current player's turn.
                            - g.year = the current year in integar format (0 = 4000BC).
                            - player.capital = the current player's capital city.
                            - unitrecord.attack = the attack strength of the unit.

                            This is the number one problem with Civ3 that I have, no event language. It really locks Civ3 into one pattern.

                            The second file I've attached is an actual SLIC script file I wrote for the Apolyton Pack for CTP2. I've commented to explain what it does.

                            Hope this helps.
                            Attached Files

                            Comment

                            Working...
                            X