View unanswered posts | View active topics It is currently 20 Apr 2025, 20:22



Reply to topic  [ 86 posts ]  Go to page 1, 2, 3  Next
 The game I am working on 
Author Message
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
I know, theres a few people here working on BOTF remakes/sequels, and they are all great and look splendid.

What I am doing however is a bit outside the BOTF box, although i do draw some of the games inspiration from BOTF and other games(MoO2, Stars!, Pax Impera, Galactic Conquest, even Civ2 *gasp* lol)

Some of the main features of the game so that you might understand why this isn't simply just a BOTF2 type project

TBS(turn based strategy) possibly RTS elements like in Pax Impera
Will have a massive galaxy size(in BOTF terms this would be around 150x150 sector map, with sectors being more than just a square, more on this below)

Fully customizable(races, ships, modules*, techs, UI, etc) - everything except for game mechanics lol.

*Modules -> Think Mo2, Stars!, Pax Impera. All ships will be designed by modules, you make the ships the way you need them, when you need them.

Research will NOT be linear progression. You will multiple types of research in various areas. Theoretical research where you research an Idea. Developmental research where you turn that idea into a design you can use. and Prototype research, you take that design and actually build it, make sure it works right, etc. This feels more natural, and obviously research times are going to be dcided by trial and error, making the initial game as balanced as possible.

Ship speeds will be determined by a multitude of factors, like how far you are travelling, what TYPE of engines you are using(eg Warp, Hyperdrive, Interdimensional, etc) possible obstacles, depending on engines again.

Different techs for different races. Not every race will think the same, why should they follow the same types of research trees. an Aquatic race is going to think in a way that might make space travel and planetary construction similar. A race that lives underground might see construction and astronomy very similar, etc.

Which brings me to my next part - Races.
Races will be fully customizable(along the same lines as Pax, Stars!, MoO2). Yes, you could make the UFP, or even decide to make the shadows from B5 and play them against each other. The only limit will be your imagination(and the code ... cause lord knows i cant do EVERYTHING). Diplomacy will be fully interactive, allowing for a wide range of treaties and various other agendas, including things like determining a neutral zone, have a military only alliance, having a research alliance, creating a full alliance(with multiple races and full/partial co-op).

I will write more later on ... this was quite a bit of typing and im tired of all the typing i've done today lol.


07 May 2007, 05:45
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
Here's the class I use for storing empire-specific map data that I told you about. I had mistakenly said that I use an array of type UInt32 (uint), but it's actually an array of type UInt16 (ushort). That makes it considerably more space efficient. For clarification, I display fog of war on any sector that has not been scanned (meaning scanned at least once by a ship passing within range of the sector). Planets and the star name are not visible unless a sector has been explored. As you can probably infer from the code, MapLocation is a struct containing only properties for X and Y coordinates. Publicly, the coordinates are exposed as UInt32 values (for simplicity's sake), but internally they are stored as Bytes to save space. This effectively limits the map size to 256x256 sectors, which is more than I ever plan to support. Lastly, the term 'Fuel Range' as used in the code actually represents a sector's distance from the nearest supply post (or, effectively, the minimum range required for any ship to travel to that sector without tapping into its fuel reserves). I should probably change that naming convention for clarity's sake.

The code:
Code:
using System;

using Supremacy.Universe;

namespace Supremacy.Game
{
    /// <summary>
    /// Contains the map visibility data for a civilization in the game.
    /// </summary>
    [Serializable]
    public sealed class CivilizationMapData
    {
        /// <summary>
        /// The maximum scan strength value per sector.
        /// </summary>
        private const byte MaxScanStrength = 63;

        /// <summary>
        /// The maximum fuel range value per sector.
        /// </summary>
        private const byte MaxFuelRange = 255;

        /// <summary>
        /// The 'Scanned' value mask;
        /// </summary>
        private const ushort ScannedMask = 0x8000;

        /// <summary>
        /// The 'Explored' value mask;
        /// </summary>
        private const ushort ExploredMask = 0x4000;

        /// <summary>
        /// The 'Scan Strength' value mask;
        /// </summary>
        private const ushort ScanStrengthMask = 0x3F00;

        /// <summary>
        /// The 'Fuel Range' value mask;
        /// </summary>
        private const ushort FuelRangeMask = 0x00FF;

        /// <summary>
        /// The 'Scan Strength' value offset;
        /// </summary>
        private const byte ScanStrengthOffset = 8;

        /// <summary>
        /// The 'Fuel Range' value offset;
        /// </summary>
        private const byte FuelRangeOffset = 0;

        private ushort[,] _mapData;

        /// <summary>
        /// Initializes a new instance of the <see cref="CivilizationMapData"/> class.
        /// </summary>
        /// <param name="gameMap">The game map.</param>
        public CivilizationMapData(SectorMap gameMap)
        {
            if (gameMap == null)
                throw new ArgumentNullException("gameMap");
            _mapData = new ushort[gameMap.Width, gameMap.Height];
        }

        /// <summary>
        /// Determines whether the specified location is explored.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <returns>
        /// <c>true</c> if the specified location is explored; otherwise, <c>false</c>.
        /// </returns>
        public bool IsExplored(MapLocation location)
        {
            return ((_mapData[location.X, location.Y] & ExploredMask) == ExploredMask);
        }

        /// <summary>
        /// Determines whether the specified location has been scanned.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <returns>
        /// <c>true</c> if the specified location has been scanned; otherwise, <c>false</c>.
        /// </returns>
        public bool IsScanned(MapLocation location)
        {
            return ((_mapData[location.X, location.Y] & ScannedMask) == ScannedMask);
        }

        /// <summary>
        /// Gets the scan strength at the specified location.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <returns>The scan strength.</returns>
        public int GetScanStrength(MapLocation location)
        {
            return ((_mapData[location.X, location.Y] & ScanStrengthMask) >> ScanStrengthOffset);
        }

        /// <summary>
        /// Gets the fuel range at the specified location.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <returns>The fuel range.</returns>
        public int GetFuelRange(MapLocation location)
        {
            return ((_mapData[location.X, location.Y] & FuelRangeMask) >> FuelRangeOffset);
        }

        /// <summary>
        /// Determines whether the specified sector is explored.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <returns>
        /// <c>true</c> if the specified sector is explored; otherwise, <c>false</c>.
        /// </returns>
        public bool IsExplored(Sector sector)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            return IsExplored(sector.Location);
        }

        /// <summary>
        /// Determines whether the specified sector has been scanned.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <returns>
        /// <c>true</c> if the specified sector has been scanned; otherwise, <c>false</c>.
        /// </returns>
        public bool IsScanned(Sector sector)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            return IsScanned(sector.Location);
        }

        /// <summary>
        /// Gets the scan strength at the specified location.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <returns>The scan strength.</returns>
        public int GetScanStrength(Sector sector)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            return GetScanStrength(sector.Location);
        }

        /// <summary>
        /// Gets the fuel range at the specified location.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <returns>The fuel range.</returns>
        public int GetFuelRange(Sector sector)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            return GetFuelRange(sector.Location);
        }

        /// <summary>
        /// Sets whether the specified location has been explored.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">Whether the specified location has been explored.</param>
        public void SetExplored(MapLocation location, bool value)
        {
            if (value)
            {
                SetScanned(location, true);
                _mapData[location.X, location.Y] |= ExploredMask;
            }
            else
            {
                _mapData[location.X, location.Y] =
                    (ushort)(_mapData[location.X, location.Y] & ~ExploredMask);
            }
        }

        /// <summary>
        /// Sets whether the specified location has been scanned.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">Whether the specified location has been scanned.</param>
        public void SetScanned(MapLocation location, bool value)
        {
            if (value)
            {
                _mapData[location.X, location.Y] |= ScannedMask;
            }
            else
            {
                _mapData[location.X, location.Y] =
                    (ushort)(_mapData[location.X, location.Y] & ~ScannedMask);
            }
        }

        /// <summary>
        /// Sets the scan strength at the specified location.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The scan strength.</param>
        public void SetScanStrength(MapLocation location, int value)
        {
            ushort newValue = (ushort)Math.Min(value, MaxScanStrength);
            ushort newData = (ushort)(_mapData[location.X, location.Y] & ~ScanStrengthMask);
            newData |= (ushort)(newValue << ScanStrengthOffset);
            _mapData[location.X, location.Y] = newData;
        }

        /// <summary>
        /// Sets the fuel range at the specified location.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The fuel range.</param>
        public void SetFuelRange(MapLocation location, int value)
        {
            ushort newValue = (ushort)Math.Min(value, MaxFuelRange);
            ushort newData = (ushort)(_mapData[location.X, location.Y] & ~FuelRangeMask);
            newData |= (ushort)(newValue << FuelRangeOffset);
            _mapData[location.X, location.Y] = newData;
        }

        /// <summary>
        /// Sets whether the specified sector has been explored.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="value">Whether the specified sector has been explored.</param>
        public void SetExplored(Sector sector, bool value)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            SetExplored(sector.Location, value);
        }

        /// <summary>
        /// Sets whether the specified sector has been scanned.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="value">Whether the specified sector has been scanned.</param>
        public void SetScanned(Sector sector, bool value)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            SetScanned(sector.Location, value);
        }

        /// <summary>
        /// Sets the scan strength at the specified sector.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="value">The scan strength.</param>
        public void SetScanStrength(Sector sector, int value)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            SetScanStrength(sector.Location, value);
        }

        /// <summary>
        /// Sets the fuel range at the specified sector.
        /// </summary>
        /// <param name="sector">The sector.</param>
        /// <param name="value">The fuel range.</param>
        public void SetFuelRange(Sector sector, int value)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            SetFuelRange(sector.Location, value);
        }

        /// <summary>
        /// Resets the scan strength and fuel range for all sectors.
        /// </summary>
        public void ResetScanStrengthAndFuelRange()
        {
            for (int x = 0; x < _mapData.GetLength(0); x++)
            {
                for (int y = 0; y < _mapData.GetLength(1); y++)
                {
                    SetScanStrength(new MapLocation(x, y), 0);
                    SetFuelRange(new MapLocation(x, y), MaxFuelRange);
                }
            }
        }

        /// <summary>
        /// Sets whether the sectors within a specified radius of a given location
        /// have been explored.
        /// </summary>
        /// <param name="location">The origin location.</param>
        /// <param name="value">Whether or not the sectors have been explored.</param>
        /// <param name="radius">The radius.</param>
        public void SetExplored(MapLocation location, bool value, int radius)
        {
            int startX = Math.Max(0, location.X - radius);
            int startY = Math.Max(0, location.Y - radius);
            int endX = Math.Min(_mapData.GetLength(0) - 1, location.X + radius);
            int endY = Math.Min(_mapData.GetLength(1) - 1, location.Y + radius);
            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    SetExplored(new MapLocation(x, y), value);
                }
            }
        }

        /// <summary>
        /// Sets whether the sectors within a specified radius of a given location
        /// have been scanned.
        /// </summary>
        /// <param name="location">The origin location.</param>
        /// <param name="value">Whether or not the sectors have been scanned.</param>
        /// <param name="radius">The radius.</param>
        public void SetScanned(MapLocation location, bool value, int radius)
        {
            int startX = Math.Max(0, location.X - radius);
            int startY = Math.Max(0, location.Y - radius);
            int endX = Math.Min(_mapData.GetLength(0) - 1, location.X + radius);
            int endY = Math.Min(_mapData.GetLength(1) - 1, location.Y + radius);
            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    SetScanned(new MapLocation(x, y), value);
                }
            }
        }

        /// <summary>
        /// Sets whether the sectors within a specified radius of a given sector
        /// have been explored.
        /// </summary>
        /// <param name="sector">The origin sector.</param>
        /// <param name="value">Whether or not the sectors have been explored.</param>
        /// <param name="radius">The radius.</param>
        public void SetExplored(Sector sector, bool value, int radius)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            SetExplored(sector.Location, value, radius);
        }

        /// <summary>
        /// Sets whether the sectors within a specified radius of a given sector
        /// have been scanned.
        /// </summary>
        /// <param name="sector">The origin sector.</param>
        /// <param name="value">Whether or not the sectors have been scanned.</param>
        /// <param name="radius">The radius.</param>
        public void SetScanned(Sector sector, bool value, int radius)
        {
            if (sector == null)
                throw new ArgumentNullException("sector");
            SetScanned(sector.Location, value, radius);
        }

        /// <summary>
        /// Upgrades the scan strength at the specified location to a given value.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The value.</param>
        public void UpgradeScanStrength(MapLocation location, int value)
        {
            if (value > GetScanStrength(location))
                SetScanStrength(location, value);
        }

        /// <summary>
        /// Upgrades the fuel range at the specified location to a given value.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The value.</param>
        public void UpgradeFuelRange(MapLocation location, int value)
        {
            if (value < GetFuelRange(location))
                SetFuelRange(location, value);
        }

        /// <summary>
        /// Upgrades the scan strength of all sectors within a given radius of the origin location to a given value.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The value.</param>
        /// <param name="radius">The radius.</param>
        public void UpgradeScanStrength(MapLocation location, int value, int radius)
        {
            int startX = Math.Max(0, location.X - radius);
            int startY = Math.Max(0, location.Y - radius);
            int endX = Math.Min(_mapData.GetLength(0) - 1, location.X + radius);
            int endY = Math.Min(_mapData.GetLength(1) - 1, location.Y + radius);
            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    UpgradeScanStrength(
                        new MapLocation(x, y),
                        value);
                }
            }
        }

        /// <summary>
        /// Upgrades the scan strength of all sectors within a given radius of the origin location to a given value.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The value.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="falloff">The falloff incurred at each step away from the origin.</param>
        /// <param name="minValue">The minimum target value, regardless of falloff.</param>
        public void UpgradeScanStrength(MapLocation location, int value, int radius, int falloff, int minValue)
        {
            int startX = Math.Max(0, location.X - radius);
            int startY = Math.Max(0, location.Y - radius);
            int endX = Math.Min(_mapData.GetLength(0) - 1, location.X + radius);
            int endY = Math.Min(_mapData.GetLength(1) - 1, location.Y + radius);
            falloff = Math.Abs(falloff);
            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    MapLocation targetLocation = new MapLocation(x, y);
                    UpgradeScanStrength(
                        targetLocation,
                        Math.Max(minValue, value - (falloff * MapLocation.GetDistance(location, targetLocation))));
                }
            }
        }

        /// <summary>
        /// Upgrades the fuel range of all sectors within a given radius of the origin location to a given value.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="value">The value.</param>
        /// <param name="radius">The radius.</param>
        public void UpgradeFuelRange(MapLocation location, int value, int radius)
        {
            int startX = Math.Max(0, location.X - radius);
            int startY = Math.Max(0, location.Y - radius);
            int endX = Math.Min(_mapData.GetLength(0) - 1, location.X + radius);
            int endY = Math.Min(_mapData.GetLength(1) - 1, location.Y + radius);
            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    UpgradeFuelRange(new MapLocation(x, y), value);
                }
            }
        }
    }
}

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


07 May 2007, 06:40
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
very nicely written and the comments are great ... one question, the maxscanstrength means that they can NEVER exceed that value correct? Ok, after skimming the functions yeah thats what it does ... im guessing your purposely limited it to prevent something, or just did that as a means to have if needed?

i need to take a look at this a bit more once i've gotten some sleep .., the looping of the upgradescanstrength functions has me stuck, but i'm sure i'll see it clearly tomorrow lol


07 May 2007, 07:10
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
The maximum value of the scan strength is determined by the number of bits that I have allocated for storing the scan strength value in each sector's corresponding UInt16 (5 bits).

The UpgradeScanStrength functions that loop do so because the function upgrades the scan strength for all sectors within a radius of a specified origin sector. Therefore, it loops to cover all sectors within that radius. For instance, if a ship located in sector [2, 2] has a scan strength of 3 and a sensor range of 2 (with a reduction/falloff of 1 unit of scan strength per sector from the origin), it would modify the scan strength values of all the sectors between [0, 0] and [4, 4]. The resulting scan strength would be as follows (assuming it was zero across the board prior to the function call):

<pre>1 1 1 1 1 0 ...
1 2 2 2 1 0 ...
1 2 3 2 1 0 ...
1 2 2 2 1 0 ...
1 1 1 1 1 0 ...
0 0 0 0 0 0 ...</pre>Make sense now? :)

