When?

World in Flames is the computer version of Australian Design Group classic board game. World In Flames is a highly detailed game covering the both Europe and Pacific Theaters of Operations during World War II. If you want grand strategy this game is for you.

Moderator: Shannon V. OKeets

Shannon V. OKeets
Posts: 22165
Joined: Wed May 18, 2005 11:51 pm
Location: Honolulu, Hawaii
Contact:

RE: When?

Post by Shannon V. OKeets »

ORIGINAL: bo

ORIGINAL: micheljq

ORIGINAL: Joseignacio

I think he made the dates public to have an extra push to meet them, since all the fans would know them.

And I think now he doesn't (by now) because the time to dedicate to the bugs is unpredictable.
Mich I have always respected yours and Joses opinions, always, but this bug thing annoys me to no end, if the code is written right in the first place why is there so many so called bugs, I trully dont get it. I have not posted because I will end up saying the wrong thing but I do read the posts every 2 weeks or so.

BO
I agree with that, but I mean there is unpredictable bugs happening in the development of all PC games anyway. So they never know when the product will be finished until it is. It is like that in all the industry, MWiF is not an exception. [:)]
"... the code is written right in the first place ..." made me chuckle.[:D]

You might examine the '2' sentences you wrote for spelling and grammar mistakes. And then think about writing 300,000 sentences where zero mistakes are permitted. Indeed, simply count to 300,000 while pondering the elusiveness of perfection in all things human.[;)]
Steve

Perfection is an elusive goal.
User avatar
TemKarl
Posts: 43
Joined: Tue Feb 21, 2006 2:10 am
Contact:

RE: When?

Post by TemKarl »

".. the code is written right in the first place ..."

Of course ... is there any other way??
User avatar
wworld7
Posts: 1726
Joined: Tue Feb 25, 2003 2:57 am
Location: The Nutmeg State

RE: When?

Post by wworld7 »

ORIGINAL: Shannon V. OKeets

And then think about writing 300,000 sentences where zero mistakes are permitted. Indeed, simply count to 300,000 while pondering the elusiveness of perfection in all things human.[;)]

Is this a job:

For Superman...no
For Batman.......no
For an Irishman........HELL YES!!!
Flipper
User avatar
BallyJ
Posts: 142
Joined: Sun May 25, 2008 1:04 pm

RE: When?

Post by BallyJ »

Just have to say:
1. Love this game. Played it long time!!
2. Love this forum. Read it every day!!!
Don't agree with every decision that has been made, but willing to live with itTry in vain to once again past a smiley???
ImageImage???????
Keep up the good work.[:)]
Finally got it right???
bo
Posts: 4175
Joined: Thu Apr 30, 2009 9:52 pm

RE: When?

Post by bo »

ORIGINAL: Shannon V. OKeets

ORIGINAL: bo

ORIGINAL: micheljq



Mich I have always respected yours and Joses opinions, always, but this bug thing annoys me to no end, if the code is written right in the first place why is there so many so called bugs, I trully dont get it. I have not posted because I will end up saying the wrong thing but I do read the posts every 2 weeks or so.

BO
I agree with that, but I mean there is unpredictable bugs happening in the development of all PC games anyway. So they never know when the product will be finished until it is. It is like that in all the industry, MWiF is not an exception. [:)]
"... the code is written right in the first place ..." made me chuckle.[:D]

You might examine the '2' sentences you wrote for spelling and grammar mistakes. And then think about writing 300,000 sentences where zero mistakes are permitted. Indeed, simply count to 300,000 while pondering the elusiveness of perfection in all things human.[;)]
Mistakes where, I dont understand about bugs, I am not a programmer, but if you are a trained programmer with a lot of experience at programming why isnt the code written right in the first place I am not being smart just inquisitive after reading some of the posts since last month, I mean wouldnt it save you a lot of trouble then having to go back over it time and time again which has delayed this endeavour for years not months, I know [meaning me] go back where you came from, how dare you challenge the powers that be.[:-] I hope you posters have other lives then just hanging around her for a couple more years of frustration[&:]


Bo
bo
Posts: 4175
Joined: Thu Apr 30, 2009 9:52 pm

RE: When?

Post by bo »

ORIGINAL: flipperwasirish

ORIGINAL: Shannon V. OKeets

And then think about writing 300,000 sentences where zero mistakes are permitted. Indeed, simply count to 300,000 while pondering the elusiveness of perfection in all things human.[;)]

Is this a job:

For Superman...no
For Batman.......no
For an Irishman........HELL YES!!!
Yeah if he can stay sober[:D]

Bo
User avatar
SamuraiProgrmmr
Posts: 416
Joined: Sun Oct 17, 2004 3:15 am
Location: NW Tennessee

RE: When?

Post by SamuraiProgrmmr »

ORIGINAL: Shannon V. OKeets

You might examine the '2' sentences you wrote for spelling and grammar mistakes. And then think about writing 300,000 sentences where zero mistakes are permitted. Indeed, simply count to 300,000 while pondering the elusiveness of perfection in all things human.[;)]

HEAR HEAR!!!!!!
Bridge is the best wargame going .. Where else can you find a tournament every weekend?
User avatar
SamuraiProgrmmr
Posts: 416
Joined: Sun Oct 17, 2004 3:15 am
Location: NW Tennessee

RE: When?

Post by SamuraiProgrmmr »

ORIGINAL: bo

Mistakes where, I dont understand about bugs, I am not a programmer, but if you are a trained programmer with a lot of experience at programming why isnt the code written right in the first place

Bo,

None of this is directed at you in a bad way. You asked a question in good faith and deserve an answer. The problem is that for the people who are capable of delivery of an answer backed by experience, this top is inflammatory.

I am not trying to be too sarcastic or mean. Please do not be offended. Part of this is intended to be humorous. This is, however, a subject near and dear to my heart.



Consider a program that takes two numbers as input and outputs the average of those two numbers.

Things that must be considered....(for code to be written right)

1) The mathematical relationship between the 3 numbers
2) The visual display of each number (how many decimal places, font size, negative values, etc.)
3) The data entry of the two numbers (how do you handle when someone puts a letter in when it should be a number, etc.)
4) When does the math get done (do you do it immediately when a number changes, do you give them a button to control the execution, etc.)
5) Are there special circumstances that will affect any of the decisions that you have already made? (Do we need to be able to cut and paste info from another program, do we need to link behind the scenes to another program, etc.)
6) Who will use the program and what is their level of expertise? (Is it for accountants or is it for 3rd graders to check their homework, etc.) How will that affect #2

I could go on... and admittedly this is a bit of overkill, but you would be surprised at how each of those items can be a failure point.

Now multiply the situation by Thousands of variables and Thousands of operations.
Now multiply the situation by Mulitple methods of display that are often graphical.

Very quickly the problem is large enough that it makes sense to modularize it.

Now the trick becomes to keep these millions (yes millions - do the math) of relationships in your mind so that when you change one thing, you make sure that everything else that it affects is changed if needed.

Trust me on this one... HOPE THE PHONE DOESN'T RING AT EXACTLY THE WRONG MOMENT.. you will 'drop' the cloud of quickie tasks floating in your head and likely not pick them all back up when you resume.

NOW

Consider the idea that many of these tasks are complicated. They are not simple averages of two numbers. They are events that must gather data from multiple locations and perform dozens of steps to be accomplished.

NOW consider this analogy....


When was the last time that you got lost driving somewhere you have never been before. Consider that - Really.

You had a map. You studied it ahead of time. You consulted Mapquest. You followed the path as good as you could, but you just couldn't find the spot.

Oh, you got there eventually - maybe even quickly ... but DID YOU DO IT CORRECTLY THE VERY FIRST TIME?

And then, what if when you did not drive directly to the destination, it had the potential to disrupt any other trips that you are about to take OR have taken previously.

Furthermore, if you suspect that a previously taken route may have been affected, now you have to retrace it EXACTLY and alter it if needed.

Meanwhile.... you are being paid based on how many trips you make.

Meanwhile... everyone believes they are the best navigator in the world and consider you a failure if you choose (for reasons they may have never considered) a path that they would not have chosen.

And it has to work even if the streets have potholes (bad drivers, hardware problems, etc.)

And it needs to work for cities where the speed limit is low (old machines)

And it needs to work well enough that at the end of the day, people feel that it *almost* made as good of choices as they would have (i.e. the AI needs to be a challenge but can be beat - otherwise everyone will accuse it of being stupid or cheating)


SUMMARY

Writing large computer programs is a very challenging task that involves keeping up with huge amounts of detail and tying ALL of the loose ends together in a nice package.

POST SCRIPT

Even though there are theorists and university types that will sing the praises of TOP DOWN STRUCTURED PROGRAMMING or OBJECT ORIENTED PROGRAMMING as if they are the second coming and will prevent any systemic and endemic problems from occurring...

Experience has shown that they are full of $#|T

This rant has not been directed at anyone in general.

I feel better.

Thanks for enduring it.

Bridge is the best wargame going .. Where else can you find a tournament every weekend?
Shannon V. OKeets
Posts: 22165
Joined: Wed May 18, 2005 11:51 pm
Location: Honolulu, Hawaii
Contact:

RE: When?

Post by Shannon V. OKeets »

ORIGINAL: bo

ORIGINAL: Shannon V. OKeets

ORIGINAL: bo



"... the code is written right in the first place ..." made me chuckle.[:D]

You might examine the '2' sentences you wrote for spelling and grammar mistakes. And then think about writing 300,000 sentences where zero mistakes are permitted. Indeed, simply count to 300,000 while pondering the elusiveness of perfection in all things human.[;)]
Mistakes where, I dont understand about bugs, I am not a programmer, but if you are a trained programmer with a lot of experience at programming why isnt the code written right in the first place I am not being smart just inquisitive after reading some of the posts since last month, I mean wouldnt it save you a lot of trouble then having to go back over it time and time again which has delayed this endeavour for years not months, I know [meaning me] go back where you came from, how dare you challenge the powers that be.[:-] I hope you posters have other lives then just hanging around her for a couple more years of frustration[&:]


Bo
Bo,

Here is an example of the world I work in every day. This is a little over 500 lines of code that determine the odds column for a land combat. It does not roll the die/dice, nor does it "look up" the result within the column once the die/dice is/are rolled. I have revised this code quite a lot over the past 2-3 months to maintain fractions during its calculations and leave the decision about whether to use rounded numbers or not to the calling/external routines. Notice all the reference to optional rules, in particular, the dual logic paths for 1D10 and 2D10. There are 12 parameters for this routine which have to be set prior to its execution, and the routine is called from 26 different places in the code. Just setting the parameters correctly for this one routine offers 312 opportunites for typos. Any changes to the routine requires examining the 26 places this routine is called, to make sure the changes for one of them does not cause problems for any of the others.

By the way, while most of the MWIF is written using "object oriented" code, this is a stand-alone routine and merely "grouped with" the object Land_Combat_Hex.
===

Code: Select all

 // ****************************************************************************
 function LandCombatColumn(
   const IsAssault: Boolean; // Set to False for testing overruns.
         A, D: Extended;     // A = Attack & D = Defend factors are input.
 	out DRMRounded: Integer;  // Returned die roll modifier for 2D10.
   out DRM: Extended;        // Same as DRMRounded, but not rounded.
   const ColMod: Extended;   // Shifts due to Fractional Odds and 1D10 HQ support.
   out TableCol: Byte;       // Returned value for 1D10: between 0 and 9.
   const Hex: TSmallPoint;   // Used to find TLandCombatHex.
         AUseSnowUnits, DUseSnowUnits: Boolean;
   const FractionBonus: Boolean;
   const ForceInvading: Boolean = False): Boolean;
 // ****************************************************************************
 // LandCombatColumn does not roll dice to determine the odds.  The aspects of
 // land combat resolution that require die rolls to determine odds are performed
 // prior to the call to LandCombatColumn.  These are for 1D10 HQ Support and
 // fractional odds.  These are the input parameters ColMod and FractionBonus.
 // ****************************************************************************
 var
 	CRatio: Extended;
   Inverse: Integer;
 	AnyInvading: Boolean;
 	Index: Longint;
   CR: TLandCombatHex;
 	Counter: Integer;
   WorkCol: Integer;
 	ColShifts: Integer;
   IsCombatHex: Boolean;
   LCTerrain: TTerrainTypes;
   LCWeather: TWeatherTypes;
   InCity: Boolean;
   AttackingStack: TUnitStack;
   DefendingStack: TUnitStack;
   AHasArmor: Boolean;
   CityDRM: Extended;
 
   procedure GetHQBonus;
   begin     // If there is HQ Support, it is automatic when using the 2D10 CRT.
     if OptRules.TwoD10LandCRT and IsCombatHex then
     begin   // HQ's provide half their Reorganization value as a modifier.
       if CR.HQA <> nil then DRM := DRM + (CR.HQA.Reorg / 2);
 
       if CR.HQD <> nil then DRM := DRM - (CR.HQD.Reorg / 2);
     end;
   end;
 
   procedure AddAttacker(var U: TUnit);
   begin
     if U.Side = Game.PhasingSide then AttackingStack.Add(U);
   end;
 
   procedure DoubleAntiTankUnits(var U: TUnit);
   begin     // Defending units only.
     if U.UnitType in AntiTankSet then D := D + TLandUnit(U).CurrDefenseArmor;
   end;
 
   procedure DoubleRedAntiTankUnits(var U: TUnit);
   begin     // Attacking units only.
     if (U.UnitType in AntiTankSet) and (TLandUnit(U).AntiTank = latAttDef) then
        A := A + TLandUnit(U).CurrAttackArmor;
   end;
 
   function AttackModifier(const U: TUnit): Integer;
   var      // Calculate the die roll modifier.
     AttackHex: TSmallPoint;
   begin
     AttackHex := AttackLocation(U);
 // ****************************************************************************
 // Set the attack modifier (divisor) from AttackHex through Hexside.  This
 // accounts for straits, all-sea hexsides, alpine hexsides, and forts
 // (cumulative).  A result of 0 means no attack is possible.  Invasions never
 // have any modifier (i.e., the divisor is 1).
 // ****************************************************************************
     if Map.Terrain[AttackHex.X, AttackHex.Y] = teSea then Result := 1
     else Result := TLandUnit(U).HexsideAttackModifier(AttackHex,
                    THexArea.ConnectingHexsideRange(AttackHex, Hex), True);
   end;
 
   procedure AttackingUnitsDRM(var U: TUnit);
 // ****************************************************************************
 // Only used by 2D10 CRT & BlitzBonus.  Modify DRM due to individual attacking
 // units.
 // ****************************************************************************
   var
     HS: THexsideRange;
     HSAM: Integer;
     AttackHex: TSmallPoint;
   begin
     AttackHex := AttackLocation(U); // Hex where attacker started.
 
    	if (U is TLandUnit) and
        (not TLandUnit(U).Invading) and
        (Map.Terrain[AttackHex.X, AttackHex.Y] <> teSea) then
     begin
       THexArea.ConnectingHexsideRange(AttackHex, Hex, HS); // This sets HS.
       HSAM := AttackModifier(U);
 
       if HSAM > 0 then
       begin
 // ****************************************************************************
 // Include jungle benefit for some elite marines and infantry.
 // ****************************************************************************
         if (LCTerrain = teJungle) and
            TLandUnit(U).Elite and
            ((U.Country = Japan.ID) or
             (U.Country = Australia.ID) or
             ((U.Country = UnitedStates.ID) and
              (U.UnitType in MarineSet))) then
           DRM := DRM + (1 / HSAM);     // Hexside may affect modifier.
 // ****************************************************************************
 // Include armor bonus for attacker.
 // ****************************************************************************
         if (not IsAssault) and
            (U.UnitType in ArmoredSet) and
            (not InCity) and
            (LCTerrain in [teClear, teDesert]) and  // I.e., not jungle.
            (LCWeather = wFine) and                 // Forts negate this bonus.
            (Map.HexsideTerrainSet[U.Column, U.Row, HS] * FortHexsideSet = []) then
         begin                          // Hexside may affect modifier.
           if OptRules.BlitzBonus then
           begin
 // ****************************************************************************
 // BlitzBonus: Add 1 to the die roll for each two attacking ARM, MECH, HQ-A
 // units conducting a blitz attack against a clear or desert (non-city) hex in
 // fine weather.
 // ****************************************************************************
             if U.Small then DRM := DRM + (0.25 / HSAM) // 1/4 for a division.
             else DRM := DRM + (0.5 / HSAM);            // 2 full corps = 1.
           end
           else
           begin    // 2D10 modifiers is twice that of BlitzBonus.
             if U.Small then DRM := DRM + (0.5 / HSAM)  // Half for a division.
             else DRM := DRM + (1 / HSAM);
           end;
         end;
 // ****************************************************************************
 // Include bonus for attacking with winterized units.
 // ****************************************************************************
         if AUseSnowUnits and TLandUnit(U).SnowUnit then
           DRM := DRM + (1 / HSAM);     // Hexside may affect modifier.
       end;
     end;
 // ****************************************************************************
 // Include bonus for paradrop.
 // ****************************************************************************
     if (U is TLandUnit) and TLandUnit(U).Paradropping then
     begin
       if U.Small then DRM := DRM + 0.5      // Half for a division.
       else DRM := DRM + 1;
     end;
   end;
 
   procedure DefendingUnitsDRM(var U: TUnit);
 // ****************************************************************************
 // Used by both 1D10 and 2D10 CRTs.  Modify DRM due to individual defending
 // units.
 // ****************************************************************************
   var
     LU: TLandUnit;
   begin
    	if U is TLandUnit then
     begin
       LU := TLandUnit(U);
 // ****************************************************************************
 // Increment die roll for disorganized units.
 // ****************************************************************************
       if U.Disrupted then
       begin
         if OptRules.TwoD10LandCRT then
         begin
           if LU.Small then DRM := DRM + 1    // Half for a division.
           else DRM := DRM + 2;
         end
         else DRM := DRM + 1;                 // 1D10 CRT.
       end;
 // ****************************************************************************
 // Benefit for winterized defenders (TwoD10LandCRT only).
 // ****************************************************************************
       if OptRules.TwoD10LandCRT or OptRules.BlitzBonus then
       begin
         if OptRules.TwoD10LandCRT and
            DUseSnowUnits and
            LU.SnowUnit then
           DRM := DRM - 2;
 // ****************************************************************************
 // Benefit for anti-tank defenders (TwoD10LandCRT only).
 // ****************************************************************************
         if OptRules.TwoD10LandCRT and
            AHasArmor and
            (U.UnitType in AntiTankSet) then
           DRM := DRM - 1;
 // ****************************************************************************
 // Benefit for armored defenders, regardless of CRT chosen.
 // ****************************************************************************
         if (U.UnitType in ArmoredSet) and
            (not InCity) and
            (LCTerrain in [teClear, teDesert]) and
            (LCWeather = wFine) then
         begin
           if OptRules.BlitzBonus then
           begin
 // ****************************************************************************
 // BlitzBonus: Subtract 1 from the die roll for each defending ARM, MECH, HQ-A
 // unit in a clear or desert (non-city) hex in fine weather.
 // ****************************************************************************
             if U.Small then DRM := DRM - 0.5      // Half for a division.
             else DRM := DRM - 1;
           end
           else
           begin    // OptRules.TwoD10LandCRT.
             if U.Small then DRM := DRM - 1        // Half for a division.
             else DRM := DRM - 2;
           end;
         end;
       end;
     end;
   end;
 
   procedure CheckEngineerD(var U: TUnit);
   var       // Hexside terrain may double this modifier.
     LU: TLandUnit;
   begin
     LU := TLandUnit(U);
 
     if LU.UnitType in EngineerSet then
       CityDRM := CityDRM - (LU.Combat * LU.DefenseTerrainModifier);
   end;
 
   procedure CheckEngineerA(var U: TUnit);
   var       // Hexside terrain may reduce this modifier.
     LU: TLandUnit;
   begin
     LU := TLandUnit(U);
 
     if LU.UnitType in EngineerSet then
       CityDRM := CityDRM + (LU.Combat / AttackModifier(U));
   end;
 
   procedure IsHQ(var U: TUnit);
   begin     // Hexside terrain may reduce this modifier.
     if U.UnitType in HeadquartersSet then
       CityDRM := CityDRM + (1 / AttackModifier(U));
   end;
 
 begin
 // ****************************************************************************
 // LandCombatColumn.
 // ****************************************************************************
   AttackingStack := TUnitStack.Create;
   DefendingStack := TUnitStack.Create;
 
   try
     LCTerrain := Map.Terrain[Hex.X, Hex.Y];     // Attacked hex terrain.
     LCWeather := Map.HexWeather[Hex.X, Hex.Y];  // Attacked hex weather.
     InCity := Map.City[Hex.X, Hex.Y] <> cyNone; // Whether a city is in the hex.
 // ****************************************************************************
 // Negate the use of snow units if the weather is wrong.
 // ****************************************************************************
     if AUseSnowUnits then AUseSnowUnits := LCWeather in SnowWeather;
 
     if DUseSnowUnits then DUseSnowUnits := LCWeather in SnowWeather;
 // ****************************************************************************
 // Round off attack and defense strength if not using Fractional Odds.
 // ****************************************************************************
     if not OptRules.FractionalOdds then
     begin
       A := Util.Round(A);
       D := Util.Round(D);
     end;
 // ****************************************************************************
 // See if the hex is already in the list of declared land combat hexes.  If so,
 // set the value of CR.  Both IsCombatHex and DRM are used by GetHQBonus.
 // ****************************************************************************
     IsCombatHex := LandCombatHexes.Search(Hex, Index, CR); // Sets CR.
     DRM := 0;                                 // Initialized to zero.
 // ****************************************************************************
 // Check for whether any units are attacking the hex.
 // ****************************************************************************
     if (A = 0) and                            // No attack strength.
        ((D > 0) or                            // Some defense strength, or
         ((Game.Phase <> pHQSupportD) and      // not in these 2 phases.
          (not Game.AdvanceSubphase))) then
     begin
       TableCol := 0;
       GetHQBonus;          // If zero attack strength only HQ Support applies .
       Result := False;
       Exit;
     end;
 // ****************************************************************************
 // Place attacking units in AttackingStack.  CR contains units previously
 // committed to the attack - they are not in MovingStack.
 // ****************************************************************************
     if IsCombatHex then CR.CombatHexUnits.ForEach(@AddAttacker);
 
     if (not (Game.Phase in [pHQSupportD, pHQSupportA, pShoreBombardmentD])) and
        ((Game.Phase <> pGroundSupport) or
         ((Game.AirSubPhase = aspFlyA) and
          MovingStack.HasLandUnit)) then
       AttackingStack.AddStack(MovingStack);
 // ****************************************************************************
 // Set flags based on the armor units attacking & defending, and units invading.
 // ****************************************************************************
     AHasArmor := AttackingStack.HasUnit(UFilterArmoredUnit);
     AnyInvading := ForceInvading or AttackingStack.HasUnit(UFilterInvading);
 // ****************************************************************************
 // Place defending land units in DefendingStack.  Filter removes notional units.
 // ****************************************************************************
     DefendingStack.AddStack(MapStacks[Hex.X, Hex.Y], UFilterLandUnitNotInvading);
 // ****************************************************************************
 // Place defensive ground support (artillery) units in DefendingStack.
 // ****************************************************************************
     if (Game.Phase = pGroundSupport) and
        (Game.AirSubPhase = aspFlyD) and
        MovingStack.HasLandUnit then
       DefendingStack.AddStack(MovingStack);
 // ****************************************************************************
 // Now calculate the Die Roll Modifier (DRM).
 // ****************************************************************************
 // Loss of attack effectiveness when multiple major powers are attacking.
 // ****************************************************************************
     if OptRules.AlliedCombatFriction then
       DRM := DRM - Pred(MajorCountryCount(AttackingStack.MajorPowersInStack));
 // ****************************************************************************
 // Invasion against a notional unit benefits the attacker.
 // ****************************************************************************
     if AnyInvading and
        ((not IsCombatHex) or
         (not CR.IgnoreNotional)) then
       DRM := DRM + 1;
 // ****************************************************************************
 // -2 for all attacking units being territorials and at least 1 defending unit
 // being a non-territoiral land unit.
 // ****************************************************************************
     if AttackingStack.HasAllUnit(UFilterTerritorialUnit) and
        DefendingStack.HasLandUnit and
        (DefendingStack.HasUnit(UFilterNotTerritorialUnitDefending)) then
     begin
       if OptRules.TwoD10LandCRT then DRM := DRM - 2
       else DRM := DRM - 1;     // 1D10.
     end;
 // ****************************************************************************
 // +2 for all defending units being territorials and at least 1 attacking unit
 // being a non-territoiral land unit.
 // ****************************************************************************
     if DefendingStack.HasAllUnit(UFilterTerritorialUnit) and
        AttackingStack.HasLandUnit and
        (AttackingStack.HasUnit(UFilterNotTerritorialUnitAttacking)) then
     begin
       if OptRules.TwoD10LandCRT then DRM := DRM + 2
       else DRM := DRM + 1;    // 1D10.
     end;
 // ****************************************************************************
 //
 // Final calculations for 2D10 CRT.
 //
 // ****************************************************************************
     if OptRules.TwoD10LandCRT then
     begin
       if D = 0 then DRM := AutoVictoryModifier // Automatic land combat victory.
       else
       begin
 // ****************************************************************************
 // Modify the die roll modifier due to individual units.
 // ****************************************************************************
         AttackingStack.ForEach(@AttackingUnitsDRM); // Includes armor shifts.
         DefendingStack.ForEach(@DefendingUnitsDRM); // Includes armor shifts.
         GetHQBonus;   // Include HQ support for both sides.
 // ****************************************************************************
 // Calculate the effect of a city on DRM.
 // ****************************************************************************
         if InCity then
         begin         // CityDRM can never be more than 0.
           CityDRM := -1;
           CityDRM := CityDRM - Map.FactoryList.PrintedFactory[Hex.X, Hex.Y];
           DefendingStack.ForEach(@CheckEngineerD); // Decrements CityDRM.
           AttackingStack.ForEach(@CheckEngineerA); // Increments CityDRM.
           AttackingStack.ForEach(@IsHQ);           // Increments CityDRM.
           DRM := DRM + MinExtended([0, CityDRM]);  // Never a positive effect.
         end;
 // ****************************************************************************
 // Jungle benefit.
 // ****************************************************************************
         if LCTerrain = teJungle then DRM := DRM - 4;
 // ****************************************************************************
 // Include the effect of weather on the die roll modifier.
 // ****************************************************************************
         DRM := DRM - (Map.HexWeatherCombatMod[Hex.X, Hex.Y] * 2);
         CRatio := A / D;        // Raw odds ratio.
         TableCol := 0;          // Default value.
 // ****************************************************************************
 // Determine the CRT column based on the raw odds ratio.
 // ****************************************************************************
         for Counter := 16 downto 0 do
         begin
           if CRatio >= OddsColumnFraction[Counter] then
           begin
             TableCol := Counter;
             Break;
           end;
         end;
 // ****************************************************************************
 // Take into consideration fractional odds.
 // ****************************************************************************
         if OptRules.FractionalOdds then
         begin       // ColMod was set using ComputeFractionalOdds.
           if CRatio >= 1 then DRM := DRM + ColMod + (CRatio * 2)
           else DRM := DRM + ColMod + 4 - ((1/CRatio) * 2);
         end
         else
         begin  // Without fractional odds, the given ColMod is applied directly.
           TableCol := Range(TableCol + Round(ColMod), 0, 16);
           DRM := DRM + OddsModifier[TableCol];
         end;
       end;
     end
     else
 // ****************************************************************************
 //
 // Final calculations for 1D10 CRT.
 //
 // ****************************************************************************
     begin
 // ****************************************************************************
 // Modify the die roll modifier due to individual units.
 // ****************************************************************************
       if OptRules.BlitzBonus then
       begin
         AttackingStack.ForEach(@AttackingUnitsDRM); // Armor benefit.
 // ****************************************************************************
 // Include penalty for attacking a city with 2 or 3 printed factories.
 // ****************************************************************************
         if Map.FactoryList.PrintedFactory[Hex.X, Hex.Y] > 1 then DRM := DRM - 1;
       end;
 
       DefendingStack.ForEach(@DefendingUnitsDRM);
 
       if D = 0 then TableCol := AutoVictoryColumn // Automatic combat victory.
       else
       begin
         CRatio := A / D;      // Raw odds ratio.
 // ****************************************************************************
 // ColMod includes 1D10 HQ support shifts.  The 1D10 CRT only has the attacking
 // snow bonus, and it's a two column shift.  FractionBonus is the fractional
 // odds shift that was passed as a parameter; it's value was calculated using
 // ComputeFractionalOdds.
 // ****************************************************************************
         ColShifts := Round(ColMod) +
                      (Ord(AUseSnowUnits) * 2) +
                      Ord(FractionBonus) -
                      Map.HexWeatherCombatMod[Hex.X, Hex.Y];
 
         WorkCol := 0;
 
         for Counter := 8 downto 0 do
         begin
           if IsAssault then
           begin     //	(0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 7.0, 10.0);
             if CRatio >= AssaultColumnRatios[Counter] then
             begin
               WorkCol := Counter;
               Break;
             end;
           end
           else      // Blitzkrieg table.
           begin     //	(0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0);
             if CRatio >= BlitzkriegColumnRatios[Counter] then
             begin
               WorkCol := Counter;
               Break;
             end;
           end;
         end;
 // ****************************************************************************
 //  Give an extra column shift for every odds ratio lower than 1:2.
 // ****************************************************************************
         if CRatio < 0.5 then
         begin                       // Ord(False) = 0; Ord(True) = -1.
           Inverse := Trunc(D / A) - Ord(Frac(D / A) > 0); // +1 if remainder > 0.
           ColShifts := ColShifts - Inverse;
         end;
 
         WorkCol := WorkCol + ColShifts;  // This may be negative.
 
         if WorkCol < 0 then
         begin     // Add to die roll modifier for shifts below 1:2.
           TableCol := 0;
           DRM := DRM - WorkCol;
         end       // WorkCol is > 0.
         else TableCol := Min([WorkCol, 8]);
       end;
     end;
 
     Result := True;
   finally
     AttackingStack.Clear;
     DefendingStack.Clear;
     AttackingStack.Free;
     DefendingStack.Free;
 
     if OptRules.TwoD10LandCRT then DRMRounded := Range(Util.Round(DRM), -21, 21)
     else DRMRounded := Util.Round(DRM);
   end;
 end;
 
Steve

Perfection is an elusive goal.
WIF_Killzone
Posts: 277
Joined: Thu Apr 30, 2009 8:51 pm

RE: When?

Post by WIF_Killzone »

Glad you feel better Samurai, well said. Writing code is a b!tch. I once wrote a parser-compiler for own custom programming language and it almost broke my brain. Don't think I have been the same since but it was bug free-NOT!
&nbsp;
Back to the topic at hand, do we have a resised albiet estimated date of release?
WIF_Killzone
Posts: 277
Joined: Thu Apr 30, 2009 8:51 pm

RE: When?

Post by WIF_Killzone »

Steve, there is a bug. Should there not be a statement such as:
&nbsp;
If attacking([username])="Shannon V. OKeets" add 6 to die-roll.
Shannon V. OKeets
Posts: 22165
Joined: Wed May 18, 2005 11:51 pm
Location: Honolulu, Hawaii
Contact:

RE: When?

Post by Shannon V. OKeets »

By way of comparison, here is the code for the same routine as I received it from CWIF. There were no comments!
===

Code: Select all

 function LandCombatColumn(const IsAssault: Boolean; A, D: Extended;
 	out DieRollMod: Integer; out DRM: Extended; const ColMod: Integer;
   out Column: Byte; const Hex: TSmallPoint;
   AUseSnowUnits, DUseSnowUnits: Boolean;
   const CheckFraction: Boolean; const ForceInvading: Boolean = False): Boolean;
 var
 	Res: Extended;
   TempRes: Integer;
 	AnyInvading: Boolean;
 	Index: Longint;
   CR: TLandCombatHex;
 	Counter: Integer;
 	ColAmt: Integer;
   IsCombatHex: Boolean;
   LCTerrain: TTerrainTypes;
   LCWeather: TWeatherTypes;
   InCity: Boolean;
   AttackingStack: TUnitStack;
   DefendingStack: TUnitStack;
   AHasArmor: Boolean;
   CityDRM: Extended;
 
   function AttackLocation(const U: TUnit): TSmallPoint;
   begin
     with U do
     begin
       if Column = MovingStackValue then
         Result := MovingStack.OldLocation
       else
         Result := Location;
     end;
   end;
 
   function AttackModifier(const U: TUnit): Integer;
   begin
     with TLandUnit(U) do
     begin
       if AttackLocation(U).X = SeaAreaValue then
         Result := 1
       else
         Result := HexsideAttackModifier(AttackLocation(U),
           THexArea.ConnectingHexsideRange(AttackLocation(U), Hex), True);
     end;
   end;
 
   procedure CheckAttacker(var U: TUnit);
   var
     HS: THexsideRange;
     HSAM: Integer;
   begin
   	with TLandUnit(U) do
     begin
 	  	if (U is TLandUnit) and not Invading and
           (AttackLocation(U).X <> SeaAreaValue) then
       begin
         THexArea.ConnectingHexsideRange(AttackLocation(U), Hex, HS);
         HSAM := AttackModifier(U);
         if HSAM <> 0 then
         begin
           if (LCTerrain = teJungle) and Elite and
             ((Country = Japan.ID) or (Country = Australia.ID) or
               ((Country = UnitedStates.ID) and (UnitType in MarineSet))) then
             DRM := DRM + (1 / HSAM);
           if not IsAssault and (UnitType in ArmoredSet) and not InCity and
             (LCTerrain in [teClear, teDesert]) and
             (LCWeather = wFine) and
             (Map.HexsideTerrainSet[Column, Row, HS] * FortHexsideSet = []) then
             DRM := DRM + (1 / HSAM);
           if AUseSnowUnits and SnowUnit then
             DRM := DRM + (1 / HSAM);
         end;
       end;
       if (U is TLandUnit) and Paradropping then
         DRM := DRM + 1;
     end;
   end;
 
   function CheckDefender(var U: TUnit): Boolean;
   begin
   	with Options, TLandUnit(U) do
     begin
 	  	if U is TLandUnit then
       begin
         Result := True;
         if Disrupted then
         begin
           if TwoD10LandCRT then
           begin
             if TLandUnit(U).Small then
               DRM := DRM + 1
             else
               DRM := DRM + 2;
           end
           else
             DRM := DRM + 1;
         end;
         if TwoD10LandCRT then
         begin
           if DUseSnowUnits and SnowUnit then
             DRM := DRM - 2;
           if (UnitType in ArmoredSet) and not InCity and
               (LCTerrain in [teClear, teDesert]) and
               (LCWeather = wFine) then
             DRM := DRM - Succ(Ord(not Small));
           if AHasArmor and (UnitType in AntiTankSet) then
             DRM := DRM - 1;
         end;
       end
       else
         Result := False;
     end;
   end;
 
   procedure IsHQ(var U: TUnit);
   begin
     if U.UnitType in HeadquartersSet then
       CityDRM := MaxExtended([CityDRM, 1 / AttackModifier(U)]);
   end;
 
   procedure AddAttacker(var U: TUnit);
   begin
     if U.Side = PhasingSide then
       AttackingStack.Add(U);
   end;
 
   procedure CheckEngineerA(var U: TUnit);
   begin
     with TLandUnit(U) do
     begin
       if UnitType in EngineerSet then
         CityDRM := CityDRM + (Combat / AttackModifier(U));
     end;
   end;
 
   procedure CheckEngineerD(var U: TUnit);
   begin
     with TLandUnit(U) do
     begin
       if UnitType in EngineerSet then
         CityDRM := CityDRM - Combat;
     end;
   end;
 
   procedure GetHQBonus;
   begin
     if Options.TwoD10LandCRT and IsCombatHex then
     begin
       with CR do
       begin
         if HQA <> nil then
           DRM := DRM + (HQA.Reorg / 2);
         if HQD <> nil then
           DRM := DRM - (HQD.Reorg / 2);
       end;
     end;
   end;
 
 begin
   AttackingStack := TUnitStack.Create;
   DefendingStack := TUnitStack.Create;
   try
     with Map, Hex do
     begin
       LCTerrain := Terrain[X, Y];
       LCWeather := HexWeather[X, Y];
       InCity := City[X, Y] <> cyNone;
     end;
     if AUseSnowUnits then
       AUseSnowUnits := LCWeather in SnowWeather;
     if DUseSnowUnits then
       DUseSnowUnits := LCWeather in SnowWeather;
     if not Options.FractionalOdds then
     begin
       A := Util.Round(A);
       D := Util.Round(D);
     end;
     DRM := 0;
     IsCombatHex := LandCombatHexes.Search(Hex, Index, CR);
     if (A = 0) and (not (Phase in [pHQSupportD, pAdvanceAfterCombat]) or
       (D > 0)) then
     begin
       Column := 0;
       GetHQBonus;
       Result := False;
       Exit;
     end;
     if IsCombatHex then
       CR.Units.ForEach(@AddAttacker);
     if not (Phase in HQSupportPhases + [pShoreBombardmentD]) and
       ((Phase <> pGroundSupport) or
         ((SubPhase = spFlyA) and MovingStack.HasLandUnit)) then
       AttackingStack.AddStack(MovingStack);
     AHasArmor := AttackingStack.HasUnit(UFilterArmoredUnit);
     with Hex do
       DefendingStack.AddStack(UnitStacks[X, Y], UFilterLandUnitNotInvading);
     AnyInvading := ForceInvading or AttackingStack.HasUnit(UFilterInvading);
     if (Phase = pGroundSupport) and (SubPhase = spFlyD) and
       MovingStack.HasLandUnit then
       DefendingStack.AddStack(MovingStack);
     if Options.AlliedCombatFriction then
       DRM := DRM - Pred(MajorCountryCount(AttackingStack.MajorCountrySet));
     if AnyInvading then
     begin
       if not IsCombatHex or not CR.IgnoreNotional then
         DRM := DRM + 1;
     end;
     with Options do
     begin
       if AttackingStack.HasAllUnit(UFilterTerritorialUnit) then
         DRM := DRM - Succ(Ord(TwoD10LandCRT));
       if DefendingStack.HasLandUnit and
         not DefendingStack.HasUnit(UFilterNotTerritorialUnitDefending) then
         DRM := DRM + Succ(Ord(TwoD10LandCRT));
     end;
     if Options.TwoD10LandCRT then
     begin
       if D = 0 then
         DRM := AutoVictoryModifier
       else begin
         with CR do
         begin
           AttackingStack.ForEach(@CheckAttacker);
           DefendingStack.ForEach(@CheckDefender);
           GetHQBonus;
           if InCity then
           begin
             CityDRM := 0;
             AttackingStack.ForEach(@IsHQ);
             AttackingStack.ForEach(@CheckEngineerA);
             DefendingStack.ForEach(@CheckEngineerD);
           end;
         end;
         if LCTerrain = teJungle then
           DRM := DRM - 4;
         if InCity then
         begin
           CityDRM := CityDRM - 1;
           with Map, Hex do
             CityDRM := CityDRM - FactoryCount[X, Y];
           DRM := DRM + MinExtended([0, CityDRM]);
         end;
         with Hex do
           DRM := DRM - (Map.HexWeatherCombatMod[X, Y] * 2);
         Res := A / D;
         for Counter := 16 downto 0 do
         begin
           if Res >= OddsColumnFraction[Counter] then
           begin
             Column := Counter;
             Break;
           end;
         end;
         if Options.FractionalOdds then
         begin
           if Res >= 1 then
             DRM := DRM + Trunc((Res * 2) + ColMod)
           else
             DRM := DRM + Trunc(4 - (1/Res * 2) + ColMod);
         end
         else begin
           Column := Range(Column + ColMod, 0, 16);
           DRM := DRM + OddsModifier[Column];
         end;
       end;
     end
     else begin
       DefendingStack.ForEach(@CheckDefender);
       if D = 0 then
         Column := AutoVictoryColumn
       else begin
         Res := A / D;
         with Hex, Map do
         begin
           ColAmt := ColMod - HexWeatherCombatMod[X, Y] +
             (Ord(AUseSnowUnits) * 2) + Ord(CheckFraction);
           for Counter := 1 to Abs(ColAmt) do
           begin
             if Res >= 2 then
             begin
               if ColAmt > 0 then
                 A := A + D
               else if Res < 3 then
                 A := A - (D / 2)
               else
                 A := A - D;
             end
             else if (Res >= 1) and (Res < 2) then
             begin
               if ColAmt > 0 then
                 A := A + (D / 2)
               else
                 A := A - (D / 2);
             end
             else begin
               if A < D then
                 DRM := DRM - 1
               else
                 A := D;
             end;
             Res := A / D;
           end;
         end;
         if IsAssault and (Res >= 5) then
         begin
           if Res >= 10 then
             TempRes := Trunc(Res) - 2
           else if Res >= 7 then
             TempRes := 7
           else
             TempRes := 6;
         end
         else if Res >= 2 then
           TempRes := Succ(Trunc(Res))
         else if Res >= 1.5 then
           TempRes := 2
         else if Res >= 1 then
           TempRes := 1
         else if Res >= 0.5 then
           TempRes := 0
         else begin
           Column := 0;
           DRM := DRM - Trunc(D / A) + Ord(Frac(D /A) > 0) - 2;
           Result := True;
           Exit;
         end;
         Column := Min([8, TempRes]);
       end;
     end;
     Result := True;
   finally
     AttackingStack.Free;
     DefendingStack.Free;
     if Options.TwoD10LandCRT then
       DieRollMod := Range(Util.Round(DRM), -21, 21)
     else
       DieRollMod := Util.Round(DRM);
   end;
 end;
 
Steve

Perfection is an elusive goal.
Shannon V. OKeets
Posts: 22165
Joined: Wed May 18, 2005 11:51 pm
Location: Honolulu, Hawaii
Contact:

RE: When?

Post by Shannon V. OKeets »

ORIGINAL: WIF_Killzone

Steve, there is a bug. Should there not be a statement such as:

If attacking([username])="Shannon V. OKeets" add 6 to die-roll.
Too crude.[:-] There is a weighted probability of how much to add.[;)]
Steve

Perfection is an elusive goal.
bo
Posts: 4175
Joined: Thu Apr 30, 2009 9:52 pm

RE: When?

Post by bo »

I knew I should not have come back, Steve I am not upset with you how could I be you are the most open programmer I have ever seen on the forums anywhere, but why should you get a free pass you took on this job not me, my complaint is that you should have got more help and if this coding for this game is so difficult then you should have gone to Matrix and got the best programmers around to assist you, I dont care about contracts with you and Matrix thats your problem not mine, not being mean Steve but these people on this forum [not me] are the most patient, kind and considerate group you will find anywhere in cyber land and they dont deserve this 5 or 6 year wait, I stopped posting when I asked you not to give completion dates but you went ahead anyway with dates that could not be met and you knew it, and if the people here can find anything I am saying is incorrect fine go to it, I truly hope for the sake of everyone here you will be able to complete this game bugs and all sometime next year but I have my doubts and I refuse to stick my head in the sand waiting for this to happen.

Bo
WIF_Killzone
Posts: 277
Joined: Thu Apr 30, 2009 8:51 pm

RE: When?

Post by WIF_Killzone »

Easy does it Bo, you may have an ammunition&nbsp;explosion.&nbsp;
&nbsp;
Seriously, it maybe a matter of scope (i.e., additional forms, and other added functionality (e.g., training videos) that were not in the original estimates, not to mention&nbsp;a superlative&nbsp;development approach) that is adding to the time.&nbsp;&nbsp;The contract you mention is giving increased flexibity (for lack of a better word)&nbsp;to the end product, and perhaps this is welcomed by some if not most.
&nbsp;
A different approach would certainly speed up the development albeit at the expensive of scope and quality, and&nbsp;most-likely budget although that is being managed with contract approach (which AGAIN, is why there is so much scope-quality).
&nbsp;
However, with that said, perhaps as you mention, it is time to put a lid on "extras", and wrap up the product with the use of additional resources although at this point it may not be feasible vis-a-vis the learning curve?
&nbsp;
I am sure this will be the product of the decade, if not the century, and most certainly for its genre.&nbsp;It may be worth your wait but I too feel your frustration of not yet getting to play :(
&nbsp;
&nbsp;
User avatar
wworld7
Posts: 1726
Joined: Tue Feb 25, 2003 2:57 am
Location: The Nutmeg State

RE: When?

Post by wworld7 »

ORIGINAL: bo

I knew I should not have come back, Steve I am not upset with you how could I be you are the most open programmer I have ever seen on the forums anywhere, but why should you get a free pass you took on this job not me, my complaint is that you should have got more help and if this coding for this game is so difficult then you should have gone to Matrix and got the best programmers around to assist you, I dont care about contracts with you and Matrix thats your problem not mine, not being mean Steve but these people on this forum [not me] are the most patient, kind and considerate group you will find anywhere in cyber land and they dont deserve this 5 or 6 year wait, I stopped posting when I asked you not to give completion dates but you went ahead anyway with dates that could not be met and you knew it, and if the people here can find anything I am saying is incorrect fine go to it, I truly hope for the sake of everyone here you will be able to complete this game bugs and all sometime next year but I have my doubts and I refuse to stick my head in the sand waiting for this to happen.

Bo

There are no other viable options other then to wait until it is completed. Not to be mean, but your posts which are from someone who admits a lack of understanding of programming actually are humerous to people who understand the difficulties.

I know you want it completed faster than it is being done, but that opinion/desire is not the reality the project is in.

Yes, you have a right to WHINE, but please don't mistake that for being a positive benefit to the project when you do.


Flipper
winky51
Posts: 164
Joined: Tue Jan 18, 2005 3:19 am

RE: When?

Post by winky51 »

There are a lot of processes that go on in our brain we take for granted when interpreted to programming.

There is only 1 being who can write perfect code the 1st time around and he is an android on Star Trek, fictional.

You can only write code as best you can, then comes debugging. My small programs from 20 years ago probably took me at least 100 times for me to go back in the program and debug it. I am still testing my AI for SC2 and I have fixed close to 200 errors alone.

A game of this magnitude? Im surprised the programmer has had his head explode. Frankly Im surprised there is only 1 programmer for this complex game.
Skanvak
Posts: 572
Joined: Sun Apr 03, 2005 4:57 pm

RE: When?

Post by Skanvak »

Though Bo should learn how to write (no point and lack other things I don't know how to say in english made his text unreadable), I think he has a point, as winky51 told it : Matrix should have put a team on this game. I know, being a team manager in an other field, that when you want to speed up a process, putting more people always work in the long run.

Telling me that for budget reason they cannot put more people on this project is just a rationalization to accept things we have no control on. This is their choice, we can challenge it. Chris have been on the project for several years alone and didn't complete it, it was easy to forseen that someone alone won't complete it faster especially when it has to be bring up to Matrix standard.

Btw I did programm a game from scratch when I was at high school, so I agree with the difficulty encounter which are two different things in my opinion. As we knows there will be a lot of bugs, it is wise to put more people on the projet (unless we are happy to have it completed in 10 years, again their choice, we can disagree with it).

Best regards

Skanvak
WIF_Killzone
Posts: 277
Joined: Thu Apr 30, 2009 8:51 pm

RE: When?

Post by WIF_Killzone »

I took a moment to fictionalize how the project could have been managed, and usually is, at least in the business world of computing, as opposed to the game development world--which I admit I don't know much of.
&nbsp;
Lets say the game was developed with a more traditional approach, with a team of consultants (or Matrix employees) hired, the project structure may look something like this:
&nbsp;
Project&nbsp;Manager (reporting to Matrix)
Project Leads (reporting to the PM)
Business Analysts
Technical Analysts
Architecture (security, application, database, network)
Programmers and Programmer Analysts (5-10)
Graphic Artists
Research
Test Lead, Testers
Marketing and Communications
Controller
Coffee&nbsp;Girl (I wish)
&nbsp;
So now you have a staff of say 20 people&nbsp;being paid everyday (although some are contracted-in when the time is appropriate (i.e. testers). Regardless, there is&nbsp;a certain monthly burn rate in cash for the project.
&nbsp;
The first thing the PM would do is determine from Matrix where their priorities lay. Matrix would have most likely already set&nbsp;a budget&nbsp;after&nbsp;performing a&nbsp;feasibility study&nbsp;and determined the ROI (return on investment) which said we can afford XYZ dollars to make this viable.&nbsp;Perhaps the PM first needs to perform that with the business analysts in order to determine if they should even start the undertaking. Either way, they come out with a fixed dollar amount with some contingency that the PM can play with to deliver the project.
&nbsp;
Now, the PM's first conversation with Matrix is focused on the project priorities in Scope(Quality and Breadth of product), Budget, and Schedule in order for him/her to manage the project and make the ongoing decisions without having to run&nbsp;to Matrix for approval on every decision. How do you&nbsp;think the conversation would go? Most likely is would be; budget (high priority), you need to deliver the project on budget or we don't make any money. Schedule, you need to deliver this in a reasonable timeframe and you can sacrifice some scope-quality in order to meet the schedule. Let me be clear Mr. PM,&nbsp;sacrifice scope in order to deliver on schedule&nbsp;and on budget--we don't need bells and whistles (as they cost) but we do need a quality product.&nbsp;So off he goes, he has his marching orders and he tackles the project.
&nbsp;
He starts a forum so he can get input from the knowledgeable user community. And he starts to notice that maybe he has underestimated this project. It looks like a bigger project than he first realized. The user community is&nbsp;passionate and a little demanding (not that he cares really), but&nbsp;they have tons of good advice for&nbsp;him.&nbsp;I will utilize them he thinks, like free resources-money for the project. Cool. In fact, I am going to&nbsp;appoint my star business analyst-programmer&nbsp;to moderate the forum as he is&nbsp;very passionate as well--he wants to deliver the best product he can.
&nbsp;
Time goes on, and he starts directing the projects activities, reporting monthly to Matrix, and everything goes along fine but he start to notice that his star is running everything by the user community and&nbsp;its starting to impact the project negatively. He sits his star down and has the following conversation:
&nbsp;
I need you to stop asking for so much input, its holding up the project and your adding modules and functionality we just can't afford. His star argues back, we need this, we need that, their are colour blind people and they need to be able to read the maps and counters(like me). Are you saying we have to re-do all the counters and maps for the colour blind? Yes. Do you know how much that will cost, NO, it's already programmed, sorry. His star storms away and notifies the user community. They rebel (as this is just one example in many design decisions that were denied in order to deliver on-time and on-budget).&nbsp;The PM determines this a project risk and decides to limit communications with the user community and just build it to the best of their ability within the current budget and time constraints. The user community from then on is shown only marketing hype,&nbsp;some glitz and glamour and&nbsp;a whole bunch of good news stories and they are happy again, waiting for their new game--how exciting.
&nbsp;
The project gets delivered, the PM is payed, gets a nice bonus for delivering on time and within budget and goes to Jamaica with the Coffee Girl.
&nbsp;
Wonder how the game would turn out?[X(]
&nbsp;
I'm not going to get on my soap-box and&nbsp;discuss&nbsp;how Matrix's and&nbsp;Steves approach is better, suffice to say in my humble opinion I like what I see. As a PM myself&nbsp;you seldom, if ever, get&nbsp;a chance to do what they are doing. Matrix I would theorize (oh-oh the soap box) doesn't care how long it takes (they will still be in business), the money isnt coming out of their pocket. Moreover, you can seldom&nbsp;hire&nbsp;people to perform peace work (i.e. not get paid) to speed up the project--most people are risk adverse or need money&nbsp;to support themselves on an ongoing basis.&nbsp;If they did hire ($$) extra people&nbsp;design decisions would be&nbsp;made that&nbsp;would result&nbsp;in a lessor product being delivered--guaranteed, full stop!
&nbsp;
Keep up the fantastic work Steve. Btw, maybe you can get someone else to moderate the forum so you can concentrate on the programming (could'nt resist--I'm evil) Seriously--keep up the good work.
&nbsp;
Craig
User avatar
wworld7
Posts: 1726
Joined: Tue Feb 25, 2003 2:57 am
Location: The Nutmeg State

Very Good

Post by wworld7 »

WIF_Killzone...well done.

I believe this was an excellent explaination of the realities/difficulties of a software design company. Your example in the beginning fits large well funded companies, but more common in the game world is the little shop that does it all with a smaller fraction of resources and people. As often, that is all many projects can support with resources that are available.

Most people understand the financial payoff for a popular game does not have the possible payoff at the end that say a popular business application may have.

Perhaps moving Steve to a hut in the Artic would speed completion? More likely his quartet would freeze-to-death singing to a group of local polar bears...[:)][:)][:)]









Flipper
Post Reply

Return to “World in Flames”