I have some very wierd things going on in my codebase. Unexplainable things. WTF moments!!!

Hi,

I need some help understanding how some of the things that I've coded fail for unexplainable reasons; ie its not a syntax error, or a logic error, or a runtime error; it just fails. I have a few examples:

  1. I had wanted to add Shield Spikes and Armor Spikes into my RPG/Text Adventure Hybrid. All the necessary code was there to work properly. When I went to test it, the game would properly apply Armor Spikes, but when I tried to do the same with Shield Spikes, it failed to work. The code used to apply armor spikes, is the exact same as the code to apply shield spikes; I checked in both the UI and code view and they were identical. I deleted a variable in the Shield Spike code. I then re-added the exact same variable (checked in UI and code view and it was identical) and then suddenly the code works. If it was a syntax error or logic error or runtime error on my part I would understand that, but when I tried to apply the shield spike initially, no error report occurred and none of the code activated. Why?

  2. I have code that does a variety of conditional checks when I perform melee attacks. If a melee attack doesn't do sufficient damage because enemy armor is too high, it will produce the message; "you hit the target but failed to penetrate their armor." And that is that. However, when testing the game yesterday, I had performed a few shield bashes on a foe. The first 3 bashes properly produced this message, but the 4th, and the 5th and 6th, instead stated, "You hit the target and did -11 damage to the target" (this as I'm sure you are aware heals the target instead of damaging them). The code is setup however to prevent this (I checked thoroughly for logic errors and there are none) and nothing should affect the enemy's health variable when you fail to penetrate their armor and as -11 is NOT > their protection value, it should have continued to give "failed to penetrate armor." Why?

  3. I had a friend playtest my game and he ran into a situation that I deem impossible, but yet it happened. In my game, you start out in a room to create your character. Then you use a command "begin" that will transfer the player out of the room and into the actual game-playing area. Other than this command, which is a one-way command, you cannot in the code EVER get back to this room. All of the scripts for character generation are built directly into the room's description and aren't found anywhere else. Some how, while going through the dungeon proper, he managed to get teleported into the character generation room again OR the script from the character generation room magically transferred into the dungeon room, and he was prompted for his name and race again. And as race determines starting stats, he got a large boost in health and mana from choosing his race again. I don't know how he could have managed it to get back into the start room or how the start room script which is coupled with the start room's description managed to get into the dungeon room. I'm completely baffled at what is going on right now. In all my 30+ hours of playtesting my own game I've never encountered this. What the hell is going on?


We would need to see your game code to be able to offer any useful advice. Could you pastethe relevant bits into a post (click on Code View, and paste that in).


INB4 comments about nesting: Up to this point, I've had no issues with it and as I can personally read my own code and follow the logic around I've not bothered to refactor it yet. As it had done it job flawlessly before, and was a much more elegant and efficient solution than I had with previous attempts, that's why I have so many nested If/Elses. And as I've had more pressing work with fixing bugs and adding in content for my playtesters, its not been on my priority list to refactor it.

