Announcement

Collapse
No announcement yet.

Clash Coding Standards Discussion

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

  • Clash Coding Standards Discussion

    Clash Coding Standards

    We have been discussing a lot recently coding standards for the project, and what the correct architecture we should use is. There have also been discussions about how much memory we can afford for which models, and how the guys in charge of the models interact with people programming the models. What I would like to do is use this thread to hash out agreements on these various issues. For instance, I will put up some information on how many of which type of objects we expect so designers and programmers can make crude estimates of memory usage and clock usage. F_Smith is making some persuasive arguments about how the code should be laid out, using the government model as a testbed. So hopefully he will give us a description here of what he thinks the coding standards for the project should be. Other things that generally relate to coding progress, like how we can attract more programmers are also welcome here. If they get out of hand, we can just subdivide topics, but for now I think starting this all in one place is a good idea so we can have one-stop shopping

    Since we have also discussed some of these topics before, I'm going to provide several links to some old threads that I think are relevant. If anyone else has an old thread they would like to nominate, please let me know. Hopefully, once we have discussed things a bit we can come up with some real coding standards documents and put them up on the web page.

    Links to previous threads:

    Coding organization for Clash started August 22, 1999.

    Clash Coding is a discussion of how to more effectively use the programmers in the project. Richard Bruns suggests doing the coding so that many model specifics can be input by non-programmers. This ties in with the efforts that F_Smith and Garth are pursuing in their respective coding areas.

    Ooa/ood where we talk about object-oriented design as it relates to the tech model, but the comments are a general usefulness.

    And also check out the Coding Model page on the Clash Web page for some more threads.


    Max Numbers of Game Objects

    (My) expectations for the numbers in the game of a variety of objects. I'm going to state effective maximums here, so we keep things a little conservative. The main reason for that is that our super-duper AI will require both a fair amount of memory (Much more than the industry standard) and clock cycles. So if we use the maximum estimate for everything and come in under budget, it means there will still be a fair amount of memory and clocks for the AI.

    I suggest a memory budget for pure objects of something like 10 MB. In addition to this we will have graphics that are permanently in memory, graphics that are transient, and other stuff. One issue that has to do with memory usage is how we run the game for Multiplayer. I like to hear peoples thoughts on that either here, or in the long-dormant Multiplayer Coding/Issues.

    (This is just a very incomplete list to start off the discussions -- current Java class names are shown in parentheses)

    General:
    500 civilizations (Civ.java) -- many will be passive and not have the full AI, perhaps 100 full-fledged civs
    2000 provinces (Province)
    64k map squares (BaseMapSquare) including ocean and unpopulated land. If we put an aerial layer above for future type stuff, then it would be double this.
    20k land map squares (MapSquare)
    10k populated land map squares (PopSquare)

    Military:
    100 task forces per civ (TF.Java)
    500 units per civ (Unit)

    Well, I need to break to do some other stuff. I will get back to this soon.
    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!

  • #2
    Hi, all:

    I'd like to get ya'lls input on a proposed 'Coding Standards' statement to orient new programmers. This is just a rough draft, so please jump in with any disagreements or suggestions. Do not feel this is being imposed on ya'll -- anything you do not agree with, we will work together to find a compromise.

    * * *

    From the book 'Extreme Programming
    Explained' by Kent Beck (p. 48):

    "Designing is creating a structure that organizes the logic in the system.
    Good design organizes the logic so that a change in one part of the system
    doesn't always require a change in another part of the system. Good design
    ensures that every piece of logic in the system has one and only one home.
    Good design puts the logic near the data it operates on. Good design allows
    the extension of the system with changes in only one place.

    Bad design is just the opposite. One conceptual change requires changes to
    many parts of the system. Logic has to be duplicated. Eventually, the cost
    of a bad design becomes overwhelming. You just can't remember any more
    where all the implicitly linked changes have to take place. You can't add a
    new function without breaking existing functions."


    Our basic 'Coding Standard' has to be the M-V-C approach. All programs consist of exactly three parts, each with a specific purpose, and Clash is no exception.

      [*]You have 'DataModel' classes that hold all the state information for the
      Game data. These classes should extend 'Observable', or implement a vector
      of observers internally.
      [*]You have 'Data View' classes (panels and such) that must each be
      declared as 'Observers' (implement the 'Observer' interface, actually very
      simple) and observe the Data model. The data model will fire off updates
      whenever anything in the game data changes, and the View classes will
      recieve those updates and update their screen details.
      [*]Finally we'll have the 'Controller' classes -- game state, turn logic,
      File IO stuff (including streaming for multiplay), etc."[/list]
      All code should be seperated into three directories, along these lines."


      Does this sound alright to everyone? I'll post some basic, minimal coding rules next. They'll definitely help to keep everyone on the same page, and should allow new programmers to step right in and make a contribution anywhere they want.

      As I said, I want this to be a 'team' opinion, so do not be shy on telling me exactly how full of shinola you think I am, on any (or all) of the details!
      [This message has been edited by F_Smith (edited July 15, 2000).]

    Comment


    • #3
      F_SMITH :
      I's OK for me.
      I think that the more important is to know where are the pieces of the code. So if we have allways three parts it will be easier to localize things.
      1. Do you think it would be possible to have a example of that in pseudo code so we can have a very concrete base to adopt (or to discuss :-) ?
      2. Could you briefly (for more we can look at the help) explain us what are the Observer class and how you want to use it ?
      regards
      Laurent

      Comment


      • #4
        Hi, Laurent:

        Thanks so much for being a part of this. I agree with you completely -- finding what you need quickly is going to be a big bonus to using this structure.

        1) Yes, tonight from home I'll post some actual base classes and samples here, to begin a discussion on.

        2) The base classes I post tonight will put it much more clearly, but here's a brief run thru:

        The 'Observer' interface has one method -- 'update(Observable o, Object arg)'. Whenever the data changes, this method will fire off, and 'arg' will be the new data.

        The 'Observable' class (or any class you make into an observable) has a vector of 'observers', and related methods (addObserver, removeObserver). It also has a method 'notifyObservers(Object arg)'. Whenever someone changes something in that data class, (using a method like 'addCivilization(Civ c)') that method must call 'notifyObservers(c)'. This will tell all panels (or any type of observer) that have been added as observers that the data has changed, and pass along the data.

        So, for a class like 'GameData', it will extend observable.

        So when you build a 'View' of 'Data', you do something like:

          [*]Build data class using full encapsulation rules (getters and setters), and extend observable. All setters must call 'notifyObservers(Object arg)'.
          [*]Build 'View' class. Typically a Panel that implements observer. When you add this class to the screen, also call 'data.addObserver(view_panel). The 'View' panel should be built in two parts, to seperate the data from the view -- an 'initView()' method that just builds the Panel with blank components (do not fill in any data) and a 'updateView()' method that is called after 'update(Object arg)' fires off. 'update(Object arg)' needs to set the new data to 'arg' (selected_civ, for a 'CivViewPanel', as in the above example, and then call 'updateView()'.[/list]
          This is actually less complicated than it sounds. When I post the base classes tonight, it should be very clear.

        Comment


        • #5
          Hi:

          Sorry to just now be getting to this. Here's my proposal for 'base' classes and structures.

          Sample 'Data' Class:
          Code:
          [b]
          import java.util.*;
          
          public class GameData extends Observable implements Observer
          {
              private Vector civilizations;
              
              public GameData()
              {
                  initData();
              }
              
              private void initData()
              {
                  civilizations = new Vector();        
              }
              
              public void addCivilization(Civilization c)
              {
                  civilizations.addElement(c);
                  notifyObservers(c);
              }
              
              public void removeCivilization(Civilization c)
              {
                  int index = civilizations.indexOf(c);
                  civilizations.removeElementAt(index);
                  notifyObservers(c);
              }
              
              public Enumeration getAllCivs()
              {
                  return civilizations.elements();
              }
              
              public void update(Observable o, Object arg)
              {
                  notifyObservers(arg);
              }
          }
          
          [/b]
          }

          Sample 'View' class that is tied to the above data:

          Code:
          [b]import java.awt.*;
          import java.util.*;
          
          public class CivilizationsView extends Panel implements Observer
          {    
              private GameData data;
              private java.awt.List civ_list;
              
              public CivilizationsView(GameData d)
              {
                  initData(d);
                  initView();
                  updateView();
              }
              
              private void initData(GameData d)
              {
                  data = d;
                  data.addObserver(this);
              }
              
              private void initView()
              {
                  civ_list = new java.awt.List(4);
                  add(civ_list, "Center");
              }
              
              private void updateView()
              {
                  Enumeration enum = data.getAllCivs();
                  
                  while(enum.hasMoreElements())
                  {
                      Civilization c = (Civilization)enum.nextElement();
                      
                      civ_list.addItem(c.getName());
                  }
              }
              
              public void update(Observable o, Object arg)
              {
                  updateView();
              }
          }
          [/b]
          And, for illustration, a beginning 'Civilization' data class:

          Code:
          [b]
          import java.util.*;
          
          public class Civilization extends Observable
          {
              private String name;
              
              public Civilization()
              {
                  
              }
              
              public Civilization(String n)
              {
                  setName(n);
              }
              
              public void setName(String n)
              {
                  name = n;
                  notifyObservers(name);
              }
          }
          [/b]
          Does this meet with everone's approval?

          The pattern is simple, I think. This way, all GUI components are built in exactly the same way. And all GUI components interact with the data thru a single object -- GameData. So we can change the data model around all we want, and not have to worry about re-working any of the 'View' code.

          Okay? Comments, suggestions, flames?

          Comment


          • #6
            Sounds good! Thanks for putting up the quickie example code. I think it will be quite some effort to put the existing code into this sort of framework, but there are very clear benfits also. I think I'll need to see the govt code further along before I can appreciate many of the nuances...

            Thanks for pushing forward on this!
            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


            • #7
              To put existing code into this framework is going to take a little time, but it's mostly going to be copy/pasting things. Very little actual code will have to be re-written, and the code that will be rewritten will shrink and become vastly simpler to understand and use/modify. I could do it in about a week or two, I think. But it might be good practice for other people to try, too, for some 'hands on' coding in an MVC architecture.

              And if the existing code is reworked, then future enhancement of the code -- and therefore making future releases -- will be much, much faster. You can begin to develop and deploy new versions with added/refined models in a matters of weeks or months -- not once a year.

              Because I hope that this one thing alone has already been proven with the 'object builder' I'm working on (if the darn website ever lets me upload the newest version again!!!) -- speed of development.

              I coded the entire data structure for the social model in about a weekend, then found errors in the model that could be changed to provide a faster and more powerful system. The code could be integrated into the main game in about a weekend.

              The entire game, using this methodology, can be ready by Christmas.

              I don't think that will happen using a 'Monolithic' approach to development.

              Comment


              • #8
                Playable maybe, in the sence that you can do most things, but i think xmas is a bit optimistic, especially with models like my character model which has no coding and really can't have any until most of the basics of all the other models are done.
                Which Love Hina Girl Are You?
                Mitsumi Otohime
                Oh dear! Are you even sure you answered the questions correctly?) Underneath your confused exterior, you hold fast to your certainties and seek to find the truth about the things you don't know. While you may not be brimming with confidence and energy, you are content with who you are and accepting of both your faults and the faults of others. But while those around you love you deep down, they may find your nonchalance somewhat infuriating. Try to put a bit more thought into what you are doing, and be more aware of your surroundings.

                Comment


                • #9
                  Lordy:

                  No, I'm certain Xmas is do-able. And that's assuming we don't get anymore help on coding.

                  Honestly, that's how fast the proper OO approach to development is. Which is why I'm so on ya'll to switch your methodology.

                  If you develop the model rules at the same time we develop the model's code, both the modelling and the coding go very fast and end up bug-free. Because all 'Data' objects get coded in exactly the same way -- so it's extremely fast to code them. All 'View' objects get coded in exactly the same way. Again, it's extremely fast to write them.

                  If I were doing this at work, and could spend all my time on it, I could do it myself in about 3 months.

                  P.S. -- speaking of which, the new version of the object editor is up, for anyone that wants to help move this project along to an Xmas completion!!!

                  Comment


                  • #10
                    Hmmm, not as much discussion here as I'd hoped for...

                    We're having extensive discussions in various threads about at what level various game information should be stored. I'm going to try to provide a very short, hopefully balanced, account of the general issues involved, so we can discuss these big issues without getting caught up in the specifics of any model. Also, for thinking about whether we should "decentralize" the economic system down into individual squares, I need to get some answers to some of these questions.

                    F. Smith has been pushing a good OOD approach for all the models. This includes using the model view controller (MVC) paradigm for handling code function, and also pushing data storage and handling down to the lowest conceivable level. He has talked a bunch more about these things in a lot of places, and some of it is even in this thread. He's invited to do so here again if he'd like , I'm sure you're up to it F_Smith! I need to add here that he is a professional programmer, which most of us are not. So he has a lot more experience with this stuff. It may be as F_Smith claims that I'm worrying about things that can be easily taken care of in the future. But still, I'd like to hear what others think.

                    My problem with the OOD approach above, is not at the philosophical level. If there were no issues of memory storage, clock cycles, Internet bandwidth, and other similar things, I agree that the things F. Smith is pushing have the ring of truth. I think they are also widely accepted in the OO programming community. Also, I have no problem with the MVC paradigm, it seems very reasonable, and would be very good for keeping us immature programmers out of trouble.

                    My problems with that approach is when the theory appears to collide with reality. The main problem is that we are pushing the limits in terms of model complication on virtually every front. We are also combining this with a fairly high-resolution map (64 K. squares standard). This combination of detailed models and a map with a lot of squares in it gives us great potential to have a game that is truly revolutionary. But it also gives us the chance to have a game that:
                    requires a 5 MB save file (for example)
                    takes much more than the targeted minimum rate of ten seconds per turn just to execute the game models
                    is almost impossible to play multiplayer because too much information needs to go down the pipe

                    I have raised all these issues before (there he goes again...). In some cases programming a model at the lowest level is not a problem. Since computers are so fast and have so much memory these days, it only comes up if there are a Lot of objects. In other cases, if it is found to be a problem, the code can easily be rewritten to an aggregate information at an appropriate level to fix things. But in some models (like the economy) it seems to me it would be difficult to go back. (Although careful planning might be able to prevent this)

                    F. Smith has raised some good points that makes some of my perceived issues less significant. For instance, sometimes things don't need to be calculated every turn, or change very modestly meaning we can estimate without much use of clocks, putting less stress on clock cycles and bandwidth. So that may offer an out in some cases. I'm still left with a few issues...

                    I think the file save size needs to be one MB or less. What do others think about that as a guideline? Even at 5MB files, if you save 200 of them (about the number of civ2 saves I have) that's 1GB... And I call Microsoft stuff Bloatware

                    For multiplayer you should be able to play the game with something like ten seconds turns on a 56 K. modem. Orders that the player or AI issue would not be the problem. The problem is updating information on a potentially large number of map squares. With 100squares (say during a war) needing updates of 100 Bytes each gives 80kb. So at max rate it'd take more than a second just to get the mapsquare change info across... Maybe not a problem, but civ2 plays pretty badly sometimes with Much Much less info going down the pipe.

                    So, your thoughts on these issues are solicited
                    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


                    • #11
                      Save files i'm not too concerned about...5 MB is kinda big, but 2MB is fine...

                      I'm just using that as referance since that's the size of a psx save file. With HDs getting bigger and cheaper at an alarming rate i dounbt this will be a big issue.
                      Which Love Hina Girl Are You?
                      Mitsumi Otohime
                      Oh dear! Are you even sure you answered the questions correctly?) Underneath your confused exterior, you hold fast to your certainties and seek to find the truth about the things you don't know. While you may not be brimming with confidence and energy, you are content with who you are and accepting of both your faults and the faults of others. But while those around you love you deep down, they may find your nonchalance somewhat infuriating. Try to put a bit more thought into what you are doing, and be more aware of your surroundings.

                      Comment


                      • #12
                        Thanks for the opinions LGJ. I may indeed be fussing about nothing, that's why I asked.
                        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


                        • #13
                          200 save files?

                          Seriously? Whoah. That has got to be some serious Civ playing time!

                          My 'StarCraft' save files regularly run half-a meg or more, and we've got *way* more info than that. The largest map in starcraft is, I believe, something like 250 by 250 tiles, with far less pop detail and almost no econ. Caesar 3 save files are from 200 - 300 k, and that's saving one province's worth of data (altho the econ is on the scale we're talking about). So 10 provinces of data would be 2 - 3 meg, and we're going to have more than 10 provinces, for sure. And then we'll have civ data, and more.

                          I personally think we don't worry about it. We just concentrate on doing it 'right'. I've got a 27 gig hard drive I've loaded down with so much industrial software it isn't funny and I've still got 16 gig free. Within 2 years almost everyone will have 30+ gig hard drives. So even a 20 or 30 meg save file isn't a problem, except for save/reload time issues.

                          For multiplayer, we don't move the game world around every turn, only the variables that have changed state. So that's not an issue.

                          Comment


                          • #14
                            So what do you do using MVC when you Don't want the view to change even when something changes? FE when an object is going to undergo potentially many state changes before the player can do anything, and you just want to present the final state. If you show them all the player will see a mishmash blur for a bit, which would be Really annoying...
                            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


                            • #15
                              Mark:

                              We control that thru the arguments passed to the observers.

                              That's all controlled by the 'controller' code (in this case, specific 'TurnHandlers' like 'MapSquareTurnHandler', 'EthnicGroupTurnHandler', and 'ProvinceTurnHandler'). These controller classes will hold the 'turn()' method for the relevant objects. So in that code we should labor to update each piece of data only once, as often as possible.

                              When that is impossible, we can have the 'view' observe the 'TurnHandler' also, and update the 'view' only when the 'TurnHandler' calls 'update' on the view classes -- and even then take specific action in the 'view' classes depending on what argument is passed to it in the 'update(Object observable, Object arg)' method.

                              Since when 'update' fires you know the object that fired it, and can pass another 'argument' object, we have a powerful amount of control. This argument can be a string with a meaning ("update view") that can be tested for, a boolean value, or whatever.

                              Comment

                              Working...
                              X