
//initialize the level, once we actually start playing it
var initialize = func()
{
	var level = registerlevel();

	level.var_done = 'false';

	level.var_muscletip = 'false';
	level.var_motortip = 'false';
	level.var_openedbrain = 'false';

	level.var_savetip = 'false';

	//first lineset we load will be the default we'll use if play_line isn't given one
	level.load_lineset('tut_full');

};


//update the level, runs every loop
var update = func() {
	var level = registerlevel();

	//guide the player put down a body
	if (level.var_done == 'false') {
		level.play_line('01_thisistheloom');

		if (level.creature_has_part('spine') < 4) {
			//if we prematurely opened the brain
			if (level.window_focus() == 0) {
				level.set_tutorialpointer('creature','');
			} else {
				level.play_line('02_firstthingsfirst');
				if (level.line_playing() == 0) {
					level.set_tutorialpointer('body','spine');
				} else {
					level.hide_tutorialpointer();
				}
			}

		} else if (level.creature_has_part('fin') < 1) {
			if (level.window_focus() == 0) {
				level.set_tutorialpointer('creature','');
			} else {
				level.set_tutorialpointer('body','fin');
				level.play_line('03_wewontgetfar');
			}

		} else if ((level.creature_has_muscle() < 2) || ((level.mouse_down() == 1) && (level.var_openedbrain == 'false'))) {
			if (level.window_focus() == 0) {
				level.set_tutorialpointer('body','muscle');

			} else if (level.editor_category() != 'muscles') {
				level.set_tutorialpointer('body','muscle');
				level.play_line_interrupt('04_musclesgivemotion');

			//once they click the muscle mode
			} else if ((level.creature_has_muscle() == 0) && (level.editor_category() == 'muscles') && (level.mouse_down() == 0))  {
				level.set_gif_popout('controls/newstitch_numbered_small.gif', 'Stitching muscles');

			} else {
				level.set_tutorialpointer('body','muscle');
				level.play_line('05_rememberonelongmuscle');
			}

		//if we're focusing on the body
		} else if (level.window_focus() == 1) {
			level.set_gif_popout('');
			level.set_tutorialpointer('creature','');
			level.play_line('06_thebrainiswhere');

		// === OPEN BRAIN STAGE ===
		} else if (level.var_openedbrain == 'false') {
			level.var_openedbrain = 'true';
			level.play_line_interrupt('07_thoseredcells');
			level.hide_tutorialpointer();

		} else if (level.creature_has_neuron('pacemaker') == 0) {
			level.set_tutorialpointer('cells','pacemaker');

			//before they select the placemaker
			if (level.brain_painting() != 'pacemaker') {
				level.play_line('08_easiestwaytoget');

			//after they've selected the placemaker
			} else {
				level.play_line('09_putonedown');
			}

		//} else if (level.creature_has_synapse('excite', 'pacemaker') >= 1) {
		//	level.set_tutorialpointer('circuit','excite', '','Oops! Other way around. Right-click to delete.');
		//	level.play_line_interrupt('react_otherwayaround');

		} else if (level.creature_has_synapse('excite') == 0) {
			level.play_line('10_andthenconnectit');

			if (level.mouse_down() == 0) {
				level.set_tutorialpointer('circuit','pacemaker');
			} else {
				level.hide_tutorialpointer();
			}

		} else if (level.creature_has_neuron('pacemaker') < 2) {
			level.set_tutorialpointer('cells','pacemaker');
			level.play_line('10b_niceonemore');

		} else if (level.creature_has_synapse('excite') < 2) {
			level.set_tutorialpointer('circuit','pacemaker');

		} else if (level.live == 0) {
			level.set_tutorialpointer('hud','play');
			level.play_line('11_letsseeitgo');

		}

		if (level.live == 1) {
			level.hide_tutorialpointer();
			level.var_done = 'true';
			//level.play_line('frankenstein_ibeheldthewretch','passage');
			level.play_line('frankenstein_accursedcreator','passage');
		}

	//if we've gone live and set var_done to 'true'
	// } else {
	// 	//once we go back to edit, show a tooltip to save/load
	// 	if (level.live == 0) {
	// 		if (level.var_savetip == 'false') {
	// 			level.set_tutorialpointer('hud','patterns');
	//
	// 			//detect this in a super hacky way: just detects if window was opened.
	// 			if (level.creature_is_saved() == 1) {
	// 				level.hide_tutorialpointer();
	// 				level.var_savetip = 'true';
	// 			}
	// 		}
	// 	}
	}

	if (level.live == 1) {
		level.play_line('frankenstein_ibeheldthewretch','passage');
	}
};


//set the level info for menus, etc
var setinfo = func()
{
	var level = registerlevel();
	level.name = 'Loominologist HQ';
	level.desc = 'Training center for mending loominals.';
	level.coord_x = .38;
	level.coord_y = .47;
	level.icon = 'map_icon_hq.svg';

	level.start_highlight();
};

//initialize the level, once we actually start playing it
var initialize = func() {
	var level = registerlevel();

	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');

	//initialize the help script
	level.runscript('script_help.mc', 'initialize');

	// hide the patterns window even if it's set to open at start
	level.hide_pattern_window();

	// preload the tutorial voice lines
	level.load_lineset('tut_full');
};

//update the level, runs every loop
var update = func() {
	var level = registerlevel();

	level.runscript('script_help.mc', 'update');
};

var event = func() {
	var level = registerlevel();
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Ruby Ridge | Race';
	level.desc = 'Choose creatures to race through a narrow canyon.';
	level.coord_x = -.01;
	level.coord_y =  .37;
	level.icon = 'map_icon_race.svg';
};

var initialize = func() {
	var level = registerlevel();

	// -- load the map
	level.load_room('map'); // room_straight
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');

	// initialize the race (after map load so it can access the markers)
	level.runscript('races/script_race.mc', 'initialize');
};

var update = func() {
	var level = registerlevel();
	level.runscript('races/script_race.mc', 'update');
};

// called when something happens the level script might want to know about
var event = func() {
	var level = registerlevel();
	level.runscript('races/script_race.mc', 'event');
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Tracing | Wet Lab';
	level.desc = 'Perform experiments on a creature with hidden connections';
	level.coord_x = .66;
	level.coord_y = .81;
	level.icon = 'map_icon_obelisk.svg';
};

var initialize = func() {
	var level = registerlevel();

	level.live = 1;						//start live
	// level.disable('can_toggle_live')	//lock it to be live

	level.disable('creature_at_start');	//level doesn't give us a creature
	// level.disable('free_camera');	//can't move the camera around
	level.disable('edit_brain');		//can't modify the brain
	level.disable('edit_limbs');		//can't modify the body
	level.disable('file_save');			//can't save, can only load
	level.disable('creature_death');	//creautures don't die from death or dismemberment (for initial wait-for-loading)

	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');

	level.timer_create('brain_prompt', 1.0);
	level.var_brainopened = 'false';

	level.var_blocked_glu = 'false';
	level.var_blocked_gaba = 'false';
	level.var_blocked_all = 'false';

	level.var_creatureloaded = 'false';
};

var update = func() {
	var level = registerlevel();

	if (level.var_creatureloaded == 'false') {
		level.open_creature_file_modal();
		level.var_creatureloaded = 'loading';

	} else if (level.var_creatureloaded == 'loading') {
		// hang out here and wait until the loaded_creature event

	// once people discover that they can open the brain
	} else if (level.window_focus() == 0) {
		if (level.var_brainopened == 'false') { level.var_brainopened = 'true'; }

	// tell them to open the brain after a short waiting period
	} else if (level.var_brainopened == 'false') {
		level.timer_tick('brain_prompt');
		// if (level.timer_current('brain_prompt') <= 0) {
		// 	level.set_tutorialpointer('creature','', '','Open brain.');
		// }
	}
};

// called when something happens the level script might want to know about
var event = func() {
	var level = registerlevel();
	if (level.event_name == 'new_player_creature') {
		level.creature_hide_neurons('Axon');
		level.window_set_focus(0);			//start with brain open
		level.var_creatureloaded = 'true';

	} else if (level.event_name == 'menu_reset') {
		level.creature_reset_ions(); //in case they changed the ion concentrations
		level.creature_reset_optogenetics();
		level.creature_unablate_neurons();
		level.creature_enable_channels();//enables all channels

		level.var_blocked_glu = 'false';
		level.var_blocked_gaba = 'false';
		level.var_blocked_all = 'false';

		level.show_text('Reset creature.');

	} else if (level.event_name == 'edit') {
		level.show_text('Reset creature.'); // yup, totally meant to do that

	// GLUTAMATE BLOCKER
	} else if (level.event_name == 'menu_block_glu') {
		if (level.var_blocked_glu == 'false') {
			level.creature_disable_channels('Glu');
			level.show_text('CNQX applied. Excitation blocked.');
			level.var_blocked_glu = 'true';
		} else {
			level.creature_enable_channels('Glu');
			level.show_text('CNQX washed out. Excitation enabled.');
			level.var_blocked_glu = 'false';
		}

	// GABA BLOCKER
	} else if (level.event_name == 'menu_block_gaba') {
		if (level.var_blocked_gaba == 'false') {
			level.creature_disable_channels('GABA');
			level.creature_jolt_neurons();
			level.show_text('Bicuculline applied. Inhibition blocked.');
			level.var_blocked_gaba = 'true';
		} else {
			level.creature_enable_channels('GABA');
			level.show_text('Bicuculline washed out. Inhibition enabled.');
			level.var_blocked_gaba = 'false';
		}

	// TTX BLOCKER
	} else if (level.event_name == 'menu_block_all') {
		if (level.var_blocked_all == 'false') {
			level.creature_disable_channels('VGSC');
			level.creature_disable_channels('GluR'); //bugfix for where passive conductance still lets synapses work with VGSCs disabled
			level.creature_disable_channels('GABAR');
			level.show_text('TTX applied. Action potentials blocked.');
			level.var_blocked_all = 'true';
		} else {
			level.creature_enable_channels('VGSC');
			level.creature_enable_channels('GluR'); //bugfix for where passive conductance still lets synapses work with VGSCs disabled
			level.creature_enable_channels('GABAR');
			level.show_text('TTX washed out. Action potentials enabled.');
			level.var_blocked_all = 'false';
		}
	}
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Action Potentials | Wet Lab';
	level.desc = 'Examine a creature with visible action potentials.';
	level.coord_x = .66;
	level.coord_y = .71;
	level.icon = 'map_icon_obelisk.svg';
};

var initialize = func() {
	var level = registerlevel();

	level.live = 1;						//start live
	level.disable('can_toggle_live');	//lock it to be live

	level.disable('file_save');			//can't save creatures
	level.disable('file_load');			//can't load creatures
	level.disable('free_camera');		//can't move the camera around
	level.disable('edit_brain');		//can't modify the brain

 	//put down the background room
 	level.runscript('backgrounds/cave/cave.mc', 'initialize');

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

 	level.add_creature('seasquirt', 'player', 'start');	//set the starting creature
	level.creature_disable_neurons('Pacemaker');
	level.creature_disable_neurons('Axon');

	level.timer_create('brain_prompt', 10.0);
 	level.var_brainopened = 'false';

	level.var_channelstate = 'disabled';	// all channels start disabled
};

var update = func() {
	var level = registerlevel();

	//once people discover that they can open the brain
	if (level.window_focus() == 0) {
		level.var_brainopened = 'true';

	//tell them to open the brain after a short waiting period
	} else {
		level.timer_tick('brain_prompt');
		if ((level.timer_current('brain_prompt') <= 0) && (level.var_brainopened == 'false')) {
			level.set_tutorialpointer('creature','');
		}
	}
};

// called when something happens the level script might want to know about
var event = func() {
	var level = registerlevel();
	if (level.event_name == 'menu_reset') {
		if (level.var_channelstate == 'disabled') {
			level.var_channelstate = 'enabled';
			level.creature_enable_neurons('Pacemaker');
			level.creature_enable_neurons('Axon');
		} else {
			level.var_channelstate = 'disabled';
			level.creature_disable_neurons('Pacemaker');
			level.creature_disable_neurons('Axon');
		}
	}

	// level.print('EVENT:');
	// level.print(level.event_name);
};


initialize = func() {
	var level = registerlevel();

	//------ STARTING LAYER PROPERTIES ------
	//multiplier for how to shift following layers with the camera in x / y
	level.set_parallax_zoom(.25);

	//------ ADD LAYERS TO THE BACKGROUND ------
	//name: file of the png
	//<SVG ONLY> layer name
	//layer number: serves as sorting & camera distance
	//position (can be omitted)
	//scale	(can be omitted)

	level.set_parallax(.05, 0);
	level.add_layer('cave.svg', 'bg0', -10, 0,50);

	level.set_parallax(.05, .03);
	level.add_layer('cave.svg', 'bg1', -9, 0,75);

	level.set_parallax(.10, .05);
	level.add_layer('cave.svg', 'bg2', -8, 0,100);

	level.set_parallax(.15, .07);
	level.add_layer('cave.svg', 'bg3', -7, 0,150);

	level.set_parallax(.25, .12);
	level.add_layer('cave.svg', 'bg4', -5, 0,250);

	level.set_parallax(.35, .15);
	level.add_layer('cave.svg', 'bg5', -4, 0,2350);
};

//set the level info for menus, etc
var setinfo = func()
{
	var level = registerlevel();
	level.name = 'Sewee Bay | Area';
	level.desc = 'Explore one of the few remaining pre-Rubicon ecosystems.';
	level.coord_x = .450;
	level.coord_y = -.130;
	level.icon = 'map_icon_area.svg';
};

//initialize the level, once we actually start playing it
var initialize = func() {
	var level = registerlevel();

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');
};

//update the level, runs every loop
var update = func() {
	var level = registerlevel();
};

var event = func() {
	var level = registerlevel();
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Sand Flats | Area';
	level.desc = 'A desolate, empty seabed. Useful as a test-ground.';
	level.coord_x = .700;
	level.coord_y = .700;
	level.icon = 'map_icon_area.svg';
};

var initialize = func() {
	var level = registerlevel();

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
 	level.runscript('backgrounds/cave/cave.mc', 'initialize');
};

var update = func() {
	var level = registerlevel();

};

var event = func() {
	var level = registerlevel();
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Open Sea | Area';
	level.desc = 'A large open area free of walls. Be careful not to get lost.';
	level.coord_x = .130;
	level.coord_y = -.350;
	level.icon = 'map_icon_area.svg';
};

var initialize = func() {
	var level = registerlevel();

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');
};

var update = func() {
	var level = registerlevel();
};

var event = func() {
	var level = registerlevel();
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Empty | Area';
	level.desc = 'Literally nothing. Used for testing';
	level.coord_x = .230;
	level.coord_y = -.350;
	level.icon = 'map_icon_area.svg';
};

var initialize = func() {
	var level = registerlevel();

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');
};

var update = func() {
	var level = registerlevel();
};

var event = func() {
	var level = registerlevel();
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Caverns | Area';
	level.desc = 'Open cavern surrounded by tight tunnels.';
	level.coord_x = -.03;
	level.coord_y = -.72;
	level.icon = 'map_icon_area.svg';
};

var initialize = func() {
	var level = registerlevel();

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');
};

var update = func() {
	var level = registerlevel();

};

var event = func() {
	var level = registerlevel();
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Whisker';
	limb.desc = 'A sensitive fiber that can react to touch.';

	limb.category = senses;			//basic | organs | senses
	//limb.icon = 'whisker_icon';	//automatically defaults to this
};


var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('whisker.svg', limb.scale * .55);

	//set the drag of all branches ('normal' drag is 1.0)
	limb.set_drag(.2);

	//set the density of all branches ('normal' density is .05, going lower than .03 is danger)
	//limb.set_density(.1);

	//make all created branches unavailable for serving as a base for other limbs
	limb.cannot_attach_other_limbs();

	//make the whole thing a sensory organ
	limb.entire_organ(base, 'touch', 'cell_sensory.svg');
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Orientation';
	limb.desc = 'Activates when held at a specific angle.';

	limb.category = senses;		//basic | organs | senses
	limb.icon = 'orientation_icon';

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('orientation.svg', limb.scale * .5);

	//set the drag of all branches that have been created so far
	limb.set_drag(.05);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.05);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Eye';
	limb.desc = 'Activates when something blocks its line of sight.';

	limb.category = senses;		//basic | organs | senses
	//limb.icon = 'eye_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('eye.svg', limb.scale * .3);

	//set the drag of all branches that have been created so far
	limb.set_drag(.05);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.05);

	//make all created branches unavailable for serving as a base for other limbs
	limb.cannot_attach_other_limbs();
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Balloon';
	limb.desc = 'Bouyant. Floats upwards.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'balloon_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('weight_balloon.svg', limb.scale * .4);

	//set any created organ neurons to use this graphic
	limb.set_neuron_graphic('cell_organ_balloon.svg');

	//make all created branches unavailable for serving as a base for other limbs
	limb.cannot_attach_other_limbs();

	//set the drag of all branches that have been created so far
	limb.set_drag(.15);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Ballast';
	limb.desc = 'Heavy. Sinks downwards.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'ballast_icon';	//automatically defaults to this

	// limb.add_slider('Density%', .5, 2.0);
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('weight_ballast.svg', limb.scale * .5);

	limb.set_bouyancy(base, 2.5);

	//set the drag of all branches that have been created so far
	limb.set_drag(.15);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Sucker';
	limb.desc = 'Attaches on contact. Let go by silencing the neuron.';

	limb.category = organs;			//basic | organs | senses
	//limb.icon = 'sucker_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('sucker.svg', limb.scale * .5);

	//set the drag of all branches that have been created so far
	limb.set_drag(.05);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.05);

	//make all created branches unavailable for serving as a base for other limbs
	limb.cannot_attach_other_limbs();
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Nibbler';
	limb.desc = 'Tiny basic herbivorous mouth.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'molar_icon';	//automatically defaults to this
};


var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('mouth_nibbler.svg', limb.scale * .6);

	//set the drag of all branches ('normal' drag is 1.0)
	limb.set_drag(.1);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.01);

	//make all created branches unavailable for serving as a base for other limbs
	//limb.cannot_attach_other_limbs();
};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Molars';
	limb.desc = 'Filter-feeding herbivorous mouth.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'molar_icon';	//automatically defaults to this
};


var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('mouth_molars.svg', limb.scale * .6);

	//set the drag of all branches ('normal' drag is 1.0)
	limb.set_drag(.1);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.01);

	//make all created branches unavailable for serving as a base for other limbs
	//limb.cannot_attach_other_limbs();
};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Jaw';
	limb.desc = 'Meat-eating mouth with a bite.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'jaw_icon';	//automatically defaults to this
};


var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('mouth_jaw.svg', limb.scale * .5);

	//set the drag of all branches ('normal' drag is 1.0)
	limb.set_drag(.1);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.01);

	//make all created branches unavailable for serving as a base for other limbs
	//limb.cannot_attach_other_limbs();
};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Larynx';
	limb.desc = 'A crackling cry.';

	limb.category = organs;		//basic | organs | senses
	limb.icon = 'nub_icon';

	//limb.add_option('Croak', 'Larynx. A crackling cry.');
	//limb.add_option('Screal', 'Larynx. An aggressive cry.');
	//limb.add_option('Whisper', 'Larynx. A soft, subtle cry.');
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	var larynx = limb.add_svg('nub.svg', limb.scale * 1.0);

	//the name of the larynx determines the sound it plays; it will look for 'sfx\call_<<name>>.wav'
	//var cry = '';
	//if (limb.name == 'Croak') 	{ cry = 'croak'; }
	//if (limb.name == 'Screal') 	{ cry = 'screal'; }
	//if (limb.name == 'Whisper')	{ cry = 'Whisper'; }
	//limb.organ(larynx, ('larynx_'+cry), 'cell_sensory.svg');
	limb.organ(larynx, 'larynx_croak', 'cell_sensory.svg');

	//make all created branches use their convex hulls for drag instead of what they literally are
	limb.set_usehullfordrag();//not needed since convex anyway?

	//set any created organ neurons to use this graphic
	limb.set_neuron_graphic('cell_organ_larynx.svg');

	//set the drag of all branches that have been created so far
	limb.set_drag(.05);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Jet';
	limb.desc = 'Squeeze to propel thyself with a stream of water.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'jet_icon';	//automatically defaults to this

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('jet.svg', limb.scale * .4);

	//set the drag of all branches that have been created so far
	limb.set_drag(.5);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.0025);

	//make all created branches unavailable for serving as a base for other limbs
	limb.cannot_attach_other_limbs();
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Harpoon';
	limb.desc = 'A dart that can stick to rocks... or prey.';

	limb.category = organs;		//basic | organs | senses
	//limb.icon = 'harpoon_icon';	//automatically defaults to this

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('harpoon.svg', limb.scale * .5);

	//set the drag of all branches that have been created so far (normal drag is 1.0)
	limb.set_drag(0);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.01);

	//make all created branches unavailable for serving as a base for other limbs
	limb.cannot_attach_other_limbs();

};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Fiber';
	limb.desc = 'Trailing hair-like structure.';

	limb.category = decoration;	//basic | organs | senses | decoration
	//limb.icon = 'fiber_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	var branch = limb.add_svg('fiber.svg', limb.scale * .31);

	//aesthetic organs are intangible & near-massless
	limb.entire_organ(branch, 'aesthetic');
};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Camouflage';
	limb.desc = 'Get in touch with your inner kelp.';

	limb.category = decoration;	//basic | organs | senses | decoration
	//limb.icon = 'camouflage_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	var branch = limb.add_svg('camouflage.svg', limb.scale * .35);

	//aesthetic organs are intangible & near-massless
	limb.entire_organ(branch, 'aesthetic');
};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Spine';
	limb.desc = 'Flexible section of bone.';

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'spine_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('spine.svg', limb.scale * .25);

	//set the drag of all branches that have been created so far
	limb.set_drag(2.0);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Spindle';
	limb.desc = 'Rigid spindle with very low drag.';

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'spindle_icon';	//automatically defaults to this

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('nub_spindle.svg', limb.scale * .7);
	//set the drag of all branches that have been created so far
	limb.set_drag(.1);
	// limb.set_drag(.01);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Plate';
	limb.desc = 'Wide solid plate.';

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'plate_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('nub_wide.svg', limb.scale * .6);
	//set the drag of all branches that have been created so far
	limb.set_drag(.25);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Nub';
	limb.desc = 'Bump with a muscle attachment point.';

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'nub_icon';	//automatically defaults to this
};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('nub.svg', limb.scale * .7);
	//set the drag of all branches that have been created so far
	limb.set_drag(.25);
};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Hip';
	limb.desc = "Pair of springy appendages. They don't lie.";

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'hip_icon';	//automatically defaults to this

};


var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('hip.svg', limb.scale * .675);

	//set the drag of all branches ('normal' drag is 1.0)
	limb.set_drag(.5);

	//set the density of all branches ('normal' density is .05)
	limb.set_density(.05);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Hinge';
	limb.desc = 'Loose pivot point.';

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'spine_icon';	//automatically defaults to this

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('hinge.svg', limb.scale * .33);

	//set the drag of all branches that have been created so far
	limb.set_drag(0.3);
};
var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Fin';
	limb.desc = 'Tail with high drag. Helps move when on the end of a limb.';

	limb.category = basic;		//basic | organs | senses
	//limb.icon = 'fin_icon';	//automatically defaults to this

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('fin.svg', limb.scale * .3);
	// limb.add_svg('fin_frills.svg', limb.scale * .3);

	limb.set_drag(2.0);

	limb.set_density(.05);

};var metadata = func() {
	var limb = registerlimb();

	limb.name = 'Block';
	limb.desc = 'Stiff section of bone.';

	limb.category = basic;		//basic | organs | senses
	// limb.icon = 'block_icon';	//automatically defaults to this

};

var makebranches = func() {
	var limb = registerlimb();

	//make it from an svg (file, scale)
	limb.add_svg('block.svg', limb.scale * .25);

	//set the drag of all branches that have been created so far
	limb.set_drag(1.0);
};
var setinfo = func() {
	var level = registerlevel();
	level.name = 'Loominologist HQ';
	level.desc = 'Training center for mending loominals.';
	level.coord_x = .38;
	level.coord_y = .47;
	level.icon = 'map_icon_hq.svg';

	//level.scenic();	//not clickable
	level.zooms_out();	//closes the submap when clicked
};

var setinfo = func() {
	var level = registerlevel();
	level.name = 'Loominologist HQ';
	level.desc = 'Training center for mending loominals.';
	level.coord_x = .38;
	level.coord_y = .47;
	level.icon = 'map_icon_hq.svg';

	level.start_highlight();

	level.submap('map_cuba.png');
	level.submap_levels(
		'headquarters_icon.mc',
		'actionpotentials/level.mc',
		'full/level.mc',
		'01_stimulate/level.mc',
		'02_connect/level.mc',
		// '03_radiation/level.mc',
		'04_toybox/level.mc',
		'05_delay/level.mc',
		'06_senses/level.mc',
		'07_nest/level.mc');
};


// call this ~ AFTER ~ loading the map so it has access to the markers
var initialize = func() {
	var level = registerlevel();

	// ===== game settings ====== //
	level.disable('can_drag');				//can't drag creatures around
	level.disable('creature_at_start');		//level doesn't give us a creature
	level.disable('creature_on_pause');		//level doesn't give us a creature
	level.disable('creature_is_hatched');	//creatures start as eggs
	level.disable('edit_brain');			//can't modify the brain
	level.disable('edit_limbs');			//can't modify the body
	level.disable('egg_babies');			//things hatch as full adults
	level.disable('egg_laying');			//creatures can't lay eggs
	level.disable('file_save');				//can only load, can't save
	// level.disable('free_camera');		//can't move the camera around
	level.disable('no_creature_labels');	//show creature names

	level.maximum_zoom = 30; 				//can zoom out a lot (default is 20)
	level.enable_waveforce = 0;				//force sometimes is pointing in the wrong way at start, so removing for races

	// ===== script variables ====== //
	//don't start looking for win/lose conditions until things have hatched
	level.var_hatched = 'false';
	//nothing has won
	level.var_won = 'false';

	//make a timer to hatch all eggs
	level.timer_create('hatch', 3.2);//2.2); // same as the run_countdown, below
	level.timer_loop('hatch', 0);

	 //max time for each race
	level.timer_create('maxtime', 3600.0); // an hour
	level.timer_loop('maxtime', 0);

	// ====== MAP REQUIREMENTS ======= //
	// four markers labeled 'start1' through 'start4'
	// one marker titled 'raceend' to put the beacon
	level.add_beacon('raceend');

	level.open_contestant_modal();
};



//update the level, runs every loop
var update = func() {
	var level = registerlevel();

	//follow all creatures/eggs
	level.camera_follows_everything();

	//have things hatched yet? i.e. are we looking for a win condition
	if (level.var_hatched == 'true') {
		//show the timer
		// level.set_objective('maxtime');

		//if we run out of time, end the level (now unlikely to happen since it's like an hour)
		if (level.timer_tick('maxtime') > 0) {
			level.var_won = 'Out of time!';
		}

		if (level.var_won == 'false') {
			//if only one creature is left, end the level
			if (level.count_creatures() <= 1) {
				level.var_won = "A carnivore's victory";
			}
		}

		//if something reaches the finish line, hoover them up, end the level, and remove them from being tracked
		if (check_if_creature_has_won(level.var_creature_id_1)) { level.var_creature_id_1 = ''; }
		if (check_if_creature_has_won(level.var_creature_id_2)) { level.var_creature_id_2 = ''; }
		if (check_if_creature_has_won(level.var_creature_id_3)) { level.var_creature_id_3 = ''; }
		if (check_if_creature_has_won(level.var_creature_id_4)) { level.var_creature_id_4 = ''; }
	}

	// show the end-of-level screen
	if (level.var_won != 'false') {
		level.complete(level.var_won);
	}

	//hatch all eggs?
	if (level.timer_tick('hatch') > 0) {
		level.hatch_all_eggs();
		level.var_hatched = 'true';
	}
};

// if the given creature ID is in range of the beacon, capture the creature and wrap up the race
var check_if_creature_has_won = func(creature_id) {
	if (creature_id != '') {
		var distance = level.check_distance('raceend', creature_id);
		if (distance < 11) {
			var creature_name = level.get_creature_name(creature_id);

			// set the win message if it hasn't been yet
			if (level.var_won == 'false') { level.var_won = creature_name + ' wins!'; }
			// add them & their time to the race-end screen
			level.add_contestant_to_endscreen(creature_name, level.timer_elapsed('maxtime'));
			// hoover them up into a golden ball of light
			level.beacon_capture('raceend', creature_id);
			return true;
		}
	}
	return false;
};

// called when something happens the level script might want to know about
var event = func() {
	var level = registerlevel();
	if (level.event_name == 'edit') {
		level.open_contestant_modal();

	} else if (level.event_name == 'contestants_chosen') {
		reset_race();	// start the race
		level.live = 1;	// go live (in case the window was brought up by pausing)

	} else if (level.event_name == 'level_complete_next') {
		reset_race(); // start the race

	} else if (level.event_name == 'level_complete_back') {
		level.open_contestant_modal();
	}
};

// adds a creature from the contestant list & returns the ID
var add_contestant = func(contestant_index, marker_array) {

	var marker = marker_array[contestant_index];

	var creature_id = level.add_contestant_creature(contestant_index, marker);
	return creature_id;
};

var shuffled_marker_array = func() {
	var base_array = ['start1','start2','start3','start4'];
	var marker_array = ['','','',''];

	for (var i = 0; i < 4; i++) {
		var shuffled_i = 0;
		var next_marker = '';
		var abort = 0;
		while (next_marker == '' && abort <= 12) {
			shuffled_i = level.rand(0, 4);
			next_marker = base_array[shuffled_i];
			abort = abort + 1;
		}
		marker_array[i] = next_marker;
		base_array[shuffled_i] = '';
	}

	return marker_array;
};

var reset_race = func() {
	level.uncomplete(); 		// deactivate the end-of-level gui
	level.order66(); 			// clear all creatures + eggs
	level.set_objective('');	// clear the timer

	// make the given creatures, recording their IDs
	var marker_array = shuffled_marker_array();
	level.var_creature_id_1 = add_contestant(0, marker_array);
	level.var_creature_id_2 = add_contestant(1, marker_array);
	level.var_creature_id_3 = add_contestant(2, marker_array);
	level.var_creature_id_4 = add_contestant(3, marker_array);

	level.timer_reset('hatch');
	level.timer_reset('maxtime');

	level.var_hatched = 'false';
	level.var_won = 'false';

	level.run_countdown(2.6);

	level.print(' ');
	level.print('------------------- resetting race --------------------');
};
var setinfo = func() {
	var level = registerlevel();
	level.name = 'Ruby Ridge';
	level.desc = 'Underwater canyons that make natural race-courses.';
	level.coord_x = -.01;
	level.coord_y =  .37;
	level.icon = 'map_icon_race.svg';

	level.submap('map_rubyridge.png');
	level.submap_levels(
		'rubyridge/icon_rubyridge.mc',
		'rubyridge/level_choice.mc',
		'rubyridge/level_fishbowl.mc',
		'rubyridge/level_course.mc',
		'rubyridge/level_necked.mc',);
};
var setinfo = func() {
	var level = registerlevel();
	level.name = 'Rubicon Crater';
	level.desc = '???';
	level.coord_x = -.62;
	level.coord_y =  .18;
	level.icon = 'map_icon_compass.svg';

	level.start_locked();	//greyed out
	level.scenic();			//not clickable
};

game.mc
ocean.mcinitialize = func()
{
	var set = registertileset();

	set.newTileBatch('boulder');
	set.body = 'dynamic';				//tile will generate unmovable bodies [''|'static'|'dynamic']
	set.bouyancy = '35';				//will sink.
	set.drag = '0.1';					//low drag so it can sink fast
	set.density = '0.01';				//default is 0.1
	set.rotation = 'scramble';			//placed at a random rotation
	set.scale = '0.5';
	set.shiftscale = '.25';				//shifts the scale of the created thing randomly
	set.add('boulder1');
	set.add('boulder2');


	set.newTileBatch('seaweed');			//sets the next category (clears any properties we're applying to new set)
	set.spritebehavior = 'kelpdrift';	//tile sprites behave thusly
	set.drawlayer = 'main_forefront,main_back';	//sets the draw layer to put these (multiple with ',' randomly distribute)
	//set.shiftcolor = '0.02';			//shifts all the colors randomly
	set.shiftbrightness = '0.04';		//shifts all the colors by the same random value
	set.shiftposition = '35';			//shifts all the positions randomly
	set.shiftscale = '.3';				//shifts the scale of the created thing randomly
	set.scale = '.8';
	set.add('spinykelp1');
	set.add('spinykelp2');
	set.add('spinykelp3');

	set.newTileBatch('rockdecor');
	set.drawlayer = 'static_front';		//sets the draw layer to put these
	set.rotation = 'scramble';			//placed at a random rotation
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.shiftposition = '20';			//shifts all the positions randomly
	set.scale = '0.3';
	set.shiftscale = '.2';				//shifts the scale of the created thing randomly
	set.add('rockdecor1.png');
	set.add('rockdecor2.png');
	set.add('rockdecor3.png');
	set.add('rockdecor4.png');
	set.add('rockdecor5.png');
	set.add('rockdecor6.png');

	set.newTileBatch('biolumdecor');
	set.drawlayer = 'static_front';		//sets the draw layer to put these
	set.rotation = 'scramble';			//placed at a random rotation
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.shiftscale = '.25';				//shifts the scale of the created thing randomly
	set.scale = '0.15';
	set.light = 'bioyellow';			//will eventualyl call this script to make a light
	set.lightlayer = 'main_front';
	set.add('biolumdecor1.png');
	set.add('biolumdecor2.png');
	set.add('biolumdecor3.png');

	set.newTileBatch('mushroom_blue_right');
	set.drawlayer = 'static_front';		//sets the draw layer to put these
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.shiftscale = '.10';				//shifts the scale of the created thing randomly
	set.scale = '0.5';
	set.add('mushroom_blue_right_1');
	set.add('mushroom_blue_right_2');
	set.add('mushroom_blue_right_3');

	set.newTileBatch('fuzzypods');
	set.drawlayer = 'static_front';		//sets the draw layer to put these
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.shiftscale = '.10';				//shifts the scale of the created thing randomly
	set.scale = '0.5';
	set.add('fuzzypods1');
	set.add('fuzzypods2');
	set.add('fuzzypods3');

	set.newTileBatch('algae');
	set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	set.bouyancy = '.05';				//will sink.
	set.drag = '1.5';					//rough, high drag
	set.rotation = 'scramble';			//placed at a random rotation
	set.scale = '0.2';
	set.shiftscale = '.25';				//shifts the scale of the created thing randomly
	set.spritebehavior = 'kelpdrift';	//tile sprites behave thusly
	set.shiftcolor = '0.2';				//shifts all the colors randomly
	set.shiftposition = '8';			//shifts all the positions randomly
	set.material = 'plant';				//sfx, food type, etc.
	set.calories = '10';				//amount of energy gained by eating this
	set.add('plant1');


	set.newTileBatch('faenest');
	set.class = 'faenest';				//the generated item will be this special class
	set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	set.bouyancy = '20';				//will sink, fast
	set.drag = '1.0';
	set.scale = '.65';
	//set.shiftscale = '.25';				//shifts the scale of the created thing randomly
	//set.shiftcolor = '0.4';				//shifts all the colors randomly
	//set.light = 'bigblue';				//will eventualyl call this script to make a light
	set.add('coralnest3');


	//## EDIBLE SNACKS ##//
	set.newTileBatch('fae');
	set.class = 'plankton';				//the generated item will be this special class
	set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	set.scale = '0.15';
	set.collisiongroup = '-255';		//sets the collision group of the object; negative numbers that match skip each other
	set.bump = '5.0';					//randomly bumps the object by this much on start
	set.drag = '0';						//skip the physics drag system; we'll fake it with behaviors
	set.spritebehavior = 'smoothburr';	//tile sprites behave thusly
	set.rotation = 'scramble';			//placed at a random rotation
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.shiftposition = '7';			//shifts all the positions randomly
	set.shiftscale = '0.2';				//shifts the scale of the created thing randomly
	set.light = 'medblue';				//will eventualyl call this script to make a light
	set.material = 'plankton';
	set.calories = '10';				//amount of energy gained by eating this
	set.add('fae1');
};
initialize = func()
{
	var set = registertileset();

	//======================== EGG ==================================================================
	set.newTileBatch('egg');
	set.class = 'egg';						//the generated item will be this special class
	set.body = 'dynamic';					//set will generate unmovable bodies [''|'static'|'dynamic']
	set.bouyancy = '.01';					//will sink slowly -- no sinking! they get stuck in the terrain!
	set.drag = '2.0';
	set.shiftposition = '7';				//shifts all the positions randomly
	set.rotation = 'scramble';				//placed at a random rotation
	set.scale = '0.75';
	//set.spritebehavior = 'heartbeat_slow';	//tile sprites behave thusly
	set.shiftcolor = '0.1';					//shifts all the colors randomly
	set.light = 'bigblue';					//will eventualyl call this script to make a light
	set.add('egg.svg');

	set.newTileBatch('eggpiece1');
	set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	set.behavior = 'decompose';
	set.bouyancy = '.5';				//will sink slowly
	set.drag = '1.0';
	set.material = 'meat';				//sfx, food type, etc.
	set.calories = '10';				//amount of energy gained by eating this
	set.scale = '0.65';
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.spritebehavior = 'tint';		//tile sprites behave thusly
	set.add('eggpiece1.svg');

	set.newTileBatch('eggpiece2');
	set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	set.behavior = 'decompose';
	set.bouyancy = '.5';				//will sink slowly
	set.drag = '1.0';
	set.material = 'meat';				//sfx, food type, etc.
	set.calories = '10';				//amount of energy gained by eating this
	set.scale = '0.65';
	set.shiftcolor = '0.1';				//shifts all the colors randomly
	set.spritebehavior = 'tint';		//tile sprites behave thusly
	set.add('eggpiece2.svg');


	//======================== OBELISKS ==================================================================
	// set.newTileBatch('obelisk');
	// set.class = 'obelisk';				//the generated item will be this special class
	// set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	// set.bouyancy = '20';				//will sink, fast
	// set.drag = '1.5';					//rough, high drag
	// set.scale = '0.8';//'0.4';
	// set.light = 'hugeblue';				//will eventualyl call this script to make a light
	// set.add('obelisk.svg');
	//
	// set.newTileBatch('dome');
	// set.class = 'obelisk';				//the generated item will be this special class
	// set.body = 'static';				//set will generate unmovable bodies [''|'static'|'dynamic']
	// set.scale = '0.4';
	// set.light = 'hugeblue';				//will eventualyl call this script to make a light
	// set.add('dome.svg');
	//
	// //======================== CRYOPODS ==================================================================
	// set.newTileBatch('cryopod');
	// set.class = 'cryopod';				//the generated item will be this special class
	// set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	// set.bouyancy = '10';				//will sink, fast
	// set.drag = '1.5';					//rough, high drag
	// set.scale = '2.2';
	// set.add('cryopod.svg');
	//
	// set.newTileBatch('nemesis');
	// set.class = 'nemesis';				//the generated item will be this special class
	// set.body = 'dynamic';				//set will generate unmovable bodies [''|'static'|'dynamic']
	// set.bouyancy = '10';				//will sink, fast
	// set.drag = '1.5';					//rough, high drag
	// set.scale = '2.2';
	// set.add('nemesis.svg');


};
var initialize = func()
{
	var synapse = registersynapse();

	synapse.name = 'Modulate';
	synapse.desc = 'Increases the strength of nearby synapes by releasing noradrenaline.';
	synapse.icon = 'icon_modulate.png';

	//set up the options
	synapse.add_variants('effect', 'enhance', 'suppress');
	synapse.set_default_option('effect', 'enhance');		//will otherwise default to the first one

	var effect = synapse.get_selected_option('effect');
	if (effect == 'enhance') {
		synapse.set_channel_pre('channel_pre_noradrenaline.mc');
		synapse.set_channel_post('channel_post_noradrenaline.mc');
	}
	if (effect == 'suppress') {
		synapse.set_channel_pre('channel_pre_serotonin.mc');
		synapse.set_channel_post('channel_post_serotonin.mc');
	}
};
var initialize = func()
{
	var synapse = registersynapse();

	synapse.name = 'Excite';
	synapse.desc = 'Activates the connected neuron by releasing glutamate.';
	synapse.icon = 'icon_excite.png';

	synapse.set_channel_pre('channel_pre_glutamate.mc');	//releases neurotransmitter into the synapse
	synapse.set_channel_post('channel_post_glutamate.mc');	//responds to neurotransmitter in the synapse
};
var initialize = func()
{
	var synapse = registersynapse();

	synapse.name = 'Inhibit';
	synapse.desc = 'Silences the connected neuron by releasing GABA.';
	synapse.icon = 'icon_inhibit.png';

	synapse.set_channel_pre('channel_pre_gaba.mc');		//releases neurotransmitter into the synapse
	synapse.set_channel_post('channel_post_gaba.mc');	//responds to neurotransmitter in the synapse
};
synapse_glutamate.mc
synapse_gaba.mc
synapse_modulate.mc

var initialize = func()
{
	var room = registerroom();



	room.tileset = 'game';


	//room.nextgroup('position:.5,.75');
	//	room.grouplimit = 1;			//only run rules in this group this many times

	//	room.nextrule(1);
	//	room.tile('nemesis');

	//	room.nextrule(1);
	//	room.tile('cryopod');
	//room.run_rules();



	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule


	//room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
	//room.nextgroup('position:.5,.5');
	//	room.nextrule(1, 1);
	//	room.marker('start');
	//room.run_rules();


	room.nextgroup('floor','empty');
		room.grouplimit = 2;			//only run rules in this group this many times

		room.nextrule(1);
		room.tile('boulder');
	room.run_rules();


	room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own

		room.nextrule(4);
		room.tile('algae');

		room.nextrule(8);
		room.tile('fae');
		room.tile('fae');
		room.tile('fae');

		room.nextrule(12);
		room.tile('fae');

		room.nextrule(120);
	room.run_rules();


	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');




};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';

	//room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
	//	room.nextrule(1, 1);
	//	room.marker('start');
	//room.run_rules();

	// room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
	// 	room.grouplimit = 1;			//only run rules in this group this many times

	// 	room.nextrule(1);
	// 	room.egg('');						//not giving it anything will pull from the creature server OR just the disc (if unavailable)

	// 	//room.nextrule(1);
	// room.run_rules();

	room.nextgroup('empty');
		room.nextrule(8);
		room.tile('algae');
		room.tile('algae');
		room.tile('algae', 'adjacent','open','bubbled');

		room.nextrule(12);
		room.tile('algae');

		room.nextrule(8);
		room.tile('fae');
		room.tile('fae');
		room.tile('fae');

		room.nextrule(12);
		room.tile('fae');

		room.nextrule(200);
	room.run_rules();


	room.nextgroup('floor','empty');
		room.nextrule(1);
		room.tile('boulder');
		
		room.nextrule(10);				//make boulders sorta uncommon
	room.run_rules();


	room.nextgroup('floor','empty');
		room.grouplimit = 2;			//only run rules in this group this many times

		room.nextrule(1);
		room.tile('faenest');
		
		room.nextrule(1);
	room.run_rules();

	
	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');
};
scenery.mc
cryopod.mc
seabed.mc
simple.mc
extracreatures.mc
var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule

	room.nextgroup('filled');
		room.nextrule(2);
		room.tile('rockdecor');
		room.tile('rockdecor', 'adjacent','filled');
		room.tile('rockdecor', 'adjacent','filled');

		room.nextrule(6);
		room.tile('rockdecor');

		room.nextrule(1);
		room.tile('biolumdecor');
		room.tile('biolumdecor', 'adjacent','backdrop');
		room.tile('biolumdecor', 'adjacent','backdrop');

		room.nextrule(3);
		room.tile('biolumdecor');

		room.nextrule(70);	
	room.run_rules();

	//room.nextgroup('backdrop');
	//	room.nextrule(1);
	//	room.tile('biolumdecor');
	//	room.tile('biolumdecor', 'adjacent','backdrop');
	//	room.tile('biolumdecor', 'adjacent','backdrop');
//
//		room.nextrule(3);
//		room.tile('biolumdecor');
//
//		room.nextrule(35);	
//	room.run_rules();


};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// TODO:
	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule

	room.nextgroup('floor_island','filled');
		room.nextrule(4);				//makes a new result with x propability
		room.tile('seaweed');			//adds some seaweed to the selected polygon
		room.tile('seaweed');
		room.tile('seaweed');

		room.nextrule(2);				//makes a new result with x propability
		room.tile('seaweed');			//adds some seaweed to the selected polygon
		room.tile('seaweed');
		room.tile('seaweed', 'adjacent','filled','floor'); //... and to some of its neighbors
		room.tile('seaweed', 'adjacent','filled','floor');

		room.nextrule(10);				//empty rule
	room.run_rules();
	
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule


	//room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
	//	room.nextrule(1, 1);
	//	room.marker('start');
	//room.run_rules();

	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule

	//FOR NOW, just added via level script instead
	//room.nextgroup('position:.7,.35');
	//	room.nextrule(1, 1);
	//	room.marker('start');
	//room.run_rules();
//
	//room.nextgroup('position:.7,.65');
	//	room.nextrule(1, 1);
	//	room.marker('start');
	//room.run_rules();

	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule


	room.nextgroup('center');	//find the tile closest to the center of the given group
		room.nextrule(1, 1);
		room.marker('start');
	room.run_rules();

	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'game';
	
	
	room.nextgroup('position:.75,.5');		//tries to position somewhere in the room
		room.grouplimit = 1;				//only run rules in this group this many times

		room.nextrule(1);
		room.tile('dome');
	room.run_rules();


	//temparary until we can add multiple stamps to rooms
	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule

/*
	room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
		room.nextrule(8);
		room.tile('algae');
		room.tile('algae');
		room.tile('algae', 'adjacent','open','bubbled');

		room.nextrule(12);
		room.tile('algae');

		room.nextrule(8);
		room.tile('fae');
		room.tile('fae');
		room.tile('fae');

		room.nextrule(12);
		room.tile('fae');

		room.nextrule(120);
	room.run_rules();
*/	

	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'game';
	
	
	room.nextgroup('floor','empty','not_ceiling');
		room.grouplimit = 1;			//only run rules in this group this many times

		room.nextrule(1);
		room.tile('obelisk');
	room.run_rules();


	//temparary until we can add multiple stamps to rooms
	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
		room.grouplimit = 3;			//only run rules in this group this many times

		room.nextrule(1);
		room.egg('');						//not giving it anything will pull from the creature server OR just the disc (if unavailable)

	room.run_rules();

};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule


	//room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
	//	room.nextrule(1, 1);
	//	room.marker('start');
	//room.run_rules();

	room.include('scenery_walls.mc');
};

var initialize = func()
{
	var room = registerroom();

	room.tileset = 'game';

	room.nextgroup('position:.5,.75');
		room.grouplimit = 1;			//only run rules in this group this many times

		room.nextrule(1);
		room.tile('nemesis');

		room.nextrule(1);
		room.tile('cryopod');
	room.run_rules();



	room.tileset = 'ocean';
	
	//apply props and stuff to this room

	// be able to guarantee that a thing will happen once if possible
	// be able add a tile to X proportion of times some condition is filled
	// be able to have rules be mutually exclusive : can't place a tile on a poly if something else is already there
	//  >>> did this in rubicon with a 'layers' system. all rules added until we hit a layer are mutually exclusive.
	//    >>> if there's only one rule but you want it to only happen some of the time, can just add an empty rule


	//room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
	room.nextgroup('position:.5,.5');
		room.nextrule(1, 1);
		room.marker('start');
	room.run_rules();


	room.nextgroup('floor','empty');
		room.grouplimit = 2;			//only run rules in this group this many times

		room.nextrule(1);
		room.tile('boulder');
	room.run_rules();


	room.nextgroup('empty','bubbled');	//'bubbled' is political: surrounded by polys whose filled status matches its own
		//room.nextrule(8);
		//room.tile('algae');
		//room.tile('algae');
		//room.tile('algae', 'adjacent','open','bubbled');

		room.nextrule(4);
		room.tile('algae');

		room.nextrule(8);
		room.tile('fae');
		room.tile('fae');
		room.tile('fae');

		room.nextrule(12);
		room.tile('fae');

		room.nextrule(120);
	room.run_rules();


	room.include('scenery_seaweed.mc');
	room.include('scenery_walls.mc');




};
# FOLDER FORMAT: <name>_<page_max>
# With a <name>.gif and <name>_<page>.png images inside of it.

basic/
peahen/
dna/
zippy/
walker/
basic/spine.mc
basic/fin.mc
basic/block.mc
basic/hip.mc
basic/hinge.mc
basic/nub_basic.mc
basic/nub_plate.mc
basic/nub_spindle.mc

organs/mouth_molars.mc
organs/mouth_jaw.mc
organs/mouth_nibbler.mc
organs/jet.mc
organs/sucker.mc
organs/harpoon.mc
organs/weight_balloon.mc
organs/weight_ballast.mc

senses/whisker.mc
senses/eye.mc
senses/orientation.mc

decoration/fiber.mc
decoration/camouflage.mcvar initialize = func()
{
	var light = registerlight();

	light.scale = 0.25;
	light.alpha = 1.0;

	light.r = .2;
	light.g = .9;
	light.b = .9;

	light.pulseStrength = .1;
};
var initialize = func()
{
	var light = registerlight();

	light.scale = 0.5;
	light.alpha = 1.0;

	light.r = .2;
	light.g = .9;
	light.b = .9;

	light.pulseStrength = .1;
};
	var initialize = func()
{
	var light = registerlight();

	light.scale = 3;
	light.alpha = 1.0;

	light.r = .2;
	light.g = .9;
	light.b = .9;
	
	light.pulseStrength = .1;
};
var initialize = func() {
	var light = registerlight();

	light.scale = 3;
	light.alpha = 1.0;

	light.r = .91;
	light.g = .67;
	light.b = .19;
	
	light.pulseStrength = .1;
};
var initialize = func()
{
	var light = registerlight();

	light.scale = 1.3;
	light.alpha = 0.3;

	light.r = .9;
	light.g = .9;
	light.b = .2;

	light.pulseStrength = .25;
};
var initialize = func()
{
	var light = registerlight();

	light.scale = 1.25;
	light.alpha = 1.0;

	light.r = .2;
	light.g = .9;
	light.b = .9;
	
	light.pulseStrength = .1;
};

var setinfo = func() {
	var level = registerlevel();
	level.name = '%TEMPLATE_NAME%';
	level.desc = "The seaweed is always greener // in somebody else's lake";
	level.coord_x = 0.000;
	level.coord_y = 0.000;
	level.icon = 'map_icon_area.svg';
};

var initialize = func() {
	var level = registerlevel();

 	// -- load the map
	level.load_room('map');
	level.set_start('start');

	//add the background cave layers
	level.runscript('backgrounds/cave/cave.mc', 'initialize');
};

var update = func() {
	var level = registerlevel();
};

var event = func() {
	var level = registerlevel();
};
tutorials/full/level.mc

areas/seweebay/level.mc
areas/sandflats/level.mc
areas/opensea/level.mc
areas/caverns/level.mc

races/rubyridge/level.mc

areas/crater.mc
channel.name = 'VGSC';
channel.longname = 'Voltage-Gated Sodium Channel';//defaults to normal name if blank
channel.desc = 'Opens & excites if the cell gets excited above -68 mV. Then, after a short delay, closes & locks until cell returns to baseline';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 500);

channel.set_opening_speed(0.9);
channel.set_closing_speed(0.5);

//triggers to open when it goes above a threshold
channel.if_closed();
channel.if_voltage_above(-68);
channel.open();
channel.reset_timer('open');

//CLOSES + inactivates if it's been open for too long
channel.if_open();
channel.if_timer('open', 11);
channel.close();
channel.lock();

//CLOSES + inactivates if it depolarizes
channel.if_open();
channel.if_voltage_above(10);
channel.close();
channel.lock();

//un-inactivates when it gets back low enough
channel.if_closed();
channel.if_voltage_below(-72);
channel.unlock();
channel.name = 'VGSC';
channel.longname = 'Voltage-Gated Sodium Channel';//defaults to normal name if blank
channel.desc = 'Opens & strongly excites if the cell exceeds -50mV. Closes & locks at 35mV until it gets back below -70mV.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 400);


//triggers to open when it goes above a threshold
channel.if_closed();
// channel.if_voltage_above(-60);
channel.if_random(-65, -10); //linearly increases in chance from first to second number
channel.open();
channel.reset_timer('_safety');

//CLOSES + inactivates if it depolarizes
channel.if_open();
channel.if_voltage_above(25);
channel.close();
channel.lock();

//CLOSES + inactivates if it's been open for too long (safety measure)
channel.if_open();
channel.if_timer('_safety', 8);
channel.close();
channel.lock();

//un-inactivates when it gets back low enough
channel.if_closed();
channel.if_voltage_below(-61);
channel.unlock();
channel.name = 'VGKC';
channel.longname = 'Voltage-Gated Potassium Channel';//defaults to normal name if blank
channel.desc = 'Opens & inhibits if the cell gets too excited.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_k, 300);

channel.set_opening_speed(0.25);
channel.set_closing_speed(0.20);

//keep resetting the open delay until we get above a point
// channel.if_voltage_below(-48);
// channel.reset_timer('opendelay');

//once we have stopped constantly resetting the opendelay timer, open er up
// channel.if_timer('opendelay', 15);
// channel.open();

//just open if we get high enough
channel.if_voltage_above(0);
channel.open();


//just close if we get low enough
channel.if_voltage_below(-72);
channel.close();

//CLOSES if it gets back low enough
// channel.if_open();
// channel.if_voltage_above(-55);
// channel.reset_timer('closedelay');

// channel.if_timer('closedelay', 6);
// channel.close();
channel.name = 'VGKC';
channel.longname = 'Voltage-Gated Potassium Channel';//defaults to normal name if blank
channel.desc = 'Opens & strongly inhibits if cell exceeds 35mV. Closes once it gets below -70mV.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_k, 350);

// channel.set_opening_speed(0.20);
// channel.set_closing_speed(0.70);

//just open if we get high enough
channel.if_voltage_above(25);
channel.open();

//just close if we get low enough
channel.if_voltage_below(-70);
channel.close();
channel.name = 'Jitter';
channel.desc = 'Adds some noise.';

var conductance = 60;
if (channel.option == 'slight') { conductance = 20; }
if (channel.option == 'some') { conductance = 80; }
if (channel.option == 'lots') { conductance = 200; }

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, conductance);

channel.set_opening_speed(0.20);
channel.set_closing_speed(0.20);

// randomly open/close
channel.if_closed();
channel.if_random(.5);
channel.open();

channel.if_open();
channel.if_random(.5);
channel.close();
channel.name = 'Jitter';
channel.desc = 'Adds some noise.';

// How much jitter? (passed in by the neuron script)
var conductance = 20;
if (channel.option == 'none') { conductance = .1; }
if (channel.option == 'slight') { conductance = 20; }
if (channel.option == 'some') { conductance = 80; }
if (channel.option == 'lots') { conductance = 200; }

// relative conductance of ions when channel is open
channel.set_conductance(ion_k, conductance);

channel.set_opening_speed(0.20);
channel.set_closing_speed(0.20);

// randomly open/close
channel.if_closed();
channel.if_random(.5);
channel.open();

channel.if_open();
channel.if_random(.5);
channel.close();
channel.name = 'SFA';
channel.longname = 'Spike Frequency Adaptation';//defaults to normal name if blank
channel.desc = 'AKA getting tired. While excited, slowly opens & inhibits until cell returns to baseline.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_k, 200);

// How quickly should the adaptation kick in? (passed in by the neuron script)
var open_speed = 0.0005;
if (channel.option == 'none') { open_speed = 0; }
if (channel.option == 'slow') { open_speed = 0.0005; }
if (channel.option == 'fast') { open_speed = 0.0025; }

// channel.set_opening_speed(0.0025);
// channel.set_closing_speed(0.0025);

channel.set_opening_speed(open_speed);
channel.set_closing_speed(0.0025);

//let it fire for a bit before closing and ending the party
channel.if_voltage_above(-40);
channel.open();

// only close
channel.if_voltage_below(-70);
channel.close();
channel.name = 'Sense';
channel.longname = '';//defaults to normal name if blank
channel.desc = 'Opens & weakly excites when triggered by a body part.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 15);

// all channels set as sensory are automatically opened by the corresponding body sensor.
// while recieving input, they constantly reset the first timer we declare here to keep it open
channel.sensory = 1;

channel.if_timer('open', 20);
channel.close();
channel.name = 'Sens';
channel.longname = 'Sensory';
channel.desc = 'Opens & excites when triggered by a body part.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 100);

// all channels set as sensory are automatically opened by the corresponding body sensor.
// while recieving input, they constantly reset the first timer we declare here to keep it open
channel.sensory = 1;

channel.if_timer('open', 20);
channel.close();
channel.name = 'Queer';
channel.longname = 'Queer Current';//defaults to normal name if blank
channel.desc = 'Opens when cell falls below -80 mV. Closes after the cell reaches -40 mV.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 50);

var open_speed = .008;
if (channel.option == 'fast') { open_speed = .5; }
if (channel.option == 'normal') { open_speed = .008; }
if (channel.option == 'slow') { open_speed = .003; }

channel.set_opening_speed(open_speed);
channel.set_closing_speed(0.5);

channel.if_closed();
channel.if_voltage_below(-80);
channel.open();

channel.if_open();
channel.if_voltage_above(-40);
channel.close();
channel.name = 'Queer';
channel.longname = 'Queer Current';//defaults to normal name if blank
channel.desc = 'When cell falls below -65 mV, excites after a delay.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 100);

//channel.if_voltage_below(-70);
//channel.open();

channel.if_closed();
channel.if_voltage_above(-68);
channel.reset_timer('opendelay');

channel.if_voltage_below(-60);
channel.unlock();

channel.if_closed();
channel.if_timer('opendelay', 35);
channel.reset_timer('open');
channel.open();

channel.if_timer('open', 120);
channel.close();
channel.lock();
channel.name = '5HT';
channel.longname = 'Serotonin Vesicle';//defaults to normal name if blank
channel.desc = 'Pre-synaptic protein that releases neurotransmitter when excited.';

channel.set_opening_speed(0.20);
channel.set_closing_speed(0.20);

channel.if_voltage_above(-40);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();

channel.if_open();
channel.release_transmitter(serotonin);
channel.name = 'NA';
channel.longname = 'Noradrenaline Vesicle';//defaults to normal name if blank
channel.desc = 'Pre-synaptic protein that releases neurotransmitter when excited.';

channel.set_opening_speed(0.20);
channel.set_closing_speed(0.20);

channel.if_voltage_above(-40);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();

channel.if_open();
channel.release_transmitter(noradrenaline);
channel.name = 'Glu';
channel.longname = 'Glutamate Vesicle';//defaults to normal name if blank
channel.desc = 'Pre-synaptic protein that releases neurotransmitter when excited.';

channel.set_opening_speed(0.20);
channel.set_closing_speed(0.20);

channel.if_voltage_above(-40);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();

channel.if_open();
channel.release_transmitter(glutamate);
channel.name = 'GABA';
channel.longname = 'GABA Vesicle';//defaults to normal name if blank
channel.desc = 'Pre-synaptic protein that releases neurotransmitter when excited.';

channel.set_opening_speed(0.20);
channel.set_closing_speed(0.20);

channel.if_voltage_above(-40);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();

channel.if_open();
channel.release_transmitter(gaba);
channel.name = '5HTR';
channel.longname = 'Serotonin Receptor';//defaults to normal name if blank
channel.desc = 'Post-synaptic channel that suppresses other synapses when open.';

channel.set_modulation(-1.0);	// this is further modified by the synapse strength & opening amount

// channel.set_opening_speed(0.70);
channel.set_closing_speed(0.10);

channel.if_transmitter(serotonin);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();
channel.name = 'NAR';
channel.longname = 'Noradrenaline Receptor';//defaults to normal name if blank
channel.desc = 'Post-synaptic channel that enhances other synapses when open.';

channel.set_modulation(1.0);	// this is further modified by the synapse strength & opening amount

// channel.set_opening_speed(0.70);
channel.set_closing_speed(0.10);

channel.if_transmitter(noradrenaline);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();
channel.name = 'GluR';
channel.longname = 'Glutamate Receptor';//defaults to normal name if blank
channel.desc = 'Post-synaptic channel that excites the cell when open.';

channel.set_conductance(ion_na, 100);//ion, conductance (relative, buit shouldn't be crazy)

// channel.set_opening_speed(0.70);
channel.set_closing_speed(0.10);

channel.if_transmitter(glutamate);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();
channel.name = 'GABAR';
channel.longname = 'GABA Receptor';//defaults to normal name if blank
channel.desc = 'Post-synaptic channel that inhibits the cell when open.';

channel.set_conductance(ion_k, 325);

// channel.set_opening_speed(0.70);
channel.set_closing_speed(0.10);

channel.if_transmitter(gaba);
channel.open();
channel.reset_timer('open');

channel.if_timer('open', 4);
channel.close();
channel.name = 'Plat';
channel.longname = '';//defaults to normal name if blank
channel.desc = 'Maintains excitation; opens & excites when the cell is already excited.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 80);

//turn on
channel.if_closed();
channel.if_voltage_above(-50);
channel.open();

//turn off
channel.if_open();
channel.if_voltage_below(-45);
channel.close();channel.name = 'Burst';
channel.longname = 'Pacemaker Burst';
channel.desc = 'When cell goes over -57 mV, opens & keeps the cell excited for a period.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 170);

channel.start_closed();

var open_time = 100;
var close_speed = .025;
if (channel.option == 'short')  { close_speed = .040; open_time = 10; }
if (channel.option == 'normal') { close_speed = .025; open_time = 100; }
if (channel.option == 'long')   { close_speed = .018; open_time = 200; }

channel.set_opening_speed(.5);
channel.set_closing_speed(close_speed);

//triggers to open when it goes above a threshold
channel.if_closed();
channel.if_voltage_above(-57);
channel.open();
channel.reset_timer('open_time');

channel.if_open();
channel.if_timer('open_time', open_time);
// channel.if_voltage_above(-30);
channel.close();
channel.lock();

//un-inactivates after a while
channel.if_closed();
channel.if_voltage_below(-64);
channel.unlock();
channel.name = 'Leak';
channel.longname = 'Leak: Small Na';
channel.desc = 'Always open. Weakly maintains the baseline Vm.';

channel.set_conductance(ion_na, 1.5);
channel.name = 'Leak';
channel.longname = 'Leak: Small K';
channel.desc = 'Always open. Weakly maintains the baseline Vm.';

channel.set_conductance(ion_k, 4);
channel.name = 'Leak';
channel.longname = 'Leak Na';
channel.desc = 'Always open. Maintains the baseline Vm.';

channel.set_conductance(ion_na, 16);
channel.name = 'Leak';
channel.longname = 'Leak K';
channel.desc = 'Always open. Maintains the baseline Vm.';

channel.set_conductance(ion_k, 16);
channel.name = 'Leak';
channel.longname = 'Leak: Big Na';
channel.desc = 'Always open. Strongly maintains the baseline Vm.';

channel.set_conductance(ion_na, 32);
channel.name = 'Leak';
channel.longname = 'Leak: Big K';
channel.desc = 'Always open. Strongly maintains the baseline Vm.';

channel.set_conductance(ion_k, 75);
channel.name = 'Key';
channel.longname = 'Keyboard Channel';//defaults to normal name if blank
channel.desc = 'Opens & excites the cell when a key is pressed.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 80);

//CLOSES if it's been open for too long
channel.if_timer('open', 10);
channel.close();

//given keypress opens the channel
if (channel.option != '') {
	channel.if_keyboard(channel.option);
	channel.open();
	channel.reset_timer('open');
}

channel.name = 'Wait';
channel.longname = '';//defaults to normal name if blank
channel.desc = 'When cell goes over -70mV, counteract it with inhibition for a short time.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_k, 625);

channel.set_opening_speed(1.0);
channel.set_closing_speed(0.01);

if (channel.option == 'short') { channel.set_closing_speed(0.02); }
if (channel.option == 'med') { channel.set_closing_speed(0.01); }
if (channel.option == 'long') { channel.set_closing_speed(0.005); }


//inhibit self in response to excitation
channel.if_closed();
channel.if_voltage_above(-70);
	channel.open();
	channel.reset_timer('open');

//start release the inhibition immediately after opening
channel.if_open();
channel.if_timer('open', 4);
	channel.reset_timer('refractory');
	channel.close();
	channel.lock();


//becomes available to re-open once it gets low enough
channel.if_closed();
channel.if_locked();
channel.if_voltage_below(-75);
channel.if_timer('refractory', 300);
	channel.unlock();
channel.name = 'Fire';
channel.longname = '';//defaults to normal name if blank
channel.desc = 'When cell goes over -70mV, wait a short time and then excite.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 120);

channel.set_opening_speed(0.01);
channel.set_closing_speed(0.5);

if (channel.option == 'short') { channel.set_opening_speed(0.02); }
if (channel.option == 'med') { channel.set_opening_speed(0.01); }
if (channel.option == 'long') { channel.set_opening_speed(0.002); }


//slowly excite self in response to excitation
channel.if_closed();
channel.if_unlocked();
channel.if_voltage_above(-70);
	channel.open();

// stay open for a little bit
channel.if_open();
channel.if_voltage_below(-40);
	channel.reset_timer('open');

// close when we're done
channel.if_open();
channel.if_timer('open', 60);
	channel.close();
	channel.lock();

//becomes available to re-open once it gets low enough
channel.if_closed();
channel.if_locked();
channel.if_voltage_below(-75);
	channel.unlock();
channel.name = 'ON';
channel.longname = 'Always-on';//defaults to normal name if blank
channel.desc = 'Always open. Moderately excites the cell.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 100);

//always be open
channel.if_voltage_below(100);
channel.open();

channel.name = 'Ad K';
channel.longname = 'Potassium Adaptor';//defaults to normal name if blank
channel.desc = 'Triggered by excitation after a long delay. Slowly opens & inhibits until returned to baseline.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_k, 400);

channel.set_opening_speed(0.0025);
channel.set_closing_speed(0.20);

//let it fire for a bit before closing and ending the party
channel.if_voltage_above(-75);
channel.open();

//whenever we go above reseting, resets the 'we-need-to-stay-at-resting' timer
channel.if_voltage_above(-75);
channel.reset_timer('closedelay');

// only close
channel.if_voltage_below(-75);
channel.if_timer('closedelay', 200);
channel.close();
// channel.reset_timer('opendelay');
channel.name = 'Ad Na';
channel.longname = 'Sodium Adaptor';//defaults to normal name if blank
channel.desc = 'Triggered by excitation. Opens & excites for a period, then locks closed until inhibited.';

// relative conductance of ions when channel is open
channel.set_conductance(ion_na, 80);

//channel.set_conductance_closed(ion_k, 10);	//help the other phase out a little

//if we're closed and get excited, open up + excite the cell!
channel.if_closed();
channel.if_voltage_above(-70);
channel.open();
channel.reset_timer('open');

//once we've finished being open, close + lock
channel.if_open();
channel.if_timer('open', 200);
channel.close();
channel.lock();

//un-inactivates when it gets back low enough
channel.if_closed();
channel.if_voltage_below(-75);
channel.unlock();
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Sensory';
	cell.desc = 'Activated when attached. INHIBIT to release.';
	cell.graphic = 'cell_sensory_sucker.svg';

	cell.capacitance = 2;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');

	cell.add_channel('channel_sensory.mc');

	//set up the options
	cell.add_variants('attach', 'all', 'rock', 'biology');
	cell.set_default_option('attach', 'all');
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Sensory';
	cell.desc = 'Activated by some kind of external stimuli.';
	cell.graphic = 'cell_sensory.svg';

	cell.capacitance = 2;
	cell.resistance = 1;

	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_small_na.mc');

	//three of these so organs can individually turn them on
	cell.add_channel('channel_sensory_weak.mc');
	cell.add_channel('channel_sensory_weak.mc');
	cell.add_channel('channel_sensory_weak.mc');
	cell.add_channel('channel_sensory_weak.mc');

	//set up the options
	cell.add_variants('adapt', 'none', 'slow', 'fast');
	cell.set_default_option('adapt', 'none');
	var adapt = cell.get_selected_option('adapt');
	if (adapt != 'none') { cell.add_channel('channel_spikefreqadapt.mc', adapt); }
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Sensory';
	cell.desc = 'Activated by some kind of external stimuli.';
	cell.graphic = 'cell_sensory_eye.svg';

	cell.capacitance = 2;
	cell.resistance = 1;

	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_small_na.mc');

	//multiple copies so organs can individually turn each on
	cell.add_channel('channel_sensory_weak.mc');
	cell.add_channel('channel_sensory_weak.mc');
	cell.add_channel('channel_sensory_weak.mc');
	cell.add_channel('channel_sensory_weak.mc');

	//set up the options
	cell.add_variants('adapt', 'none', 'slow', 'fast');
	cell.set_default_option('adapt', 'none');
	var adapt = cell.get_selected_option('adapt');
	if (adapt != 'none') { cell.add_channel('channel_spikefreqadapt.mc', adapt); }

	cell.add_variants('sees', 'all', 'rock', 'biology');
	cell.set_default_option('sees', 'all');

	cell.add_variants('touchy', 'high', 'normal', 'low');
	cell.set_default_option('touchy', 'normal');

	cell.add_slider('arc', 15, 60, 150);
	cell.set_default_option('arc', 60);

	cell.add_slider('range%', .25, 1.0, 2.0);
	cell.set_default_option('range%', 1.0);
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Sensory';
	cell.desc = 'Activated by some kind of external stimuli.';
	cell.graphic = 'cell_sensory.svg';

	cell.capacitance = 2;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');

	cell.add_channel('channel_sensory.mc');

	//set up the options
	cell.add_variants('adapt', 'none', 'slow', 'fast');
	cell.set_default_option('adapt', 'none');
	var adapt = cell.get_selected_option('adapt');
	if (adapt != 'none') {
		cell.add_channel('channel_spikefreqadapt.mc', adapt);
		cell.add_channel('channel_spikefreqadapt.mc', adapt);
	}
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Queer';
	cell.desc = 'Activates after being silenced.';

	cell.graphic = 'cell_queer.svg';

	cell.capacitance = 8;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');

	cell.add_channel('channel_queer.mc');	//depolarizes on hyperpolarization
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Plateau';
	cell.desc = 'Excite it to turn on, inhibit to turn off.';

	cell.graphic = 'cell_plateau.svg';

	cell.capacitance = 8;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_na.mc');

	cell.add_channel('channel_plateau.mc');

	cell.add_variants('start', 'off', 'on');
	cell.set_default_option('start', 'off');		//will otherwise default to the first one

	//implement the selected options for the current cell:
	var start = cell.get_selected_option('start');
	if (start == 'off') { cell.starting_voltage = -70; }
	if (start == 'on')  { cell.starting_voltage = 10; }

};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Photophore';
	cell.desc = 'Controls lights.';

	cell.graphic = 'cell_photophore.svg';

	//can't drag axons out of this; output-only
	cell.can_move = 1;
	cell.can_connect = 0;

	cell.capacitance = 2.5;
	cell.resistance = 1;

	//set up the options
	cell.add_variants('resting', 'on', 'off');
	cell.set_default_option('resting', 'on');

	//implement the selected options for the current cell:
	var rate = cell.get_selected_option('resting');
	if (rate == 'off')	{
		cell.add_channel('channel_leak_big_k.mc');
		cell.add_channel('channel_leak_big_k.mc');
		cell.add_channel('channel_leak_big_na.mc');
	}
	if (rate == 'on')	{
		cell.add_channel('channel_leak_big_k.mc');
		cell.add_channel('channel_leak_big_na.mc');
		cell.add_channel('channel_leak_big_na.mc');
	}
};
var initialize = func() {
	var cell = registercell();

	cell.name = 'Pacemaker';
	cell.desc = 'Turns on and off.';

	cell.graphic = 'cell_pacemaker.svg';

	cell.capacitance = 3;
	cell.resistance = 1;

	cell.simulate_axons = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');

	//set up the options
	cell.add_variants('rhythm', 'fast', 'normal', 'slow');
	cell.set_default_option('rhythm', 'normal');		//will otherwise default to the first one

	cell.add_variants('burst', 'short', 'normal', 'long');
	cell.set_default_option('burst', 'normal');		//will otherwise default to the first one

	//implement the selected options for the current cell:
	var rhythm = cell.get_selected_option('rhythm');
	if (rhythm == 'fast')	{ cell.graphic = 'cell_pacemaker_fast.svg'; cell.add_channel('channel_queer_variable.mc', 'fast'); }
	if (rhythm == 'normal')	{ cell.graphic = 'cell_pacemaker.svg'; cell.add_channel('channel_queer_variable.mc', 'norm'); }
	if (rhythm == 'slow')	{ cell.graphic = 'cell_pacemaker_slow.svg'; cell.add_channel('channel_queer_variable.mc', 'slow'); }

	var burst = cell.get_selected_option('burst');
	if (burst == 'short')	{ cell.add_channel('channel_pacemaker.mc', 'short'); }
	if (burst == 'normal')	{ cell.add_channel('channel_pacemaker.mc', 'norm'); }
	if (burst == 'long')	{ cell.add_channel('channel_pacemaker.mc', 'long'); }

};
var initialize = func() {
	var cell = registercell();

	cell.name = 'Pacemaker';
	cell.desc = 'Turns on and off.';

	cell.graphic = 'cell_pacemaker.svg';

	cell.capacitance = 3;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_small_na.mc');

	//set up the options
	cell.add_variants('rhythm', 'fast', 'normal', 'slow');
	cell.set_default_option('rhythm', 'normal');		//will otherwise default to the first one

	cell.add_variants('burst', 'short', 'normal', 'long');
	cell.set_default_option('burst', 'normal');		//will otherwise default to the first one

	//implement the selected options for the current cell:
	var rhythm = cell.get_selected_option('rhythm');
	if (rhythm == 'fast')   { cell.add_channel('channel_queer_variable.mc', 'fast'); cell.graphic = 'cell_pacemaker_fast.svg'; }
	if (rhythm == 'normal')	{ cell.add_channel('channel_queer_variable.mc', 'norm'); cell.graphic = 'cell_pacemaker.svg'; }
	if (rhythm == 'slow')	{ cell.add_channel('channel_queer_variable.mc', 'slow'); cell.graphic = 'cell_pacemaker_slow.svg'; }

	var burst = cell.get_selected_option('burst');
	if (burst == 'short')  { cell.add_channel('channel_pacemaker.mc', 'short'); }
	if (burst == 'normal') { cell.add_channel('channel_pacemaker.mc', 'normal'); }
	if (burst == 'long')   { cell.add_channel('channel_pacemaker.mc', 'long'); }

	cell.add_variants('jitter', 'slight', 'some', 'lots');
	cell.set_default_option('jitter', 'slight');
	var jitter = cell.get_selected_option('jitter');
	if (jitter != 'none') { cell.add_channel('channel_stochastic_k.mc', jitter); }
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Orientation';
	cell.desc = 'A handle for an array of cells, which activate when held at certain angles.';

	cell.graphic = 'cell_sensory_orientation.svg';

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');

	//not a 'real' cell, just a hollowed-out thing that moves all the others around.
	cell.can_connect = 0;
	cell.can_accept_connections = 0;

	//tell it to make a number of other sensory cells (second number is direction: 0 = north, proceeds clockwise until 5 = north-west)
	cell.add_to_bundle('soma_sensory_graded.mc', 0);
	cell.add_to_bundle('soma_sensory_graded.mc', 1);
	cell.add_to_bundle('soma_sensory_graded.mc', 2);
	cell.add_to_bundle('soma_sensory_graded.mc', 3);
	cell.add_to_bundle('soma_sensory_graded.mc', 4);
	cell.add_to_bundle('soma_sensory_graded.mc', 5);
};

var initialize = func()
{
	var cell = registercell();

	cell.name = 'Muscle';
	cell.desc = 'Controls a muscle.';

	cell.graphic = 'cell_sensory_jet.svg';

	//can't drag axons out of this; output-only
	cell.can_move = 1;
	cell.can_connect = 0;

	cell.capacitance = 6;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Muscle';
	cell.desc = 'Controls a muscle.';

	cell.graphic = 'cell_motor.svg';

	//can't drag axons out of this; output-only
	cell.can_move = 1;
	cell.can_connect = 0;

	cell.capacitance = 2.5;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_big_na.mc');
};
var initialize = func() {
	var cell = registercell();

	cell.name = 'Keyboard';
	cell.desc = 'Responds to keyboard input.';

	cell.graphic = 'cell_keyboard.svg';
	cell.text = 'nil';

	cell.capacitance = 4;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');

	cell.add_variants('input', 'up', 'down', 'left', 'right');

	var key = cell.get_selected_option('input');
	if (key == 'up') { key_up(); }
	if (key == 'down') { key_down(); }
	if (key == 'left') { key_left(); }
	if (key == 'right') { key_right(); }
};

var key_up = func() {
	var cell = registercell();
	cell.add_channel('channel_keyboard.mc', 'w');
	cell.add_channel('channel_keyboard.mc', 'up');
	cell.text = '^';
};

var key_down = func() {
	var cell = registercell();
	cell.add_channel('channel_keyboard.mc', 's');
	cell.add_channel('channel_keyboard.mc', 'down');
	cell.text = 'v';
};

var key_left = func() {
	var cell = registercell();
	cell.add_channel('channel_keyboard.mc', 'a');
	cell.add_channel('channel_keyboard.mc', 'left');
	cell.text = '<';
};

var key_right = func() {
	var cell = registercell();
	cell.add_channel('channel_keyboard.mc', 'd');
	cell.add_channel('channel_keyboard.mc', 'right');
	cell.text = '>';
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Harpoon';
	cell.desc = 'A handle for an array of cells which control the harpoon.';

	cell.graphic = 'cell_organ_harpoon.svg';

	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_na.mc');

	//not a 'real' cell, just a hollowed-out thing that moves all the others around.
	cell.can_connect = 0;
	cell.can_accept_connections = 0;

	//tell it to make a number of other sensory cells (second number is direction: 0 = north, proceeds clockwise until 5 = north-west)
	cell.add_to_bundle('soma_motor.mc', 0); // fire
	cell.add_to_bundle('soma_sensory.mc', 1); // latched?
	cell.add_to_bundle('soma_motor.mc', 2); // release
};
var initialize = func() {
	var cell = registercell();

	cell.name = 'Flex';
	cell.desc = 'Build your own cell! Many different optional properties.';

	cell.graphic = 'cell_flex.svg';

	cell.capacitance = 4; // overwritten by inertia, below
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	// cell.add_channel('channel_leak_na.mc');  //set by option

	//set up the options
	cell.add_variants('resting', 'low', 'normal', 'high');
	cell.set_default_option('resting', 'normal');
	var resting = cell.get_selected_option('resting');
	if (resting == 'low') { cell.add_channel('channel_leak_small_na.mc'); }
	if (resting == 'normal') { cell.add_channel('channel_leak_na.mc'); }
	if (resting == 'high') { cell.add_channel('channel_leak_big_na.mc'); }

	cell.add_variants('jitter', 'slight', 'some', 'lots');
	cell.set_default_option('jitter', 'slight');
	var jitter = cell.get_selected_option('jitter');
	if (jitter != 'none') { cell.add_channel('channel_stochastic_k.mc', jitter); }

	cell.add_variants('inertia', 'light', 'medium', 'heavy');
	cell.set_default_option('inertia', 'light');
	var inertia = cell.get_selected_option('inertia');
	if (inertia == 'light')	{ cell.capacitance = 4; } // default
	if (inertia == 'medium'){ cell.capacitance = 16; }
	if (inertia == 'heavy')	{ cell.capacitance = 32; }

	cell.add_variants('adapt', 'none', 'slow', 'fast');
	cell.set_default_option('adapt', 'none');
	var adapt = cell.get_selected_option('adapt');
	if (adapt != 'none') { cell.add_channel('channel_spikefreqadapt.mc', adapt); }

	cell.add_variants('queer', 'none', 'some', 'lots');
	cell.set_default_option('queer', 'none');
	var queer = cell.get_selected_option('queer');
	if (queer == 'some') { cell.add_channel('channel_queer_variable.mc', 'norm'); }
	if (queer == 'lots') { cell.add_channel('channel_queer_variable.mc', 'fast'); }

	cell.add_variants('plateau', 'none', 'medium', 'endless');
	cell.set_default_option('plateau', 'none');
	var plateau = cell.get_selected_option('plateau');
	if (plateau == 'medium') { cell.add_channel('channel_pacemaker.mc', 'normal'); }
	if (plateau == 'endless') { cell.add_channel('channel_plateau.mc'); }




};
var initialize = func() {
	var cell = registercell();

	cell.name = 'Delay';
	cell.desc = 'Fires after a brief delay.';

	cell.graphic = 'cell_delay_1.svg';

	cell.capacitance = 4;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_small_na.mc');

	cell.add_variants('delay', 'short', 'medium', 'long');
	cell.set_default_option('delay', 'medium');		//will otherwise default to the first one

	//implement the selected options for the current cell:
	var delay = cell.get_selected_option('delay');
	if (delay == 'short')	{ delay_1(); }
	if (delay == 'medium')	{ delay_2(); }
	if (delay == 'long')	{ delay_3(); }
};

var delay_1 = func() {
	var cell = registercell();
	cell.add_channel('channel_delay_wait.mc', 'short');
	cell.add_channel('channel_delay_fire.mc', 'short');
	cell.graphic = 'cell_delay_1.svg';
};

var delay_2 = func() {
	var cell = registercell();
	cell.add_channel('channel_delay_wait.mc', 'med');
	cell.add_channel('channel_delay_fire.mc', 'med');
	cell.graphic = 'cell_delay_2.svg';
};

var delay_3 = func() {
	var cell = registercell();
	cell.add_channel('channel_delay_wait.mc', 'long');
	cell.add_channel('channel_delay_fire.mc', 'long');
	cell.graphic = 'cell_delay_3.svg';
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Simulated';
	cell.desc = 'Action potentials in, action potentials out.';

	cell.graphic = 'cell1.svg';

	cell.capacitance = 4;
	cell.resistance = 1;

	cell.simulate_axons = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_na.mc');
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Basic';
	cell.desc = 'Action potentials in, action potentials out.';

	cell.graphic = 'cell1.svg';

	cell.capacitance = 4; // overwritten by inertia, below
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_k.mc');
	cell.add_channel('channel_leak_small_na.mc');


	cell.add_variants('jitter', 'slight', 'some', 'lots');
	cell.set_default_option('jitter', 'slight');

	var jitter = cell.get_selected_option('jitter');
	cell.add_channel('channel_stochastic_na.mc', jitter);
	cell.add_channel('channel_stochastic_k.mc', jitter);


	cell.add_variants('inertia', 'light', 'medium', 'heavy');
	cell.set_default_option('inertia', 'light');
	var inertia = cell.get_selected_option('inertia');
	if (inertia == 'light')	{ cell.capacitance = 4; } // default
	if (inertia == 'medium'){ cell.capacitance = 16; }
	if (inertia == 'heavy')	{ cell.capacitance = 32; }
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Always-On';
	cell.desc = 'What it says on the label. Fires at a constant rate.';

	cell.graphic = 'cell_alwayson.svg';

	cell.capacitance = 8;
	cell.resistance = 10;

	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_big_na.mc');

	//set up the options
	cell.add_variants('rate', 'weak', 'normal', 'rapid');
	cell.set_default_option('rate', 'normal');
	var rate = cell.get_selected_option('rate');
	var na_leak_count = 0;
	if (rate == 'weak')		{ na_leak_count = 0; }
	if (rate == 'normal')	{ na_leak_count = 3; }
	if (rate == 'rapid') 	{ na_leak_count = 5; }
	for (var i = 1; i < na_leak_count; i++) {
		cell.add_channel('channel_leak_big_na.mc');
	}
};
var initialize = func()
{
	var cell = registercell();

	cell.name = 'Adaptor';
	cell.desc = 'Fires a burst when excited, but soon turns self off.';

	cell.graphic = 'cell_adaptor.svg';

	cell.capacitance = 8;
	cell.resistance = 1;

	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_big_k.mc');
	cell.add_channel('channel_leak_na.mc');

	cell.add_channel('channel_adaptor.mc');
	cell.add_channel('channel_adaptor_close.mc');
};
soma_flex.mc
soma_plateau.mc
soma_alwayson.mc
soma_adaptor.mc
soma_delay.mc
soma_keyboard.mc
soma_pacemaker.mc
soma_default.mcvar initialize = func()
{
	var cell = registercell();

	cell.desc = 'dendrite';
	cell.type = dendrite;

	cell.capacitance = .75;
	cell.resistance = 10;

	cell.add_channel('channel_leak_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_small_na.mc');
};
var initialize = func()
{
	var cell = registercell();

	cell.desc = 'axon';
	cell.type = axon;

	cell.capacitance = .75;
	cell.resistance = 20;

	cell.add_channel('channel_leak_k.mc');
	cell.add_channel('channel_leak_small_na.mc');

	cell.add_channel('channel_vgsc_simulated.mc');		//voltage-gated sodium channel for ACTION POTENTIALS
	cell.add_channel('channel_vgkc_simulated.mc');		//voltage-gated potassium channel, helps bring AP back down
};
var initialize = func()
{
	var cell = registercell();

	cell.desc = 'axon';
	cell.type = axon;

	cell.capacitance = .4;
	cell.resistance = 20;

	cell.add_channel('channel_leak_k.mc');	//potassium leak channel to set the resting potential
	cell.add_channel('channel_leak_small_na.mc');

	cell.add_channel('channel_vgsc.mc');		//voltage-gated sodium channel for ACTION POTENTIALS
	cell.add_channel('channel_vgkc.mc');		//voltage-gated potassium channel, helps bring AP back down
};
<By>
Olive Perry
link:wick.works


<Special Thanks>
Lucy Bellwood
Enyo Sherman
Sam Liebow
Adam P Farnsworth
Minat Jaravata
Laura Klinkner
Tyler Edwards
Joe Wasserman
Mark Chen

<Neuron Math>
Gabriel Barello

<Voices>
Jae Hero
Ken Yoshikawa

<Recording Studio>
Jeffrey Brice
Portland Community
   College Media Lab

<Languages>
Cerberus X
link:cerberus-x.com

MiniC by Nicholas Grant
link:patreon.com/nrgsoft

<Font>
Rawengulk by Grzegorz Luk
link:glukfonts.pl

<Music & Sound>
Uluru by Kevin Macleod
link:incompetech.com

link:freesound.org

<Other Software>
Inkscape
link:inkscape.org
Paint.net
link:getpaint.net
Audacity
link:audacityteam.org
Scrivener
link:literatureandlatte.com
ScreenToGif
link:screentogif.com

<Quotes>
Mary Shelly
  Frankenstein
Karel Capek
  R.U.R.
Emily Short
  Galatea
Old Testament

<Kickstarter Backers>
Hunter Mayer
Gabriel
Allen & Martha Neuringer
Marc Falabregues
Chris Zaharia
Hayden Meyer
Joseph Dufour
The Marder Lab,
  Brandeis University
Dexorcist
Aya Maguire
Konrad Feiler
Barney
Caedmon "FancyPants" Webb
David Tyler Edwards
Perry
Mike Vignal
TheMaker51
Dee Faaborg
GamerQuest
Andrew Krause
John Kevin Sabino
Joe Glassy
Joshua "Renanse" Slack
Mica Peacock
Geek & Dad
Orestis Papaioannou
Meghan OConnell
Ed Stastny
Matthew Case
Kate Leitermann
K. Todd
Lorenzo Clark
Anna Henkin
Josh Boykin
Jason Hardwyre
Maggie Graham
hexmoire
Sam Liebow
Allison M
Mike Young
Phillip Pearson
Mikkel Snyder
Joy Mersmann
Tayler Stokes
Yori Kvitchko
Matt Robinson
Ken Yoshikawa
Hugh Owens
Bob Koutsky
Harrison
Bill Clark
Jules Chatelain
J. Kominsky
Richard 'Scylld' Comfort
Manuel Freiberger
Joe A. Wasserman
psadil
A. Lingawi
Scott Reichelt
Christo Meid
Christopher
   Auger-Dominguez
Skylar Troth
Nabil Maynard
Charles Emrich
M Pete
Benj Williams
Cary Staples
Housand JAM
Emily Merfeld
James Doe
Jackson Lango
Jason Leonard
Wesley James
Patrick Kimo
Robert Potter
Scott Lowrie
Corollarytower
Derek Outwater
Aquilasight
Anna and Matthew Dorsey
Zemerson
Lacey Van Nortwick
N. Reynolds
Shannon VanDyke
Timothy Storey
Dmitri Salcedo
Sam and Tyler Davidson
Laura Klinkner
Finn Ellis
Thomas Suckow
Connor Smith
Rebecca Groom
Benjamin Staffin
Amber Yust
Fraser K
Rebecca Nickerson
Cancy Chu
No thanks I don't want to
  be named I'm not
  declining this I want
  this whole thing put in
  the credits including
  this part
Shane Sullivan
Sean Harris
Ian M. Bone
Satchel Parker
Erin Hoffman-John
Ross Williams
Mark Ashton
Nick Cummings
Blake Werner
DW
James Miller
Kai and Kale Turner
Michael J. Gardner II
~
Jon Pepler
Sam Gordon
Louis Webb
dzil123
Fatmonkey
Lucy Bellwood
James LaRue
mcdanger
Dr. Lawton
Ben Sheff
John K Biro
mo
Luke T
chernobelenkiy
Mike Bundt
Ali R. Malek, M.D.
Arian Treffer
Emily Goldman
Markus Rosse
Owen Morgan
Traa VN
Billorko
Sara Bahmanyar
David Nyer
TJ "Daggaroth" Connolly
Adam Jones
Louis Garczynski
Petezah
Soren Jones
Alpha Quail
Sasha M
Jossef Osborn
A. Tamar Conner
Jon Dodson
Amper J.
Nic biondi
Karrin Blue
Craig M
Alex C
KLW
Brian Rosenberger
mrattus
Gina F.
Ifer
Dan DuVall
Rachel Moody
JH
Naomi Hemmings
moof
Adric "ArcaneZedric"
Brianna Roberts
Carlie & Matt Stolz
Ali Aras
Anthony
Nate Herrmann
Moth
Dr. Christoph Meisselbach
Cameron Merrick
James Parsons
Francis Botero
Merlin
Rob Abrazado
Carissa Hayden
Screwtape
Wes Brown
Marc7454
Zeo Cohen
JT Hughes
Padre E.T.
Katie L
Justen Palmer
Micha Stettler
cherie heiberg
Mark DeLoura
Malachi de AElfweald
Brandi Bryant
Meeghan Appleman
Justin Wilkinson
Ian M. Jenks
Erica Pettit
John Willcox-Beney
Humberto Eduardo
Krystal Leger
Patrick!
SilveryBeing
Jason Hall
Ingo Duarte
Anonymous
Simon H
Elena Churilov
Ian O'Dea
fabri mafessoni
Zombomb
Logan Tibbetts
N7Snake
Mattias Lehman
Robin Luft-Kite
Kaya Reed
Autumnnnnnn
Jordan Barnes
Doug M.
dr Piotr Migdal
Daryn
Beatscribe
Hap Hazard
Heather D. Fulton
Elena Churilov
Ian O'Dea
fabri mafessoni
Ajeeet

