Here is the shield bash code:

  if ((player.TotalAccuracy + getrandomint(1,10)) > (object.Dodge + getrandomint(1,10))) {
    if (((player.ShieldProtection + player.ShieldEnchantment + player.AttributeStrength + player.ShieldSpikeDamage) * Spellbook.ForceShieldMultiplier) > object.Protection) {
      object.CurrentHP = object.CurrentHP - (((player.ShieldProtection + player.ShieldEnchantment + player.AttributeStrength) * Spellbook.ForceShieldMultiplier) - object.Protection)
      msg ("You bash the " + object.alias + "  with your " + player.SpikedString + " " + player.EquippedShield + " and inflict " + ((player.ShieldProtection + player.ShieldEnchantment + player.AttributeStrength - object.Protection) * Spellbook.ForceShieldMultiplier) + " damage, reducing the " + object.alias + "'s health to " + object.CurrentHP + ".")
      player.BashPenalty = (player.Level * 2 + player.ShieldEnchantment) * (Spellbook.ForceShieldMultiplier)
      player.StrengthTraining = player.StrengthTraining + 50 + (player.DepthLevel * 10)
      if (player.BracersLeech = true) {
        object.CurrentHP = object.CurrentHP - (player.Level)
        player.CurrentHP = player.CurrentHP + (player.Level)
        if (player.CurrentHP > player.MaximumHP) {
          player.CurrentHP = player.MaximumHP
        }
        msg ("You leech life from the " + object.alias + " and your health is restored and set to = " + player.CurrentHP + ".")
      }
    }
    else {
      msg ("You hit the " + object.alias + " with your " + player.SpikedString + " " + player.EquippedShield + ", but you fail to penetrate their armor.")
      SetObjectFlagOn (player, "Bash")
      player.StrengthTraining = player.StrengthTraining + 200 + (player.DepthLevel * 10)
      if (player.BracersLeech = true) {
        object.CurrentHP = object.CurrentHP - (player.Level)
        player.CurrentHP = player.CurrentHP + (player.Level)
        if (player.CurrentHP > player.MaximumHP) {
          player.CurrentHP = player.MaximumHP
        }
        msg ("You leech life from the " + object.alias + " and your health is restored and set to = " + player.CurrentHP + ".")
      }
    }
    player.PerceptionTraining = player.PerceptionTraining + 50 + (player.DepthLevel * 10)
  }
  else {
    msg ("You swing your " + player.SpikedString + " " + player.EquippedShield + " and miss the " + object.alias + ".")
    player.PerceptionTraining = player.PerceptionTraining + 200 + (player.DepthLevel * 10)
  }
}
else {
  msg ("You don't have a shield equipped, and thus you can't do a bash!")
  SetObjectFlagOn (player, "ActionCancelled")
}```

Here is the shield spike code that will apply the spikes:

```if (ListContains(ScopeVisible(), ShieldTower)) {
  if (ShieldTower.SpikesApplied = true) {
    msg ("Your tower shield already has armor spikes!")
  }
  else {
    if (player.SoulShards > 999) {
      msg ("<br/>You purchase shield spikes for your tower shield.")
      player.SoulShards = player.SoulShards - 1000
      ShieldTower.SpikesApplied = true
    }
    else {
      msg ("You don't have enough soul shards. You only have " + player.SoulShards + " soul shards. You need " + (1000) + " soul shards!")
    }
  }
}
else {
  msg ("You aren't carrying a Tower Shield.")```

And the second part of it (as this just sets the variable; which ironically is the exact variable that was giving me trouble) that applies the spike damage effects:

```player.ShieldProtection = ShieldTower.Protection
player.ShieldEnchantment = ShieldTower.Enchantment
player.ShieldEnhancement = ShieldTower.Enhancement
if (ShieldTower.SpikesApplied = true) {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0) + ShieldTower.Protection + ShieldTower.Enchantment + ShieldTower.Enhancement
  player.SpikedString = "Spiked"
}
else {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0)
  player.SpikedString = ""
}```

If it is relevant; the code to apply the spike is within a "command" while the code to apply the damage is within a "turnscript".

Finally the last issue; here is the code that is used for character generation:

```msg ("<br/>What is your name? Please type it in and hit enter.<br/>")
get input {
  player.PlayerName = result
  msg ("Your name is = <b>" + result + "</b>.")
  msg ("<br/><b>Whenever the game requests input, type in a choice, verbatim, within the ( ).</b> <br/>You can play your character as you like, and you can define your own personal playstyle. You only choose your race at the start.<br/><br/><u>Dwarves</u> start with 90 HP and 10 MP. They start with a Longsword, Tower Shield and Platemail. They don't know any spells, initially. They make great pure-combat characters.<br/><br/><u>Quicklings</u> start with 70 HP and 30 MP. They start with a Shortsword, Buckler and Leather. They know Arcane Zap and Minor Healing spells. They make great pure-assasin characters.<br/><br/><u>Humans</u> start with 40 HP and 60 MP. They start with a Staff and Robes. They know all spells in the first tier. They make great pure-spellcaster characters.<br/>")
  msg ("<b>Races</b> = Please enter one of the following options as your chosen race.<br/>Dwarves (<b>dwarf</b>) [high strength and vitality], Quicklings (<b>quick</b>) [high agility and perception], or Humans (<b>human</b>) [high intellect and willpower]<br/>")
  get input {
    switch (result) {
      case ("dwarf") {
        msg ("You choose to be a <b>Dwarf</b>! You start out with a longsword, tower shield, platemail, and no known spells.")
        player.Race = "Dwarf"
        player.AttributeStrength = 10
        player.AttributeAgility = 5
        player.AttributeVitality = 10
        player.AttributeIntellect = 5
        player.AttributeWillpower = 5
        player.AttributeLuck = 5
        player.AttributePerception = 5
        player.MaximumHP = player.MaximumHP + (89)
        player.MaximumMP = player.MaximumMP + (9)
        player.CurrentHP = player.MaximumHP
        player.CurrentMP = player.MaximumMP
        AddToInventory (WeaponLongsword)
        AddToInventory (ShieldTower)
        AddToInventory (ArmorPlatemail)
        player.EquippedWeapon = "Longsword"
        player.EquippedShield = "Tower Shield"
        player.EquippedArmor = "Platemail"
      }
      case ("quick") {
        msg ("You choose to be a <b>Quickling</b>! You start out with a shortsword, buckler, leather armor, and you know the Minor Healing and Arcane Zap spells.")
        player.Race = "Quickling"
        player.AttributeStrength = 5
        player.AttributeAgility = 10
        player.AttributeVitality = 5
        player.AttributeIntellect = 5
        player.AttributeWillpower = 5
        player.AttributeLuck = 5
        player.AttributePerception = 10
        player.MaximumHP = player.MaximumHP + (69)
        player.MaximumMP = player.MaximumMP + (29)
        player.CurrentHP = player.MaximumHP
        player.CurrentMP = player.MaximumMP
        AddToInventory (WeaponShortsword)
        AddToInventory (ArmorLeather)
        AddToInventory (ShieldBuckler)
        player.EquippedWeapon = "Shortsword"
        player.EquippedArmor = "Leather"
        player.EquippedShield = "Buckler"
        Spellbook.KnowMinorHealing = true
        Spellbook.KnowArcaneZap = true
      }
      case ("human") {
        msg ("You choose to be an <b>Human</b>! You start out with a staff and robes, and you know all first tier spells!")
        player.Race = "Human"
        player.AttributeStrength = 5
        player.AttributeAgility = 5
        player.AttributeVitality = 5
        player.AttributeIntellect = 10
        player.AttributeWillpower = 10
        player.AttributeLuck = 5
        player.AttributePerception = 5
        player.MaximumHP = player.MaximumHP + (39)
        player.MaximumMP = player.MaximumMP + (59)
        player.CurrentHP = player.MaximumHP
        player.CurrentMP = player.MaximumMP
        AddToInventory (ArmorRobes)
        AddToInventory (WeaponStaff)
        MoveObject (WeaponLongsword, XXWeapons)
        player.EquippedWeapon = "Staff"
        player.EquippedArmor = "Robes"
        Spellbook.KnowMinorHealing = true
        Spellbook.KnowArcaneZap = true
        Spellbook.KnowFirebolt = true
        Spellbook.KnowMinorAid = true
        Spellbook.KnowAnalysis = true
      }
      default {
        msg ("Incorrect input. However, all is not lost. When you type the \"begin\" command, you will be prompted again for race input and until you enter a correct input, you cannot start the game. ")
        player.Race = "Unknown"
      }
    }
    msg ("<br/>Are you a new player? (<b>yes</b>) or (<b>no</b>)<br/>")
    get input {
      switch (result) {
        case ("yes") {
          msg ("<u>As a new player, these are the commands accepted by the text parser, with conditions for usage of each command.  The commands are listed in the ( ) :</u><br/>")
          msg ("(<b>help</b>) = Whenever you are in need of help, just type = help. Will provide you with a variety of useful information. Additionally, it will also tell you how to get back to this command list!<br/>")
          msg ("(<b>explore</b>) = When you are in the actual \"dungeon\", this will generate a new room on the floor you are on. You can only explore when the room is empty of hostiles. If you explore the surface, you will discover a Stairwell going Down, which will allow you to enter the sewers.<br/>")
          msg ("(<b>ascend</b>) = When you aren't in combat and are at a Stairwell going Up, you can go up a floor. You find stairwells randomly.<br/>")
          msg ("(<b>descend</b>) = When you aren't in combat and are at a Stairwell going Down, you can go down a floor. You find stairwells randomly. Additionally, if you are on the surface/in the Capital City, you can descend into the sewers, as there is always a Stairwell going Down on the surface/in the Capital City.<br/>")
          msg ("(<b>look at spellbook</b>) = This allows you to view all your known spells, their effects, and if they can be cast in combat or not. You can look at your spellbook at any time.<br/>")
          msg ("(<b>look at satchel</b>) = This allows you to view how many healing/mana potions are carried and how many enchanting orbs or enhancement kits you have on hand. You can look at your satchel at any time.<br/>")
          msg ("(<b>unequip \"item\"</b>) or (<b>equip \"item\"</b>) = These commands allow you to, unequip or equip items in your inventory. Replace \"item\" with the name of an item, lower-case. You cannot equip items in combat, but you can unequip them in combat.<br/>")
          msg ("(<b>enchant \"item\"</b>) or (<b>enhance \"item\"</b>) = These commands allow you to enchant an item with enchanting orbs or enhance an item with enhancement kits. Again, replace \"item\" with the name of an item, lower-case. Enchanting and Enhancing cannot be performed in combat.<br/>")
          msg ("(<b>drink healing potion</b>) or (<b>drink mana potion</b>) = This asks you how many potions you wish to drink and you drink that many concurrently. The game will tell you what your maximum HP or MP is before you drink potions. Can be performed at any time.<br/>")
          msg ("(<b>buy</b>) or (<b>sell</b>) or (<b>salvage \"item\"</b>) = These are commands you can perform at the surface (the Capital City) or at a shrine found randomly in the dungeon, when not in combat. You trade with the Celestial and entering in one of the commands should be self-explanatory, depending on the command chosen. Buy allows you to spend soul shards for stuff you want. Sell allows you to sell items in your satchel for soul shards. Salvage allows you to convert an old, unused item into soul shards, but you cannot perform salvaging on equipped items.<br/>")
          msg ("(<b>cast \"spell\"</b>) = This command allows you to cast non-combat spells and combat versions of non-combat spells; ie Aid is the combat version of Healing. Combat spells will result in the enemy retaliating as usual. Replace \"spell\" with the name of a spell you want to case, all lower-case. If you lack the mana to cast a spell, the action will be cancelled and you won't get attacked.<br/>")
          msg ("(<b>attack \"target\"</b>) = This command allows you to perform mundane attacks or sneak attacks. For most actions, you can cancel it and thus avoid getting attacked. However, if you follow through on an attack, you will get retaliated against, unless you manage to kill them first. Replace \"target\" with part of the name of target; the game engine is fairly flexible and thus you can choose a shortened target name and it will find it acceptable; if it doesn't, nothing will happen and you won't get attacked.<br/>")
          msg ("(<b>flee from \"target\"</b>) = This command allows you to flee from a target that you either don't want to fight or you don't think you can beat. If it is the first round, which means you've not tried attacking it yet, then you can flee without it getting a chance to attack you. Otherwise, it gets one opportunity to attack you if you try to flee. Fleeing will generate a new room, much like the command (<b>explore</b>) does. Again, replace \"target\" with the name of the creature you are fighting.<br/>")
          msg ("(<b>setup camp</b>) = This command allows you to regain much needed HP and MP. If you perform the action in the Capital City or at a shrine, you will restore 100% of both HP and MP. If you do it anywhere else, you regain 5 * current floor level for both HP and MP, and you will get attacked by a wandering monster. Thus, it is often best to wait until you can find a shrine, and then sleep there than to try doing it anywhere else. <br/>")
          msg ("(<b>investigate \"object\"</b>) = When you have defeated the monster, often there will be objects in the room, listed under Points of Interest, that can be investigated. Each object has three outcomes: 1) Nothing good/bad with a small chance for loot. 2) Extremely good with lots of loot. 3) A trap of some kind, with decent loot.<br/>")
          msg ("(<b>save</b>) = Saves the game, nuff said. <br/>")
          msg ("(<b>storytime</b>) = Currently only gives the player the background story to why they are here doing what they are doing. <br/>")
          msg ("(<b>cast \"spell\" at \"target\"</b>) = Casts a combat spell at an enemy target. Replace \"spell\" with the name of the spell and \"target\" with your intended target. Again, the text parser is fairly flexible and will accept a shortened version of the target's name. Ex: if the target is \"Primal Chaos Rat\", the parser would accept \"Primal\" just fine by itself. You only get retaliated against if you spend the mana to cast it, otherwise it is cancelled.<br/>")
          msg ("(<b>look</b>) = Currently only is useful in the starting area of the game, which is the surface area, or Capital City. In the future, it will be added to to provide additional functions useful to gameplay.<br/>")
          msg ("(<b>buy \"thing\"</b>) = An alternative method to the buy command. If you know precisely what you want to buy with your soul shards, you can use this command to quickly go to the type of purchase you desire. Replace \"thing\" with the menu option you would have been given if you had used the buy command. So, if you knew you wanted training, you would type = <b>buy training</b>. You also also directly buy consumables, if you know precisely which one you want by typing = <b>buy healing potion</b> or <b>buy mana potion</b> or <b>buy enchanting orb</b> or <b>buy enhancement kit</b> <br/>")
          msg ("(<b>sell \"thing\"</b>) = An alternative method to the sell command. If you know precisely what you want to sell, you can use this command to quickly go to the type of sale you desire. Replace \"thing\" with the menu option you would have been given if you had used the sell command. So, if you knew you wanted sell healing potions, you would type = <b>sell healing</b><br/>")
          msg ("(<b>inspect \"orb\"</b>) = If you couldn't decide which boss artifact to choose or you entered an incorrect input, this command will allow you to choose an artifact from a chaos orb carried in your inventory. Replace \"orb\" with the name of the Chaos Orb in your inventory. Additionally, until you make a valid artifact choice, the orb will remain in your inventory; once you've made a choice, it will disappear.<br/>")
          msg ("(<b>analyze \"target\"</b>) = While the spell \"Analysis\" is active, you can use this command. By replacing \"target\" with the name of the creature in the room, you will get a detailed analysis of all their statistics, to make informed decisions. Using this command is a free action and will not result in retaliation from the monster.")
          msg ("<br/>You can view these commands at any time during the game by typing: (<b>display info</b>) and then type (<b>commands</b>).<br/><br/>If you want to, you can also take a look at the gameplay tips! You can view them by typing: (<b>display info</b>) and then (<b>gameplay tips</b>).<br/><br/>The command (<b>storytime</b>) is used currently to give you the backstory.<br/><br/>The command (<b>help</b>) is used when you need help.<br/><br/><b>Game Tip: Whenever you use a command with \"target\" in the name, you do not need to use the target's full name. So if you attacked a Giant Crocodile, you could simply type \"attack giant\".</b><br/><br/>Type (<b>begin</b>) when ready to play the game.")
        }
        case ("no") {
          msg ("The command (<b>display info</b>) is extremely useful.<br/>The command (<b>save</b>) will save your game.<br/>The command (<b>explore</b>) is used to explore new areas.<br/>The command (<b>storytime</b>) is used currently to give you the backstory.<br/>The command (<b>help</b>) is used when you need help.<br/><br/><b>Game Tip: Whenever you use a command with \"target\" in the name, you do not need to use the target's full name. So if you attacked a Giant Crocodile, you could simply type \"attack giant\".</b><br/><br/>Type (<b>begin</b>) when ready.<br/>")
        }
        default {
          msg ("The command (<b>display info</b>) is extremely useful.<br/>The command (<b>save</b>) will save your game.<br/>The command (<b>explore</b>) is used to explore new areas.<br/>The command (<b>storytime</b>) is used currently to give you the backstory.<br/>The command (<b>help</b>) is used when you need help.<br/><br/><b>Game Tip: Whenever you use a command with \"target\" in the name, you do not need to use the target's full name. So if you attacked a Giant Crocodile, you could simply type \"attack giant\".</b><br/><br/>Type (<b>begin</b>) when ready.<br/>")
        }
      }
    }
  }
}```

If you want to see these in action, V3 is up in the WIP section of the Quest Games here, under the name Cataclysm of Chaos.

The forums won't let me update my post, to break up the code. Keeps telling me "You can't post that here" whenever I hit update. Sorry!


With regard to the "failed to penetrate their armor" message, you calculate the damage inflicted 3 times.

  1. for the 'if' statement that determines whether to display the "failed to penetrate their armour" message
  2. To display the "You hit the target and inflict XX damage" message
  3. To actually reduce the enemy's HP.

Comparing the 3 formulae side by side (with names abbreviated for ease of comparison):

Case 1: ((ShieldProtection + ShieldEnchantment + Strength + SpikeDamage) * ForceShieldMultiplier) > Protection
Case 2: ((ShieldProtection + ShieldEnchantment + Strength - Protection) * ForceShieldMultiplier)
Case 3: ((ShieldProtection + ShieldEnchantment + Strength) * ForceShieldMultiplier) - Protection

It will display a negative damage if ((ShieldProtection + ShieldEnchantment + Strength + SpikeDamage) * ForceShieldMultiplier) is greater than the target's Protection, but ShieldProtection + ShieldEnchantment + Strengthis not.


...

Thanks for finding the logic error with the shield bash. That will solve that issue. Thanks!

And for indirectly helping me find another logic error XD; the object protection should be subtracted after force shield multiplication occurs, not before.

What about the other two?


not sure if this helps, but:

your use of 'getrandomint (MIN, MAX)' Function is wrong, it's:

GetRandomInt (MIN, MAX)

as quest is case sensitive


also, if you use a Function or Object+Script_Attribute+Delegate, aka have/use Arguments/Parameters, than you can assign the Objects into your scripting, for super simple example, using a Function:

<game name="example_game">
  <attr name="start" type="script">
    attack_function (player, orc)
    attack_function (orc, player)
  </attr>
</game>

<object name="room">
</object>

<object name="player">
  <attr name="parent" type="object">room</attr>
  <attr name="damage" type="int">50</attr>
  <attr name="current_life" type="int">999</attr>
</object>

<object name="orc">
  <attr name="parent" type="object">room</attr>
  <attr name="damage" type="int">25</attr>
  <attr name="current_life" type="int">500</attr>
</object>

<function name="attack_function" parameters="attacker, defender">
  defender.current_life = defender.current_life - attacker.damage
</function>

I've noticed that Quest is fairly case-sensitive. But, in this case it still properly produces an integer number within the range specified. It might have something to do with the most recent update, as the update also made it so that you don't have to type the full object's name to trigger code. ie If you are in combat with a giant crocodile, you could type "attack gia" and it will apply the combat code to the giant crocodile.

Functions can make things easier to read, but it means taking time away from developing content or addressing bugfixes. And as I'm the only one adding things to the code, and I can read my crazy nested ifs, and they do do what I want them to do properly, I've just not gotten around to refactoring the code into function calls. I know I have to refactor my cast #text# (one of my spellcasting systems) so I'll experiment with function calls there; if they really make my life easier, I'll look into implementing them elsewhere.

EDIT: Also updated my game with a third hotfix, fixing the Shield Bash logic errors and a bunch of other stuff. Hopefully the other weird edge cases don't prop up again. If anyone has an idea of why they cropped up, I might be able to design failsafes to prevent them from happening... if they happen.


also, I think you got a mistake here:

if (ShieldTower.SpikesApplied = true) {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0) + ShieldTower.Protection + ShieldTower.Enchantment + ShieldTower.Enhancement
  player.SpikedString = "Spiked"
}
else {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0)
  player.SpikedString = ""
}

as, I think you want it like this:

(or whatever the Value you want, instead of my use of '1')

if (ShieldTower.SpikesApplied = true) {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 1) + ShieldTower.Protection + ShieldTower.Enchantment + ShieldTower.Enhancement
  player.SpikedString = "Spiked"
}
else {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0)
  player.SpikedString = ""
}

Nope, I want to properly reset the value to 0. That is intentional.

Its that way because there are a variety of things that will change the other values in that calculation, and thus you will have a rampant addition problem if the base value isn't reset to 0. Its also that way in the rare chance that a junk value is assigned to the memory address (which can happen, rarely) or the junk value already in the memory address isn't properly replaced. This is to ensure that every time this turn script is run, that it is always dealing with a fresh calculation each time.


about getting back into your character_creation/dungeon rooms:

Do you have a 'warp/teleport' spell functionality/effect in your game? for example

<command name="example_command">
  <pattern>warp #text#</pattern>
  <script>
    example_function (text)
  </script>
</command>

<function name="example_function" parameters="destination">
  player. parent = GetObject (text)
</function>

Nope. The only functionality I have is modifying player Depth Level, by using Ascend or Descend commands at appropriate staircases... but all of that if built for the dungeon room and not the character generation room.


if you want some ideas, you can take a look at my old combat code (this is based off of Pertex' Combat code, and with Pertex' help too, so all credit goes to him):

(this is back when I was learning combat coding for the first time, so there's lots of inefficiencies, as well as a mistake with getting my 'pd' and 'pr' mixed up, lol ---- I've learned to never ever use abrevs ever again, lol, and also I have a lot of un-needed boolean variable flags in it --- you might want to download pertex' download link of fixing up my combat code in his post, if it still works. Otherwise, you can just ask me about anything about my code you don't understand and/or that doesn't work with it)

(if you can understand/follow it... as I myself have a hard time understanding/following other peoples' code, as you can tell from my attempts at trying to help you with your code, not understanding how it works, and thus I point out stuff that's not wrong in my attempt at trying to find possible causes for why your code isn't working):

https://textadventures.co.uk/forum/quest/topic/3348/noobie-hks-help-me-thread#22483
https://textadventures.co.uk/forum/quest/topic/3348/noobie-hks-help-me-thread#22486 (key/legend for all of my abrevs --- I've learned since to NEVER ever use abrevs ever again, lol)


Question though: If I were to market it commercially, wouldn't that mean I'd be inadvertently stealing your copyright to your combat code, if I were to adapt it to work with mine? When doing projects completely for fun, copyrights rarely matter (unless it is Nintendo product ofc as they are a-nal about their stuff), but if I were to sell it (as my text adventure I think is quite different from most text-adventures, though I could be wrong about that) I'd want to do things right, use my own stuff, and not steal from someone else (even though that does seem to be a trend in the gaming industry of stealing other people's ideas)

I am open to learning more and improving upon my code to be both more elegant, efficient, and effective. I just don't want to steal other people's works, as I deem that unethical.

Thoughts?

EDIT:

Took a look at the code, and could read through most of it without needing to use your abbreviation list. The only thing that really caught my eye was the concept of "extra actions". That intrigues me. Otherwise the combat code is too simple for my needs.

  1. I have situations where attacks apply debuffs to enemies or different attack types with different benefits/drawbacks and are each situationally useful, depending on the creature you are fighting.
  2. I have a first-round mechanic that allows a player to sneak attack a foe if they succeed at their stealth roll OR they can sneak out of the room if they don't think they can defeat the creature as long as it is the first round.
  3. I have some spells that prevent monster retaliation, such as Invisibility, or a spell called Terrify, to chase it out of the room without fighting it.
  4. I have a lot of actions that I want to be deemed "free" actions and thus can perform as many of them as you like in a round as you like, while I have other actions that cause a retaliation. I couldn't tell with your code if the monster retaliates whenever a round passes or not.

However, it does look a lot easier to read than my code.


well, you'd have to ask Pertex if it's alright, as my code is based upon some of his combat coding structure, it's his design, not mine

in general... programmers (in non-illegal ways) 'plagerize' code all of the time, as "why re-invent the wheel".

the legality however of it is complex, including in terms of coding IP... if you can manipulate it enough and use it in an unique-enough way, in that it is "your unique design", then that's legal (though never is legal/illegal until to win/lose in court, as even if something is/should-be completely legal... if you don't prove it/win in court that it is indeed so/legal.... than it is not so, lol):

see the 'led zeppelin staircase to heaven case', for an example (same concept as IP laws)

here, see this thread, has a lot of info on copyright/patent/trademark/IP stuff:

https://textadventures.co.uk/forum/design/topic/5797/copyright


sighs... when will this mis-information be removed from the masses.... sighs

the commerciality/profit or lack of it, has absolutely NOTHING to do with whether something is legal or not, NONE WHAT-SO-EVER !!!


True, but people will often sue if they think they have a reasonable chance of succeeding in court and getting money out of it; whether it was legal or not. But if it is legal, then people generally avoid suing as it will be unlikely that they will succeed in court.

As yes, plagirization does occur a lot; at least with the idea. The code may be different, but it creates the same overall implementation. I know that true Original works, are rare, and most games take inspiration from others. But, taking inspiration is different, than copying and renaming a few variables.


edited in some more stuff to my previous post (including a link to a thread with much more and more detailed info), sorry about that.


nothing is safe legally, not even a work/creation entirely original/unique by you! As if it can be "proven" in court that you used other people's ideas/concepts/designs from their works/creations (even if you actually didn't do so --- it's still possible that you accidentally have something in common with someone else's work/creation, as it's impossible to be truly original/unique, even if you were in the creation of your work/creation. For example, if you've never read shakespear, you will still have some themes of shapespeare in your story, as they're universal themes that you can't avoid from using --- and shakespeare plagerized these story-telling themes from the greeks, lol), you're guilty of IP/plagerism/copyright/trademark/patent theft/vandalism, unfortunately...


yes, indeed, original/unique (most efficient) code is created/crafted/discovered by code/math geniuses... which we then all use... hehe


ya, my combat code is simple (this was back when I was first learning to do combat coding, but it wasn't simple at the time, lol), I can probably do more complex stuff too now for combat, but I've not got around to making a more advanced combat code yet...

I have a few neat combat features in my combat code ('extra turns' chance based on speed difference, 7th Saga SNES game's unique 'defend' feature, the 'if' checks for if you can fight or not, critical hits, etc), but definitely nothing fancy code wise. My code involves combat rounds (you and monster both get to have a turn, who goes first is determined by speed), and the combat rounds continue until one of you are dead and/or one of you escape. Well, some of this wasn't implemented, but that was the design goal of it anyways. I hadn't finished it back when I did it, and am not going to finish it now (as I'd make a better and more advanced combat code now --- if/when I ever get around to it, lol, sighs).

Ya, I'm missing a lot of combat features: sneaking/stealth bonus damage, buffs (elemental/damage types, stat ups, down downs, etc) and other magic effects, status effects, positioning/distance/etc, spells/magic (including: bonus/penalty damages, reflect, absorb, etc), equipment, items, abilities/etc, weapon type damage bonuses/penalities against specific types of monsters (ie: blunts/mace vs undead, axes vs demons, swords vs humans, spears vs ???, crossbow vs armored, etc etc etc), etc etc etc, hehe (I've played A LOT of rpgs...)

(I'm still working on just my 'character creation', though it and any quest work has been on hiatus for awhile, due to school and its work, sighs)


Well, I figured out the character generation bug. The player didn't leave the character generation room, and every time they typed "look" they regenerated their character and got the HP/MP boosts. As the character generation is built into the room description, look would cause that code to be re-executed.

Apparently, I made a slight logic error in my "Descend" command. Since the game defaults the floor depth to 0, if you are on floor 0, you can descend without needing a staircase. I had assumed the player would hit "begin" first and then "descend"... as it says "Type (begin) to start the game." But, I suppose when dealing with players... anything is possible. hahahah... >.>

So I'll fix up that logic error and that should prevent that problem in the future.

Still not sure why the code to apply Shield Spikes failed though.


I'm still not sure why you're multiplying numbers by zero. Like:

if (ShieldTower.SpikesApplied = true) {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0) + ShieldTower.Protection + ShieldTower.Enchantment + ShieldTower.Enhancement
  player.SpikedString = "Spiked"
}
else {
  player.ShieldSpikeDamage = (player.ShieldSpikeDamage * 0)
  player.SpikedString = ""
}

why not have:

if (ShieldTower.SpikesApplied) {
  player.ShieldSpikeDamage = ShieldTower.Protection + ShieldTower.Enchantment + ShieldTower.Enhancement
  player.SpikedString = "Spiked"
}
else {
  player.ShieldSpikeDamage = 0
  player.SpikedString = ""
}

Which would be exactly the same thing, only shorter.
In general, shorter code is better. It's faster not to type redundant code that does nothing, and when you have a problem, it's easier for you (or someone else) to see the errors.

Looking at your game, I see you have a whole lot of repetition. Cutting down on this would really make it easier to find the problem when an error occurs.

For example, you have a turnscript to calculate stats based on equipment, including the armour section:

      switch (true) {
        case (player.EquippedArmor = "Chainmail") {
          player.ArmorProtection = ArmorChainmail.Protection
          player.ArmorEnchantment = ArmorChainmail.Enchantment
          player.ArmorEnhancement = ArmorChainmail.Enhancement
          if (ArmorChainmail.SpikesApplied = true) {
            player.ArmorSpikeDamage = (player.ArmorSpikeDamage * 0) + ArmorChainmail.Protection + ArmorChainmail.Enchantment + ArmorChainmail.Enhancement
          }
          else {
            player.ArmorSpikeDamage = (player.ArmorSpikeDamage * 0)
          }
        }
        case (player.EquippedArmor = "Platemail") {
          player.ArmorProtection = ArmorPlatemail.Protection
          player.ArmorEnchantment = ArmorPlatemail.Enchantment
          player.ArmorEnhancement = ArmorPlatemail.Enhancement
          if (ArmorPlatemail.SpikesApplied = true) {
            player.ArmorSpikeDamage = (player.ArmorSpikeDamage * 0) + ArmorPlatemail.Protection + ArmorPlatemail.Enchantment + ArmorPlatemail.Enhancement
          }
          else {
            player.ArmorSpikeDamage = (player.ArmorSpikeDamage * 0)
          }
        }
        case (player.EquippedArmor = "Leather") {
          player.ArmorProtection = ArmorLeather.Protection
          player.ArmorEnchantment = ArmorLeather.Enchantment
          player.ArmorEnhancement = ArmorLeather.Enhancement
          if (ArmorLeather.SpikesApplied = true) {
            player.ArmorSpikeDamage = (player.ArmorSpikeDamage * 0) + ArmorLeather.Protection + ArmorLeather.Enchantment + ArmorLeather.Enhancement
          }
          else {
            player.ArmorSpikeDamage = (player.ArmorSpikeDamage * 0)
          }
        }
        case (player.EquippedArmor = "Robes") {
          player.ArmorProtection = ArmorRobes.Protection
          player.ArmorEnchantment = ArmorRobes.Enchantment
          player.ArmorEnhancement = ArmorRobes.Enhancement
          player.ArmorSpikeDamage = 0
        }
        case (player.EquippedArmor = "Unarmored") {
          player.ArmorProtection = player.ArmorProtection * 0
          player.ArmorEnchantment = player.ArmorEnchantment * 0
          player.ArmorEnhancement = player.ArmorEnhancement * 0
          player.ArmorSpikeDamage = 0
        }
      }

I assume you're copy and pasting the code for every new item; this leaves a possibility of errors in future, because there are so many values on screen, it would be very easy to miss one when adding the new item.
This section could be more simply written as:

      if (IsDefined ("Armor"+player.EquippedArmor)) {
        currentarmor = GetObject("Armor"+player.EquippedArmor)
        player.ArmorProtection = currentarmor.Protection
        player.ArmorEnchantment = currentarmor.Enchantment
        player.ArmorEnhancement = currentarmor.Enhancement
        if (GetBoolean (currentarmor, "SpikesApplied")) {
          player.ArmorSpikeDamage = currentarmor.Protection + currentarmor.Enchantment + currentarmor.Enhancement
        }
        else {
          player.ArmorSpikeDamage = 0
        }
      }
      else if (player.EquippedArmor = "Unarmored") {
        player.ArmorProtection = 0
        player.ArmorEnchantment = 0
        player.ArmorEnhancement = 0
        player.ArmorSpikeDamage = 0
      }
      else {
        // You don't need an 'else' or 'default' clause; but it can really help to catch mistakes
        msg ("Error: Unknown armor: "+player.EquippedArmor)
      }

As well as reducing the chance of copy errors (I see a lot of people use copy-and-paste code like that and then miss one instance of the name, so your new armor is using one of the stats of the one you copied it from), it means that if you want to add a new kind of spikes in a later version, or put poison on them or something, you only need to add it in one place rather than three.


I multiply by zero because:

  • I'm not a programmer, and I don't really think like a programmer.
  • I'm paranoid, and I like safeguards and failsafes in my code, even if they aren't necessary. I like the illusion of safety that my code will always under any circumstance (barring BSOD that comes when technology gets too hot) work as I intend it to.
  • I used to human mathematics and not computer mathematics. In human mathematics, if the value in Spike Damage is 12, and the other values equal to 11, well 12 =/=. But in computer mathematics, it assigns the total calculation to Spike Damage, and thus if it was 12, it is now 11. I use the multiply by zero to indicate to myself that the old value is being completely removed.

I'll likely be needed to do a refactor of my Update Script eventually, so thank you for the advice and the code suggestions on how to improve it. I appreciate it. Maybe I don't need multiply by 0 after all.


I'll agree with the third point. I really thought it was better when languages had = for comparing two values to see if they're equal, and := for assigning a value; because it makes it clear they're different things. But most modern languages use == and =, and a few (like Quest) use = for both meanings; so I guess that's something I've got to get used to.

I'm also a little paranoid with my code. Even if I know for sure that a variable is either A or B, I'll do if(A) { ... } else if (B) { ... } else { ... display an error message ...}. Because no matter how careful I am, there's a chance I made a mistake, or mistyped something, that results in it being something else entirely. The 'else' case that should never happen means that I know something is wrong, and also makes it a lot easier to track the mistake down.
If I know for sure that the switch will always be one of the predefined values, I'll still include a:

default {
  msg ("CAN'T HAPPEN! If you see this message, please tell the developer. I'm in turnscript 4, and player.offhandWeapon is "+player.offhandWeapon)
}

That way, I know that one of my attributes is something that doesn't match any of the case statements; and I know which piece of code has a problem; and I know what that attribute actually was. If a lot of my switch blocks start displaying the message, i know that some script somewhere is setting player.offhandWeapon to something weird. If it's only happening in one switch block, I know I probably made a typo in one of the case statements.

Paranoia can be useful :¬) Two minutes typing a message that should never be displayed is much better than spending hours trying to find the error. You could learn to channel your paranoia; occasionally check that your variables contain what they're supposed to, and if they don't it can print a message that helps you figure out why.


@lordpalandus
If anything, I'd think the whatever * 0 would only cause more problems. Rarely, not very likely. But still.


for people new to coding, just getting code that works is an achievement, and once you got code that works, you copy and paste it for doing other stuff that's similar, as you know its safe to use it, as it works (but you just got to remember to make the small changes in the pasted code for your other uses, of course, which is not easy to do, lol. I copy and paste code, always forgetting to change the name or whatever of something in the code for that new thing I'm pasting the code for, laughs. But, it's generally pretty easy to catch such forgetful mistakes... well sometimes... laughs... I got lots of stupid mistakes that I couldn't realize... lots of funny stories of mistakes, laughs)

Once, people start to get more used to coding and learn a bit more of it and a bit into different designs, then they got the knowledge to go back and refactor/improve/streamline their code. We who are decent or better coders, forget that people new to coding, can't easily notice or understand how code can be improved upon, that takes some experience and knowledge of coding that doesn't come until you become a decent coder with a larger design base of knowledge and etc of coding designs and etc.


in mathematics the '=' is actually a comparison operation, which isn't taught, unfortunately. You just know it as 'equals', instead of as it actually is: 'equals to', a comparison operation.

as a comparison operation, you can do this:

2 + 3 = 5
5 = 2 + 3

what you're actually doing is saying:

'2+5' is the-same-as/equal-to '5'
'5' is the-same-as/equal-to '2+5'


and thus in programming, it takes awhile to learn to the '=' Assignment' operation, for math people:

VARIABLE = EXPRESSION

the EXPRESSION'S result is stored into the VARIABLE

N = 3 + 2

EXPRESSION: 3 + 2
EXPRESSION's result: 5
the '5' is stored into the 'N' VARIABLE

You can't do:

3 + 2 = N

due to that it's not programmed to parse like that... as it's just not worth the effort to try to program it to parse it as this


now in programming you got your comparison operation, which is always paired with the 'if' Function:

if (3 + 2 = 5)
if (5 = 3 + 2)

in which it doesn't matter which way it's flipped as can be seen above.

also, in most programming languages, these use '=' for the Assignment operation, and use '==' for the comparison operation, to help you distinguish between them, but quest uses the '=' for both Assignment and comparison operations, which is good for poeple new to coding in that they're not scared by the '==' and don't have to remember all these different symbols that programming uses for its various operations/operators, but it still causes confusion as people new to code, don't know the difference between comparison and assignment operations, as they just know 'equals', not even aware of the assignment operation, usually.


being wary of catching errors in code, is actually a very good practice of professional programmers, so this is good that you're doing it already!

but there's better ways of doing it, than in copy and pasting and using redundent code...

most programming languages have a built-in 'error and exception handling' coding for you to use, usually named as 'try' and 'catch' Functions. So, if you were to learn C++, Java, and Python, you'll like that this is already built into them for your use, hehe.

quest has some in its underlying coding, as seen by its errors messages ('catching' the errors and displaying the error message/info to you about what went wrong --- albiet not the best/clearest of error messages, lol)

but, unfortunately for us at the user level... we don't really have anything... aside from manually putting in your own 'msg' Functions everywhere you need them, to see what's going on/wrong with your code, for example:

<game name="example_game">
  <attr name="start" type="script">
   msg ("test 1")
   character_creation_function
   msg ("test 5")
  </attr>
</game>

<function name="character_creation_function">
  msg ("Name?")
  msg ("test 2")
  get input {
    player.alias = result
    msg ("test 3: Player Alias: " + player.alias)
    show menu ("Sex?", split ("male;female", ";"), false) {
      player.sex = result
      msg ("test 4: Player Sex: " + player.sex)
    }
  }
</function>

this way, you can see which 'test #' step/location/place you got to in your scripting before/at the error that occurred, and you're displaying your data along the way, so you can see if anything went wrong with the data as well.


now, good coders/programmers, can make fancy code designs that can do this without manually putting 'msg' Functions everywhere... or even make code that can scan over their quest code, finding errors and etc... hehe, but this is for coders/programmers with a degree and that level of knowledge... I'm not there yet... got a long ways to go, sighs.


if you're good at math, and know coding, you'd actually write at a low level language (Assembly language), and use bit manipulation and bit logic and boolean logic, hehe. For example:

XOR'ing a '0' or a '1' by itself/the-same-number, results in zero: 'zeroes/resets' it

OR truth table:

'0' or '0' ---> '0'
'0' or '1' ---> '1'
'1' or '0' ---> '1'
'1' or '1' ---> '1'

XOR (eXclusive OR) truth table:

'0' or '0' ---> '0'
'0' or '1' ---> '1'
'1' or '0' ---> '1'
'1' or '1' ---> '0'

(0) XOR'ed with itself (0) ----> 0
(1) XOR'ed with itself (1) ----> 0

pseudo ASSEMBLY LANGUAGE example:

mov Register_1, 0h // '0 h' literal/direct hexidecimal (base 16) value is being stored into Register_1
xor Register_1, Register_1 // xor'ing Register_1 (0) with Register_1 (0) ----> Register_1 = 0

mov Register_2, 1h // '1 h' literal/direct hexidecimal (base 16) value is being stored into Register_2
xor Register_2, Register_2 // xor'ing Register_2 (1) with Register_2 (1) ----> Register_2 = 0


read up (google search) on bit manipulation and bit arithmetic (or just see links below, lol), if you're interested in this type of math

http://pages.cs.wisc.edu/~smoler/x86text/lect.notes/represent.html
http://pages.cs.wisc.edu/~smoler/x86text/lect.notes/arith.int.html


Actually = in mathematics isn't always a comparison operation. Take linear algebra and matrix math (shivers), but I digress.

I know about the complexities of logical Boolean stuff; I took Discrete Computational Math in college... a course that consistently confused the heck out of me. I know that you can also do some pretty crazy Booleans if someone is so inclined... ie:

if !(!((x > 2) and (y > 1)) and !(z > (3 * q)^2/3))

A programmer would at that, and question the first programmer on why they had to make the Boolean so damn confusing.


I prefer to try and keep my Booleans readable for me a 5 second glance. A more complex Boolean might reduce the amount of code, but if there is ever a problem with the code, it will drive me up a wall.


I actually prefer the copy-paste method as I find it is far less error prone, than typing it out. When I had tried self-teaching myself C++ back in 2014-2015, I always found that I'd forget semicolons everywhere and when the code would try to compile and couldn't it would puke out all these errors and 95% of the time it was a semicolon or squiggly bracket for conditionals... the other 5% was a spelling mistake. So by copy-pasting, I'm able to eliminate the major syntax errors which are a pain in the butt to hunt down, now my errors are because of forgetting rename something or failing to put the variable into the code; ie like the Shield Bash code!

I am open to refactoring my code to make it be better and efficient. And many of my systems have been greatly reduced in size and redundancy and as I figure out new ways of doing the same gameplay effect, but with less code. However, with all that said, my game is currently in V3 beta status, and I'm about 1/3 to done for V4 beta release. It takes a significant amount of time for me to refactor the code base because I have to be sure that the new system does everything the old system did... except better and with less code. A major refactor of my codebase takes me about 3-4 hours, coding marathon straight, to complete. That's a lot of time to spend refactoring a system. So I prefer to only refactor systems right now that I intend to be needed a refactor for, because I'm adding a bunch of content for it and there is too much redundancy in it. I don't like simply refactoring the code, just for the refactor sake. Theres a lot of bad examples in game development history of people who spent way too much time on refactoring and rebuilding a code base, and never actually producing a game. I try to avoid refactoring if the system is fairly efficient, effective and elegant. If I had an unlimited amount of time at my fingertips, I might just spend it refactoring everything. But I don't. And as I have testers who are really starting to enjoy my game, and are wanting more content, I have to choose carefully how to spend my time; opportunity cost if you will.

Now with all that said, I know that I will need to refactor my Player Updates script (where the armor values are) and a spellcasting System, so The suggestions in this thread are being very helpful, so thank you for that, guys/gals!

EDIT: On the point of C++... do function calls in Quest work the same way as function calls in C++? ie They take arguments, which replace the values of formal parameters, do some number crunching and return a value; or are there also ones that don't return a value and are generally used for taking input from the user or outputting something onto the screen?


I've not at linear algebra yet, laughs. It's the next math class I got to take. I understood calc 2 well, but I was lazy and didn't study enough for some of the tests, and thus did badly on them... sighs... I hate math, it's just so boring for me now... but I have to take it for my programming (CS: computer science) major requirement, argh.

might have done a little work with matrixes ... maybe.... but if I did, can't remember any of it now, lol.


(when is advanced mathematics ever used in normal life? NEVER! It's only for those going into engineering/robotics or being an economist/financial/business or being a math professor/teacher at college/school --- I know higher programming classes will probably delve more into math/theory... HK shivers... I'll have to deal with that when I get to upper division for bachelors and/or for masters/ph-d.... in the far far far future if it's even going to happen... sighs)


oh, you eventually learn to put in those semicolons and make sure you got your brackets in and correct... lol... Syntax is actually learned pretty quick, as it's just structure/pattern of code lines/blocks. I took 3 programming languages at once my first semester: C++, Java, and Python ... it was a bit difficult as I was get them mixed up, but you can just look at code that is already done, to see what syntax you're suppose to use.

seriously, 95% of the time, it IS some stupid small simple mistake/typo that is causing an error with your code from working, lol. The hard part is finding it... grrr

(while you don't have to worry about semicolons in quest, you still got to deal with the brackets and those '/' in the ending tags... grrr)

(the worst though is when you accidentally have spaces/whitespaces, such as from highlighting a bit too far for copying and pasting ... those are so hard to spot... lol)

if you ever want any help with C++ or Java, I can help with them


ya... you can refactor forever... that's my problem, laughs. I look at my code, and I'm like... how can I do a better design and which is also more scalable... I never make any progress on my game making because of it. I'm a (wanna be) perfectionist (as you got to be good at math to be perfectionist: economists are the best at non-physical-ability-skill games, as they can crunch the mechanics of the game to get the best performance possible within the game) ... so, I'm always victim of the trap of endless refactoring, lol.


Boolean Logic (and also can look-up/google-search "Symbolic Logic" of Philosophy/Logic too):

1 <---> true/TRUE
0 <---> false/FALSE

AND logic truth table:

0 and 0 ---> 0
0 and 1 ---> 0
1 and 0 ---> 0
1 and 1 ---> 1

OR logic truth table:

0 or 0 ---> 0
0 or 1 ---> 1
1 or 0 ---> 1
1 or 1 ---> 1

Negation ("not") / 1st Complement, logic truth table::

not 0 ---> 1 // (0)' ---> 1
not 1 ---> 0 // (1)' ---> 0

XOR (eXclusive OR) logic truth table:

0 xor 0 ---> 0
0 xor 1 ---> 1
1 xor 0 ---> 1
1 xor 1 ---> 0

NAND (Not AND) logic truth table:

0 nand 0 ---> 1
0 nand 1 ---> 1
1 nand 0 ---> 1
1 nand 1 ---> 0

NOR (Not OR) logic truth table:

0 nor 0 ---> 1
0 nor 1 ---> 0
1 nor 0 ---> 0
1 nor 1 ---> 0

XNOR (Not eXclusive OR) logic truth table:

0 xnor 0 ---> 1
0 xnor 1 ---> 0
1 xnor 0 ---> 0
1 xnor 1 ---> 1

Boolean Arithmetic: Basic Identities:

(ignore the dot/period in front, that was/is to prevent the posting code from displaying the bullet symbol instead, lol)

. + === OR
. * === AND
. ' === Negation ("not") / 1st Complement

AB === A * B === AND

(the 'X' represents a "don't care" state: it can be '0' or '1', as it doesn't matter)

// basic truth table identities (see the 'AND' and 'OR' truth tables above):

  1. X + 0 = X
  2. X * 0 = 0
  3. X + 1 = 1
  4. X * 1 = X
  5. X + X = X
  6. X * X = X
  7. X + X' = 1
  8. X * X' = 0
    // these are similar to ordinary algebra:
  9. X + Y = Y + X
  10. X * Y = Y * X
  11. X + (Y + Z) = (X + Y) + Z
  12. X * (Y * Z) = (X * Y) * Z
  13. X * (Y + Z) = (X * Y) + (X * Z)
    // this is the NON-Algebra (aka, the seemingly weird) one (purely boolean logic):
  14. X + (Y * X) = (X + Y) * (X + Z)
    // DeMorgan's Rules/Theorems:
  15. (X + Y)' = (X') * (Y')
  16. (X * Y)' = (X') + (Y')
    // simple double negation/1st-complement rule (similar to: --1 = 1, ---1 = -1):
  17. (X')' = X

My normal rule for refactoring is to think: will rearranging this code be quicker than fixing the bug or adding the feature.

If I have a batch of copy/pasted case statements, and some calculation might go wrong if I missed changing one of the object names, I usually find that reducing it to a single case is quicker than poring over the code making sure every name is right.
More complex refactoring, I'll put off until the code does everything it's supposed to do.


In computer science, calculus comes into play with Game Physics or Lighting. Matrix math is important for moving objects within the game world. In business, mathematics is rarely used directly by people anymore (I'd know, I have a Bachelors in General Business). Sure you might use Excel to calculate the beta value of a company on the stock market, or the partial derivative for some high-level macroeconomics, but in general math isn't used. However, if you are in Accounting, you have to do math often, and the same goes for those in Logistics. Finance people rarely use calculators, except when it is forced upon them in classes; they have programs that do the work for them.

Its possible the bug with the applying Shield Spikes was a single white space. That would be extremely hard to notice and might explain why replacing the variable with a brand new one, solved the issue.

In programming, there is designers and developers. Designers design systems and love redesigning code. Developers create code and love seeing the code in action, and not necessarily enjoy refactoring old code. You might do better as a Designer, than a Developer. Sometimes, people have to don both hats, and be both a designer and a developer, as the situation needs it. But that's not for everyone.

You remind me of why I didn't like Discrete Computational Math; looking at that stuff makes my head hurt. XD


Logic is not for everyone, and working with symbolic arithmetic, and heavy math, makes it even more not for everyone.

Symbolic Logic (and thus as arithmetic equations) of Philosophy/Logic (though also used/useful for mathematics, programming, circuitry design, human languages, etc):

(I don't know what discreet mathematics is, as I've not taking the class: linear algebra, discreet mathematics, are courses I think I got to take after calc 2, but it sounds like its at least a bit similar to Symbolic Logic, or at least uses it, anyways)

  1. mathematics
  2. programming
  3. circuitry design
  4. human languages
  5. etc

I think if you took a 'Symbolic Logic' class (or just study up on it online for free), it'd help you understand this stuff better, as it does a good job of getting into this stuff and of understanding it well. We had to take it, to help us with understanding boolean logic in programming as our programming required classes. It dealt only with human languages, but it teaches you to understand how it works very well and to be good at it.


It depends on what type of logic we are talking about.

I read an article that said an old people from some thousands of years ago, probably the Syrians, had a form of trigonemtry that used right angles, not sins and cosine, and what not. It's supposed to be simpler than the trigonometry we learn in school.
Well, they tried to teach me modern Trigonometry in Algebra 2, which didn't work because we had a substitute or whatever you call it (the other teacher was pregnant). That wasted my time.
(I learned enough trigonometry that, at the time, I was right 50% of the time. But, I couldn't tell you what I did wrong on the ones I got wrong. Now, I don't even remember the steps to the problems.)

What kind of logic is it that there is a better and simpler trigonometry, and yet we toil with the one we already have?


trig is more useful, as nature/universe works with curves (and recursion/fractals), not lines (humans love lines, look at all of our rectangle/triangle/etc buildings), and the cosine is everywhere in nature/universe, engineers love the cosine.

nature/universe uses curves and recursion/fractals, humans use lines.

if interested on recursion/fractals:

https://www.youtube.com/watch?v=w4t63uQhoYk (Fractals: the Hidden Dimension, by Nova)

great vid (except I found the historical stuff on van bradenbroff --- can't spell, lol --- very boring, but the rest of the vid is awesome)


I think humans like lines, because they are simple. There always seems to be a call in life, to try and simple things down, to ask complex questions and expect simple answers/solutions. Fractals are complex, and thus people don't like them. Engineers might like them, because they like complex things and making other complex things... and hate trying to explain their complex things to simple people who want simple answers. :)

Nature/Universe is a complex beast of very complex mathematics, chemistry and physics.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums