I did a bit of playing with “Braitenberg Vehicles” a while back. These were based loosely on the ideas of cyberneticist Valentino Braitenberg. His purpose was to describe how complex behavior in organisms might arise from very simple reactive behaviors. My purpose was to have a little fun programming such things.

The game we’re working on now has the working title of “Braitenbugs”, and it goes like this:

There will be a world in which our bugs live. It will have some amount of complexity built in, terrain, resources, food, all to be determined as we grow the game. The point of the game is for the player to define creatures, Braitenbugs, and give them behavior based on available modules like eyes and the ability to move or eat.

Right now I’m envisioning a bug-building component to the game where you choose or maybe even define your bug’s shape, and then somehow connect together modules of senses and behavior. Sort of wiring the bug up.

Then in the play mode, a world is created, the bugs are set free in some kind of population, and they behave while we watch. Maybe there’ll be a multi-player mode of some kind, where we compete (or even collaborate!) in the world.

Who knows? This is pretty blue sky, and I’ll surely stop before this turns into anything very complete. So plan on this project coming to an end when it ceases to be entertaining at least to me. Probably long after it stops interesting all three of my readers.

A Very Tentative Plan

I’/ve got the ability to generate fairly complex terrain, using either Dave1707’s code or even John’s much more complicated and robust system. I’ll probably start with flat terrain, perhaps patterned a bit to make grassy areas or something. And I’ll start with a pretty small world (after all).

So an early next step will be to generate a flat world, probably entirely plain, and put one simple bug into it and let it drive around a bit. I’ll script the bug in Lua for now, while staying alert for useful behavior modules and thinking about how one might package them up and link them together.

I’ve got a decent two-dimensional demo from the prior articles, including a neat little blue bug who gets hungry, seeks food, and then wanders off when he’s not hungry.

I’m not sure what to do about 3D terrain, and adapting the 2D version to a flat 3D space may entertain us for a while. I’m a bit leery about giving these bugs a full 3D sensorium. It may suffice to have them “think” in 2D, perhaps with an energy penalty if they’re walking uphill or something like that. We should make a point of doing an early spike on non-flat terrain, but a lot of our work can be done in the flat, if we’re sure we can do what we need to.

I envision the bugs as being constructed from a few spheres and ovals and such, much like the ones in the video only 3D. Doing that in Lua won’t be hard, and if we want to build a tool for it, that should be straightforward (but probably costly in time to do it).

Today’s first steps …

I’ve made some minor tweaks to the code in Game-1 and after I show it to you, I’ll try to put in a very simple bug … hmm, we’re going to have a problem with that word, aren’t we? I think I’ll call them creatures. Braitencreatures? Anyway here’s the starting code:

-- Game-1
-- RJ 20200222 initial plan, make a floor
-- RJ 20200226 camera object works w/o touch
-- RJ 20200227 cleanup
-- RJ 20200307 clean a bit for bugs

function setup()
    scene = craft.scene()

    -- Setup camera and lighting
    scene.sun.rotation = quat.eulerAngles(25, 125, 0)

    -- Set the scenes ambient lighting
    scene.ambientColor = color(127, 127, 127, 255)   
    
    allBlocks = blocks()
    
    -- Setup voxel terrain
    local m = 1 -- 5
    scene.voxels:resize(vec3(5,1,5))      
    scene.voxels.coordinates = vec3(-16*m,0,-16*m)    
    scene.voxels:fill("Dirt Grass")
    scene.voxels:box(0,1,0,16*m,1,16*m)
    scene.voxels:fill("Bedrock")
    scene.voxels:box(0,0,0, 16*m,0,16*m)
    
    setupCamera(scene)
end

function setupCamera(scene)
    scene.camera:add(GameCamera)
end


function update(dt)
    scene:update(dt)
end


function draw()
    update(DeltaTime)
    scene:draw()	
end

-- blocks
-- RJ 20200222
-- ERJ 20200226 fixed dirt grass

function blocks()
    scene.voxels.blocks:addAssetPack("Blocks")
    local dirt = scene.voxels.blocks:new("Dirt Grass")
    dirt.setTexture(ALL, "Blocks:Dirt Grass")
    dirt.setTexture(UP, "Blocks:Grass Top")
    dirt.setTexture(DOWN, "Blocks:Dirt")
    local bedrock = scene.voxels.blocks:new("Bedrock")
    bedrock.setTexture(ALL, "Blocks:Greystone")
    local allBlocks = scene.voxels.blocks:all()
    return allBlocks
end


-- GameCamera
-- RJ 20200226
-- RJ 20200227 move camera rotation inside; cleanup
-- RJ 20200307 change starting rx ry for fun

GameCamera = class()

function GameCamera:init(entity)
    self.entity = entity
    self.camera = entity:get(craft.camera)
    self.rx = 45
    self.ry = 45
    self.rz = 0
    self.distance = 20
    self.target = vec3(8,0,8)
    self.camera.ortho = false
    self.camera.orthoSize = 5
    self.camera.fieldOfView = 60
end

function GameCamera:update(dt)
    if CurrentTouch.state == MOVING then 
        self.rx = self.rx - CurrentTouch.deltaY * 0.25 -- note XY inversion
        self.ry = self.ry - CurrentTouch.deltaX * 0.25
    end
    local rotation = quat.eulerAngles(self.rx, self.ry, self.rz)
    self.entity.rotation = rotation
    self.entity.position = -self.entity.forward * self.distance + self.target
end

With a bit of judicious copying from the Orc project, I got to this definition of Creature:

Creature = class()

function Creature:init(entity, x, z)
    self.entity = entity
    entity.x = x
    entity.z = z
    entity.y = 2 -- just above the ground
    entity.model = craft.model("Blocky Characters:Orc")
    entity.scale = vec3(1,1,1)/8
end

function Creature:update(dt)
    
end

I had to add a setup for the Creature, of course:

-- Game-1
-- RJ 20200222 initial plan, make a floor
-- RJ 20200226 camera object works w/o touch
-- RJ 20200227 cleanup
-- RJ 20200307 clean a bit for bugs

function setup()
    scene = craft.scene()

    -- Setup camera and lighting
    scene.sun.rotation = quat.eulerAngles(25, 125, 0)

    -- Set the scenes ambient lighting
    scene.ambientColor = color(127, 127, 127, 255)   
    
    allBlocks = blocks()
    
    -- Setup voxel terrain
    local m = 1 -- 5
    scene.voxels:resize(vec3(5,1,5))      
    scene.voxels.coordinates = vec3(-16*m,0,-16*m)    
    scene.voxels:fill("Dirt Grass")
    scene.voxels:box(0,1,0,16*m,1,16*m)
    scene.voxels:fill("Bedrock")
    scene.voxels:box(0,0,0, 16*m,0,16*m)
    
    setupCreature(scene)
    
    setupCamera(scene)
end

function setupCamera(scene)
    scene.camera:add(GameCamera)
end

function setupCreature(scene)
    scene:entity():add(Creature, 7, 7)
end


function update(dt)
    scene:update(dt)
end


function draw()
    update(DeltaTime)
    scene:draw()	
end

This worked almost at once, subject to a few typos. I started with a full-size Orc, who dwarfed my small square world, then a 1/32 size one, who showed me the need for zooming in my camera code.

We probably want some other kind of character. There are other assets that I could borrow, or I could just make one out of primitives.

It should be easy to make him move around, I just need to update x and z (remember that y is up), so that’s not particularly exciting.

I’m responsible for bringing pizza home at lunch time, for supper, so I think I’ll call it a day right here.

See you next time!