128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
|
|
/**
|
||
|
|
* Configuration & Settings Management
|
||
|
|
* Handles default values, slider bounds, custom defaults, and localStorage persistence.
|
||
|
|
*/
|
||
|
|
|
||
|
|
export const FACTORY_DEFAULTS = {
|
||
|
|
// Starting entity counts & limits
|
||
|
|
initialSheep: 25,
|
||
|
|
initialWolves: 3,
|
||
|
|
initialPlants: 35,
|
||
|
|
maxPlantCap: 90, // Hard cap to keep CPU lightweight and meadow balanced
|
||
|
|
|
||
|
|
// Sheep behavioral attributes
|
||
|
|
sheepHungerDepletionRate: 1.2, // per second (sheep graze frequently)
|
||
|
|
sheepGrazingReach: 18, // radius in pixels to snap up plants
|
||
|
|
sheepMatingCooldown: 22, // seconds between sheep births
|
||
|
|
|
||
|
|
// Wolf behavioral attributes & combat exertion
|
||
|
|
wolfLungeCost: 7, // Health expended per attack bite (fatigue/struggle)
|
||
|
|
wolfHungerDepletionRate: 1.3, // per second
|
||
|
|
wolfAttackDamage: 38, // damage per bite to sheep
|
||
|
|
wolfMatingCooldown: 35, // seconds between wolf litters
|
||
|
|
wolfMatingThreshold: 86, // minimum hunger required to seek mate
|
||
|
|
|
||
|
|
// Plant & flora dynamics
|
||
|
|
plantSeedRate: 8, // % chance for clustered mature plants to disperse seed
|
||
|
|
plantDryRate: 2.2, // moisture loss per second in clear weather
|
||
|
|
rainFrequency: 45, // 0 - 100%
|
||
|
|
decaySpeed: 1.0, // 0.2x to 3.0x multiplier on carcass decomposition
|
||
|
|
|
||
|
|
// Movement speeds (preset balance)
|
||
|
|
sheepMaxSpeed: 1.8,
|
||
|
|
sheepFleeSpeed: 2.8,
|
||
|
|
sheepPerceptionRadius: 160,
|
||
|
|
wolfMaxSpeed: 2.2,
|
||
|
|
wolfChaseSpeed: 4.1,
|
||
|
|
wolfPerceptionRadius: 280,
|
||
|
|
wolfAttackCooldown: 0.65,
|
||
|
|
|
||
|
|
// World constraints
|
||
|
|
worldWidth: 1280,
|
||
|
|
worldHeight: 760,
|
||
|
|
boundaryMargin: 40,
|
||
|
|
|
||
|
|
// Continuous Mode (Screen Saver / Endless Ecosystem)
|
||
|
|
continuousMode: false,
|
||
|
|
continuousSheepInterval: 14,
|
||
|
|
continuousWolfInterval: 32,
|
||
|
|
continuousMaxGroupSize: 3,
|
||
|
|
};
|
||
|
|
|
||
|
|
const STORAGE_KEY = 'LifeSimulator_Config_v2';
|
||
|
|
const CUSTOM_DEFAULTS_KEY = 'LifeSimulator_Custom_Defaults_v2';
|
||
|
|
|
||
|
|
export class ConfigManager {
|
||
|
|
constructor() {
|
||
|
|
this.current = this.load();
|
||
|
|
}
|
||
|
|
|
||
|
|
load() {
|
||
|
|
try {
|
||
|
|
const saved = localStorage.getItem(STORAGE_KEY);
|
||
|
|
if (saved) {
|
||
|
|
const parsed = JSON.parse(saved);
|
||
|
|
return { ...FACTORY_DEFAULTS, ...parsed };
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
console.warn('Failed to load settings from localStorage:', e);
|
||
|
|
}
|
||
|
|
return { ...FACTORY_DEFAULTS };
|
||
|
|
}
|
||
|
|
|
||
|
|
save(newConfig) {
|
||
|
|
this.current = { ...this.current, ...newConfig };
|
||
|
|
try {
|
||
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.current));
|
||
|
|
} catch (e) {
|
||
|
|
console.warn('Failed to save settings to localStorage:', e);
|
||
|
|
}
|
||
|
|
return this.current;
|
||
|
|
}
|
||
|
|
|
||
|
|
saveAsNewDefaults(config) {
|
||
|
|
this.current = { ...this.current, ...config };
|
||
|
|
try {
|
||
|
|
localStorage.setItem(CUSTOM_DEFAULTS_KEY, JSON.stringify(this.current));
|
||
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.current));
|
||
|
|
} catch (e) {
|
||
|
|
console.warn('Failed to save custom defaults:', e);
|
||
|
|
}
|
||
|
|
return this.current;
|
||
|
|
}
|
||
|
|
|
||
|
|
resetToDefaults() {
|
||
|
|
// Check if user set custom defaults, otherwise use factory defaults
|
||
|
|
let base = FACTORY_DEFAULTS;
|
||
|
|
try {
|
||
|
|
const custom = localStorage.getItem(CUSTOM_DEFAULTS_KEY);
|
||
|
|
if (custom) {
|
||
|
|
base = { ...FACTORY_DEFAULTS, ...JSON.parse(custom) };
|
||
|
|
}
|
||
|
|
} catch (e) {
|
||
|
|
console.warn('Failed to read custom defaults:', e);
|
||
|
|
}
|
||
|
|
|
||
|
|
this.current = { ...base };
|
||
|
|
try {
|
||
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.current));
|
||
|
|
} catch (e) {
|
||
|
|
console.warn('Failed to reset settings:', e);
|
||
|
|
}
|
||
|
|
return this.current;
|
||
|
|
}
|
||
|
|
|
||
|
|
resetToFactory() {
|
||
|
|
this.current = { ...FACTORY_DEFAULTS };
|
||
|
|
try {
|
||
|
|
localStorage.removeItem(CUSTOM_DEFAULTS_KEY);
|
||
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.current));
|
||
|
|
} catch (e) {
|
||
|
|
console.warn('Failed to reset to factory defaults:', e);
|
||
|
|
}
|
||
|
|
return this.current;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export const configManager = new ConfigManager();
|