Results 1 to 31 of 31

Inner workings of the combiner

  1. #1
    The Duke Nukem
    Guest

    Inner workings of the combiner

    Ok, most of this should be review for you guys, but I did some tests and crunched together the numbers to figure out how stats are calculated.

    HP: A certain percentage of HP is mapped to each leg, the torso and the head (for land critters). Exactly 20% is mapped to each leg, 10% to the head and 50% to the torso. For creatures with no legs, the leg hp is simply mapped to the torso and head instead (I can't figureout exactly how much goes to the torso and how much to the head, but it's definitely spread out). The exception seems to be the Walrus, which has 'invisivible' legs that can only be used in conjunction with the Walrus torso, but can be switched out for other legs. No HP is ever mapped to the tail, pincers/claws or wings. HP is magnified by size. A size 10 creature with all ant parts has 753 hp, as opposed to 30 hp for a size 1 ant (the combiner always uses the size of the larger creature). The amount by which HP gets multiplied seems to be constant for each size.
    EDIT: For birds, front leg hp is mapped instead to the torso.

    Defense: Defense works exactly like HP, except that it's unaffected by size. The only exceptions seem to be the snapping turtle, armadillo and lobster (partial credit for this goes to Once Known as X), where much more of the defense is mapped to the torso (note that using a snapping turtle torso does not garauntee 90 defense). Again, for creatures with no legs (excepting the Walrus), map leg HP to the torso and head. (Btw, the 'Defense' stat is a percentage of damage that will be removed, and horns/piercing reduce defense by 50%.)
    EDIT: 25% of bird defense is mapped to the back legs, while 65% is mapped to the torso (as opposed to bird HP).

    Speed: 40% of land speed is mapped to each leg, and the other 20% is mapped to the torso. For snakes, all land speed is mapped to the torso (the Walrus uses standard speed-mapping for its invisible legs). For swimmers, water speed seems to be unpredictable. For the Electric Eel, the vast majority of water speed is mapped to the torso, whereas for the Killer Whale (and most swimmers), the majority of water speed is mapped to the tail. Water speed is never affected by legs. 20% of air speed is mapped to the torso, and the other 80% is mapped to the wings. No air speed is ever mapped to non-fliers, no water speed is ever mapped to ground-only movers, etc. Speed is affected by size (higher size means lower speed), but not by very much; at the most dramatic size difference (size 1 to size 10), and using all the size 1 creature's parts, speed is reduced to 2/3 of the speed it would be at size 1.

    Damage: Each attack is mapped to a certain body part, and melee damage is the sum of all melee attacks (artillery and ranged attacks do not mix like melee attacks do). Damage is greatly amplified by damage; in the most dramatic example, a dragonfly (size 1, attack 10) mixed with a sperm whale (size 10) and using all Dragonfly parts, gets you an attack of 42. Although there does seem to be some unpredictability; an ant, which has the same size and attack as a droganfly, mixed with a sperm whale only gets you an attack of 30.
    EDIT: Relic actually made the way each creature changes with size different for balancing purposes.

    EDIT: Sight radius: Sight radius is determined entirely by the creature's head, and is unaffected by size. It does appear to have an effect on coal cost. Flying units always have at least 25 sight radius (even if the creature's head has less), but do not get a bonus for heads with sight radii of 25 or greater.

    That covers pretty much everything. If you have a correction ot request to make, or any comments to add, feel free to do so.

    Edited to correct something
    Edited again to correct something else
    Edited yet again to correct a previous edit
    Edited once more add some new stuff

  2. #2
    QuickSloth
    Guest
    Very interesting, thank you for your time and effort. This is rather useful info.

  3. #3
    Once known as X
    Guest
    gee sounds nice but it has some flaws..

    1) lobster/scoprion also get a high defense bonus with the toso section

    2) each animal is not the same. Explain to me why a wolverine + spermwhale combo has the most hp in the game based on your theory?

    While it is nice to put time and efferot into work, and it is a nice start, there are many seeminly random factors that relic put in with different combinations.

  4. #4
    The Duke Nukem
    Guest
    Alright:

    1) lobster/scoprion also get a high defense bonus with the toso section
    I have yet to test that, so no objection there. I'll check it out and add it if I find that to be the case.

    EDIT: OKAX, you were right about the lobster having more hp mapped to its torso than other creatures, however the scorpion is not different from other creatures as far as where its defense is mapped to.

    2) each animal is not the same. Explain to me why a wolverine + spermwhale combo has the most hp in the game based on your theory?
    I don't see how that contradicts anything I said. The wolverine has very high hp (160) and very low size (size 2). In fact, the highest hp even in size 3 is 165. In size 1, the highest hp is 35. The wolverine has the best hp to size ratio of all the creatures in the game, making the size 10 wolverine the highest hp creature. The example of the wolverine/sperm whale fits right into my observations.

    While it is nice to put time and efferot into work, and it is a nice start, there are many seeminly random factors that relic put in with different combinations.
    I don't believe much of it is random. I encountered two 'random' things; 1) The damage multiplier (from lower to higher sizes). This seems to vary for different creatures, but not by very much. 2) The amount of water speed mapped to the tail as opposed to the torso. The number of swimming creatures is small enough so that Relic probably made the percentages unique to each creature.

    Thanks for the comments so far guys .

  5. #5
    PaladinKing
    Guest
    Originally posted by The Duke Nukem
    Alright:
    I don't believe much of it is random. I encountered two 'random' things; 1) The damage multiplier (from lower to higher sizes). This seems to vary for different creatures, but not by very much. 2) The amount of water speed mapped to the tail as opposed to the torso. The number of swimming creatures is small enough so that Relic probably made the percentages unique to each creature.

    Thanks for the comments so far guys .
    It seems to me that mammal and shark has more swimming speed mapped to the tail. Definitely not random because it is how the real animal swim.

  6. #6
    The Duke Nukem
    Guest

    Fliers

    Okay, figuring out the stats for the two different kinds of fliers (bugs and birds) is giving me headahces. I'm going to be away for a couple weeks, so hopefully someone else can do that for me .

    EDIT: Scratch that. I'm back.

  7. #7
    GIMPbeowulf
    Guest
    I don't think you can say speed, hitpoints, and armor are mapped here or there. I think what happens is each part has speed, health, and armor ratings. Those rating are added up to get the stats for the creature.

  8. #8
    PaladinKing
    Guest
    I do not know what Nuke want to figure out but I'll make my effort. Since speed is the main issue with flying creatures, I'll start with that.

    The difference between insect and bird:

    1. with insect, you have to use its torso to fly. Like he already said, speed decease by 1 with 1 size increase. Simple enough.

    2. with bird, you can choose to use the torso and wings, or just the wings.

    3. If you use the torso and wings, you lose about 15-20% speed for the first size change, and then it gets smaller. It's better illustrated with an example. I'll use Bat since it's a size 1,

    Animal Speed
    Bat 32
    Bat/2 26
    Bat/3 24
    Bat/4 22
    Bat/5 21

    Pretty much you will lose 1 in speed from then on with size change.

    4. If you use only the wings, speed drops very quickly with the first change and then it's about the same.

    Animal Speed
    Bat 32
    Bat/2 21
    Bat/3 19
    Bat/4 17
    Bat/5 16

    Again, you lose 1 speed from there on.

    Hope this help.

  9. #9
    PaladinKing
    Guest
    I also did a check on the electricity cost of abilities. Here's the list:

    High endurance 5
    Immunity 15
    Camouflage 30
    Keen sense 10
    Regeneration 25

    Poison 50
    Poison touch 50
    Plague 50

    Leap attack 30
    Charge attack 30

    Flight 75
    Digging 10

    Pack Hunter 45
    Herding 45
    Frenzy 40
    Barrier destroy 25
    Horns 50

    Sonic pulse 30
    Sonic attack 100 (damn expensive, why?)
    Tongue attack 40
    Rock artillery 40
    Water artillery 40
    Stink cloud 30

    It doesn't matter what size or creature, the cost stay the same. If I am missing anything, you are welcome to add to the list.

  10. #10
    CyanideNow
    Guest
    Originally posted by PaladinKing


    It seems to me that mammal and shark has more swimming speed mapped to the tail. Definitely not random because it is how the real animal swim.
    You mean...like the polar bear?

  11. #11
    Deathhawk
    Guest
    Great work Duke and Paladin, keep up the good work so we don't have to.

  12. #12
    The Duke Nukem
    Guest

    Thanks Paladin

    In case you're confused, I was supposed to leave more two weeks or so but that plan is basically kaput.

    We might use this stuff to make an IC FAQ on Gamefaqs later on (there aren't any right now ).

    I do not know what Nuke want to figure out but I'll make my effort. Since speed is the main issue with flying creatures, I'll start with that.

    The difference between insect and bird:

    1. with insect, you have to use its torso to fly. Like he already said, speed decease by 1 with 1 size increase. Simple enough.

    2. with bird, you can choose to use the torso and wings, or just the wings.

    3. If you use the torso and wings, you lose about 15-20% speed for the first size change, and then it gets smaller. It's better illustrated with an example. I'll use Bat since it's a size 1,

    Animal Speed
    Bat 32
    Bat/2 26
    Bat/3 24
    Bat/4 22
    Bat/5 21

    Pretty much you will lose 1 in speed from then on with size change.

    4. If you use only the wings, speed drops very quickly with the first change and then it's about the same.

    Animal Speed
    Bat 32
    Bat/2 21
    Bat/3 19
    Bat/4 17
    Bat/5 16

    Again, you lose 1 speed from there on.

    Hope this help.
    Thanks for doing the size/speed calculations, although I think it's percentage-based (a size 10 turtle has 11 speed rather than 7).

    The discrepancy I noted between bird and bug fliers was the way HP and defense are calculated. I noticed they were different but didn't have the time to figure them out exactly. I think I have it figured out now; bug fliers (dragonflies and hornets) have the regular amount of stats mapped their body parts (two legs, torso, head etc). Birds, on the other hand, are missing the front legs, so they work slightly differently. Basically, 20% of bird hp goes to the back legs, but 25% of bird defense goes to the legs. I’m pretty sure of it after testing out many different bird combos. It’s pretty minor, but it was confusing me earlier.

    Anyway thanks for the ability/elec cost table. I think it's also worth mentioning that swimming doesn't cost any elec. I was thinking of doing something like that myself, but I guess now I don’t have to .

    Great work Duke and Paladin, keep up the good work so we don't have to.
    Thanks, you lazy bastard .

  13. #13
    Stoo
    Guest
    I know there's a seperate calculation system for doing sizes of flying creatures; perhaps the difference is related to that?

  14. #14
    PaladinKing
    Guest

    Re: Thanks Paladin

    Originally posted by The Duke Nukem
    We might use this stuff to make an IC FAQ on Gamefaqs later on (there aren't any right now ).
    Great, I was writing a walkthrough for the single player campaign a while ago. Let me know if anyone would be interested in that.

  15. #15
    Kaylum
    Guest
    Originally posted by Stoo
    I know there's a seperate calculation system for doing sizes of flying creatures; perhaps the difference is related to that?
    seperate calculations for size on which flying creatures?

    all the combos ive tested have always used the size of the largest creature, same as the ground creatures.

  16. #16
    Kaylum
    Guest
    Originally posted by PaladinKing
    The difference between insect and bird:
    1. with insect, you have to use its torso to fly.
    2. with bird, you can choose to use the torso and wings, or just the wings.
    this isnt true.

    you can select all of the ground creatures parts and just add the wings of any flying creature, including the insects. you dont need to use the torso. adding the torso just adds speed but is not required to fly.

    Originally posted by PaladinKing
    Like he already said, speed decease by 1 with 1 size increase. Simple enough.
    3. If you use the torso and wings, you lose about 15-20% speed for the first size change, and then it gets smaller.
    Pretty much you will lose 1 in speed from then on with size change.
    4. If you use only the wings, speed drops very quickly with the first change and then it's about the same.
    Again, you lose 1 speed from there on.
    its not quite that simple; your calculations dont work for most of the air creatures.

    compare the only 3 creatures in the game that start with the same airspeed and all 3 end up with varying speeds with each size change. if the formula were simple they would all combine to the same speeds at higher sizes.

    the raven for example is 1.35 times faster than a hornet both at size 10 even though they started at the same speeds at size 1. heres a chart to show each of the 3, speed 35 creatures at every size from 1 to 10.

    (Size/RavenSpeed/HornetSpeed/DragonflySpeed)
    SZ/ RS / HS / DS
    1 / 35 / 35 / 35 <-starting speed and size for all 3 creatures
    2 / 32 / 29 / 31
    3 / 31 / 26 / 29
    4 / 30 / 25 / 28
    5 / 29 / 23 / 27
    6 / 29 / 22 / 26
    7 / 28 / 21 / 25
    8 / 28 / 21 / 25
    9 / 28 / 20 / 24
    10/ 27 / 20 / 24

    the other air creatures are harder to cross compare because none have matching base speeds; however, they all lose a differant % of speed off the starting values for even the first size change. therefore they seem to be all pre-set to lose a unique amount of speed for each size change regardless of their base starting air speed. so there is no formula.

    best you can do is document the unique speed changes for each air creature at each size.

  17. #17
    PaladinKing
    Guest
    Thanks for the correction. Duke has already mentioned it's more of a percentage calculation. Have you figured out whether the same percentage applies for all birds/insects, or it's different for every creature? I don't think they will make different table for every creature so there should be some kind of connection.

    May be it should just be described as a general trend instead of number.

    But then again I cannot figure out how they calculate the coal cost. There's simply too many factors to decipher. Reverse engineering is never easy.

  18. #18
    Kaylum
    Guest
    Originally posted by GIMPbeowulf
    I don't think you can say speed, hitpoints, and armor are mapped here or there. I think what happens is each part has speed, health, and armor ratings. Those rating are added up to get the stats for the creature.
    you just contradicted yourself.

    by stating that each part has a speed/health/armor rating:
    you are saying each part is mapped (or set to, or charted) a specific value (or rather its a formula that determines its current specific value)

    you can word it any way you want but the final creature is of course a sum of all parts used.

    the question being answered by mapping/charting it out is:
    what deterimines the value of each part?

    the easiest method for comparison is to start with "pure creatures"

    you can for example choose all lemming parts and no matter what size 1 creature you mix it with, you will have a pure lemming with the exact same stats as if you didn mix it with anything at all.

    go right down the list, choose any creature in the game, than mix it with a matching size creature, and if you choose all the pure parts of one creature, you will have only the base stats of that one creature, unchanged as if you didnt combine it.

    now with further experimentation you can by changing only one body part at a time, see what changes for each.

    lets use mountain lion/chimpanzee for example

    you will see that since both mountain lion and chimpanzee have the same base health and base size that no matter what mixture of body parts you use you will always end up with a 65 health unit.

    no combination of parts from a mountainlion/chimpanzee combo will result in a differant health.

    however, testing a musk ox/wolverine will have very differant results.

    they both again have the same base health, but since the sizes are differant, you will see that each body part changed to a wolverine part will be magnified by the musk ox's size.

    and yet, if you use all of the musk ox parts, there is no change in health at all from the natural base health. why? because they arent changing size.

    test this further with other animals that have matching base health:

    kangaroo, horse, dolphin
    cheetah, porcupine
    lemming, raven
    ant, hornet

    and so on.

    each animal is therefore broken down by its prospective body parts each worth a % of the creatures total value in each stat.

    that part if attached to another creature is than magnified by the size of the other creature (if that creature is larger)

    the rest is explained already in previous posts so im not going to repeat it all.

  19. #19
    Kaylum
    Guest
    Originally posted by PaladinKing
    Have you figured out whether the same percentage applies for all birds/insects, or it's different for every creature? I don't think they will make different table for every creature so there should be some kind of connection.

    May be it should just be described as a general trend instead of number.
    its not the same % for all birds/insects. each creature has a unique (though similar) deevolution of speed with each size change.

    so it would seem they started with a basic pattern then tweeked it for each creature which is why a general trend is visible but not an exact formula.

    this may actually be true for every stat.

    since the health/defense/sight etc seem to follow a much tighter pattern (which is why some formulas seem to work for many creatures) it would also explain why theres only a handful of body parts that break that mold (turtle body defense, etc).

    they could therefore have set up the general guidelines for every body part/stat in the game and than only felt the need to tweek specific things on that chart such as flying, swimming, and the occasional turtle shell, and so on

    perhaps the forumulas than are simply pointing out their guidelines, but the final charts have all been modified.

    But then again I cannot figure out how they calculate the coal cost. There's simply too many factors to decipher. Reverse engineering is never easy.
    wish i had time to play with it, but my roomates glaring at me and wants the computer, sigh...

  20. #20
    PaladinKing
    Guest
    Originally posted by Kaylum
    wish i had time to play with it, but my roomates glaring at me and wants the computer, sigh...
    That's easier to handle than my girlfriend glaring at me and want me .

  21. #21
    Stoo
    Guest
    Kaylum - the flier sizes are different; they use the same size scale (1-10), but the actual size of a size 5 flier is different than a size 5 ground creature. I'm not sure if or how this affects stats, but you can see the differences in the creaturescalinginfo.lua and flyerscalinginfo.lua (in the combiner files).

    PaladinKing - each creature has its own table which lists how much of each attribute is in each creature's parts, and also tells how much to scale that attribute based on a size change. Check in the stock creature .lua files; IIRC, each animal has two numbers for each entry: A percentage amount by which the part affects that trait, and a second number that tells (exponentially) how much to alter it with size.

    One of the devs detailed how they work a few days ago, I wish I could find that thread again...

  22. #22
    GIMPbeowulf
    Guest
    What I'm saying is that I don't think it goes by percentages.

    I think it's a value for each part that scales with size when apropriate.

  23. #23
    The Duke Nukem
    Guest
    GIMP: Ok, have you done any tests or have any numbers to prove it? Why leads you to think each part has a 'rating' as opposed to a creature's stats being mapped to a particular part?

    Stoo: You mentioned .LUA files for the stock creatures. Where can I find these files? The way you describe it, it sounds like all the stuff we need is in there.

  24. #24
    Kaylum
    Guest
    Originally posted by Stoo
    Kaylum - the flier sizes are different; they use the same size scale (1-10), but the actual size of a size 5 flier is different than a size 5 ground creature. I'm not sure if or how this affects stats, but you can see the differences in the creaturescalinginfo.lua and flyerscalinginfo.lua (in the combiner files).
    sorry, misunderstood your statement than. your right about the appearances of size being differant from air to ground.

    but from what testing ive done the stats are based purely on the numbers regardless of the graphical end result of the model.

    PaladinKing - each creature has its own table which lists how much of each attribute is in each creature's parts, and also tells how much to scale that attribute based on a size change. Check in the stock creature .lua files; IIRC, each animal has two numbers for each entry: A percentage amount by which the part affects that trait, and a second number that tells (exponentially) how much to alter it with size.

    One of the devs detailed how they work a few days ago, I wish I could find that thread again...
    that would definately answer a great deal of our questions...

  25. #25
    Kaylum
    Guest
    Originally posted by GIMPbeowulf
    What I'm saying is that I don't think it goes by percentages.

    I think it's a value for each part that scales with size when apropriate.
    the end results of which could still be mapped out :call2:

    even if the value is unique for each creature, and not a simple over-arching formula that applies to them all: stating that a unicorn with a 100 health rating has 20 health on front legs, 20 health on rear legs, 50 health on the body, 10 health on the head and 0 health on its tail would still result in the ability to state:

    unicorn:
    head 10% of health
    body 50% of health
    legs 20% each
    tail 0%

    the simple fact of testing is that many of the creatures in the game do follow very similar trends in how their attributes are distrubuted among their body parts.

    expresing those trends as percentages allows us to see those guidelines and further understand the changes made to the creatures with unique attribute dispersion among their body parts.

    thus its easier to say the following Xcreatures all use Ymap for attributes; and than only list the ones that break from that mold rather than listing 50 duplicate body maps for every one unique animal.

  26. #26
    Stoo
    Guest
    Oh, sorry! The .lua files are compressed in the engine.sga file. You need Delphy's .sga extractor to get at them, look here. Install it, and open engine.sga with it. Then go into the /combiner directory. That's where the files that specify how the attributes are derived from the parts are.

    The animal.lua files (one for each of the 60-some) are in art/EBP/stock.
    (edit) Quinn explains how the numbers in there work here

    You could very well be right about the size differences being purely graphical, I agree after having looked at the files a bit.

    I'm sorry, I hadn't even thought that you guys wouldn't know about that. If you like, I can dissect the combiner files and go step-by-step in another post and say how each attribute and special is calculated. It might be faster than figuring out by experimentation.

  27. #27
    Kaylum
    Guest
    they are just lists. its going to take a long time to edit and compile it all into readable info.

    heres just the wolf:

    -- Wolf
    limbattributes = {
    isFromExcel = {1,1.0},
    ["endurance_bonus"]={1,0.15},
    ["size"]={1,2},
    ["sight_radius1"]={4,25},
    ["night_sight_radius"]={4,25},
    ["stocktype"]={1,1},
    ["armour-head"]={4,0.015},
    ["armour-front"]={2,0.03},
    ["armour-back"]={3,0.03},
    ["armour-torso"]={6,0.075},
    ["exp_armour"]={1,0},
    ["exp_dodge"]={1,-0.125},
    ["hitpoints-head"]={4,7.5},
    ["hitpoints-front"]={2,15},
    ["hitpoints-back"]={3,15},
    ["hitpoints-torso"]={6,37.5},
    ["exp_hitpoints"]={1,1.4},
    ["speed_mid-front"]={2,1.5},
    ["speed_mid-torso"]={6,2},
    ["speed_mid-back"]={3,1.5},
    ["exp_speed_mid"]={1,0.025},
    ["speed_max-front"]={2,13.2},
    ["speed_max-torso"]={6,6.6},
    ["speed_max-back"]={3,13.2},
    ["exp_speed_max"]={1,-0.18},
    ["airspeed_max-torso"]={6,0},
    ["airspeed_max-wings"]={7,0},
    ["exp_airspeed_max"]={1,-0.16},
    ["waterspeed_max-torso"]={6,0},
    ["waterspeed_max-tail"]={5,0},
    ["exp_waterspeed_max"]={1,-0.1},
    ["melee4_number"]={4,1},
    ["melee4_dmgtype"]={4,0},
    ["melee4_damage"]={4,8},
    ["melee4_rate"]={4,1.4},
    ["melee4_contact"]={4,0.5},
    ["melee4_name"]={4,5520},
    ["melee4_shortdesc"]={4,5521},
    ["melee4_longdesc"]={4,5522},
    ["melee_damage"]={1,8},
    ["exp_melee4_damage"]={1,0.6},
    ["stink_attack"]={5,0},
    ["electric_burst"]={5,0},
    ["charge_attack"]={3,0},
    ["frenzy_attack"]={0,0},
    ["plague_attack"]={4,0},
    ["quill_burst"]={6,0},
    ["can_dig"]={2,0},
    ["pack_hunter"]={0,1},
    ["herding"]={0,0},
    ["leap_attack"]={3,0},
    ["poison_touch"]={5,0},
    ["is_stealthy"]={5,0},
    ["is_immune"]={0,0},
    ["regeneration"]={0,0},
    ["keen_sense"]={4,1},
    ["sonar_pulse"]={4,0},
    ["end_bonus"]={6,1},
    ["end_penalty"]={6,0},
    ["front_foot_type"]={2,1},
    ["rear_foot_type"]={3,1},
    ["vocal_type"]={4,59},
    ["Hide_type"]={6,3},
    ["actbeselect"]={0,1},
    ["selection_sloppyness"]={6,0.5},
    ["boneblobshadow"]={0,1},
    ["simvis_occludee"]={0,1},
    ["singleselectonly"]={0,0},
    ["isvisible"]={0,1},
    ["fadeAndDeleteWhenDead"]={0,1},
    ["stayInPathfindingAfterDead"]={0,0},
    ["min_triangle_count"]={1,175},
    ["simterrain"]={0,0},
    ["simcollides"]={0,1},
    ["simfogged"]={0,1},
    ["combinervisible"]={0,1},
    ["minimap_enable"]={0,1},
    ["minimap_teamcolour"]={0,1},
    ["ghost_enable"]={0,0},
    ["tag_desc"]={1,24197},
    ["lefthalf_name"]={1,24198},
    ["righthalf_name"]={1,24199},
    }


    many of them do seem to have the same scalable breakdowns between body parts. which would seem to support the theory that they started with a basic pattern than tweaked each creature.

    anyway, someone feel like compiling them into a spreadsheet?
    heh

    -----

    a more interesting read is perhaps the attributecombiner.lua:

    -- attrCombiner.lua
    ----------------------------------------------------------------
    -- This file processes creature attributes for each combined creature. It...
    -- boundary-checks and fixes numerical attributes
    -- computes cost and rank based on attributes and abilities
    -- determines the rankings of attributes
    -- sets the ui display values
    ----------------------------------------------------------------

    function combine_creature()

    -- This needs to be solved in a better way. **SPECIAL CASE FOR SNAKE/SWIMMER COMBO BUG**
    if getgameattribute("speed_max") == 0 and
    getgameattribute("waterspeed_max") == 0 and
    getgameattribute("airspeed_max") == 0 then
    setgameattribute("speed_max",8.0)
    end

    -- Give Flyers minimum sight radius

    if ( getgameattribute("is_flyer") == 1 ) and
    ( getgameattribute("sight_radius1") < 25 ) then
    setgameattribute("sight_radius1",25.0)
    end


    -- Checks to see if creature has defense equal or higher than 75
    function has_high_defense()

    if (getgameattribute("armour")>0.74) then
    return 1
    else
    return 0
    end
    end

    -- Checks to see if creature has defense equal or higher than 85
    function has_really_high_defense()

    if (getgameattribute("armour")>0.84) then
    return 1
    else
    return 0
    end
    end


    -- These variables will be updated throughout the file.

    -- Total renewable resource cost of creature.
    CostRenew = 0;
    -- Total gatherable resource cost of creature.
    CostGather = 0;
    -- Final rank of creature. 0 = I, 1 = II, 2 = III, 3 = IV, 4 = V
    CreatureRank = 0;
    -- Minimum rank of creature, based on abilities.
    MinRank = 0;


    ----------------------------------------------------------------
    -- Utility functions.
    ----------------------------------------------------------------

    -- Set the game and ui attribute.
    function setattribute( attribute_string, value )
    setgameattribute(attribute_string,value);
    setuiattribute(attribute_string,value);
    end

    -- Find the first index i in an array of ascending values rank_upper_bounds for which x <= rank_upper_bounds[i].
    -- i.e. find the "rank" of the value x in the rank array.
    -- parameters:
    -- x - a number to find the rank of
    -- rank_upper_bounds - an array of nondescending upper bounds for each rank
    -- returns:
    -- the rank of x, i.e. the first index i such that x <= rank_upper_bounds[i], starting from i = 1
    -- if there is no such i, returns one more than the number of contiguous non-nil elements starting from 1 in the array.
    function Rank( x, rank_upper_bounds )
    -- Find where x falls in the array of ranges.
    local i = 1;
    while rank_upper_bounds[i] do
    if x <= rank_upper_bounds[i] then
    return i;
    end
    i = i + 1;
    end
    return i;
    end

    ----------------------------------------------------------------
    -- Attribute Bound Check and Rating
    ----------------------------------------------------------------

    -- Attribute data.

    -- Column ids.
    AT_Name = 1;
    AT_ZeroOK = 2;
    AT_Min = 3;
    AT_Max = 4;
    AT_RankList = 5;
    AT_UIName = 6;
    AT_UIScale = 7;

    -- Game attribute bound and rank data.
    AttributeData =
    {
    -- { attribute name, zero ok, min, max, rank list, ui attribute name, game->ui scale factor }

    { "hitpoints", nil, 1, 2000, {0.0, 90.0, 160.0, 240.0}, "health", 1 },
    { "armour", 1, 0, 0.9, {0.0, 0.15, 0.20, 0.35}, "armour", 100 },
    { "speed_max", 1, 8, 50, {0.0, 25.0, 35.0, 45.0}, "landspeed", 1 },
    { "waterspeed_max", 1, 8, 40, {0.0, 4.0, 6.0, 8.5}, "waterspeed", 1 },
    { "airspeed_max", 1, 8, 50, {0.0, 5.0, 15.0, 20.0}, "airspeed", 1 },
    { "sight_radius1", nil, 10, 1000, {0.0, 25.0, 35.0, 45.0}, "sightradius", 1 },
    { "size", nil, 1, 10, {0, 3, 6, 9}, "size", 1 },

    { "melee_damage", 1, 0, 1000, {0.0, 5.0, 9.0, 11.5}, "damage", 1 },
    --{ "range2_damage", 1, 0, 1000, {0.0, 1.0, 2.0, 3.0}, "range2_damage", 1 },
    --{ "range4_damage", 1, 0, 1000, {0.0, 1.0, 2.0, 3.0}, "range4_damage", 1 },
    { "range2_max", 1, 0, 35, {0.0, 5.0, 9.0, 16.0}, "range2_max", 1 },
    { "range4_max", 1, 0, 35, {0.0, 5.0, 9.0, 16.0}, "range4_max", 1 }
    };

    -- Apply boundaries and rank attributes.
    for k, at in AttributeData do

    local attribute = at[AT_Name];
    local val = 0;
    local rating = 1;

    if checkgameattribute( attribute ) == 1 then

    -- Boundary check and fix.
    val = getgameattribute( attribute );

    if not ( at[AT_ZeroOK] == 1 and val == 0 ) and at[AT_Min] and ( val < at[AT_Min] ) then
    setgameattribute( attribute, at[AT_Min] );
    val = at[AT_Min];
    end

    if at[AT_Max] and val > at[AT_Max] then
    setgameattribute( attribute, at[AT_Max] );
    val = at[AT_Max];
    end

    -- Ranking.
    if at[AT_RankList] then
    rating = Rank( val, at[AT_RankList] );
    end
    end

    if at[AT_UIName] then
    -- Add the rating to the creature's variable list -- rating is in the range [0-4].
    setattribute( at[AT_UIName].. "_rating", rating - 1 );
    -- Add the display version to the creature's variable list.
    setattribute( at[AT_UIName] .. "_val", val * at[AT_UIScale] );
    end

    end

    if checkgameattribute( "range2_damage" ) == 1 then
    val = getgameattribute( "range2_damage" );
    if (val and val > 0) then
    -- if this is artillyer
    --if (getgameattribute( "range2_special" ) > 0) then
    -- rating = Rank( val, {0.0,4.0,8.0,13.5} );
    -- setattribute( "range2_damage_rating", rating - 1 );
    -- this is direct range
    --else
    rating = Rank( val, {0.0,12.0,20.0,26.0} );
    setattribute( "range2_damage_rating", rating - 1 );
    --end
    setattribute( "range2_damage_val", val );
    end
    end

    if checkgameattribute( "range4_damage" ) == 1 then
    val = getgameattribute( "range4_damage" );
    if (val and val > 0) then
    -- if this is artillyer
    --if (getgameattribute( "range4_special" ) > 0) then
    -- rating = Rank( val, {0.0,4.0,8.0,13.5} );
    -- setattribute( "range4_damage_rating", rating - 1 );
    -- this is direct range
    --else
    rating = Rank( val, {0.0,12.0,20.0,26.0} );
    setattribute( "range4_damage_rating", rating - 1 );
    --end
    setattribute( "range4_damage_val", val );
    end
    end

    -- make sure flyers and swimmers don't have and are not charged for certain abilities

    if ( getgameattribute("is_flyer") == 1 ) then
    setgameattribute( "can_dig", 0 );
    setgameattribute( "leap_attack", 0 );
    setgameattribute( "charge_attack", 0 );
    end

    if ( getgameattribute("is_swimmer") == 1 and getgameattribute("is_land") == 0) then
    setgameattribute( "can_dig", 0 );
    end

    -- Give Flyers minimum sight radius

    if ( getgameattribute("is_flyer") == 1 ) and
    ( getgameattribute("sight_radius1") < 25 ) then
    setgameattribute("sight_radius1",25.0)
    end



    ----------------------------------------------------------------
    -- Attribute Costs
    ----------------------------------------------------------------

    hitpoints = getgameattribute( "hitpoints" );
    armour = getgameattribute( "armour" );
    sight_radius1 = getgameattribute("sight_radius1" );

    rangeRankModifier = 1.35;
    directCostModifier = 1.30;
    artilleryCostModifier = 1.75;

    -- melee damage
    damagem = getgameattribute( "melee_damage" );

    -- range2 damage
    damage2 = getgameattribute( "range2_damage" );
    -- tweak the ranking of damage from range units
    damage2rank = damage2 * rangeRankModifier;
    if (getgameattribute( "range2_special" ) > 0) then
    -- make artillery units cost a bit more
    damage2 = damage2 * artilleryCostModifier;
    else
    -- make direct range units cost a bit more
    damage2 = damage2 * directCostModifier;
    end

    -- range4 damage
    damage4 = getgameattribute( "range4_damage" );
    -- tweak the ranking of damage from range units
    damage4rank = damage4 * rangeRankModifier;
    if (getgameattribute( "range4_special" ) > 0) then
    -- make artillery units cost a bit more
    damage4 = damage4 * artilleryCostModifier;
    else
    -- make direct range units cost a bit more
    damage4 = damage4 * directCostModifier;
    end

    -- most damage of all types
    damage = max( damagem, max( damage2, damage4 ) );
    -- most damage_rank of all types
    damage_rank = max( damagem, max( damage2rank, damage4rank ) );


    speed_max = getgameattribute( "speed_max" );
    airspeed_max = getgameattribute( "airspeed_max" );
    waterspeed_max = getgameattribute( "waterspeed_max" );
    -- Charging only for the max speed. Electric cost can be added to flyers/swimmers to account for them having multiple modes of transportation
    speed = max( speed_max, max( airspeed_max, waterspeed_max ) );

    -- Power of the creature. Used to rank it.
    power = sqrt( damage_rank * hitpoints / ( 1-armour ) );

    -- Power of the creature, with the amount of armor reduced slightly to reduce the cost.
    power_less_armour = sqrt( damage * hitpoints/ ( 1- armour/1.5 ) );

    -- error check: checking speedcost to make sure it doesn't go below 0, if it does, setting it to 0. Without this error check anything with less than 20 speed gets a discount on it's other attributes because of it's low speed.

    speedCost = (speed * 2 - 40)
    if speedCost < 0 then
    speedCost = 0
    end

    -- setting costgather, right now we're adding speed as a flat value, but it should be some function of speed so we don't alter the cost effectiveness of units (large groups of small units are charged more for their speed than small groups of strong units if we add it as a flat value)
    CostGather = CostGather + ( 2.9 * power_less_armour ) + speedCost + ( 0.4 * sight_radius1 );

    -- Reduce cost if unit is a dedicated swimmer
    --if getgameattribute("speed_max") == 0 and
    -- getgameattribute("waterspeed_max") > 0 and
    -- getgameattribute("airspeed_max") == 0 then
    -- CostGather = CostGather * .75
    --end


    -- save this for later, just incase we do this special case thing
    SavedCostGather = CostGather

    ----------------------------------------------------------------
    -- Rank Calculations based on actual health, health, and defense
    ----------------------------------------------------------------

    if hitpoints/(1-armour) > 136 then
    MinRank = max(MinRank, 2);
    end

    if hitpoints/(1-armour) > 175 then
    MinRank = max(MinRank, 3);
    end

    if hitpoints/(1-armour) > 450 then
    MinRank = max(MinRank, 4);
    end


    --if hitpoints > 400 then
    -- MinRank = max(MinRank, 4);
    --end

    --if (has_really_high_defense()==1) then
    -- MinRank = max(MinRank, 4);
    --end


    ----------------------------------------------------------------
    -- Ranged Units Not Charged for Certain Abilities
    ----------------------------------------------------------------

    if (damage2>0) or (damage4>0) then
    setgameattribute( "charge_attack", 0 );
    setgameattribute( "leap_attack", 0 );
    end


    ----------------------------------------------------------------
    -- Ability Cost and Min Rank
    ----------------------------------------------------------------

    -- Ability type constants.
    ABT_Ability = 1;
    ABT_Melee = 2;
    ABT_Range = 3;

    -- Functions that are called with the ability id parameter and return a 1 if the ability is present.
    -- These correspond to the ability type constants above.
    ABT_CheckFunctions =
    {
    getgameattribute,
    hasmeleedmgtype,
    hasrangedmgtype
    };

    AB_AbilityType = 1;
    AB_Id = 2;
    AB_MinRank = 3;
    AB_CostRenew = 4;
    AB_CostGather = 5;

    AbilityData =
    {
    -- { ability_type, ability_id, minrank, costrenew, costgather }

    --{ ABT_Ability, "herding", 0, 45, 0 },
    { ABT_Ability, "pack_hunter", 0, 45, 0 },
    { ABT_Ability, "is_immune", 0, 15, 0 },
    { ABT_Ability, "keen_sense", 0, 10, 0 },
    { ABT_Ability, "quill_burst", 2, 30, 0 },
    { ABT_Ability, "regeneration", 0, 25, 0 },
    { ABT_Ability, "leap_attack", 2, 30, 0 },
    { ABT_Ability, "frenzy_attack", 2, 40, 0 },
    { ABT_Ability, "can_dig", 0, 10, 0 },
    { ABT_Ability, "plague_attack", 1, 50, 0 },
    { ABT_Ability, "sonar_pulse", 0, 30, 0 },
    { ABT_Ability, "is_swimmer", 2, 0, 0 },
    { ABT_Ability, "is_stealthy", 0, 30, 0 },
    { ABT_Ability, "charge_attack", 3, 30, 0 },
    { ABT_Ability, "is_flyer", 3, 75, 0 },
    { ABT_Ability, "electric_burst", 3, 75, 0 },
    { ABT_Ability, "stink_attack", 0, 50, 0, },
    { ABT_Ability, "poison_touch", 3, 50, 0 },
    --{ ABT_Ability, "end_bonus", 0, 35, 0 },


    { ABT_Range, DT_Electric, 2, 0, 0 },
    { ABT_Range, DT_Poison, 4, 35, 0 },
    { ABT_Range, DT_Sonic, 3, 60, 0 },
    { ABT_Range, DT_VenomSpray, 3, 35, 0 },

    { ABT_Melee, DT_BarrierDestroy, 0, 25, 0 },
    { ABT_Melee, DT_HornNegateArmour, 3, 50, 0 },
    { ABT_Melee, DT_HornNegateFull, 2, 40, 0 },
    { ABT_Melee, DT_Poison, 3, 50, 0 },
    };


    -- Total the costs and find min rank for all abilities.
    for n, ab in AbilityData do
    -- If we have this ability...
    if ABT_CheckFunctions[ab[AB_AbilityType]]( ab[AB_Id] ) == 1 then
    -- add on the costs.
    if ab[AB_CostRenew] then
    CostRenew = CostRenew + ab[AB_CostRenew];
    end
    if ab[AB_CostGather] then
    CostGather = CostGather + ab[AB_CostGather];
    end
    -- check for min rank.
    MinRank = max( MinRank, ab[AB_MinRank] );
    end
    end

    -- Checks to see if creature has ability that requires endurance
    function has_ability_requiring_endurance()

    if ( getgameattribute("stink_attack")==1 or
    getgameattribute("electric_burst")==1 or
    getgameattribute("sonar_pulse")==1 or
    getgameattribute("quill_burst")==1 or
    getgameattribute("frenzy_attack")==1 or
    getgameattribute("plague_attack")==1) then
    return 1
    else
    return 0
    end
    end

    -- if this creature has high endurance
    if (getgameattribute("end_bonus")==1) then

    -- check for triggered abilities that cost endurance
    if (has_ability_requiring_endurance()==1) then
    CostRenew = CostRenew + 35
    else
    CostRenew = CostRenew + 5
    end

    end

    -- if this creature has over 75 defense with herding ability
    if (getgameattribute("herding")==1) then
    if (has_high_defense()==0) then
    CostRenew = CostRenew + 45
    else
    CostRenew = CostRenew + 0
    end
    end



    -----------------------------------------------------------------------------
    -- Adding cost for All Range Creatures.

    -- used to determine whether the range type is splash damage
    function get_range_var( limb, var )

    local str = "range"..limb.."_"..var

    if checkgameattribute(str) == 1 then
    return getgameattribute( str )
    end

    return 0;
    end

    function range_artillerytype( limb )

    -- if this creature has a special field it has artillery
    return get_range_var( limb, "special");

    end

    -- These will be set to flag if the creature has any direct or any artillery range attack.
    has_direct = nil;
    has_artillery = nil;

    if (damage2>0) then
    -- if not artillery range
    if (range_artillerytype(2)==0) then
    has_direct = 1;
    CostRenew = CostRenew + 40;
    else
    has_artillery = 1;
    CostRenew = CostRenew + 40;
    end
    -- all range is at least rank 2
    if (MinRank < 2) then
    MinRank = 2;
    end
    end

    if (damage4>0) then
    -- if not artillery range
    if (range_artillerytype(4)==0) then
    has_direct = 1;
    CostRenew = CostRenew + 40;
    else
    has_artillery = 1;
    CostRenew = CostRenew + 40;
    end
    -- all range is at least rank 2
    if (MinRank < 2) then
    MinRank = 2;
    end
    end

    -- Does creature have flight and range artillery?
    if (getgameattribute( "range2_special" ) > 0) and ( getgameattribute("is_flyer") == 1 ) then
    CostRenew = CostRenew + 0;
    end

    if (getgameattribute( "range4_special" ) > 0) and ( getgameattribute("is_flyer") == 1 ) then
    CostRenew = CostRenew + 0;
    end

    -- actual hit point cap for artillery units
    if hitpoints/(1-armour) > 500 and has_artillery == 1 then
    MinRank = max(MinRank, 5);
    end



    ----------------------------------------------------------------
    -- Ranking
    ----------------------------------------------------------------

    -- These values are power ratings, the values divide the creatures up so that rank 1 has 35% of the creatures, rank 2 and 3 20% each, rank 4 15% and rank 5 10%

    -- Non-flyer specific power rankings
    if (airspeed_max == 0) then
    melee_rank_cmp = { 26.6, 39.2, 60, 105 };
    direct_rank_cmp = { 26.6, 39.2, 56.3, 90 };
    artillery_rank_cmp = { 26.6, 39.2, 56.3, 100 };

    -- Flyer specific power rankings
    else
    melee_rank_cmp = { 26.6, 39.2, 65, 115 };
    direct_rank_cmp = { 26.6, 39.2, 65, 115 };
    artillery_rank_cmp = { 26.6, 39.2, 65, 115 };
    end



    CreatureRank = Rank( power, melee_rank_cmp );

    -- Do rank calculations for range creatures

    if has_direct then
    CreatureRank = max( CreatureRank, Rank( power, direct_rank_cmp ) );
    end
    if has_artillery then
    CreatureRank = max( CreatureRank, Rank( power, artillery_rank_cmp ) );
    end

    -- cap the rank to a minimum value
    if CreatureRank < MinRank then
    CreatureRank = MinRank;
    end

    ----------------------------------------------------------------
    -- Commit aggregate attributes.
    ----------------------------------------------------------------

    setattribute( "creature_rank", CreatureRank )
    setattribute( "costrenew", CostRenew );
    setattribute( "cost", CostGather );
    setattribute( "buildtime", 10 );

    if (CreatureRank==1) then
    setgameattribute( "constructionticks", 32 );
    end
    if (CreatureRank==2) then
    setgameattribute( "constructionticks", 48 );
    end
    if (CreatureRank==3) then
    setgameattribute( "constructionticks", 64 );
    end
    if (CreatureRank==4) then
    setgameattribute( "constructionticks", 80 );
    end
    if (CreatureRank==5) then
    setgameattribute( "constructionticks", 96 );
    end

    setattribute( "popsize", 1 )

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


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


    end

  28. #28
    The Duke Nukem
    Guest
    Oh, sorry! The .lua files are compressed in the engine.sga file. You need Delphy's .sga extractor to get at them, look here. Install it, and open engine.sga with it. Then go into the /combiner directory. That's where the files that specify how the attributes are derived from the parts are.

    The animal.lua files (one for each of the 60-some) are in art/EBP/stock.
    (edit) Quinn explains how the numbers in there work here

    You could very well be right about the size differences being purely graphical, I agree after having looked at the files a bit.

    I'm sorry, I hadn't even thought that you guys wouldn't know about that. If you like, I can dissect the combiner files and go step-by-step in another post and say how each attribute and special is calculated. It might be faster than figuring out by experimentation.
    Silly me, lol. I guess I should look around the RDN forums more often. I just searched my ic directory for .lua files and didn't find anything. Most of the stuff Quinn said we had already figured out, but he failed to explain how stats are calculated for swimmers, snakes, birds etc.

    About the files in engine.sga: Hmm, I'm afraid I simply don't have the time to go through all that. Figuring stuff out by experimentation works fine for me . Although I suppose we might have to look at that for a more detailed analasys (i. e. if we were going to make a faq).



    Anyway, to add to our list of observations, fliers get a sight radius bonus .

  29. #29
    PaladinKing
    Guest
    It's pretty easy to write a program to generate a table for each creature from those files, but who's going to read those. To my surprise they did override the base rules quite a bit. May be that's why the game seems well balanced out.

  30. #30
    StrategicLearnr
    Guest

    Keen sense and digging

    I experimented areound with digging-scouts. as many know when you dig your creature into the ground the sight radius decreases.

    I noticed that keen sense negates this! Meaning that once dug in the sight radius stays the same. Experiment: Ant + Wolf or Eagle. Compare to Ant + anything else without keen sense.

  31. #31
    neutrino_cannon
    Guest

    Re: Keen sense and digging

    Originally posted by StrategicLearnr
    I experimented areound with digging-scouts. as many know when you dig your creature into the ground the sight radius decreases.

    I noticed that keen sense negates this! Meaning that once dug in the sight radius stays the same. Experiment: Ant + Wolf or Eagle. Compare to Ant + anything else without keen sense.
    That's worth knowing. Bring on the ant-eagles!

    It seems that the raven has an abnormal amount of speed scripted to the wings, but runs into a speed cap at 35 kph. The bloody hornet is just barely able to keep up.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •