The Anthology of Ants

Any sufficient simulation must be reproducibly computable. Its entropy is a function of the ability to stabilize performance in a constructed environment.

Given a set simulation, or state machine, we must agree that while outcomes/results may be complex and indescribable, such interactions are the product of logic, therefore computable, and therefore translatable into a mathematic equation.

Dependent, in nature, as we presume agents of an interactive simulated experience possess quantifiable needs/requirements.

Artificial Constraints in Dynamic Systems

Let's assume a scalar of x inclusive between 0 and 1 ( 1 >= x >= 0 ) representing some dimension/property, such as an entities speed, age, or intelligence.

propertyf(x)x = 0x = 1
speedx04
agex / max( x[] )just bornvery old?
intelligencex / max( x[] )braindeadomnipotent

With speed, we can easily quantify its value as a tangible representation of movement speed, the only logic required being that to calculate its value. We can know, by process of exhaustion and linear regression the outcome of its transformations and its effect on the system.

In any system with normalization, and with only human/culturally/subjective in nature, we risk the vanishing gradient problem, and shifting biases, wherein the case of a single property in a set of entity properties explodes in value, and in extreme cases where the average difference between the integers becomes lower resolution than can be supported by the system.

Considering, these three scalar properties exists within the context of the simulation, they are a representation of attributes of state: speedageintelligence, of which a participant's identity within the system can be defined.

class Entity { constructor(name, speed, age, smart){ this.name = name; this.speed = speed; this.age = age; this.smart = smart; this.position = (new Oak.Math.Vec2()).random(); this.direction = ((new Oak.Math.Vec2()).random()).normalize(); } } maggie = new Entity('maggie', 4, 19, 7); bob = new Entity('bob', 7, 22, 6); sue = new Entity('sue', 3, 42, 9); return Oak.Utils.HTML.arrayToTable([ Oak.Utils.Object.rollup(maggie), Oak.Utils.Object.rollup(bob), Oak.Utils.Object.rollup(sue) ], {class:"slim vertical"});

Because we are working with like parameters composed into distinct columns, we can assume that these types will not change. To produce easier** calculations, we can normalize the set of entities by the set of their columns. Resulting in normalization across.

entityf(x) = x / max(speed)f(x) = x / max(age)f(x) = x / max(int.)

Knowing that,

  • max(speed) = 7
  • max(age) = 42
  • max(int) = 9

We can calculate the normalized representation of our entities, as seen here.

return normalized = Oak.Utils.Array.normalizeProperties([maggie, bob, sue]);

Thusly, our ants could be described more simply, as the entire collection of attributes, defining what is that entity, is represented, normalized, and finite.

return Oak.Utils.HTML.arrayToTable(normalized.map((item)=>{return Oak.Utils.Object.rollup(item);}),{class:"slim"});

What we do know is that for any segment, it could be assumed that such segment was that, a segment, and therefore could be represented in a more simple, or continuous way.

iterations = 0; train_time = 0; function setBestBrain(age, brain){ let best_brain_age = getBestBrainAge(); if (age > best_brain_age){ window.localStorage.setItem("_oakframe_anthology_of_ants_best_brain_age",age); window.localStorage.setItem("_oakframe_anthology_of_ants_best_brain",JSON.stringify(brain.toJSON())) } addBestBrainTime(train_time); addBestBrainIterations(iterations); iterations = 0; train_time = 0; } function getBestBrainAge(){ return parseInt(window.localStorage.getItem("_oakframe_anthology_of_ants_best_brain_age"))||0; } function getBestBrain(){ let best_brain = window.localStorage.getItem("_oakframe_anthology_of_ants_best_brain"); if (best_brain){ best_brain = (new Oak.Neural.QLearn(3)).fromJSON(JSON.parse(best_brain)) } return best_brain; } function addBestBrainIterations(iterations){ _i = getBestBrainIterations(); window.localStorage.setItem("_oakframe_anthology_of_ants_iterations",_i+iterations); } function addBestBrainTime(time){ _t = getBestBrainTime(); window.localStorage.setItem("_oakframe_anthology_of_ants_time",_t+time); } function getBestBrainIterations(){ return parseInt(window.localStorage.getItem("_oakframe_anthology_of_ants_iterations"))||0; } function getBestBrainTime(){ return parseInt(window.localStorage.getItem("_oakframe_anthology_of_ants_time"))||0; }

What we do not know are what the representations beyond normalization, such that a more extreme example is encountered, would be needed to understand more complex internal and external stimuli.

How do we quantify behaviors such as eating, drinking, and caloric expenditure? Surely integral representations are suitable for activation, and yet the question still remains at which level is a brain sufficiently suitable for calculations of self and inner thought.

entityTraits = ["hunger", "hygiene", "social", "energy", "environment", "entertained"]; class EntityBehavior extends Entity { constructor(entity) { super(entity.name, entity.speed, entity.age, entity.smart); for (var trait of entityTraits){ this[trait] = Math.random(); } this.size = 1+(Math.random()); this.color = (new Oak.Color.RGB()).set(Math.random()*255,Math.random()*255,Math.random()*255); this.sightDistance = 0.1+Math.random(); this.worldView = []; this.score= 0; this.qlearn = new Oak.Neural.QLearn(3); } die(){ if (this.age > getBestBrainAge()){ setBestBrain(this.age, this.qlearn); } for (var trait of entityTraits){ this[trait] = Math.random(); } this.qlearn.working_history = []; this.age = 0; this.position = (new Oak.Math.Vec2()).random(); this.direction = ((new Oak.Math.Vec2()).random()).normalize(); } update() { let decay = 0.0001; for (var trait of entityTraits){ this[trait] -= decay; this.age+=(decay); } if (this.hunger < 0 || this.energy < 0){ this.die(); } } }

With an ability to carry its memories, such a being is unlike natural creatures in the world. They exist as arrays of events, tied together by a score of their lives, essentially their age, perhaps we could look at other metrics, which one might prefer to bias towards reproduction.

function updateWorldView(entity, entities, surface, draw){ iterations++; dt = Date.now(); w = surface.getWidth(); h = w; if (draw){ surface.getContext().fillStyle=entity.color.toHex(); surface.getContext().beginPath(); surface.getContext().arc(entity.position.x*w, entity.position.y*h, 10, 0, 2 * Math.PI); surface.getContext().fill(); surface.getContext().globalAlpha = 0.2; // Draw the direction the entity is facing surface.getContext().strokeStyle="#000"; surface.getContext().beginPath(); surface.getContext().moveTo(entity.position.x*w, entity.position.y*h); surface.getContext().lineTo((entity.position.x*w)+(entity.direction.x*40), (entity.position.y*h)+(entity.direction.y*40)); surface.getContext().stroke(); } entity.worldView = [entity.position.x, entity.position.y, entity.direction.x,entity.direction.y]; //Now we will sweep over the entities field of view to generate their worldview for (var fov = -90; fov <= 90; fov += 10){ if (draw){ surface.getContext().beginPath(); surface.getContext().strokeStyle="blue"; surface.getContext().moveTo(((entity.position.x)*w),((entity.position.y)*h), dist*40, 0, 2 * Math.PI); } var p = new Oak.Math.Vec2(); p.copy(entity.direction); p.rotate(fov); var saw = false; for (var dist = 0.01; dist <= entity.sightDistance; dist+=0.01){ var this_saw = false if (saw){break} // Draw each ray for each sight check p.copy(entity.direction).normalize(); p.rotate(fov); //p.mulI(w); p.mulI(dist); for (var k =0; k<entities.length;k++){ var looking = entities[k]; if (looking.name === entity.name){continue} var looking_pos = p.clone().add(entity.position); if (looking.position.dist(looking_pos) < (0.01+(dist/20))){ saw = {score:looking.score, color:looking.color, distance:1-dist}; this_saw = true; } } if (draw){ if (this_saw){ surface.getContext().stroke(); surface.getContext().fillStyle=saw.color.toHex(); surface.getContext().beginPath(); surface.getContext().arc(((p.x+entity.position.x)*w),((p.y+entity.position.y)*h), ((dist)*20)+2, 0, 2 * Math.PI); surface.getContext().fill(); }else{ surface.getContext().lineTo(((p.x+entity.position.x)*w),((p.y+entity.position.y)*h), ((dist)*20)+2, 0, 2 * Math.PI); } } } if (saw){ //entity.worldView.concat([saw.score, saw.distance]); Array.prototype.push.apply(entity.worldView, [saw.score, saw.distance]) }else{ if (draw){ surface.getContext().stroke();} // entity.worldView = entity.worldView.concat([0,1]); Array.prototype.push.apply(entity.worldView, [0, 1]) } } if (draw){ surface.getContext().globalAlpha = 1;} train_time += (Date.now() - dt); }

Such answers are not definitely clear, and as such, without the resolution to describe a simulation in totality, we are introduction constraints,

new_entities = []; for (i=0;i<20;i++){ new_entities.push(new Entity(Math.random(),1,1,1)); } entities = [...new_entities, maggie, bob, sue].map((entity)=>{ return new EntityBehavior(entity); }); world_entities = []; for (i=0;i<10;i++){ let food = {score:1, color:(new Oak.Color.RGB()).set(0,255,0), position:(new Oak.Math.Vec2()).set(Math.random(),Math.random())}; world_entities.push(food); } surface = new Oak.Rendering.Surface(); print(surface.getElement()); surface.fill("white"); w = 620; h = w; console.log(w); surface.setSize(w,w); // This make the surface square by using its width as its height full_entities = [...entities,...world_entities]; function work(draw){ world_entities.map((entity)=>{ this.iterations++; this.train_time if (draw){ surface.getContext().fillStyle=entity.color.toHex(); surface.getContext().beginPath(); surface.getContext().arc(entity.position.x*w, entity.position.y*h, 10, 0, 2 * Math.PI); surface.getContext().fill(); } entities.forEach((looking)=>{ if (looking.position.dist(entity.position) < 0.05){ if (looking.qlearn){ looking.qlearn.reward(looking.age);} looking.energy += 0.1; looking.hunger += 0.1; entity.position = (new Oak.Math.Vec2()).set(Math.random(),Math.random()); } }); }); entities.forEach((entity)=>{ entity.update(); updateWorldView(entity,full_entities,surface, draw); output = entity.qlearn.run(entity.worldView); entity.position.add(entity.direction.clone().mulI(Math.min(0.001,Math.max(output[0],-0.001)))) entity.position.add(entity.direction.clone().rotate(90).mulI(Math.min(0.001,Math.max(output[1],-0.001)))) entity.direction.rotate(Math.min(1,Math.max(output[2],-1))); entity.qlearn.addStateActionPair(entity.worldView, output); }); } window.setInterval(()=>{ surface.fill("white"); work(true); },1);
for (i=0;i<1000;i++){ work(false); } return {bestAge:getBestBrainAge(), bestBrainIterations:getBestBrainIterations(), bestBrainTrainTime: new Date(getBestBrainTime()).toISOString().substr(11, 8) };

Limitations of Experiments in a Closed System

All systems are constrained because they are themselves constraints on a computational system of constraints.

What is an agent in a system aware of?

Enumerating the Essence of Behavior

Let's take for example, the life of an ant.

Behaviors

  • Idle
  • Socialize
  • Search for (entity)
  • Consume

State

  • Energy (food/calories)

Which Questions and Assumptions can be asserted without the need to model the complexities of such a full-scale simulation with physically enabled participants?

In such a case where the data to be analyzed is known, we can use finite state transformation on it.

A more complicated question, as we would expect the need for simulation,

"What is the average grouped position of the ants?"

can be answered by modeling our initial statement to include rules for the transformation of these properties throughout the system as well.

These ants will never lead a normal life, not so much as the conscious ones we know. In reality they are still merely nothing more than numbers being jumbled about a complex computer processor. If you apply this mentality as brain theory for the ants, it is clear that their path to consciousness is limited in many ways, by our own ability to represent their environment capable of such a simulation.

This of course, also naively assumes that even with the appropriate amount of available computing space, such a configuration would produce anything remotely capable, let alone conscious. We are approximating by nature, the nature of the mind, we have effectively down sampled the dimensions on their reality.

Do ants have ant voices inside of their heads?

If they do, they’re surely not speaking, or thinking in English. This is actually beneficial, as it represents something fundamental about the nature of intelligence and consciousness; that our own minds are a reflection of our aptitude, experiences, and environments.

So we know who the person, or system it is that is speaking to the ants. It is their configurations of self, and the rules governing their systems. The voice in their heads exists as the hum of your graphics card. A trivial existence, perhaps, however, one we make to argue an existence nonetheless. We explore this further as we increase the complexity of the system.

We can say, although, maybe not definitely, that the voice in our own heads is not actually, a voice. It is the construction, perception, or expression as you wish to call it, of our own minds, individual by form and function.

Animals and other cerebral creatures, ants included, have brains. While impractical to prove, ants may or may not have a ‘mind,’ however, every dog has their own individual personality. We can progressive follow this trail to smaller and smaller creatures, bunnies, mice, and even goldfish have distinct personalities. As we follow that trail to smaller and smaller animals, consciousness undoubtedly follows, albeit, lesser and lesser clear, obfuscated by our lack of trans-species understandings.

Are dogs just as conscious as a rabbit?

Are salamanders just as conscious as a rabbit?

Are termites just as conscious as a salamander?

Do they dream about the same stars as I?

Do brains share correlation/causation with consciousness?

All Pages in Design Systems

    Design Systems

    A complete, reliable, flexible, and cost-effective infrastructure is a fundamental requirement in modern companies....

    Multimedia Marketing Strategy

    1.  Pillars and Funnel To follow the flow of the potential customer, we must direct their attention and their focus...

    Fluid Viewports vs Fixed Screens in Native Web Apps

    When designing an experience we must consider the rendering capabilities of the devices and platforms we run on....

    Concurrent and Adaptive Narrative

    Narrative and Player Expression As a narrative and game designer, you must consider that you are designing for two...

    The Anthology of Ants

    Any sufficient simulation must be reproducibly computable. Its entropy is a function of the ability to stabilize...

    Product Development

    What is Product Development? Systematic decision making related to all aspects of the development and management of...

Explore OakFrame

    Games

    Play games in your browser for free, handcrafted by us here at OakFrame!

    Oak Studio Documentation

    Simple to Embed and Integrate We designed OakFrame to be easy to extend in order to provide further integration...

    Design Systems

    A complete, reliable, flexible, and cost-effective infrastructure is a fundamental requirement in modern companies....

    About OakFrame

    OakFrame is a design, development, and research firm located in Dallas, Texas, developing experiences for audiences...