Note that the reason it's called UpgradeScanStrength is because it doesn't add to the existing value, but it will replace the existing value if it is lower than the newly computed value.

I just realized that the code used to re-initialize the map data at the beginning of each turn is not included in the code above. Basically, each turn, I reset the scan strength of each sector to 0 and reset the fuel range to its maximum value of 255. Then, I iterate through all of the empire's sensor sources (ships, listening posts, etc), and upgrade the scan strength values. Lastly, I iterate through all of the empire's supply posts (shipyards and stations), and use those to upgrade the fuel range values (I say "upgrade", but really we're reducing the distance between a sector and the supply posts).

I hope that clarifies things a bit :).

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


07 May 2007, 07:19
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
well by looping i meant that each function calls the other ... making what appears to be an infinite loop ... but after having read through the math and everything it looks ok ... just odd cause it seems like it could very quickly get stuck.

As for the second part, having looked over the functions a bit i took on the assumption that you would first clear all data and reset it, then iterate through and update with correct info to 'flush' any possible residual side affects that might somehow appear.


07 May 2007, 09:16
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
I can see why it might look recursive, but if you check the parameter count, none of the methods actually call themselves. They call like-named methods. The UpgradeScanStrength method that takes in radius parameter calls the UpgradeScanStrength method that operates on a single sector.

Also, as far as your research tree, you might want to check out what they're doing in the FreeOrion project. They have theories, applications, and refinements, much like in the MoO series.

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


07 May 2007, 14:08
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
yeah ... i kinda worded what i said a bit weird ... happens when i dont sleep well LOL ... I looked up FreeOrion, very interesting project, though its still in alpha stages(and a bit behind where you are IMO). Its an interesting game, and the research tree there is EXACTLY how I envision it working, minus the way they handle research is a bit unlike what i plan, the overall visual/style is what i am working towards. I took some time to download their source to take a look through it, been a while since i used C++.


08 May 2007, 00:09
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
I actually borrowed a lot of architectural ideas from FreeOrion, but my implementation feels a lot more object-oriented than theirs does (at least to me). Their source is worth checking out, and it's easy enough to decompile my game into C# code using Lutz Roeder's .NET Reflector. Their game is a lot more flexible than mine in some ways, but its development moves at the pace of molasses.

I subscribe to their development mailing list so I know when changes get committed, and I'll go update my working copy from Subversion. I'm anxious to see what they do with the AI (and tactical combat for that matter).

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


08 May 2007, 00:53
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
wow ... that application is quite amazing ... that will help a lot for me ... lets me see exactly what i need to lol

Thanks again.

And yeah, i was looking at their updates and seems like they go for days/weeks at a time with no real change at all


08 May 2007, 01:07
Profile
Captain
Captain

Joined: 24 Sep 2005, 01:00
Posts: 1387
ventrion wrote:
And yeah, i was looking at their updates and seems like they go for days/weeks at a time with no real change at all


lots of opensource projects do that, especially when there is only a few main developers. For instance, I hate coding, and thus I work in waves (or binges). Basically, I'll do nothing and gather ideas for a few weeks, then spend two weekends and push out tons and tons of code.

_________________
Hello!


08 May 2007, 02:01
Profile
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
yea i know there are people that do things that way but for me, if I dont work on it at least daily, i forget what im doing or where im heading with what i was working on and it takes me hours to remember where i was at ... so instead i work on it a few hours every day (avg about 15-20 hours a week) and i dont feel like im ignoring it, and i can stay on track.


08 May 2007, 02:26
Profile
Ship Engineer
Ship Engineer
User avatar

Joined: 10 Jul 2006, 01:00
Posts: 5130
Location: Space is disease and danger, wrapped in darkness and silence!
I just charge the hull with an energy plasma and put out a tachion and graviton burst. :D

_________________
Image


08 May 2007, 02:29
Profile
Captain
Captain

Joined: 24 Sep 2005, 01:00
Posts: 1387
ventrion wrote:
yea i know there are people that do things that way but for me, if I dont work on it at least daily, i forget what im doing or where im heading with what i was working on and it takes me hours to remember where i was at ... so instead i work on it a few hours every day (avg about 15-20 hours a week) and i dont feel like im ignoring it, and i can stay on track.


heh, you must get 10x more done than I do in a week :twisted:

I wish I had your work ethic or focus. Unfortunately, im lazy and get bored easily. Thats probably why I hate coding, and prefer designing.

_________________
Hello!


08 May 2007, 03:37
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
Maybe you hate coding because all you do is code boring-ass PHP applications :-P.

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


08 May 2007, 03:49
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
I agree with mike there ... coding in most other languages to me is either boring(PHP, Java) or tedious(C++, CoBol). I really enjoy C#, easy to read, easy to write, and its very versatile in the way you can handle things

Also ... i am occasionally getting crashes in firefox when im posting here and a few other PHP based boards ... anyone know what might cause this?


08 May 2007, 04:06
Profile
Captain
Captain

Joined: 24 Sep 2005, 01:00
Posts: 1387
mstrobel wrote:
Maybe you hate coding because all you do is code boring-ass PHP applications :-P.


Its not my fault that I needed something to start and SE seemed like a good starting spot, and it happened to be in PHP! Believe me, in hindsight I should have started with C#, but its too late now.

I have started this project, so I plan to finish. Once I do, (within two months), and make enough money so I dont have to get a full time job this summer, I'll be learning C# (maybe XNA)

ventrion wrote:
I agree with mike there ... coding in most other languages to me is either boring(PHP, Java) or tedious(C++, CoBol). I really enjoy C#, easy to read, easy to write, and its very versatile in the way you can handle things


its just so damn boring. Even though im almost completely rewriting the old SE code from the ground up, somedays I sit there and seriously pick watching some crap on TV over coding.

ventrion wrote:
Also ... i am occasionally getting crashes in firefox when im posting here and a few other PHP based boards ... anyone know what might cause this?


being the (unofficial) guy to handle this site (I was in charge of upgrading and fixing bugs for the site a few months back, which ended in fixing the problems with the site and just simply upping the security) I have to say that you are the only one to have that problem.

Are you blocking cookies/cache?

Are you using the latest version of FF or 1.5 or 3.0?

Are you using adblock plus or any other ad/script blocking plugins?

_________________
Hello!


08 May 2007, 04:14
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
ventrion wrote:
I agree with mike there ... coding in most other languages to me is either boring(PHP, Java) or tedious(C++, CoBol). I really enjoy C#, easy to read, easy to write, and its very versatile in the way you can handle things
That's so true... Java is soooo boring. And C++ is tedius as hell. Never used PHP myself, but based on my ASP experience, it's probably a drag. I don't even want to think about Cobol.

C# rocks, and C# 3.0 is going to be even better. I've got the Visual Studio Orcas beta running on my laptop, and it's pretty slick.

Speaking of web stuff... you could make a really awesome web-based game with Silverlight ;)

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


08 May 2007, 05:08
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
Nemitor_Atimen wrote:
being the (unofficial) guy to handle this site (I was in charge of upgrading and fixing bugs for the site a few months back, which ended in fixing the problems with the site and just simply upping the security) I have to say that you are the only one to have that problem.

being that its not just this forum, i know its not the forum itself causing the issue.

Nemitor_Atimen wrote:
Are you blocking cookies/cache?

not from this or other forums i visit, I only block cookies from specific sites anyways, and i do it manually so i know whats being blocked

Nemitor_Atimen wrote:
Are you using the latest version of FF or 1.5 or 3.0?

**EDIT**2.0.0.3 - i refuse to upgrade till 3.5 or something better comes out.

Nemitor_Atimen wrote:
Are you using adblock plus or any other ad/script blocking plugins?

I use no blockers aside from the built in popup blockers in firefox.

like i said ... i am not sure where the problem is, but i KNOW its my firefox ... IE doesn't have this problem(which is sad really, cause its IE7 which is junk).
Maybe its time to see what the latest version is and try it out ... and it only seems to happen 'every now and then' its not even consistent or reproducable.

oh, one other thing to note, my cmos battery has died, and therefore my system time/date are perpetually wrong ... not sure if that might be related somehow ... i really need to go buy a new one LOL[/b]


08 May 2007, 05:18
Profile
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
back on track ... here is a template of the research tree ... any input on this would be great. Try to remember, i want this to be as modifiable as possible, and with easy changes to made via an editor that will be included with the program. I will explain certain items below.

Code:
<?xml version="1.0" encoding="utf-8"?>
<TechTree>
  <Fields>
    <Field>
      <FieldName>Computers</FieldName>
      <FieldDescription>This field is dedicated to compter related research, including new ways of storing and manipulating data as well as security and other related items.</FieldDescription>
      <Techs>
        <Tech>
          <TechName>Bio-Electric Computers</TechName>
          <TechDescription>Tech Description Here</TechDescription>
          <TechType>Developmental</TechType>
          <ResearchCost>5000</ResearchCost>
          <Level>3</Level>
          <TechRequirements>
            <FieldName>Energy</FieldName>
            <TechLevel>1</TechLevel>
          </TechRequirements>
          <TechRequirements>
            <FieldName>Biology</FieldName>
            <TechLevel>3</TechLevel>
          </TechRequirements>
        </Tech>
      </Techs>
    </Field>
    <Field>
      <FieldName>Energy</FieldName>
      <FieldDescription>This Field is dedicated to creating and developing new ways to harness energy to power everything.</FieldDescription>
      <Techs>
        <Tech>
          <TechName>Fusion Power</TechName>
          <TechDescription>Fusion based power research</TechDescription>
          <TechType>Theory</TechType>
          <ResearchCost>100</ResearchCost>
          <Level>1</Level>
        </Tech>
      </Techs>
    </Field>
  </Fields>
</TechTree>


ok now the things that i feel *might* need explaining.

the Level item : this should probably be changed to reflect its ACTUAL purpose, but i haven't really thought if it will make a difference yet. This item will describe the tech's number, to be used by the TechRequirement fields for requirements of techs. In other words, the Bio-electric computers would require both Energy number 1(Fusion power) and Biology 3(not defined yet) to be researched BEFORE this tech can be researched.

the TechType item : this item will tell the system what type of research this is. eg, theoretical(basically conceptual research), developmental(trying to make something from theoretical research), or prototype(making a working model, testing refining, etc).

so, with all that in mind, what would make this better, what could be added to make it easier to use, what could be changed to make it more understandable. Any input would be helpful

**Edit** ... on the ironic side ... been up all night and now have a nearly completed viewer/editor for my XML files. At the moment it just views, and just one file, but tomorrow night or the day after i'll have all the functions done ... then i wont even need to do any real work to modify content, and i can get people here to do it for me ;) j/k unless someone really wants to do it, id be real grateful


08 May 2007, 06:26
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
Hmm, the above XML looks suspiciously familiar ;). Honestly, I'm not sure you want to go that route. I'm not particularly fond of my tech tree. The reason it's done that way is so it can easily conform to the BotF-style research matrix, since the BotF2 specs already used a similar system.

I would recommend something like the following:
Code:
<TechCategory ID="COMPUTERS">
  <Tech ID="COMP_BASIC_THEORY">
    <Name>Basic Computer Theory</Name>
    <Description>This is the basic theory of computers.</Description>
    <Image>Resources/TechImages/comp_basic_theory.png</Image>
    <TechType>Theory</TechType>
    <ResearchCost>100</ResearchCost>
    <Dependencies/>
  </Tech>
  <Tech ID="COMP_BASIC_APP">
    <Name>Basic Computer Application</Name>
    <Description>This allows development of actual basic computers.</Description>
    <Image>Resources/TechImages/comp_basic_app.png</Image>
    <TechType>Application</TechType>
    <ResearchCost>200</ResearchCost>
    <Dependencies>
      <Dependency>COMP_BASIC_THEORY</Dependency>
    </Dependencies>
  </Tech>
</TechCategory>
Note that the tech levels are not hard-coded, but are derived through dependencies in the tree. 'Dependencies' could also be called 'Prerequisites'.

