Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×

Survival Script isn't working what am I messing up?

Hi I am trying to set up a Script for my world on Hunting but Idk I think im messing something up /* ============================================================    D&D 5.5e SURVIVAL SYSTEM    Hunting / Lake Fishing / Gathering    ============================================================    COMMAND:    !survival    WORKFLOW:    1. Select the character token.    2. Click the Survival macro.    3. Choose Hunting, Lake Fishing, or Gathering.    4. Roll20 provides:         - d20         - Wisdom modifier         - Survival proficiency adjustment    5. API combines them.    6. Final result is capped at 30.    PROFICIENCY TYPES SUPPORTED:    - Not Proficient    - Proficient    - Expertise    - Half Proficiency    ============================================================ */ var SurvivalSystem = SurvivalSystem || (function () {     /* =========================================================        HUNTING        ========================================================= */     var HUNTING = [         {             min: 0,             max: 5,             results: [                 {                     name: "Nothing",                     description: "You find no tracks or scare away wildlife.",                     yield: "0 lbs",                     feeds: 0                 }             ]         },         {             min: 6,             max: 10,             results: [                 { name: "Empty Burrow", description: "You find signs of a small desert animal, but the burrow is abandoned.", yield: "0 lbs", feeds: 0 },                 { name: "Old Tracks", description: "The tracks are too old to follow.", yield: "0 lbs", feeds: 0 },                 { name: "Picked Clean", description: "Whatever passed through this area has already taken anything edible.", yield: "0 lbs", feeds: 0 },                 { name: "Scavenger Sign", description: "You find evidence of jackals or other scavengers, but no viable prey.", yield: "0 lbs", feeds: 0 },                 { name: "Buried Nest", description: "You find a nest, but it has already been emptied.", yield: "0 lbs", feeds: 0 },                 { name: "Broken Trail", description: "A set of fresh-looking tracks vanishes across the hard-packed sand.", yield: "0 lbs", feeds: 0 },                 { name: "Old Droppings", description: "You find droppings from a desert animal, but the trail is long gone.", yield: "0 lbs", feeds: 0 },                 { name: "Scorpion Tracks", description: "The signs lead to a dangerous burrow, but there is nothing worth eating.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Nest", description: "A small desert bird has already abandoned the nest.", yield: "0 lbs", feeds: 0 },                 { name: "Dead End", description: "You follow a promising trail only to discover it disappears among the dunes.", yield: "0 lbs", feeds: 0 },                 { name: "Scrub Sign", description: "Something has fed in the scrub recently, but you cannot locate it.", yield: "0 lbs", feeds: 0 }             ]         },         {             min: 11,             max: 15,             results: [                 { name: "Desert Lizard", description: "A small lizard hiding beneath a sun-warmed stone.", yield: "0.25 lbs", feeds: 0 },                 { name: "Sand Rat", description: "A small desert rodent caught near its burrow.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Desert Bird", description: "A tiny bird nesting among rocks or scrub.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Beetles", description: "A handful of large edible desert insects.", yield: "0.25 lbs", feeds: 0 },                 { name: "Tiny Desert Hare", description: "A very small hare with little usable meat.", yield: "0.5 lbs", feeds: 0 },                 { name: "Rock Crab", description: "A small land crab hiding beneath a stone near damp ground.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Desert Snake", description: "A thin snake found beneath a rock shelf.", yield: "0.5 lbs", feeds: 0 },                 { name: "Scrub Mouse", description: "A tiny rodent living among thorny desert brush.", yield: "0.25 lbs", feeds: 0 },                 { name: "Sand Finch", description: "A tiny desert bird caught around a patch of scrub.", yield: "0.25 lbs", feeds: 0 },                 { name: "Lizard Nest", description: "A clutch of small desert lizards is found beneath a warm stone.", yield: "0.5 lbs", feeds: 0 },                 { name: "Young Sand Hare", description: "A very small hare with barely enough meat to salvage.", yield: "0.5 lbs", feeds: 0 },                 { name: "Desert Tortoise", description: "A small tortoise with very little usable meat.", yield: "0.5 lbs", feeds: 0 }             ]         },         {             min: 16,             max: 20,             results: [                 { name: "Desert Hare", description: "A lean hare adapted to the heat and scarcity of the Borderlands.", yield: "1 lb", feeds: 1 },                 { name: "Rock Quail", description: "A small ground bird nesting among broken stone.", yield: "1 lb", feeds: 1 },                 { name: "Large Desert Lizard", description: "A broad-bodied lizard with a modest amount of usable meat.", yield: "1 lb", feeds: 1 },                 { name: "Sand Rat Colony", description: "Several small rodents are found near a sheltered burrow.", yield: "1 lb", feeds: 1 },                 { name: "Scrub Bird", description: "A hardy bird living among thorn scrub.", yield: "1 lb", feeds: 1 },                 { name: "Rock Crab", description: "A land crab hiding beneath stones near a damp area.", yield: "1 lb", feeds: 1 },                 { name: "Small Desert Snake", description: "A thin snake found beneath a rock shelf.", yield: "0.5 lbs", feeds: 0 },                 { name: "Large Quail", description: "A plump desert bird found near sheltered rock.", yield: "1 lb", feeds: 1 },                 { name: "Desert Rodent", description: "A healthy rodent living beneath a ruined stone foundation.", yield: "1 lb", feeds: 1 },                 { name: "Young Jackal", description: "A young desert jackal separated from its pack.", yield: "2 lbs", feeds: 1 }             ]         },         {             min: 21,             max: 25,             results: [                 { name: "Large Desert Hare", description: "A healthy hare found near sheltered scrub.", yield: "2 lbs", feeds: 1 },                 { name: "Desert Goat", description: "A half-wild goat surviving among the rocky slopes.", yield: "5 lbs", feeds: 1 },                 { name: "Young Gazelle", description: "A young antelope found near one of the Borderlands' surviving green pockets.", yield: "5 lbs", feeds: 1 },                 { name: "Jackal", description: "A lean desert jackal caught away from its pack.", yield: "3 lbs", feeds: 1 },                 { name: "Large Desert Bird", description: "A substantial ground bird nesting in a sheltered ruin.", yield: "3 lbs", feeds: 1 },                 { name: "Large Lizard", description: "An unusually large desert lizard with several pounds of usable meat.", yield: "3 lbs", feeds: 1 },                 { name: "Desert Tortoise", description: "A mature desert tortoise with a surprising amount of edible meat.", yield: "4 lbs", feeds: 1 },                 { name: "Large Jackal", description: "A heavy desert jackal that has survived deep in the wastes.", yield: "6 lbs", feeds: 2 },                 { name: "Rock Gazelle", description: "A lean young gazelle found among broken mountain stone.", yield: "6 lbs", feeds: 2 },                 { name: "Feral Goat", description: "A hardy goat surviving without a herd near an old settlement.", yield: "5 lbs", feeds: 1 }             ]         },         {             min: 26,             max: 30,             results: [                 { name: "Ibex", description: "A mountain goat from the rocky Border Mountains.", yield: "12 lbs", feeds: 3 },                 { name: "Gazelle", description: "A full-grown desert gazelle.", yield: "15 lbs", feeds: 3 },                 { name: "Wild Goat", description: "A large feral goat that has survived away from civilization.", yield: "10 lbs", feeds: 2 },                 { name: "Desert Antelope", description: "A mature antelope found near a rare surviving water source.", yield: "15 lbs", feeds: 3 },                 { name: "Mountain Sheep", description: "A large wild sheep taken in the Border Mountains.", yield: "15 lbs", feeds: 3 },                 { name: "Wild Camel", description: "An extraordinarily rare feral camel wandering far from the known caravan roads.", yield: "20 lbs", feeds: 4 },                 { name: "Large Ibex", description: "A powerful mountain goat from a remote pass.", yield: "18 lbs", feeds: 3 },                 { name: "Large Gazelle", description: "A mature gazelle in unusually good condition for the wastes.", yield: "18 lbs", feeds: 3 },                 { name: "Mountain Ram", description: "A heavy wild ram from the Border Mountains.", yield: "20 lbs", feeds: 4 },                 { name: "Wild Camel Herd Animal", description: "A rare mature camel separated from a wandering group.", yield: "25 lbs", feeds: 5 }             ]         }     ];     /* =========================================================        LAKE FISHING        ========================================================= */     var FISHING = [         {             min: 0,             max: 5,             results: [                 {                     name: "Snagged Line",                     description: "Your line snaps or the fish aren't biting.",                     yield: "0 lbs",                     feeds: 0                 }             ]         },         {             min: 6,             max: 10,             results: [                 { name: "Empty Line", description: "Nothing bites.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Water", description: "The water appears almost lifeless.", yield: "0 lbs", feeds: 0 },                 { name: "Broken Shellfish", description: "You find shells, but nothing worth keeping.", yield: "0 lbs", feeds: 0 },                 { name: "Picked Shore", description: "Scavengers and other travelers have already stripped the shoreline.", yield: "0 lbs", feeds: 0 },                 { name: "Lost Bait", description: "You lose your bait without catching anything.", yield: "0 lbs", feeds: 0 },                 { name: "Snagged Hook", description: "The hook catches on submerged stone and breaks free empty.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Pool", description: "You search a promising pool and discover it is nearly lifeless.", yield: "0 lbs", feeds: 0 },                 { name: "Scoured Bank", description: "The shoreline has already been picked clean.", yield: "0 lbs", feeds: 0 },                 { name: "Rotten Catch", description: "You find something dead in the water, but it is unsafe to eat.", yield: "0 lbs", feeds: 0 },                 { name: "Shallow Water", description: "The water is too shallow to support anything worth catching.", yield: "0 lbs", feeds: 0 }             ]         },         {             min: 11,             max: 15,             results: [                 { name: "Tiny Fish", description: "A tiny fish barely worth cleaning.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Crab", description: "A small crab caught beneath a stone.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Eel", description: "A thin eel pulled from shallow water.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Shellfish", description: "A few edible shellfish hidden beneath wet stones.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Oasis Fish", description: "A small fish from one of the rare surviving freshwater pools.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Mullet", description: "A very small coastal fish caught near the shore.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Rockfish", description: "A tiny fish hiding between coastal rocks.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Crab Cluster", description: "Several very small crabs are found under a rock shelf.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Carp", description: "A young carp from a surviving oasis pool.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Mudfish", description: "A small fish from stagnant desert water.", yield: "0.5 lbs", feeds: 0 },                 { name: "Thin Eel", description: "A narrow eel from a dark water channel.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Shellfish", description: "A modest handful of edible shellfish.", yield: "0.5 lbs", feeds: 0 }             ]         },         {             min: 16,             max: 20,             results: [                 { name: "Coastal Mullet", description: "A lean silver fish common near the waters around Saltspire.", yield: "1 lb", feeds: 1 },                 { name: "Rockfish", description: "A small fish found close to rocks and cliffs.", yield: "1 lb", feeds: 1 },                 { name: "Small Carp", description: "A hardy fish surviving in a rare freshwater pool.", yield: "1 lb", feeds: 1 },                 { name: "Small Catfish", description: "A bottom-feeding fish from a surviving oasis pool.", yield: "1 lb", feeds: 1 },                 { name: "Small Eel", description: "A fat eel pulled from a dark channel.", yield: "1 lb", feeds: 1 },                 { name: "Redfin", description: "A hardy fish from an isolated pool.", yield: "1 lb", feeds: 1 },                 { name: "Desert Perch", description: "A small fish surviving in a warm spring-fed pool.", yield: "1 lb", feeds: 1 },                 { name: "Sea Drum", description: "A modest coastal fish caught near Saltspire.", yield: "1 lb", feeds: 1 },                 { name: "Oasis Tilapia", description: "A hardy fish surviving in warm freshwater.", yield: "1 lb", feeds: 1 },                 { name: "Small Bream", description: "A silver coastal fish from shallow water.", yield: "1 lb", feeds: 1 }             ]         },         {             min: 21,             max: 25,             results: [                 { name: "Large Mullet", description: "A healthy coastal fish from deeper water.", yield: "3 lbs", feeds: 1 },                 { name: "Oasis Catfish", description: "A thick-bodied catfish surviving in a deep water source.", yield: "3 lbs", feeds: 1 },                 { name: "Sea Bream", description: "A solid coastal fish caught below the cliffs of Saltspire.", yield: "4 lbs", feeds: 1 },                 { name: "Large Carp", description: "An old carp that has survived in an isolated pool.", yield: "4 lbs", feeds: 1 },                 { name: "Redfin", description: "A hardy fish from a deep oasis pool.", yield: "2 lbs", feeds: 1 },                 { name: "Large Eel", description: "A thick eel pulled from a dark water channel.", yield: "3 lbs", feeds: 1 },                 { name: "Rock Bass", description: "A stocky coastal predator found around broken stone.", yield: "3 lbs", feeds: 1 },                 { name: "Oasis Trout", description: "A rare trout surviving in cold desert spring water.", yield: "4 lbs", feeds: 1 }             ]         },         {             min: 26,             max: 30,             results: [                 { name: "Large Sea Bream", description: "A heavy saltwater fish caught in the deeper waters around Saltspire.", yield: "6 lbs", feeds: 2 },                 { name: "Large Catfish", description: "A rare large catfish from a deep oasis or hidden water source.", yield: "8 lbs", feeds: 2 },                 { name: "Barracuda", description: "A dangerous coastal predator with substantial usable meat.", yield: "7 lbs", feeds: 2 },                 { name: "Giant Oasis Catfish", description: "A remarkably large catfish from an ancient surviving pool.", yield: "12 lbs", feeds: 3 },                 { name: "Ancient Carp", description: "A huge carp that has survived for years in isolated water.", yield: "10 lbs", feeds: 2 },                 { name: "Large Sea Drum", description: "A broad-bodied fish from deeper coastal waters.", yield: "9 lbs", feeds: 2 },                 { name: "Large Eel", description: "A massive eel found in a deep surviving waterway.", yield: "8 lbs", feeds: 2 },                 { name: "Deepwater Predator", description: "A rare heavy fish pulled from unusually deep coastal water.", yield: "12 lbs", feeds: 3 },                 { name: "Giant Oasis Bream", description: "An enormous fish from an exceptionally old freshwater pool.", yield: "10 lbs", feeds: 2 }             ]         }     ];     /* =========================================================        GATHERING TABLE        ========================================================= */     var GATHERING = [         {             min: 0,             max: 5,             results: [                 {                     name: "Poor Forage",                     description: "You find little worth eating. Most plants are rotten, bitter, or unsuitable.",                     yield: "0 lbs",                     feeds: 0                 },                 {                     name: "Barren Patch",                     description: "The area has already been picked over by wildlife or other travelers.",                     yield: "0 lbs",                     feeds: 0                 },                 {                     name: "Spoiled Growth",                     description: "You find plants, but they are damaged, diseased, or unsafe to eat.",                     yield: "0 lbs",                     feeds: 0                 }             ]         },         {             min: 6,             max: 10,             results: [                 { name: "Dry Cactus", description: "You find cactus, but it is too dry or damaged to provide anything useful.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Roots", description: "Roots are present beneath the sand, but they are dried beyond use.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Algae", description: "Algae coats a damp surface, but it has already spoiled.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Seed Pods", description: "You find seed pods that have already dropped their contents.", yield: "0 lbs", feeds: 0 },                 { name: "Scoured Ground", description: "Animals and travelers have already stripped the area.", yield: "0 lbs", feeds: 0 },                 { name: "Bitter Cactus", description: "The cactus is too bitter or contaminated to eat safely.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Scrub", description: "The scrub is completely dried out.", yield: "0 lbs", feeds: 0 },                 { name: "Wilted Oasis Growth", description: "The plants around a former water source are dead.", yield: "0 lbs", feeds: 0 },                 { name: "Dry Bulbs", description: "You find bulbs, but they are hard and useless.", yield: "0 lbs", feeds: 0 },                 { name: "Rotten Algae", description: "The algae has gone foul beneath the heat.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Cactus", description: "The cactus has been stripped by animals before you arrived.", yield: "0 lbs", feeds: 0 },                 { name: "Windblown Seeds", description: "You find seed husks, but almost no edible seed remains.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Vines", description: "Old vines cling to broken stone, but nothing remains edible.", yield: "0 lbs", feeds: 0 },                 { name: "Sand-Choked Roots", description: "Roots survive below the surface, but not enough to harvest.", yield: "0 lbs", feeds: 0 },                 { name: "Spoiled Fruit", description: "A few dried fruits remain, but they are unsafe.", yield: "0 lbs", feeds: 0 },                 { name: "Salt-Burned Growth", description: "The plants have been damaged by mineral-heavy water.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Reed Bed", description: "A former wetland has completely dried out.", yield: "0 lbs", feeds: 0 },                 { name: "Ruined Garden", description: "You find the remains of an old cultivated plot, but nothing useful survives.", yield: "0 lbs", feeds: 0 },                 { name: "Trampled Growth", description: "Animals have already eaten what little remained here.", yield: "0 lbs", feeds: 0 },                 { name: "Barren Hollow", description: "The hollow looks promising, but the ground contains nothing edible.", yield: "0 lbs", feeds: 0 },                 { name: "Dry Algae Mat", description: "Old algae clings to stone, but has become useless.", yield: "0 lbs", feeds: 0 },                 { name: "Crushed Seed Pods", description: "You find the remains of seed pods scattered across the ground.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Bulrush", description: "The old wetland plants have completely dried out.", yield: "0 lbs", feeds: 0 },                 { name: "Scorched Roots", description: "The heat has ruined what little root growth survived.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Scrub", description: "There is simply nothing edible here.", yield: "0 lbs", feeds: 0 }             ]         },         {             min: 11,             max: 19,             results: [                 { name: "Cactus Pulp", description: "A small amount of edible cactus flesh.", yield: "0.25 lbs", feeds: 0 },                 { name: "Cactus Fruit", description: "A few small fruits hidden beneath the thorns.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Seeds", description: "A small handful of hardy seeds.", yield: "0.25 lbs", feeds: 0 },                 { name: "Edible Roots", description: "A few thin roots found beneath stubborn scrub.", yield: "0.25 lbs", feeds: 0 },                 { name: "Fresh Algae", description: "A small patch of edible algae survives near damp ground.", yield: "0.5 lbs", feeds: 0 },                 { name: "Cactus Needles & Pulp", description: "A little usable cactus flesh hidden beneath the thorns.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Bulb", description: "A single edible bulb hidden below the sand.", yield: "0.25 lbs", feeds: 0 },                 { name: "Seed Cluster", description: "A small cluster of hardy desert seeds.", yield: "0.25 lbs", feeds: 0 },                 { name: "Oasis Shoot", description: "One small edible shoot growing beside a hidden water source.", yield: "0.25 lbs", feeds: 0 },                 { name: "Young Cactus Fruit", description: "A single ripe fruit overlooked by scavengers.", yield: "0.25 lbs", feeds: 0 },                 { name: "Edible Reed Root", description: "A small edible root from a surviving waterway.", yield: "0.5 lbs", feeds: 0 },                 { name: "Fresh Desert Herb", description: "A tiny patch of hardy edible herbs.", yield: "0.25 lbs", feeds: 0 },                 { name: "Algae Scraps", description: "A small harvest of fresh edible algae.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Desert Fruit", description: "A few small fruits from a surviving scrub plant.", yield: "0.25 lbs", feeds: 0 },                 { name: "Root Cluster", description: "Several thin edible roots beneath the sand.", yield: "0.5 lbs", feeds: 0 },                 { name: "Cactus Buds", description: "A handful of young cactus growth that can be prepared as food.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Grass Seed", description: "A small harvest of edible seed from stubborn desert grass.", yield: "0.25 lbs", feeds: 0 },                 { name: "Oasis Leaf Cluster", description: "A few edible leaves from a rare surviving plant.", yield: "0.5 lbs", feeds: 0 },                 { name: "Young Cactus Growth", description: "A small amount of fresh cactus flesh.", yield: "0.5 lbs", feeds: 0 },                 { name: "Damp Soil Roots", description: "A few edible roots found near buried water.", yield: "0.5 lbs", feeds: 0 }             ]         },         {             min: 20,             max: 30,             results: [                 { name: "Cactus Fruit & Pulp", description: "A productive cactus provides both fruit and water-rich flesh.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Roots & Seeds", description: "An underground harvest accompanied by edible seed pods.", yield: "2 lbs total", feeds: 1 },                 { name: "Oasis Greens", description: "Tender greens grow around a rare source of water.", yield: "2 lbs", feeds: 1 },                 { name: "Algae & Cactus", description: "A damp depression provides edible algae and fresh cactus.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Bulbs", description: "Small starchy bulbs survive beneath hardened soil.", yield: "2 lbs", feeds: 1 },                 { name: "Cactus Fruit & Seeds", description: "A mature cactus patch produces fruit and a modest seed harvest.", yield: "2 lbs total", feeds: 1 },                 { name: "Cactus Pulp & Roots", description: "A productive patch yields water-rich flesh and edible roots.", yield: "2 lbs total", feeds: 1 },                 { name: "Oasis Herbs & Seeds", description: "A rare water source supports hardy herbs and edible seeds.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Greens & Bulbs", description: "Several edible plants grow together in damp soil.", yield: "2 lbs total", feeds: 1 },                 { name: "Fresh Algae Bed", description: "A surviving patch of edible algae provides a modest harvest.", yield: "2 lbs", feeds: 1 },                 { name: "Cactus Fruit Grove", description: "Several mature cactus plants provide a useful amount of fruit.", yield: "3 lbs total", feeds: 1 },                 { name: "Hidden Root Patch", description: "A sheltered area contains a cluster of edible desert roots.", yield: "2 lbs", feeds: 1 },                 { name: "Seed & Cactus Harvest", description: "Edible seed pods grow among several mature cactus plants.", yield: "2 lbs total", feeds: 1 },                 { name: "Oasis Reed Roots", description: "A rare surviving wetland supports edible roots.", yield: "2 lbs", feeds: 1 },                 { name: "Desert Herb Patch", description: "A sheltered hollow contains several edible hardy herbs.", yield: "2 lbs total", feeds: 1 },                 { name: "Cactus Buds & Fruit", description: "Young cactus growth and fruit can both be harvested.", yield: "2 lbs total", feeds: 1 },                 { name: "Algae & Oasis Greens", description: "Fresh algae grows beside edible green shoots.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Root & Fruit Patch", description: "A rare pocket contains both edible roots and fruit.", yield: "2 lbs total", feeds: 1 },                 { name: "Hidden Spring Growth", description: "Moist ground supports a productive patch of roots and greens.", yield: "3 lbs total", feeds: 2 },                 { name: "Cactus Grove", description: "A mature stand of cactus provides a surprisingly large harvest.", yield: "3 lbs total", feeds: 2 }             ]         }     ];     /* =========================================================        GET SELECTED CHARACTER        ========================================================= */     function getSelectedCharacter(msg) {         if (!msg.selected || msg.selected.length === 0) {             return null;         }         var token = getObj(             "graphic",             msg.selected[0]._id         );         if (!token) {             return null;         }         var characterId =             token.get("represents");         if (!characterId) {             return null;         }         return getObj(             "character",             characterId         );     }     /* =========================================================        GET INLINE ROLL        ========================================================= */     function getInlineRoll(msg, index) {         if (             !msg.inlinerolls ||             !msg.inlinerolls[index]         ) {             return 0;         }         var roll =             msg.inlinerolls[index];         if (             roll.results &&             typeof roll.results.total !== "undefined"         ) {             return Number(                 roll.results.total             ) || 0;         }         return 0;     }     /* =========================================================        FIND BRACKET        ========================================================= */     function findBracket(         table,         result     ) {         for (             var i = 0;             i < table.length;             i++         ) {             if (                 result >= table[i].min &&                 result <= table[i].max             ) {                 return table[i];             }         }         return table[0];     }     /* =========================================================        RANDOM FIND        ========================================================= */     function randomFind(bracket) {         var index =             Math.floor(                 Math.random() *                 bracket.results.length             );         return bracket.results[index];     }     /* =========================================================        MAIN COMMAND        ========================================================= */     function runSurvival(msg) {         if (             msg.type !== "api"         ) {             return;         }         if (             msg.content.indexOf("!survival") !== 0         ) {             return;         }         var character =             getSelectedCharacter(msg);         if (!character) {             sendChat(                 "Survival System",                 "/w " +                 msg.who +                 " <b>Select a character token linked to a character sheet first.</b>"             );             return;         }         /* -----------------------------------------------------            ACTIVITY            ----------------------------------------------------- */         var parts =             msg.content.split(/\s+/);         var activity =             parts[1];         if (             activity !== "hunting" &&             activity !== "fishing" &&             activity !== "gathering"         ) {             sendChat(                 "Survival System",                 "/w " +                 msg.who +                 " <b>Choose Hunting, Lake Fishing, or Gathering.</b>"             );             return;         }         /* -----------------------------------------------------            INLINE ROLLS            0 = D20            1 = Wisdom Modifier            2 = Survival Proficiency            ----------------------------------------------------- */         var d20 =             getInlineRoll(                 msg,                 0             );         var wisdomMod =             getInlineRoll(                 msg,                 1             );         var proficiency =             getInlineRoll(                 msg,                 2             );         /* -----------------------------------------------------            SURVIVAL BONUS            ----------------------------------------------------- */         var survivalBonus =             wisdomMod +             proficiency;         /* -----------------------------------------------------            SURVIVAL RESULT            ----------------------------------------------------- */         var rawResult =             d20 +             survivalBonus;         /*          * Cap Survival at 30.          */         var survivalResult =             Math.max(                 0,                 Math.min(                     rawResult,                     30                 )             );         /* -----------------------------------------------------            SELECT TABLE            ----------------------------------------------------- */         var table;         var activityName;         if (             activity === "hunting"         ) {             table = HUNTING;             activityName = "Hunting";         } else if (             activity === "fishing"         ) {             table = FISHING;             activityName = "Lake Fishing";         } else {             table = GATHERING;             activityName = "Gathering";         }         /* -----------------------------------------------------            FIND RESULT            ----------------------------------------------------- */         var bracket =             findBracket(                 table,                 survivalResult             );         var result =             randomFind(                 bracket             );         /* -----------------------------------------------------            DISPLAY            ----------------------------------------------------- */         var output =             "&{template:default}" +             "{{name=Survival — " +             activityName +             "}}" +             "{{Character=" +             character.get("name") +             "}}" +             "{{D20 Roll=" +             d20 +             "}}" +             "{{Wisdom Modifier=" +             (wisdomMod >= 0 ? "+" : "") +             wisdomMod +             "}}" +             "{{Survival Proficiency=" +             (proficiency >= 0 ? "+" : "") +             proficiency +             "}}" +             "{{Survival Bonus=" +             (survivalBonus >= 0 ? "+" : "") +             survivalBonus +             "}}" +             "{{Survival Result=" +             survivalResult +             "}}" +             "{{Find=" +             result.name +             "}}" +             "{{Description=" +             result.description +             "}}" +             "{{Food Yield=" +             result.yield +             "}}" +             "{{Feeds=" +             result.feeds +             " people}}";         sendChat(             character.get("name"),             output         );     }     /* =========================================================        REGISTER COMMAND        ========================================================= */     on(         "ready",         function () {             log(                 "======================================"             );             log(                 "D&D 5.5e SURVIVAL SYSTEM LOADED"             );             log(                 "Command: !survival"             );             log(                 "======================================"             );             on(                 "chat:message",                 runSurvival             );         }     ); })();
What is happening? Are you getting an error in the chat window or the Mod sandbox?  What macro are you using to call the script?  You haven't put in the attribute calls for proficiency bonus or wisdom modifiers, instead using three inline rolls. Regardless, you can simply use the 'survival_bonus' attribute from the 5e sheet.  If a selected token isn't linked to a character, then nothing happens.  Calling !survival by itself won't do anything, because the second argument for the "survival type" has to be included. (When posting code on the forums, it's very helpful to put it in a code block for readability. Click on the small 'magic wand' dropdown just left of the Bold button, and select 'code'.) Hopefully this code addresses whatever issues you're having:  /* ============================================================    D&D 5.5e SURVIVAL SYSTEM    Hunting / Lake Fishing / Gathering    COMMAND:    !survival    WORKFLOW:    1. Select a token linked to a character sheet.    2. Run !survival.    3. Choose Hunting, Lake Fishing, or Gathering.    4. The script rolls 1d20 and reads the character's Survival bonus.    5. The final result is capped between 0 and 30. The script uses the sheet's final survival_bonus value, so normal proficiency, expertise, half proficiency, and other modifiers are already included.    ============================================================ */ var SurvivalSystem = SurvivalSystem || (function () {     /* =========================================================        HUNTING        ========================================================= */     var HUNTING = [         {             min: 0,             max: 5,             results: [                 {                     name: "Nothing",                     description: "You find no tracks or scare away wildlife.",                     yield: "0 lbs",                     feeds: 0                 }             ]         },         {             min: 6,             max: 10,             results: [                 { name: "Empty Burrow", description: "You find signs of a small desert animal, but the burrow is abandoned.", yield: "0 lbs", feeds: 0 },                 { name: "Old Tracks", description: "The tracks are too old to follow.", yield: "0 lbs", feeds: 0 },                 { name: "Picked Clean", description: "Whatever passed through this area has already taken anything edible.", yield: "0 lbs", feeds: 0 },                 { name: "Scavenger Sign", description: "You find evidence of jackals or other scavengers, but no viable prey.", yield: "0 lbs", feeds: 0 },                 { name: "Buried Nest", description: "You find a nest, but it has already been emptied.", yield: "0 lbs", feeds: 0 },                 { name: "Broken Trail", description: "A set of fresh-looking tracks vanishes across the hard-packed sand.", yield: "0 lbs", feeds: 0 },                 { name: "Old Droppings", description: "You find droppings from a desert animal, but the trail is long gone.", yield: "0 lbs", feeds: 0 },                 { name: "Scorpion Tracks", description: "The signs lead to a dangerous burrow, but there is nothing worth eating.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Nest", description: "A small desert bird has already abandoned the nest.", yield: "0 lbs", feeds: 0 },                 { name: "Dead End", description: "You follow a promising trail only to discover it disappears among the dunes.", yield: "0 lbs", feeds: 0 },                 { name: "Scrub Sign", description: "Something has fed in the scrub recently, but you cannot locate it.", yield: "0 lbs", feeds: 0 }             ]         },         {             min: 11,             max: 15,             results: [                 { name: "Desert Lizard", description: "A small lizard hiding beneath a sun-warmed stone.", yield: "0.25 lbs", feeds: 0 },                 { name: "Sand Rat", description: "A small desert rodent caught near its burrow.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Desert Bird", description: "A tiny bird nesting among rocks or scrub.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Beetles", description: "A handful of large edible desert insects.", yield: "0.25 lbs", feeds: 0 },                 { name: "Tiny Desert Hare", description: "A very small hare with little usable meat.", yield: "0.5 lbs", feeds: 0 },                 { name: "Rock Crab", description: "A small land crab hiding beneath a stone near damp ground.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Desert Snake", description: "A thin snake found beneath a rock shelf.", yield: "0.5 lbs", feeds: 0 },                 { name: "Scrub Mouse", description: "A tiny rodent living among thorny desert brush.", yield: "0.25 lbs", feeds: 0 },                 { name: "Sand Finch", description: "A tiny desert bird caught around a patch of scrub.", yield: "0.25 lbs", feeds: 0 },                 { name: "Lizard Nest", description: "A clutch of small desert lizards is found beneath a warm stone.", yield: "0.5 lbs", feeds: 0 },                 { name: "Young Sand Hare", description: "A very small hare with barely enough meat to salvage.", yield: "0.5 lbs", feeds: 0 },                 { name: "Desert Tortoise", description: "A small tortoise with very little usable meat.", yield: "0.5 lbs", feeds: 0 }             ]         },         {             min: 16,             max: 20,             results: [                 { name: "Desert Hare", description: "A lean hare adapted to the heat and scarcity of the Borderlands.", yield: "1 lb", feeds: 1 },                 { name: "Rock Quail", description: "A small ground bird nesting among broken stone.", yield: "1 lb", feeds: 1 },                 { name: "Large Desert Lizard", description: "A broad-bodied lizard with a modest amount of usable meat.", yield: "1 lb", feeds: 1 },                 { name: "Sand Rat Colony", description: "Several small rodents are found near a sheltered burrow.", yield: "1 lb", feeds: 1 },                 { name: "Scrub Bird", description: "A hardy bird living among thorn scrub.", yield: "1 lb", feeds: 1 },                 { name: "Rock Crab", description: "A land crab hiding beneath stones near a damp area.", yield: "1 lb", feeds: 1 },                 { name: "Small Desert Snake", description: "A thin snake found beneath a rock shelf.", yield: "0.5 lbs", feeds: 0 },                 { name: "Large Quail", description: "A plump desert bird found near sheltered rock.", yield: "1 lb", feeds: 1 },                 { name: "Desert Rodent", description: "A healthy rodent living beneath a ruined stone foundation.", yield: "1 lb", feeds: 1 },                 { name: "Young Jackal", description: "A young desert jackal separated from its pack.", yield: "2 lbs", feeds: 1 }             ]         },         {             min: 21,             max: 25,             results: [                 { name: "Large Desert Hare", description: "A healthy hare found near sheltered scrub.", yield: "2 lbs", feeds: 1 },                 { name: "Desert Goat", description: "A half-wild goat surviving among the rocky slopes.", yield: "5 lbs", feeds: 1 },                 { name: "Young Gazelle", description: "A young antelope found near one of the Borderlands' surviving green pockets.", yield: "5 lbs", feeds: 1 },                 { name: "Jackal", description: "A lean desert jackal caught away from its pack.", yield: "3 lbs", feeds: 1 },                 { name: "Large Desert Bird", description: "A substantial ground bird nesting in a sheltered ruin.", yield: "3 lbs", feeds: 1 },                 { name: "Large Lizard", description: "An unusually large desert lizard with several pounds of usable meat.", yield: "3 lbs", feeds: 1 },                 { name: "Desert Tortoise", description: "A mature desert tortoise with a surprising amount of edible meat.", yield: "4 lbs", feeds: 1 },                 { name: "Large Jackal", description: "A heavy desert jackal that has survived deep in the wastes.", yield: "6 lbs", feeds: 2 },                 { name: "Rock Gazelle", description: "A lean young gazelle found among broken mountain stone.", yield: "6 lbs", feeds: 2 },                 { name: "Feral Goat", description: "A hardy goat surviving without a herd near an old settlement.", yield: "5 lbs", feeds: 1 }             ]         },         {             min: 26,             max: 30,             results: [                 { name: "Ibex", description: "A mountain goat from the rocky Border Mountains.", yield: "12 lbs", feeds: 3 },                 { name: "Gazelle", description: "A full-grown desert gazelle.", yield: "15 lbs", feeds: 3 },                 { name: "Wild Goat", description: "A large feral goat that has survived away from civilization.", yield: "10 lbs", feeds: 2 },                 { name: "Desert Antelope", description: "A mature antelope found near a rare surviving water source.", yield: "15 lbs", feeds: 3 },                 { name: "Mountain Sheep", description: "A large wild sheep taken in the Border Mountains.", yield: "15 lbs", feeds: 3 },                 { name: "Wild Camel", description: "An extraordinarily rare feral camel wandering far from the known caravan roads.", yield: "20 lbs", feeds: 4 },                 { name: "Large Ibex", description: "A powerful mountain goat from a remote pass.", yield: "18 lbs", feeds: 3 },                 { name: "Large Gazelle", description: "A mature gazelle in unusually good condition for the wastes.", yield: "18 lbs", feeds: 3 },                 { name: "Mountain Ram", description: "A heavy wild ram from the Border Mountains.", yield: "20 lbs", feeds: 4 },                 { name: "Wild Camel Herd Animal", description: "A rare mature camel separated from a wandering group.", yield: "25 lbs", feeds: 5 }             ]         }     ];     /* =========================================================        LAKE FISHING        ========================================================= */     var FISHING = [         {             min: 0,             max: 5,             results: [                 {                     name: "Snagged Line",                     description: "Your line snaps or the fish aren't biting.",                     yield: "0 lbs",                     feeds: 0                 }             ]         },         {             min: 6,             max: 10,             results: [                 { name: "Empty Line", description: "Nothing bites.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Water", description: "The water appears almost lifeless.", yield: "0 lbs", feeds: 0 },                 { name: "Broken Shellfish", description: "You find shells, but nothing worth keeping.", yield: "0 lbs", feeds: 0 },                 { name: "Picked Shore", description: "Scavengers and other travelers have already stripped the shoreline.", yield: "0 lbs", feeds: 0 },                 { name: "Lost Bait", description: "You lose your bait without catching anything.", yield: "0 lbs", feeds: 0 },                 { name: "Snagged Hook", description: "The hook catches on submerged stone and breaks free empty.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Pool", description: "You search a promising pool and discover it is nearly lifeless.", yield: "0 lbs", feeds: 0 },                 { name: "Scoured Bank", description: "The shoreline has already been picked clean.", yield: "0 lbs", feeds: 0 },                 { name: "Rotten Catch", description: "You find something dead in the water, but it is unsafe to eat.", yield: "0 lbs", feeds: 0 },                 { name: "Shallow Water", description: "The water is too shallow to support anything worth catching.", yield: "0 lbs", feeds: 0 }             ]         },         {             min: 11,             max: 15,             results: [                 { name: "Tiny Fish", description: "A tiny fish barely worth cleaning.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Crab", description: "A small crab caught beneath a stone.", yield: "0.25 lbs", feeds: 0 },                 { name: "Small Eel", description: "A thin eel pulled from shallow water.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Shellfish", description: "A few edible shellfish hidden beneath wet stones.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Oasis Fish", description: "A small fish from one of the rare surviving freshwater pools.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Mullet", description: "A very small coastal fish caught near the shore.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Rockfish", description: "A tiny fish hiding between coastal rocks.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Crab Cluster", description: "Several very small crabs are found under a rock shelf.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Carp", description: "A young carp from a surviving oasis pool.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Mudfish", description: "A small fish from stagnant desert water.", yield: "0.5 lbs", feeds: 0 },                 { name: "Thin Eel", description: "A narrow eel from a dark water channel.", yield: "0.5 lbs", feeds: 0 },                 { name: "Small Shellfish", description: "A modest handful of edible shellfish.", yield: "0.5 lbs", feeds: 0 }             ]         },         {             min: 16,             max: 20,             results: [                 { name: "Coastal Mullet", description: "A lean silver fish common near the waters around Saltspire.", yield: "1 lb", feeds: 1 },                 { name: "Rockfish", description: "A small fish found close to rocks and cliffs.", yield: "1 lb", feeds: 1 },                 { name: "Small Carp", description: "A hardy fish surviving in a rare freshwater pool.", yield: "1 lb", feeds: 1 },                 { name: "Small Catfish", description: "A bottom-feeding fish from a surviving oasis pool.", yield: "1 lb", feeds: 1 },                 { name: "Small Eel", description: "A fat eel pulled from a dark channel.", yield: "1 lb", feeds: 1 },                 { name: "Redfin", description: "A hardy fish from an isolated pool.", yield: "1 lb", feeds: 1 },                 { name: "Desert Perch", description: "A small fish surviving in a warm spring-fed pool.", yield: "1 lb", feeds: 1 },                 { name: "Sea Drum", description: "A modest coastal fish caught near Saltspire.", yield: "1 lb", feeds: 1 },                 { name: "Oasis Tilapia", description: "A hardy fish surviving in warm freshwater.", yield: "1 lb", feeds: 1 },                 { name: "Small Bream", description: "A silver coastal fish from shallow water.", yield: "1 lb", feeds: 1 }             ]         },         {             min: 21,             max: 25,             results: [                 { name: "Large Mullet", description: "A healthy coastal fish from deeper water.", yield: "3 lbs", feeds: 1 },                 { name: "Oasis Catfish", description: "A thick-bodied catfish surviving in a deep water source.", yield: "3 lbs", feeds: 1 },                 { name: "Sea Bream", description: "A solid coastal fish caught below the cliffs of Saltspire.", yield: "4 lbs", feeds: 1 },                 { name: "Large Carp", description: "An old carp that has survived in an isolated pool.", yield: "4 lbs", feeds: 1 },                 { name: "Redfin", description: "A hardy fish from a deep oasis pool.", yield: "2 lbs", feeds: 1 },                 { name: "Large Eel", description: "A thick eel pulled from a dark water channel.", yield: "3 lbs", feeds: 1 },                 { name: "Rock Bass", description: "A stocky coastal predator found around broken stone.", yield: "3 lbs", feeds: 1 },                 { name: "Oasis Trout", description: "A rare trout surviving in cold desert spring water.", yield: "4 lbs", feeds: 1 }             ]         },         {             min: 26,             max: 30,             results: [                 { name: "Large Sea Bream", description: "A heavy saltwater fish caught in the deeper waters around Saltspire.", yield: "6 lbs", feeds: 2 },                 { name: "Large Catfish", description: "A rare large catfish from a deep oasis or hidden water source.", yield: "8 lbs", feeds: 2 },                 { name: "Barracuda", description: "A dangerous coastal predator with substantial usable meat.", yield: "7 lbs", feeds: 2 },                 { name: "Giant Oasis Catfish", description: "A remarkably large catfish from an ancient surviving pool.", yield: "12 lbs", feeds: 3 },                 { name: "Ancient Carp", description: "A huge carp that has survived for years in isolated water.", yield: "10 lbs", feeds: 2 },                 { name: "Large Sea Drum", description: "A broad-bodied fish from deeper coastal waters.", yield: "9 lbs", feeds: 2 },                 { name: "Large Eel", description: "A massive eel found in a deep surviving waterway.", yield: "8 lbs", feeds: 2 },                 { name: "Deepwater Predator", description: "A rare heavy fish pulled from unusually deep coastal water.", yield: "12 lbs", feeds: 3 },                 { name: "Giant Oasis Bream", description: "An enormous fish from an exceptionally old freshwater pool.", yield: "10 lbs", feeds: 2 }             ]         }     ];     /* =========================================================        GATHERING TABLE        ========================================================= */     var GATHERING = [         {             min: 0,             max: 5,             results: [                 {                     name: "Poor Forage",                     description: "You find little worth eating. Most plants are rotten, bitter, or unsuitable.",                     yield: "0 lbs",                     feeds: 0                 },                 {                     name: "Barren Patch",                     description: "The area has already been picked over by wildlife or other travelers.",                     yield: "0 lbs",                     feeds: 0                 },                 {                     name: "Spoiled Growth",                     description: "You find plants, but they are damaged, diseased, or unsafe to eat.",                     yield: "0 lbs",                     feeds: 0                 }             ]         },         {             min: 6,             max: 10,             results: [                 { name: "Dry Cactus", description: "You find cactus, but it is too dry or damaged to provide anything useful.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Roots", description: "Roots are present beneath the sand, but they are dried beyond use.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Algae", description: "Algae coats a damp surface, but it has already spoiled.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Seed Pods", description: "You find seed pods that have already dropped their contents.", yield: "0 lbs", feeds: 0 },                 { name: "Scoured Ground", description: "Animals and travelers have already stripped the area.", yield: "0 lbs", feeds: 0 },                 { name: "Bitter Cactus", description: "The cactus is too bitter or contaminated to eat safely.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Scrub", description: "The scrub is completely dried out.", yield: "0 lbs", feeds: 0 },                 { name: "Wilted Oasis Growth", description: "The plants around a former water source are dead.", yield: "0 lbs", feeds: 0 },                 { name: "Dry Bulbs", description: "You find bulbs, but they are hard and useless.", yield: "0 lbs", feeds: 0 },                 { name: "Rotten Algae", description: "The algae has gone foul beneath the heat.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Cactus", description: "The cactus has been stripped by animals before you arrived.", yield: "0 lbs", feeds: 0 },                 { name: "Windblown Seeds", description: "You find seed husks, but almost no edible seed remains.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Vines", description: "Old vines cling to broken stone, but nothing remains edible.", yield: "0 lbs", feeds: 0 },                 { name: "Sand-Choked Roots", description: "Roots survive below the surface, but not enough to harvest.", yield: "0 lbs", feeds: 0 },                 { name: "Spoiled Fruit", description: "A few dried fruits remain, but they are unsafe.", yield: "0 lbs", feeds: 0 },                 { name: "Salt-Burned Growth", description: "The plants have been damaged by mineral-heavy water.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Reed Bed", description: "A former wetland has completely dried out.", yield: "0 lbs", feeds: 0 },                 { name: "Ruined Garden", description: "You find the remains of an old cultivated plot, but nothing useful survives.", yield: "0 lbs", feeds: 0 },                 { name: "Trampled Growth", description: "Animals have already eaten what little remained here.", yield: "0 lbs", feeds: 0 },                 { name: "Barren Hollow", description: "The hollow looks promising, but the ground contains nothing edible.", yield: "0 lbs", feeds: 0 },                 { name: "Dry Algae Mat", description: "Old algae clings to stone, but has become useless.", yield: "0 lbs", feeds: 0 },                 { name: "Crushed Seed Pods", description: "You find the remains of seed pods scattered across the ground.", yield: "0 lbs", feeds: 0 },                 { name: "Dead Bulrush", description: "The old wetland plants have completely dried out.", yield: "0 lbs", feeds: 0 },                 { name: "Scorched Roots", description: "The heat has ruined what little root growth survived.", yield: "0 lbs", feeds: 0 },                 { name: "Empty Scrub", description: "There is simply nothing edible here.", yield: "0 lbs", feeds: 0 }             ]         },         {             min: 11,             max: 19,             results: [                 { name: "Cactus Pulp", description: "A small amount of edible cactus flesh.", yield: "0.25 lbs", feeds: 0 },                 { name: "Cactus Fruit", description: "A few small fruits hidden beneath the thorns.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Seeds", description: "A small handful of hardy seeds.", yield: "0.25 lbs", feeds: 0 },                 { name: "Edible Roots", description: "A few thin roots found beneath stubborn scrub.", yield: "0.25 lbs", feeds: 0 },                 { name: "Fresh Algae", description: "A small patch of edible algae survives near damp ground.", yield: "0.5 lbs", feeds: 0 },                 { name: "Cactus Needles & Pulp", description: "A little usable cactus flesh hidden beneath the thorns.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Bulb", description: "A single edible bulb hidden below the sand.", yield: "0.25 lbs", feeds: 0 },                 { name: "Seed Cluster", description: "A small cluster of hardy desert seeds.", yield: "0.25 lbs", feeds: 0 },                 { name: "Oasis Shoot", description: "One small edible shoot growing beside a hidden water source.", yield: "0.25 lbs", feeds: 0 },                 { name: "Young Cactus Fruit", description: "A single ripe fruit overlooked by scavengers.", yield: "0.25 lbs", feeds: 0 },                 { name: "Edible Reed Root", description: "A small edible root from a surviving waterway.", yield: "0.5 lbs", feeds: 0 },                 { name: "Fresh Desert Herb", description: "A tiny patch of hardy edible herbs.", yield: "0.25 lbs", feeds: 0 },                 { name: "Algae Scraps", description: "A small harvest of fresh edible algae.", yield: "0.5 lbs", feeds: 0 },                 { name: "Tiny Desert Fruit", description: "A few small fruits from a surviving scrub plant.", yield: "0.25 lbs", feeds: 0 },                 { name: "Root Cluster", description: "Several thin edible roots beneath the sand.", yield: "0.5 lbs", feeds: 0 },                 { name: "Cactus Buds", description: "A handful of young cactus growth that can be prepared as food.", yield: "0.25 lbs", feeds: 0 },                 { name: "Desert Grass Seed", description: "A small harvest of edible seed from stubborn desert grass.", yield: "0.25 lbs", feeds: 0 },                 { name: "Oasis Leaf Cluster", description: "A few edible leaves from a rare surviving plant.", yield: "0.5 lbs", feeds: 0 },                 { name: "Young Cactus Growth", description: "A small amount of fresh cactus flesh.", yield: "0.5 lbs", feeds: 0 },                 { name: "Damp Soil Roots", description: "A few edible roots found near buried water.", yield: "0.5 lbs", feeds: 0 }             ]         },         {             min: 20,             max: 30,             results: [                 { name: "Cactus Fruit & Pulp", description: "A productive cactus provides both fruit and water-rich flesh.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Roots & Seeds", description: "An underground harvest accompanied by edible seed pods.", yield: "2 lbs total", feeds: 1 },                 { name: "Oasis Greens", description: "Tender greens grow around a rare source of water.", yield: "2 lbs", feeds: 1 },                 { name: "Algae & Cactus", description: "A damp depression provides edible algae and fresh cactus.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Bulbs", description: "Small starchy bulbs survive beneath hardened soil.", yield: "2 lbs", feeds: 1 },                 { name: "Cactus Fruit & Seeds", description: "A mature cactus patch produces fruit and a modest seed harvest.", yield: "2 lbs total", feeds: 1 },                 { name: "Cactus Pulp & Roots", description: "A productive patch yields water-rich flesh and edible roots.", yield: "2 lbs total", feeds: 1 },                 { name: "Oasis Herbs & Seeds", description: "A rare water source supports hardy herbs and edible seeds.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Greens & Bulbs", description: "Several edible plants grow together in damp soil.", yield: "2 lbs total", feeds: 1 },                 { name: "Fresh Algae Bed", description: "A surviving patch of edible algae provides a modest harvest.", yield: "2 lbs", feeds: 1 },                 { name: "Cactus Fruit Grove", description: "Several mature cactus plants provide a useful amount of fruit.", yield: "3 lbs total", feeds: 1 },                 { name: "Hidden Root Patch", description: "A sheltered area contains a cluster of edible desert roots.", yield: "2 lbs", feeds: 1 },                 { name: "Seed & Cactus Harvest", description: "Edible seed pods grow among several mature cactus plants.", yield: "2 lbs total", feeds: 1 },                 { name: "Oasis Reed Roots", description: "A rare surviving wetland supports edible roots.", yield: "2 lbs", feeds: 1 },                 { name: "Desert Herb Patch", description: "A sheltered hollow contains several edible hardy herbs.", yield: "2 lbs total", feeds: 1 },                 { name: "Cactus Buds & Fruit", description: "Young cactus growth and fruit can both be harvested.", yield: "2 lbs total", feeds: 1 },                 { name: "Algae & Oasis Greens", description: "Fresh algae grows beside edible green shoots.", yield: "2 lbs total", feeds: 1 },                 { name: "Desert Root & Fruit Patch", description: "A rare pocket contains both edible roots and fruit.", yield: "2 lbs total", feeds: 1 },                 { name: "Hidden Spring Growth", description: "Moist ground supports a productive patch of roots and greens.", yield: "3 lbs total", feeds: 2 },                 { name: "Cactus Grove", description: "A mature stand of cactus provides a surprisingly large harvest.", yield: "3 lbs total", feeds: 2 }             ]         }     ];     /* =========================================================        GET SELECTED CHARACTER        ========================================================= */     function getSelectedCharacter(msg) {         if (!msg.selected || msg.selected.length === 0) {             return null;         }         var token = getObj("graphic", msg.selected[0]._id);         if (!token) {             return null;         }         var characterId = token.get("represents");         if (!characterId) {             return null;         }         return getObj("character", characterId);     }     /* =========================================================        GET CHARACTER        ========================================================= */     function getCharacter(msg, characterId) {         if (characterId) {             return getObj("character", characterId);         }         return getSelectedCharacter(msg);     }     /* =========================================================        WHISPER        ========================================================= */     function whisper(msg, content) {         var who = (msg.who || "GM").replace(/\s+\(GM\)$/, "");         sendChat("Survival System", '/w "' + who.replace(/"/g, "") + '" ' + content);     }     /* =========================================================        GET ATTRIBUTE NUMBER        ========================================================= */     function getAttributeNumber(character, name) {         var value = getAttrByName(character.id, name);         var number = Number(value);         return Number.isFinite(number) ? number : null;     }     /* =========================================================        FIND BRACKET        ========================================================= */     function findBracket(table, result) {         for (var i = 0; i < table.length; i++) {             if (result >= table[i].min && result <= table[i].max) {                 return table[i];             }         }         return table[0];     }     /* =========================================================        RANDOM FIND        ========================================================= */     function randomFind(bracket) {         var index = randomInteger(bracket.results.length) - 1;         return bracket.results[index];     }     /* =========================================================        SHOW MENU        ========================================================= */     function showMenu(msg, character) {         var characterId = character.id;         var output =             "&{template:default}" +             "{{name=Survival}}" +             "{{Character=" + character.get("name") + "}}" +             "{{Choose an Activity=" +             "[Hunting](!survival hunting " + characterId + ") " +             "[Lake Fishing](!survival fishing " + characterId + ") " +             "[Gathering](!survival gathering " + characterId + ")" +             "}}";         whisper(msg, output);     }     /* =========================================================        MAIN COMMAND        ========================================================= */     function runSurvival(msg) {         if (msg.type !== "api") {             return;         }         var parts = msg.content.trim().split(/\s+/);         if (parts[0] !== "!survival") {             return;         }         var activity = parts[1];         var characterId = parts[2];         var character = getCharacter(msg, characterId);         if (!character) {             whisper(                 msg,                 "<b>Select a token whose Represents Character field is linked to a character sheet first.</b>"             );             return;         }         if (!activity) {             showMenu(msg, character);             return;         }         if (             activity !== "hunting" &&             activity !== "fishing" &&             activity !== "gathering"         ) {             whisper(msg, "<b>Choose Hunting, Lake Fishing, or Gathering.</b>");             return;         }         /* -----------------------------------------------------            SURVIVAL ROLL            ----------------------------------------------------- */         var survivalBonus = getAttributeNumber(character, "survival_bonus");         if (survivalBonus === null) {             whisper(                 msg,                 "<b>Could not read the Survival bonus from this character sheet.</b> " +                 "The script expects an exposed <code>survival_bonus</code> attribute."             );             return;         }         var d20 = randomInteger(20);         var rawResult = d20 + survivalBonus;         /* Cap Survival between 0 and 30. */         var survivalResult = Math.max(0, Math.min(rawResult, 30));         /* -----------------------------------------------------            SELECT TABLE            ----------------------------------------------------- */         var table;         var activityName;         if (activity === "hunting") {             table = HUNTING;             activityName = "Hunting";         } else if (activity === "fishing") {             table = FISHING;             activityName = "Lake Fishing";         } else {             table = GATHERING;             activityName = "Gathering";         }         /* -----------------------------------------------------            FIND RESULT            ----------------------------------------------------- */         var bracket = findBracket(table, survivalResult);         var result = randomFind(bracket);         /* -----------------------------------------------------            DISPLAY            ----------------------------------------------------- */         var output =             "&{template:default}" +             "{{name=Survival — " + activityName + "}}" +             "{{Character=" + character.get("name") + "}}" +             "{{D20 Roll=" + d20 + "}}" +             "{{Survival Bonus=" + (survivalBonus >= 0 ? "+" : "") + survivalBonus + "}}" +             "{{Survival Result=" + survivalResult + "}}" +             "{{Find=" + result.name + "}}" +             "{{Description=" + result.description + "}}" +             "{{Food Yield=" + result.yield + "}}" +             "{{Feeds=" + result.feeds + " people}}";         sendChat(character.get("name"), output);     }     /* =========================================================        REGISTER COMMAND        ========================================================= */     on("ready", function () {         log("======================================");         log("D&D 5.5e SURVIVAL SYSTEM LOADED");         log("Command: !survival");         log("======================================");         on("chat:message", runSurvival);     }); })();
normally I get this message: 11:18AM (From Survival System): Survival Character Kette Choose an Activity Hunting Lake Fishing Gathering 11:18AM (From Survival System): Could not read the Survival bonus from this character sheet. The script expects an exposed survival_bonus attribute. 11:18AM (From Survival System): Survival Character Hoxil Choose an Activity Hunting Lake Fishing Gathering 11:18AM (From Survival System): Could not read the Survival bonus from this character sheet. The script expects an exposed survival_bonus attribute.
I didn't use a Macro besides the !Survival 
It sounds like you're using the D&D 5e 2024 sheet, which is Beacon-based and not all attributes are exposed to Mod scripts.  Try this - this is about as far as I can get: /* ============================================================ D&D 5.5e SURVIVAL SYSTEM Hunting / Lake Fishing / Gathering COMMAND: !survival WORKFLOW: 1. Select a token linked to a character sheet. 2. Run !survival. 3. Choose Hunting, Lake Fishing, or Gathering. 4. The script rolls 1d20 and reads the character's Survival bonus. 5. It first tries survival_bonus. 6. If unavailable, it falls back to wisdom_mod + pb. 7. The final result is capped between 0 and 30. ============================================================ */ var SurvivalSystem = SurvivalSystem || (function () { /* ========================================================= HUNTING ========================================================= */ var HUNTING = [ { min: 0, max: 5, results: [ { name: "Nothing", description: "You find no tracks or scare away wildlife.", yield: "0 lbs", feeds: 0 } ] }, { min: 6, max: 10, results: [ { name: "Empty Burrow", description: "You find signs of a small desert animal, but the burrow is abandoned.", yield: "0 lbs", feeds: 0 }, { name: "Old Tracks", description: "The tracks are too old to follow.", yield: "0 lbs", feeds: 0 }, { name: "Picked Clean", description: "Whatever passed through this area has already taken anything edible.", yield: "0 lbs", feeds: 0 }, { name: "Scavenger Sign", description: "You find evidence of jackals or other scavengers, but no viable prey.", yield: "0 lbs", feeds: 0 }, { name: "Buried Nest", description: "You find a nest, but it has already been emptied.", yield: "0 lbs", feeds: 0 }, { name: "Broken Trail", description: "A set of fresh-looking tracks vanishes across the hard-packed sand.", yield: "0 lbs", feeds: 0 }, { name: "Old Droppings", description: "You find droppings from a desert animal, but the trail is long gone.", yield: "0 lbs", feeds: 0 }, { name: "Scorpion Tracks", description: "The signs lead to a dangerous burrow, but there is nothing worth eating.", yield: "0 lbs", feeds: 0 }, { name: "Empty Nest", description: "A small desert bird has already abandoned the nest.", yield: "0 lbs", feeds: 0 }, { name: "Dead End", description: "You follow a promising trail only to discover it disappears among the dunes.", yield: "0 lbs", feeds: 0 }, { name: "Scrub Sign", description: "Something has fed in the scrub recently, but you cannot locate it.", yield: "0 lbs", feeds: 0 } ] }, { min: 11, max: 15, results: [ { name: "Desert Lizard", description: "A small lizard hiding beneath a sun-warmed stone.", yield: "0.25 lbs", feeds: 0 }, { name: "Sand Rat", description: "A small desert rodent caught near its burrow.", yield: "0.25 lbs", feeds: 0 }, { name: "Small Desert Bird", description: "A tiny bird nesting among rocks or scrub.", yield: "0.25 lbs", feeds: 0 }, { name: "Desert Beetles", description: "A handful of large edible desert insects.", yield: "0.25 lbs", feeds: 0 }, { name: "Tiny Desert Hare", description: "A very small hare with little usable meat.", yield: "0.5 lbs", feeds: 0 }, { name: "Rock Crab", description: "A small land crab hiding beneath a stone near damp ground.", yield: "0.25 lbs", feeds: 0 }, { name: "Small Desert Snake", description: "A thin snake found beneath a rock shelf.", yield: "0.5 lbs", feeds: 0 }, { name: "Scrub Mouse", description: "A tiny rodent living among thorny desert brush.", yield: "0.25 lbs", feeds: 0 }, { name: "Sand Finch", description: "A tiny desert bird caught around a patch of scrub.", yield: "0.25 lbs", feeds: 0 }, { name: "Lizard Nest", description: "A clutch of small desert lizards is found beneath a warm stone.", yield: "0.5 lbs", feeds: 0 }, { name: "Young Sand Hare", description: "A very small hare with barely enough meat to salvage.", yield: "0.5 lbs", feeds: 0 }, { name: "Desert Tortoise", description: "A small tortoise with very little usable meat.", yield: "0.5 lbs", feeds: 0 } ] }, { min: 16, max: 20, results: [ { name: "Desert Hare", description: "A lean hare adapted to the heat and scarcity of the Borderlands.", yield: "1 lb", feeds: 1 }, { name: "Rock Quail", description: "A small ground bird nesting among broken stone.", yield: "1 lb", feeds: 1 }, { name: "Large Desert Lizard", description: "A broad-bodied lizard with a modest amount of usable meat.", yield: "1 lb", feeds: 1 }, { name: "Sand Rat Colony", description: "Several small rodents are found near a sheltered burrow.", yield: "1 lb", feeds: 1 }, { name: "Scrub Bird", description: "A hardy bird living among thorn scrub.", yield: "1 lb", feeds: 1 }, { name: "Rock Crab", description: "A land crab hiding beneath stones near a damp area.", yield: "1 lb", feeds: 1 }, { name: "Small Desert Snake", description: "A thin snake found beneath a rock shelf.", yield: "0.5 lbs", feeds: 0 }, { name: "Large Quail", description: "A plump desert bird found near sheltered rock.", yield: "1 lb", feeds: 1 }, { name: "Desert Rodent", description: "A healthy rodent living beneath a ruined stone foundation.", yield: "1 lb", feeds: 1 }, { name: "Young Jackal", description: "A young desert jackal separated from its pack.", yield: "2 lbs", feeds: 1 } ] }, { min: 21, max: 25, results: [ { name: "Large Desert Hare", description: "A healthy hare found near sheltered scrub.", yield: "2 lbs", feeds: 1 }, { name: "Desert Goat", description: "A half-wild goat surviving among the rocky slopes.", yield: "5 lbs", feeds: 1 }, { name: "Young Gazelle", description: "A young antelope found near one of the Borderlands' surviving green pockets.", yield: "5 lbs", feeds: 1 }, { name: "Jackal", description: "A lean desert jackal caught away from its pack.", yield: "3 lbs", feeds: 1 }, { name: "Large Desert Bird", description: "A substantial ground bird nesting in a sheltered ruin.", yield: "3 lbs", feeds: 1 }, { name: "Large Lizard", description: "An unusually large desert lizard with several pounds of usable meat.", yield: "3 lbs", feeds: 1 }, { name: "Desert Tortoise", description: "A mature desert tortoise with a surprising amount of edible meat.", yield: "4 lbs", feeds: 1 }, { name: "Large Jackal", description: "A heavy desert jackal that has survived deep in the wastes.", yield: "6 lbs", feeds: 2 }, { name: "Rock Gazelle", description: "A lean young gazelle found among broken mountain stone.", yield: "6 lbs", feeds: 2 }, { name: "Feral Goat", description: "A hardy goat surviving without a herd near an old settlement.", yield: "5 lbs", feeds: 1 } ] }, { min: 26, max: 30, results: [ { name: "Ibex", description: "A mountain goat from the rocky Border Mountains.", yield: "12 lbs", feeds: 3 }, { name: "Gazelle", description: "A full-grown desert gazelle.", yield: "15 lbs", feeds: 3 }, { name: "Wild Goat", description: "A large feral goat that has survived away from civilization.", yield: "10 lbs", feeds: 2 }, { name: "Desert Antelope", description: "A mature antelope found near a rare surviving water source.", yield: "15 lbs", feeds: 3 }, { name: "Mountain Sheep", description: "A large wild sheep taken in the Border Mountains.", yield: "15 lbs", feeds: 3 }, { name: "Wild Camel", description: "An extraordinarily rare feral camel wandering far from the known caravan roads.", yield: "20 lbs", feeds: 4 }, { name: "Large Ibex", description: "A powerful mountain goat from a remote pass.", yield: "18 lbs", feeds: 3 }, { name: "Large Gazelle", description: "A mature gazelle in unusually good condition for the wastes.", yield: "18 lbs", feeds: 3 }, { name: "Mountain Ram", description: "A heavy wild ram from the Border Mountains.", yield: "20 lbs", feeds: 4 }, { name: "Wild Camel Herd Animal", description: "A rare mature camel separated from a wandering group.", yield: "25 lbs", feeds: 5 } ] } ]; /* ========================================================= LAKE FISHING ========================================================= */ var FISHING = [ { min: 0, max: 5, results: [ { name: "Snagged Line", description: "Your line snaps or the fish aren't biting.", yield: "0 lbs", feeds: 0 } ] }, { min: 6, max: 10, results: [ { name: "Empty Line", description: "Nothing bites.", yield: "0 lbs", feeds: 0 }, { name: "Dead Water", description: "The water appears almost lifeless.", yield: "0 lbs", feeds: 0 }, { name: "Broken Shellfish", description: "You find shells, but nothing worth keeping.", yield: "0 lbs", feeds: 0 }, { name: "Picked Shore", description: "Scavengers and other travelers have already stripped the shoreline.", yield: "0 lbs", feeds: 0 }, { name: "Lost Bait", description: "You lose your bait without catching anything.", yield: "0 lbs", feeds: 0 }, { name: "Snagged Hook", description: "The hook catches on submerged stone and breaks free empty.", yield: "0 lbs", feeds: 0 }, { name: "Empty Pool", description: "You search a promising pool and discover it is nearly lifeless.", yield: "0 lbs", feeds: 0 }, { name: "Scoured Bank", description: "The shoreline has already been picked clean.", yield: "0 lbs", feeds: 0 }, { name: "Rotten Catch", description: "You find something dead in the water, but it is unsafe to eat.", yield: "0 lbs", feeds: 0 }, { name: "Shallow Water", description: "The water is too shallow to support anything worth catching.", yield: "0 lbs", feeds: 0 } ] }, { min: 11, max: 15, results: [ { name: "Tiny Fish", description: "A tiny fish barely worth cleaning.", yield: "0.25 lbs", feeds: 0 }, { name: "Small Crab", description: "A small crab caught beneath a stone.", yield: "0.25 lbs", feeds: 0 }, { name: "Small Eel", description: "A thin eel pulled from shallow water.", yield: "0.5 lbs", feeds: 0 }, { name: "Tiny Shellfish", description: "A few edible shellfish hidden beneath wet stones.", yield: "0.5 lbs", feeds: 0 }, { name: "Small Oasis Fish", description: "A small fish from one of the rare surviving freshwater pools.", yield: "0.5 lbs", feeds: 0 }, { name: "Tiny Mullet", description: "A very small coastal fish caught near the shore.", yield: "0.5 lbs", feeds: 0 }, { name: "Small Rockfish", description: "A tiny fish hiding between coastal rocks.", yield: "0.5 lbs", feeds: 0 }, { name: "Small Crab Cluster", description: "Several very small crabs are found under a rock shelf.", yield: "0.5 lbs", feeds: 0 }, { name: "Tiny Carp", description: "A young carp from a surviving oasis pool.", yield: "0.5 lbs", feeds: 0 }, { name: "Small Mudfish", description: "A small fish from stagnant desert water.", yield: "0.5 lbs", feeds: 0 }, { name: "Thin Eel", description: "A narrow eel from a dark water channel.", yield: "0.5 lbs", feeds: 0 }, { name: "Small Shellfish", description: "A modest handful of edible shellfish.", yield: "0.5 lbs", feeds: 0 } ] }, { min: 16, max: 20, results: [ { name: "Coastal Mullet", description: "A lean silver fish common near the waters around Saltspire.", yield: "1 lb", feeds: 1 }, { name: "Rockfish", description: "A small fish found close to rocks and cliffs.", yield: "1 lb", feeds: 1 }, { name: "Small Carp", description: "A hardy fish surviving in a rare freshwater pool.", yield: "1 lb", feeds: 1 }, { name: "Small Catfish", description: "A bottom-feeding fish from a surviving oasis pool.", yield: "1 lb", feeds: 1 }, { name: "Small Eel", description: "A fat eel pulled from a dark channel.", yield: "1 lb", feeds: 1 }, { name: "Redfin", description: "A hardy fish from an isolated pool.", yield: "1 lb", feeds: 1 }, { name: "Desert Perch", description: "A small fish surviving in a warm spring-fed pool.", yield: "1 lb", feeds: 1 }, { name: "Sea Drum", description: "A modest coastal fish caught near Saltspire.", yield: "1 lb", feeds: 1 }, { name: "Oasis Tilapia", description: "A hardy fish surviving in warm freshwater.", yield: "1 lb", feeds: 1 }, { name: "Small Bream", description: "A silver coastal fish from shallow water.", yield: "1 lb", feeds: 1 } ] }, { min: 21, max: 25, results: [ { name: "Large Mullet", description: "A healthy coastal fish from deeper water.", yield: "3 lbs", feeds: 1 }, { name: "Oasis Catfish", description: "A thick-bodied catfish surviving in a deep water source.", yield: "3 lbs", feeds: 1 }, { name: "Sea Bream", description: "A solid coastal fish caught below the cliffs of Saltspire.", yield: "4 lbs", feeds: 1 }, { name: "Large Carp", description: "An old carp that has survived in an isolated pool.", yield: "4 lbs", feeds: 1 }, { name: "Redfin", description: "A hardy fish from a deep oasis pool.", yield: "2 lbs", feeds: 1 }, { name: "Large Eel", description: "A thick eel pulled from a dark water channel.", yield: "3 lbs", feeds: 1 }, { name: "Rock Bass", description: "A stocky coastal predator found around broken stone.", yield: "3 lbs", feeds: 1 }, { name: "Oasis Trout", description: "A rare trout surviving in cold desert spring water.", yield: "4 lbs", feeds: 1 } ] }, { min: 26, max: 30, results: [ { name: "Large Sea Bream", description: "A heavy saltwater fish caught in the deeper waters around Saltspire.", yield: "6 lbs", feeds: 2 }, { name: "Large Catfish", description: "A rare large catfish from a deep oasis or hidden water source.", yield: "8 lbs", feeds: 2 }, { name: "Barracuda", description: "A dangerous coastal predator with substantial usable meat.", yield: "7 lbs", feeds: 2 }, { name: "Giant Oasis Catfish", description: "A remarkably large catfish from an ancient surviving pool.", yield: "12 lbs", feeds: 3 }, { name: "Ancient Carp", description: "A huge carp that has survived for years in isolated water.", yield: "10 lbs", feeds: 2 }, { name: "Large Sea Drum", description: "A broad-bodied fish from deeper coastal waters.", yield: "9 lbs", feeds: 2 }, { name: "Large Eel", description: "A massive eel found in a deep surviving waterway.", yield: "8 lbs", feeds: 2 }, { name: "Deepwater Predator", description: "A rare heavy fish pulled from unusually deep coastal water.", yield: "12 lbs", feeds: 3 }, { name: "Giant Oasis Bream", description: "An enormous fish from an exceptionally old freshwater pool.", yield: "10 lbs", feeds: 2 } ] } ]; /* ========================================================= GATHERING TABLE ========================================================= */ var GATHERING = [ { min: 0, max: 5, results: [ { name: "Poor Forage", description: "You find little worth eating. Most plants are rotten, bitter, or unsuitable.", yield: "0 lbs", feeds: 0 }, { name: "Barren Patch", description: "The area has already been picked over by wildlife or other travelers.", yield: "0 lbs", feeds: 0 }, { name: "Spoiled Growth", description: "You find plants, but they are damaged, diseased, or unsafe to eat.", yield: "0 lbs", feeds: 0 } ] }, { min: 6, max: 10, results: [ { name: "Dry Cactus", description: "You find cactus, but it is too dry or damaged to provide anything useful.", yield: "0 lbs", feeds: 0 }, { name: "Dead Roots", description: "Roots are present beneath the sand, but they are dried beyond use.", yield: "0 lbs", feeds: 0 }, { name: "Dead Algae", description: "Algae coats a damp surface, but it has already spoiled.", yield: "0 lbs", feeds: 0 }, { name: "Empty Seed Pods", description: "You find seed pods that have already dropped their contents.", yield: "0 lbs", feeds: 0 }, { name: "Scoured Ground", description: "Animals and travelers have already stripped the area.", yield: "0 lbs", feeds: 0 }, { name: "Bitter Cactus", description: "The cactus is too bitter or contaminated to eat safely.", yield: "0 lbs", feeds: 0 }, { name: "Dead Scrub", description: "The scrub is completely dried out.", yield: "0 lbs", feeds: 0 }, { name: "Wilted Oasis Growth", description: "The plants around a former water source are dead.", yield: "0 lbs", feeds: 0 }, { name: "Dry Bulbs", description: "You find bulbs, but they are hard and useless.", yield: "0 lbs", feeds: 0 }, { name: "Rotten Algae", description: "The algae has gone foul beneath the heat.", yield: "0 lbs", feeds: 0 }, { name: "Empty Cactus", description: "The cactus has been stripped by animals before you arrived.", yield: "0 lbs", feeds: 0 }, { name: "Windblown Seeds", description: "You find seed husks, but almost no edible seed remains.", yield: "0 lbs", feeds: 0 }, { name: "Dead Vines", description: "Old vines cling to broken stone, but nothing remains edible.", yield: "0 lbs", feeds: 0 }, { name: "Sand-Choked Roots", description: "Roots survive below the surface, but not enough to harvest.", yield: "0 lbs", feeds: 0 }, { name: "Spoiled Fruit", description: "A few dried fruits remain, but they are unsafe.", yield: "0 lbs", feeds: 0 }, { name: "Salt-Burned Growth", description: "The plants have been damaged by mineral-heavy water.", yield: "0 lbs", feeds: 0 }, { name: "Dead Reed Bed", description: "A former wetland has completely dried out.", yield: "0 lbs", feeds: 0 }, { name: "Ruined Garden", description: "You find the remains of an old cultivated plot, but nothing useful survives.", yield: "0 lbs", feeds: 0 }, { name: "Trampled Growth", description: "Animals have already eaten what little remained here.", yield: "0 lbs", feeds: 0 }, { name: "Barren Hollow", description: "The hollow looks promising, but the ground contains nothing edible.", yield: "0 lbs", feeds: 0 }, { name: "Dry Algae Mat", description: "Old algae clings to stone, but has become useless.", yield: "0 lbs", feeds: 0 }, { name: "Crushed Seed Pods", description: "You find the remains of seed pods scattered across the ground.", yield: "0 lbs", feeds: 0 }, { name: "Dead Bulrush", description: "The old wetland plants have completely dried out.", yield: "0 lbs", feeds: 0 }, { name: "Scorched Roots", description: "The heat has ruined what little root growth survived.", yield: "0 lbs", feeds: 0 }, { name: "Empty Scrub", description: "There is simply nothing edible here.", yield: "0 lbs", feeds: 0 } ] }, { min: 11, max: 19, results: [ { name: "Cactus Pulp", description: "A small amount of edible cactus flesh.", yield: "0.25 lbs", feeds: 0 }, { name: "Cactus Fruit", description: "A few small fruits hidden beneath the thorns.", yield: "0.25 lbs", feeds: 0 }, { name: "Desert Seeds", description: "A small handful of hardy seeds.", yield: "0.25 lbs", feeds: 0 }, { name: "Edible Roots", description: "A few thin roots found beneath stubborn scrub.", yield: "0.25 lbs", feeds: 0 }, { name: "Fresh Algae", description: "A small patch of edible algae survives near damp ground.", yield: "0.5 lbs", feeds: 0 }, { name: "Cactus Needles & Pulp", description: "A little usable cactus flesh hidden beneath the thorns.", yield: "0.25 lbs", feeds: 0 }, { name: "Desert Bulb", description: "A single edible bulb hidden below the sand.", yield: "0.25 lbs", feeds: 0 }, { name: "Seed Cluster", description: "A small cluster of hardy desert seeds.", yield: "0.25 lbs", feeds: 0 }, { name: "Oasis Shoot", description: "One small edible shoot growing beside a hidden water source.", yield: "0.25 lbs", feeds: 0 }, { name: "Young Cactus Fruit", description: "A single ripe fruit overlooked by scavengers.", yield: "0.25 lbs", feeds: 0 }, { name: "Edible Reed Root", description: "A small edible root from a surviving waterway.", yield: "0.5 lbs", feeds: 0 }, { name: "Fresh Desert Herb", description: "A tiny patch of hardy edible herbs.", yield: "0.25 lbs", feeds: 0 }, { name: "Algae Scraps", description: "A small harvest of fresh edible algae.", yield: "0.5 lbs", feeds: 0 }, { name: "Tiny Desert Fruit", description: "A few small fruits from a surviving scrub plant.", yield: "0.25 lbs", feeds: 0 }, { name: "Root Cluster", description: "Several thin edible roots beneath the sand.", yield: "0.5 lbs", feeds: 0 }, { name: "Cactus Buds", description: "A handful of young cactus growth that can be prepared as food.", yield: "0.25 lbs", feeds: 0 }, { name: "Desert Grass Seed", description: "A small harvest of edible seed from stubborn desert grass.", yield: "0.25 lbs", feeds: 0 }, { name: "Oasis Leaf Cluster", description: "A few edible leaves from a rare surviving plant.", yield: "0.5 lbs", feeds: 0 }, { name: "Young Cactus Growth", description: "A small amount of fresh cactus flesh.", yield: "0.5 lbs", feeds: 0 }, { name: "Damp Soil Roots", description: "A few edible roots found near buried water.", yield: "0.5 lbs", feeds: 0 } ] }, { min: 20, max: 30, results: [ { name: "Cactus Fruit & Pulp", description: "A productive cactus provides both fruit and water-rich flesh.", yield: "2 lbs total", feeds: 1 }, { name: "Desert Roots & Seeds", description: "An underground harvest accompanied by edible seed pods.", yield: "2 lbs total", feeds: 1 }, { name: "Oasis Greens", description: "Tender greens grow around a rare source of water.", yield: "2 lbs", feeds: 1 }, { name: "Algae & Cactus", description: "A damp depression provides edible algae and fresh cactus.", yield: "2 lbs total", feeds: 1 }, { name: "Desert Bulbs", description: "Small starchy bulbs survive beneath hardened soil.", yield: "2 lbs", feeds: 1 }, { name: "Cactus Fruit & Seeds", description: "A mature cactus patch produces fruit and a modest seed harvest.", yield: "2 lbs total", feeds: 1 }, { name: "Cactus Pulp & Roots", description: "A productive patch yields water-rich flesh and edible roots.", yield: "2 lbs total", feeds: 1 }, { name: "Oasis Herbs & Seeds", description: "A rare water source supports hardy herbs and edible seeds.", yield: "2 lbs total", feeds: 1 }, { name: "Desert Greens & Bulbs", description: "Several edible plants grow together in damp soil.", yield: "2 lbs total", feeds: 1 }, { name: "Fresh Algae Bed", description: "A surviving patch of edible algae provides a modest harvest.", yield: "2 lbs", feeds: 1 }, { name: "Cactus Fruit Grove", description: "Several mature cactus plants provide a useful amount of fruit.", yield: "3 lbs total", feeds: 1 }, { name: "Hidden Root Patch", description: "A sheltered area contains a cluster of edible desert roots.", yield: "2 lbs", feeds: 1 }, { name: "Seed & Cactus Harvest", description: "Edible seed pods grow among several mature cactus plants.", yield: "2 lbs total", feeds: 1 }, { name: "Oasis Reed Roots", description: "A rare surviving wetland supports edible roots.", yield: "2 lbs", feeds: 1 }, { name: "Desert Herb Patch", description: "A sheltered hollow contains several edible hardy herbs.", yield: "2 lbs total", feeds: 1 }, { name: "Cactus Buds & Fruit", description: "Young cactus growth and fruit can both be harvested.", yield: "2 lbs total", feeds: 1 }, { name: "Algae & Oasis Greens", description: "Fresh algae grows beside edible green shoots.", yield: "2 lbs total", feeds: 1 }, { name: "Desert Root & Fruit Patch", description: "A rare pocket contains both edible roots and fruit.", yield: "2 lbs total", feeds: 1 }, { name: "Hidden Spring Growth", description: "Moist ground supports a productive patch of roots and greens.", yield: "3 lbs total", feeds: 2 }, { name: "Cactus Grove", description: "A mature stand of cactus provides a surprisingly large harvest.", yield: "3 lbs total", feeds: 2 } ] } ]; /* ========================================================= GET SELECTED CHARACTER ========================================================= */ function getSelectedCharacter(msg) { if (!msg.selected || msg.selected.length === 0) { return null; } var token = getObj("graphic", msg.selected[0]._id); if (!token) { return null; } var characterId = token.get("represents"); if (!characterId) { return null; } return getObj("character", characterId); } /* ========================================================= GET CHARACTER ========================================================= */ function getCharacter(msg, characterId) { if (characterId) { return getObj("character", characterId); } return getSelectedCharacter(msg); } /* ========================================================= WHISPER ========================================================= */ function whisper(msg, content) { var who = (msg.who || "GM").replace(/\s+\(GM\)$/, ""); sendChat( "Survival System", '/w "' + who.replace(/"/g, "") + '" ' + content ); } /* ========================================================= GET SURVIVAL BONUS ========================================================= */ async function getSurvivalBonus(character) { var survival = Number( await getSheetItem(character.id, "survival_bonus") ); if (Number.isFinite(survival)) { return survival; } var wisdomMod = Number( await getSheetItem(character.id, "wisdom_mod") ); var proficiencyBonus = Number( await getSheetItem(character.id, "pb") ); if ( Number.isFinite(wisdomMod) && Number.isFinite(proficiencyBonus) ) { return wisdomMod + proficiencyBonus; } return null; } /* ========================================================= FIND BRACKET ========================================================= */ function findBracket(table, result) { for (var i = 0; i < table.length; i++) { if ( result >= table[i].min && result <= table[i].max ) { return table[i]; } } return table[0]; } /* ========================================================= RANDOM FIND ========================================================= */ function randomFind(bracket) { var index = randomInteger(bracket.results.length) - 1; return bracket.results[index]; } /* ========================================================= SHOW MENU ========================================================= */ function showMenu(msg, character) { var characterId = character.id; var output = "&{template:default}" + "{{name=Survival}}" + "{{Character=" + character.get("name") + "}}" + "{{Choose an Activity=" + "[Hunting](!survival hunting " + characterId + ") " + "[Lake Fishing](!survival fishing " + characterId + ") " + "[Gathering](!survival gathering " + characterId + ")" + "}}"; whisper(msg, output); } /* ========================================================= MAIN COMMAND ========================================================= */ async function runSurvival(msg) { if (msg.type !== "api") { return; } var parts = msg.content.trim().split(/\s+/); if (parts[0] !== "!survival") { return; } var activity = parts[1]; var characterId = parts[2]; var character = getCharacter(msg, characterId); if (!character) { whisper( msg, "<b>Select a token whose Represents Character field is linked to a character sheet first.</b>" ); return; } if (!activity) { showMenu(msg, character); return; } if ( activity !== "hunting" && activity !== "fishing" && activity !== "gathering" ) { whisper( msg, "<b>Choose Hunting, Lake Fishing, or Gathering.</b>" ); return; } /* ----------------------------------------------------- SURVIVAL ROLL ----------------------------------------------------- */ var survivalBonus = await getSurvivalBonus(character); if (survivalBonus === null) { whisper( msg, "<b>Could not determine the character's Survival bonus.</b> " + "The script tried <code>survival_bonus</code>, then " + "<code>wisdom_mod + pb</code>." ); return; } var d20 = randomInteger(20); var rawResult = d20 + survivalBonus; /* Cap Survival between 0 and 30. */ var survivalResult = Math.max( 0, Math.min(rawResult, 30) ); /* ----------------------------------------------------- SELECT TABLE ----------------------------------------------------- */ var table; var activityName; if (activity === "hunting") { table = HUNTING; activityName = "Hunting"; } else if (activity === "fishing") { table = FISHING; activityName = "Lake Fishing"; } else { table = GATHERING; activityName = "Gathering"; } /* ----------------------------------------------------- FIND RESULT ----------------------------------------------------- */ var bracket = findBracket( table, survivalResult ); var result = randomFind(bracket); /* ----------------------------------------------------- DISPLAY ----------------------------------------------------- */ var output = "&{template:default}" + "{{name=Survival — " + activityName + "}}" + "{{Character=" + character.get("name") + "}}" + "{{D20 Roll=" + d20 + "}}" + "{{Survival Bonus=" + (survivalBonus >= 0 ? "+" : "") + survivalBonus + "}}" + "{{Survival Result=" + survivalResult + "}}" + "{{Find=" + result.name + "}}" + "{{Description=" + result.description + "}}" + "{{Food Yield=" + result.yield + "}}" + "{{Feeds=" + result.feeds + " people}}"; sendChat( character.get("name"), output ); } /* ========================================================= REGISTER COMMAND ========================================================= */ on("ready", function () { log("======================================"); log("D&D 5.5e SURVIVAL SYSTEM LOADED"); log("Command: !survival"); log("======================================"); on("chat:message", runSurvival); }); })();
that worked! thank you.