// Simulation script: `pub const` items are defaults and tuning constants, // `pub fn` items are entity behaviours. Every constant below is required. // World pub const WIDTH = 192; pub const HEIGHT = 128; // Calendar pub const TICKS_PER_DAY = 1800; pub const DAYS_PER_WEEK = 7; pub const WEEKS_PER_MONTH = 4; pub const MONTHS_PER_YEAR = 12; // Life stages: days spent in each stage; fertile stages can have children pub const TODDLER = #{ min_days: 2, max_days: 4, fertile: false }; pub const CHILD = #{ min_days: 4, max_days: 8, fertile: false }; pub const TEEN = #{ min_days: 4, max_days: 8, fertile: true }; pub const YOUNG_ADULT = #{ min_days: 6, max_days: 12, fertile: true }; pub const ADULT = #{ min_days: 20, max_days: 40, fertile: true }; pub const OLDER_ADULT = #{ min_days: 10, max_days: 20, fertile: true }; pub const ELDERLY = #{ min_days: 4, max_days: 10, fertile: false }; // Initial world pub const INITIAL_POPULATION = 180; pub const INITIAL_YOUNG_ADULTS = 60; pub const INITIAL_RABBITS = 1200; pub const INITIAL_WOLVES = 80; pub const INITIAL_FOOD = 1200; pub const INITIAL_PERSON_HUNGER = 10.0; pub const INITIAL_ANIMAL_ENERGY = 70.0; pub const ANIMAL_ENERGY_DEATH_THRESHOLD = 0.0; pub const STARTING_TICK_FRACTION = 4; // Population and housing pub const POPULATION_CAPACITY = 30; pub const HOUSE_CAPACITY = 3; pub const MAX_HOUSES = 20; // Daylight pub const DAYLIGHT_NIGHT_THRESHOLD = 0.2; pub const DAYLIGHT_BASE = 0.5; pub const DAYLIGHT_AMPLITUDE = 0.8; // Movement and update cadence pub const HOME_RADIUS = 1; pub const ATTACK_RANGE = 1; pub const ENTITY_UPDATE_INTERVAL = 2; // Hunger pub const HUNGER_NIGHT_AT_HOME = 0.01; pub const HUNGER_OTHER = 0.02; pub const HUNGER_EAT_HOME_THRESHOLD = 40.0; pub const HUNGER_EAT_CARRIED_THRESHOLD = 50.0; pub const HUNGER_RETURN_THRESHOLD = 40.0; pub const HUNGER_STARVATION_THRESHOLD = 100.0; pub const HUNGER_MEAL_REDUCTION = 25.0; pub const FOOD_PER_MEAL = 1; // People: gathering and hunting pub const RESOURCE_SEARCH_RADIUS = 25; pub const PERSON_HUNT_SUCCESS_CHANCE = 0.5; pub const PERSON_HUNT_FOOD_YIELD = 3; pub const PERSON_GATHER_YIELD = 1; pub const PERSON_TOOLED_GATHER_YIELD = 2; // Partnerships and births pub const PARTNERSHIP_DISTANCE = 12; pub const BIRTH_FOOD_THRESHOLD = 10; pub const BIRTH_FOOD_COST = 6; // Construction pub const TOOL_WOOD_COST = 3; pub const TOOL_STONE_COST = 1; pub const HOUSE_WOOD_COST = 12; pub const HOUSE_STONE_COST = 4; pub const HOUSE_PLACEMENT_RADIUS = 6; // Resources pub const RESOURCE_REGROW_ATTEMPTS = 20; pub const INITIAL_TREE_CHANCE = 0.6; pub const INITIAL_TREE_AMOUNT = 5; pub const INITIAL_BERRY_CHANCE = 0.04; pub const INITIAL_BERRY_AMOUNT = 4; pub const INITIAL_STONE_CHANCE = 0.15; pub const INITIAL_STONE_AMOUNT = 6; pub const TREE_REGROW_CHANCE = 0.02; pub const TREE_REGROW_AMOUNT = 5; pub const BERRY_REGROW_CHANCE = 0.02; pub const BERRY_REGROW_AMOUNT = 4; pub const STONE_REGROW_CHANCE = 0.004; pub const STONE_REGROW_AMOUNT = 6; // Animal spawning pub const ANIMAL_POPULATION_INTERVAL = 50; pub const RABBIT_SPAWN_CAP = 30; pub const WOLF_SPAWN_CAP = 4; pub const WOLF_SPAWN_RABBIT_THRESHOLD = 80; pub const WOLF_MIN_HOME_DISTANCE = 15; // Rabbits pub const RABBIT_ENERGY_DRAIN = 0.05; pub const RABBIT_ENERGY_REGEN = 0.2; pub const RABBIT_ENERGY_MAX = 100.0; pub const RABBIT_WOLF_DETECTION_RANGE = 4; pub const RABBIT_BREED_ENERGY = 80.0; pub const RABBIT_MAX_POPULATION = 300; pub const RABBIT_BREED_CHANCE = 0.01; pub const RABBIT_BREED_ENERGY_COST = 30.0; pub const RABBIT_NEWBORN_ENERGY = 50.0; // Wolves pub const WOLF_ENERGY_DRAIN = 0.15; pub const WOLF_PREY_RANGE = 10; pub const WOLF_HUNT_SUCCESS_CHANCE = 0.4; pub const WOLF_HUNT_ENERGY_GAIN = 50.0; pub const WOLF_ENERGY_MAX = 100.0; pub const WOLF_BREED_ENERGY = 90.0; pub const WOLF_MAX_POPULATION = 24; pub const WOLF_BREED_CHANCE = 0.02; pub const WOLF_BREED_ENERGY_COST = 40.0; pub const WOLF_NEWBORN_ENERGY = 50.0; // Terrain generation pub const TERRAIN_NOISE_OCTAVES = 4; pub const TERRAIN_NOISE_SCALE = 16.0; pub const TERRAIN_EDGE_HEIGHT = 0.25; pub const TERRAIN_EDGE_FALLOFF = 0.55; pub const TERRAIN_EDGE_DISTANCE_CAP = 1.5; pub const TERRAIN_MOISTURE_OFFSET = 500.0; pub const TERRAIN_MOISTURE_SEED_OFFSET = 99; pub const TERRAIN_DEEP_WATER_THRESHOLD = 0.28; pub const TERRAIN_WATER_THRESHOLD = 0.36; pub const TERRAIN_SAND_THRESHOLD = 0.41; pub const TERRAIN_FOREST_GRASS_THRESHOLD = 0.68; pub const TERRAIN_HILLS_THRESHOLD = 0.78; pub const TERRAIN_FOREST_MOISTURE_THRESHOLD = 0.52; // Misc pub const RANDOM_LAND_ATTEMPTS = 50; pub const LOG_ENTRY_LIMIT = 8; pub const WANDER_ATTEMPTS = 4; pub const WANDER_RADIUS = 1; // UI edit limits pub const MANUAL_SPAWN_LIMIT = 25; pub const MAX_SIMULATION_SPEED = 8; pub const MAX_STOCK_EDIT = 9999; pub const MAX_PERSON_INVENTORY_EDIT = 99; pub const MAX_HUNGER_EDIT = 99; pub const MAX_ANIMAL_ENERGY_EDIT = 100.0; pub const MAX_RESOURCE_EDIT = 50; // Behaviour tuning (used only by the behaviour functions below) pub const HUNGER_SCRIPT_THRESHOLD = 50.0; pub const PERSON_CARRY_LIMIT = 6; pub const PERSON_FOOD_STOCK_THRESHOLD = 12; pub const PERSON_HUNT_RABBIT_CHANCE = 0.3; pub const PERSON_WOOD_STONE_RATIO = 2; pub const PERSON_WOOD_BUFFER = 8; pub const RABBIT_BEHAVIOR_FLEE_CHANCE = 0.8; pub const RABBIT_BEHAVIOR_WANDER_CHANCE = 0.5; // Behaviours. Each function receives what the entity senses and returns the // name of an action; the Rust side carries it out. // person: sleep | go_home | eat | haul | hunt | forage | chop | mine | wander pub fn person(c) { if c.night { return if c.at_home { "sleep" } else { "go_home" }; } if c.hunger > HUNGER_SCRIPT_THRESHOLD && c.carried_food == 0 && c.stock_food > 0 { return "eat"; } if c.carry >= PERSON_CARRY_LIMIT { return "haul"; } if c.stock_food < PERSON_FOOD_STOCK_THRESHOLD || c.hunger > HUNGER_SCRIPT_THRESHOLD { if c.rabbit_near && (!c.berry_near || c.roll < PERSON_HUNT_RABBIT_CHANCE) { return "hunt"; } if c.berry_near { return "forage"; } } if c.stock_wood <= c.stock_stone * PERSON_WOOD_STONE_RATIO + PERSON_WOOD_BUFFER { if c.tree_near { "chop" } else if c.stone_near { "mine" } else { "wander" } } else { if c.stone_near { "mine" } else if c.tree_near { "chop" } else { "wander" } } } // rabbit: flee | wander | stay pub fn rabbit(c) { if c.wolf_near { if c.roll < RABBIT_BEHAVIOR_FLEE_CHANCE { "flee" } else { "stay" } } else if c.roll < RABBIT_BEHAVIOR_WANDER_CHANCE { "wander" } else { "stay" } } // wolf: hunt | wander pub fn wolf(c) { if c.prey_near { "hunt" } else { "wander" } }