You have two options for allowing your tech applications to unlock actual tech items like buildings and ships. You can either specify a list of tech prerequisites for each tech item (that's the way I would go), or you could specify which items are unlocked by a given tech.

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


08 May 2007, 15:28
Profile WWW
Evil Romulan Overlord of Evil - Now 100% Faster!
Evil Romulan Overlord of Evil - Now 100% Faster!
User avatar

Joined: 02 Dec 2004, 01:00
Posts: 7392
Location: Returned to the previous place.
Mike, you don't HAVE to stick to the BOTF style system if it makes your life harder - BOTF2 is all about improving on BOTF afterall. Just because something worked in BOTF doesn't mean it can't be improved upon. You've already proved that with the movement system in Supremacy alone! :wink:

Whilst i'm a fan of XML because it is easy to understand how to mod simple things, such as increasing the amount of food something produces etc etc - afterall it's a simple matter of finding the word "food" reading what it says next to it and changing the associated number - I don't understand what any of the rest of the coding stuff means. I'm still lurking here reading the posts though. It'll make modding the game easier later on! :twisted: :lol:

Threads like this are good because you programming guys can bounce ideas off of each other and solve each others' problems. Keep it up, it'll speed up game development! :mrgreen:

_________________
"Anyone without a sense of humour is truly at the mercy of the rest of us."

Image
Image


08 May 2007, 18:46
Profile WWW
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
Matress_of_evil wrote:
Mike, you don't HAVE to stick to the BOTF style system if it makes your life harder - BOTF2 is all about improving on BOTF afterall. Just because something worked in BOTF doesn't mean it can't be improved upon. You've already proved that with the movement system in Supremacy alone! :wink:
It doesn't make my life harder, it makes it easier. Doing the kind of tech tree I wanted would mean coming up with all the techs and their prerequisites, as well as coming up with the list of tech prerequisites for all the objects in the game. No sense in going to all that trouble when the tech levels for everything have already been set.

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


08 May 2007, 21:40
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
mstrobel wrote:
I would recommend something like the following:
Code:
<TechCategory ID="COMPUTERS">
  <Tech ID="COMP_BASIC_THEORY">
    <Name>Basic Computer Theory</Name>
    <Description>This is the basic theory of computers.</Description>
    <Image>Resources/TechImages/comp_basic_theory.png</Image>
    <TechType>Theory</TechType>
    <ResearchCost>100</ResearchCost>
    <Dependencies/>
  </Tech>
  <Tech ID="COMP_BASIC_APP">
    <Name>Basic Computer Application</Name>
    <Description>This allows development of actual basic computers.</Description>
    <Image>Resources/TechImages/comp_basic_app.png</Image>
    <TechType>Application</TechType>
    <ResearchCost>200</ResearchCost>
    <Dependencies>
      <Dependency>COMP_BASIC_THEORY</Dependency>
    </Dependencies>
  </Tech>
</TechCategory>
Note that the tech levels are not hard-coded, but are derived through dependencies in the tree. 'Dependencies' could also be called 'Prerequisites'.

You have two options for allowing your tech applications to unlock actual tech items like buildings and ships. You can either specify a list of tech prerequisites for each tech item (that's the way I would go), or you could specify which items are unlocked by a given tech.


This just reminded me of something i had thought about designing an implementation for.

using a similar style as above we'd have two things
Code:
    <Prerequisites>
      <Prerequisite>COMP_BASIC_THEORY</Prerequisite>
    </Prerequisites>


basically just your regular research items

and
Code:
    <Dependencies>
      <Dependency>SCI_BUILDING_SPECIAL_5</Dependency>
    </Dependencies>


which would be special buildings or other things that can unlock a certain technology. (this would be a highly specialized tech, probably something like you have to have utopia planitia, and starfleet command built before you can research defiant, or something along those kind of lines.)

As for the my first one looking familiar its kinda funny you say that, as some of it was a pain to try and find a way to make it feel different. I never even thought of breaking it down like you just showed ... some reason i was stuck on BOTF ... probably cause i am still pissed about losing to my friend LOL.

I think i have a few other things I should do to it. Will also give me a constistence to the XML ... the way you just posted is exactly how I designed my buildings and module lists ...


08 May 2007, 22:34
Profile
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
might as well post the templates i made for them as well

heres the buildings
Code:
<Buildings>
  <BuildingCategory ID="PROD_FOOD">
  <Building>
    <BuildingName>Simple Farm</BuildingName>
    <BuildingOutput>15</BuildingOutput>
    <BuildCost>20</BuildCost>
    <BuildingRequirements>
      <PowerRequirements>
        <PoweredBy>Population</PoweredBy>
        <Units>1</Units>
      </PowerRequirements>
      <PowerRequirements>
        <PoweredBy>Energy</PoweredBy>
        <Units>1</Units>
      </PowerRequirements>
      <TechRequirements>
        <TechName>Biology</TechName>
        <TechNumber>0</TechNumber>
      </TechRequirements>
      <TechRequirements>
        <TechName>Construction</TechName>
        <TechNumber>0</TechNumber>
      </TechRequirements>
    </BuildingRequirements>
  </Building>
  </BuildingCategory>
</Buildings>


and modules
Code:
<ModuleCategory ID="Weapons">
  <Module>
    <ModuleName>Nuclear Torpedo</ModuleName>
    <ModuleType>Torpedo</ModuleType>
    <ModuleProperties>
      <DamageModifier>10</DamageModifier>
      <DamageType>Impact</DamageType>
      <Speed>10</Speed>
      <Range>10000</Range>
      <Tracking>0</Tracking>
      <Accuracy>5</Accuracy>
      <DamageToShields>1</DamageToShields>
      <DamageToHull>35</DamageToHull>
      <TotalNumberOfShots>5</TotalNumberOfShots>
      <ShotsPerRound>1</ShotsPerRound>
    </ModuleProperties>
  </Module>
  <Module>
    <ModuleName>Laser Cannon</ModuleName>
    <ModuleType>Beam</ModuleType>
    <ModuleProperties>
      <DamageModifier>2</DamageModifier>
      <DamageType>Energy</DamageType>
      <Range>2000</Range>
      <Tracking>15</Tracking>
      <Accuracy>25</Accuracy>
      <DamageToShields>25</DamageToShields>
      <DamageToHull>5</DamageToHull>
      <ShotsPerRound>5</ShotsPerRound>
    </ModuleProperties>
  </Module>


and not sure anything in these needs to be explained, they are pretty clear. any suggestions on modifications ways to improve them would be great.


08 May 2007, 22:49
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
I'd probably use a somewhat more rigid hierarchy for your XML documents, using complex types that you've defined in an XSD schema. For instance, I'd recommend doing the following for modules:
Code:
<Modules>
    <WeaponModules>
        <WeaponModule ... />
        <WeaponModule ... />
    </WeaponModules>
    <ShieldModules>
        <ShieldModule ... />
        <ShieldModule ... />
    </ShieldModules>
    ...
</Modules>
It makes it a bit easier to parse and validate. Plus it's nice to have not to have all the different module types jumbled together. You could define a complex type "Module" that has child elements like "Name", "Description", etc., and then extend that with complex types for "WeaponModule", "ShieldModule", etc. If the XML complex types are modeled after your class hierarchy, then you should be able to have a virtual FromXml(XmlElement) method (or .ctor(XmlElement) constructor) in your Module class that reads in all the child elements of the Module XML elements, and then override it in the subclasses like ShieldModule to add the child elements of the ShieldModule XML elements.

Trust me, it's worth the few hours of extra work to create strict XSD schemas for all your XML documents.

http://www.w3schools.com/schema/default.asp
http://www.w3.org/TR/xmlschema-0/

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


08 May 2007, 23:19
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
biggest problem i had when i was trying to make a schema ... it kept telling me schema file not found, etc. I'm not sure how they are defined and linked, but I'm either doing something wrong or I don't know what.

**EDIT**
I guess one reason I wasn't being too rigid with the files aside from the schema was to allow for easy changes to the documents, adding in previously undefined types and allowing them to be used. Reading through the info you posted may have actually shown me where my problem is, but i will have to test it later.


09 May 2007, 00:20
Profile
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
Well ... I seem to have gotten it working ... not sure how to force it to validate my XML in VS so I can check it ... though i guess i could write that into my app as part of the verification process.

If you'd like I'll post the schema later and you can give me input on what could be changed to make it work better, or more exact so that there are less chances for errors.


09 May 2007, 03:09
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
I'd be glad to take a look at it and make sure you get the schema references correct in the XML, etc. It's tricky at first, then you get the hang of it after a while.

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


09 May 2007, 06:49
Profile WWW
Cadet
Cadet
User avatar

Joined: 29 Apr 2007, 01:00
Posts: 56
Code:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="TechType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Prototype" />
      <xs:enumeration value="Theory" />
      <xs:enumeration value="Application" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="Tech">
    <xs:sequence>
      <xs:sequence>
        <xs:element name="Name" type="xs:string" />
        <xs:element name="Description" type="xs:string" />
        <xs:element name="Image" type="xs:string" />
        <xs:element name="TechType" type="TechType" />
        <xs:element name="ResearchCost" type="xs:unsignedShort" />
        <xs:element name="Prerequisite" type="xs:string" minOccurs="0" />
        <xs:element name="Dependency" type="xs:string" minOccurs="0" />
      </xs:sequence>
    </xs:sequence>
    <xs:attribute ref="ID" use="required" />
  </xs:complexType>
  <xs:element name="Research">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Tech" type="Tech" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:attribute name="ID" type="xs:string" />
</xs:schema>


Im still working on the final format, and the naming scheme i still dont like(i just used what you posted to help me understand the schema, then I can just make my own at that point, though some of this probably wont change,as its pretty easy to navigate with my classes, and from what I read i can make classes from XML schema, then i can just import the XML and build a reusable research(or whatever) class, which ought to make my life a bit easier.


10 May 2007, 00:10
Profile
Chief Software Engineer
Chief Software Engineer
User avatar

Joined: 11 Aug 2005, 01:00
Posts: 2688
Howsabout this...
Techs.xsd (Schema)
Code:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Techs"
           targetNamespace="GameName:Techs.xsd"
           attributeFormDefault="unqualified"
           elementFormDefault="qualified"
           xmlns="GameName:Techs.xsd"
           xmlns:local="GameName:Techs.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="TechType">
    <xs:restriction base="xs:NCName">
      <xs:enumeration value="Prototype"/>
      <xs:enumeration value="Theory"/>
      <xs:enumeration value="Application"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="TechCategory">
    <xs:sequence>
      <xs:sequence>
        <xs:element name="Name"
                    type="xs:normalizedString"/>
        <xs:element name="Description"
                    type="xs:normalizedString"/>
        <xs:element name="Image"
                    type="xs:normalizedString"/>
      </xs:sequence>
    </xs:sequence>
    <xs:attribute name="Key"
                  use="required"
                  type="xs:NCName"/>
  </xs:complexType>
  <xs:complexType name="Tech">
    <xs:sequence>
      <xs:sequence>
        <xs:element name="Name"
                    type="xs:normalizedString"/>
        <xs:element name="Description"
                    type="xs:normalizedString"/>
        <xs:element name="Category"
                    type="xs:NCName">
        </xs:element>
        <xs:element name="TechType"
                    type="local:TechType"/>
        <xs:element name="Image"
                    type="xs:normalizedString"/>
        <xs:element name="ResearchCost"
                    type="xs:nonNegativeInteger"/>
        <xs:element name="Prerequisites"
                    minOccurs="0">
          <xs:complexType>
            <xs:sequence minOccurs="0">
              <xs:element name="Prerequisite"
                          type="xs:NCName"
                          minOccurs="0"
                          maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="UnlockedItems"
                    minOccurs="0">
          <xs:complexType>
            <xs:sequence minOccurs="0">
              <xs:element name="UnlockedItem"
                          type="xs:normalizedString"
                          minOccurs="0"
                          maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:sequence>
    <xs:attribute name="Key"
                  use="required"
                  type="xs:NCName"/>
  </xs:complexType>
  <xs:element name="TechTree">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="TechCategories">
          <xs:complexType>
            <xs:sequence minOccurs="0">
              <xs:element name="TechCategory"
                          type="local:TechCategory"
                          minOccurs="0"
                          maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Techs">
          <xs:complexType>
            <xs:sequence minOccurs="0">
              <xs:element name="Tech"
                          type="local:Tech"
                          minOccurs="0"
                          maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="techCategoryKey">
      <xs:selector xpath="local:TechCategories/local:TechCategory"/>
      <xs:field xpath="@Key"/>
    </xs:key>
    <xs:keyref name="techCategoryKeyRef"
               refer="techCategoryKey">
      <xs:selector xpath="local:Techs/local:Tech"/>
      <xs:field xpath="local:Category"/>
    </xs:keyref>
    <xs:key name="techKey">
      <xs:selector xpath="local:Techs/local:Tech"/>
      <xs:field xpath="@Key"/>
    </xs:key>
    <xs:keyref name="prerequisiteTechKeyRef"
               refer="techKey">
      <xs:selector xpath="local:Techs/local:Tech/local:Prerequisites"/>
      <xs:field xpath="local:Prerequisite"/>
    </xs:keyref>
  </xs:element>
</xs:schema>

Techs.xml (Sample Data)
Code:
<?xml version="1.0" encoding="utf-8" ?>
<TechTree xmlns="GameName:Techs.xsd">
  <TechCategories>
    <TechCategory Key="Computers">
      <Name>Computers</Name>
      <Description>Technologies related to Computers</Description>
      <Image>Resources/Images/TechCategories/Computers.png</Image>
    </TechCategory>
  </TechCategories>
  <Techs>
    <Tech Key="BasicComputers">
      <Name>Basic Computers</Name>
      <Description>Basic computer theory.</Description>
      <Category>Computers</Category>
      <TechType>Theory</TechType>
      <Image>Resources/Images/Techs/BasicComputers.png</Image>
      <ResearchCost>500</ResearchCost>
    </Tech>
    <Tech Key="Microcomputers">
      <Name>Microcomputers</Name>
      <Description>Basic microcomputer production.</Description>
      <Category>Computers</Category>
      <TechType>Application</TechType>
      <Image>Resources/Images/Techs/Microcomputers.png</Image>
      <ResearchCost>1000</ResearchCost>
      <Prerequisites>
        <Prerequisite>BasicComputers</Prerequisite>
      </Prerequisites>
    </Tech>
  </Techs>
</TechTree>

The keys and keyrefs defined in the Techs element make sure the value of a Tech's "Category" element value matches a defined TechCategory's "Key" attribute value (same goes for the Tech's "Prerequisite" element matching a Tech's "Key" attribute).

Visual Studio should validate your XML as you type it.

_________________
Lead Developer of Star Trek: Supremacy
253,658 lines of code and counting...


10 May 2007, 01:21
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 86 posts ]  Go to page 1, 2, 3  Next

Who is online

Users browsing this forum: No registered users and 30 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by STSoftware.