Recent Posts

Pages: 1 2 3 [4] 5 6 ... 10
31
Programming with Blackvoxel / Digging and sorting robot
« Last post by Yves on February 26, 2019, 11:43:38 pm »
Hello,
Here I share the program I wrote to automatically dig, and place all that was taken in the appropriate storages.

This is still a bit rough around the edges, because I did not mind too much having to interfere with the robots once in a while instead of just fixing the program :-D
For example:
— Two robots can block themselves when they are front-to-front. Just alter the stock sequence of the robot that is going towards a storage, and it will go away.
— The robots expect a free path towards the storages, which actually depends on the position of the digging zones, relative to the factory zone.

Enough “talk”, here’s the code:
Code: [Select]
// Tunnel 16x16 downward
// *******************************************************************

const SOFT_LIMIT = 50;
const HARD_LIMIT = 1323;
const QUARTER_SIZE = 8;
const KEY_LEARN = 108;    // L (https://wiki.libsdl.org/SDLKeycodeLookup)
const KEY_VALIDATE = 111; // O (https://wiki.libsdl.org/SDLKeycodeLookup)
const KEY_CANCEL = 113;   // Q (https://wiki.libsdl.org/SDLKeycodeLookup)

const ST_END = 0;
const ST_INIT = 10;
const ST_CENTER = 20;
const ST_QUARTER = 30;
const ST_ASIDE = 40;
const ST_CLIMB = 50;
const ST_RETURN = 60;
const ST_DOCK = 70;
const ST_TRANSPORT = 80;
const ST_LEARN = 90;
const ST_UNLOAD = 100;
const ST_NEXTVOXEL = 110;

const WAIT = 2000;
Time <- 0;

InitDir <- 0;
State <- 0;
StartX <- 0;
StartY <- 0;
StartZ <- 0;
CenterX <- 0;
CenterZ <- 0;
StepX <- 0;
StepZ <- 0;
StepXBeforeZ <- true;
FlatSteps <- 0;
Dir <- 0;
Depth <- 0;
Quarter <- 0;
CellCount <- 0;
RowCount <- 0;
StartStock <- 0;
UnloadType <- 0;
UnloadXYZ <- {};
HardLimitReached <- false;

// This function is called at each robot cycle.

function Voxel_Step()
{
  local ok = true;
  local slot;
  local x;
  local y;
  local z;

  switch ( State )
  {
    case ST_END:
      display("Robot " + GetRobotID() + " will not go deeper!");
      break;
    case ST_INIT:
      Init_This();
      State = ST_CENTER;
      break;
    case ST_CENTER:
      if ( GetX() < CenterX )      ok = Take_And_Move(1);
      else if ( GetX() > CenterX ) ok = Take_And_Move(3);
      else if ( GetZ() < CenterZ ) ok = Take_And_Move(0);
      else if ( GetZ() > CenterZ ) ok = Take_And_Move(2);
      else if ( Quarter < 1 && Count_Stock() == StartStock )
      {
        Quarter = -1;
        ok = Probe_And_Move(5);
      }
      else if ( Quarter < 3 )
      {
        Quarter += 1;
        Dir = (Dir + 1) % 4;
        CellCount = 0;
        RowCount = 0;
        State = ST_QUARTER;
        ok = Take_And_Move(Dir);
      }
      else
      {
        Depth += 1;
        HardLimitReached = ((StartY - GetY()) >= HARD_LIMIT);
        if ( Depth >= SOFT_LIMIT || HardLimitReached ) ok = false;
        else
        {
          Quarter = -1;
          ok = Take_And_Move(5);
        }
      }
      if ( ! ok )
      {
        display("Robot " + GetRobotID() + " going UP at (" + CenterX + "," + CenterZ + ")...");
        Init_Steps();
        State = ST_ASIDE;
      }
      break;
    case ST_QUARTER:
      if ( CellCount < (QUARTER_SIZE - 1) )
      {
        ok = Take_And_Move(Dir);
        CellCount += 1;
      }
      else if ( RowCount == (QUARTER_SIZE - 1) )
      {
        if ( (RowCount % 2) == 0 ) Turn_Left(); else Turn_Right();
        ok = Take_And_Move(Dir);
        if ( (RowCount % 2) == 0 ) Turn_Right(); else Turn_Left();
        State = ST_CENTER;
      }
      else
      {
        if ( (RowCount % 2) == 0 ) Turn_Right(); else Turn_Left();
        ok = Take_And_Move(Dir);
        if ( (RowCount % 2) == 0 ) Turn_Right(); else Turn_Left();
        CellCount = 0;
        RowCount += 1;
      }
      if ( ! ok )
      {
        display("Robot " + GetRobotID() + " going UP at (" + CenterX + "," + CenterZ + ")...");
        Init_Steps();
        State = ST_ASIDE;
      }
      break;
    case ST_ASIDE:
      switch ( CellCount )
      {
        case 0:
          CellCount = 1;
          ok = Take_And_Move(4);
          break;
        case 1:
          CellCount = 2;
          if ( StepXBeforeZ && GetX() < StepX )      ok = Take_And_Move(1);
          else if ( StepXBeforeZ && GetX() > StepX ) ok = Take_And_Move(3);
          else if ( GetZ() < StepZ )                 ok = Take_And_Move(0);
          else if ( GetZ() > StepZ )                 ok = Take_And_Move(2);
          else if ( GetX() < StepX )                 ok = Take_And_Move(1);
          else if ( GetX() > StepX )                 ok = Take_And_Move(3);
          break;
        case 2:
          CellCount = 0;
          ok = Take_And_Move(5);
          if ( GetX() == StepX && GetZ() == StepZ )  State = ST_CLIMB;
          break;
      }
      if ( ! ok )
      {
        State = ST_RETURN;
      }
      break;
    case ST_CLIMB:
      switch ( CellCount )
      {
        case 0:
        case 1:
          ok = Take_And_Move(4);
          if ( FlatSteps > 0 )
          {
            CellCount += 1;
            FlatSteps -= 1;
          }
          break;
        case 2:
          ok = Take_And_Move(Dir);
          break;
        case 3:
          ok = Take_And_Move(5);
          break;
      }
      CellCount += 1;
      if ( CellCount == 4 )
      {
        CellCount = 0;
        RowCount += 1;
        if ( GetY() >= StartY )
        {
          State = ST_RETURN;
        }
      }
      if ( RowCount == (QUARTER_SIZE * 2 + 2) )
      {
        Turn_Left();
        RowCount = 0;
      }
      if ( ! ok )
      {
        State = ST_RETURN;
      }
      break;
    case ST_RETURN:
      if ( GetY() == StartY )
      {
        if ( GetX() < StartX )       ok = Take_And_Move(1);
        else if ( GetX() > StartX )  ok = Take_And_Move(3);
        else if ( GetZ() < StartZ )  ok = Take_And_Move(0);
        else if ( GetZ() > StartZ )  ok = Take_And_Move(2);
        else
        {
          State = ST_DOCK;
          display("Robot " + GetRobotID() + " is docked.");
        }
      }
      else
      {
        if ( GetX() < CenterX )      ok = Take_And_Move(1);
        else if ( GetX() > CenterX ) ok = Take_And_Move(3);
        else if ( GetZ() < CenterZ ) ok = Take_And_Move(0);
        else if ( GetZ() > CenterZ ) ok = Take_And_Move(2);
        else if ( GetY() < StartY )  ok = Take_And_Move(4);
        else                         ok = Take_And_Move(5);
      }
      if ( ! ok )
      {
        display("Robot " + GetRobotID() + " is stuck at (" + GetX() + "," + GetY() + "," + GetZ() + ")!");
      }
      break;
    case ST_DOCK:
      slot = GetFirstUsedSlot();
      if ( slot < 0 )
      {
        if ( HardLimitReached ) State = ST_END;
        else
        {
          display("Robot " + GetRobotID() + " going down at (" + CenterX + "," + CenterZ + ")...");
          Reinit_This();
          State = ST_CENTER;
        }
      }
      else if ( GetSlot_Type(slot) in UnloadXYZ )
      {
        UnloadType = GetSlot_Type(slot);
        State = ST_TRANSPORT;
      }
      else if ( GetKey(KEY_LEARN) )
      {
        State = ST_LEARN;
      }
      else
      {
        display("Robot " + GetRobotID() + " needs to store " + GetVoxelName(GetSlot_Type(slot)));
      }
      break;
    case ST_LEARN:
      slot = GetFirstUsedSlot();
      if ( slot < 0 || GetKey(KEY_CANCEL) )
      {
        display("Robot " + GetRobotID() + " abandons.");
        State = ST_DOCK;
      }
      else if ( GetKey(KEY_VALIDATE) )
      {
        display("Robot " + GetRobotID() + " remembers.");
        UnloadXYZ[GetSlot_Type(slot)] <- [GetInfo(4), GetInfo(5), GetInfo(6)];
        State = ST_TRANSPORT;
      }
      else
      {
        display("Please stand where Robot " + GetRobotID() + " will store " + GetVoxelName(GetSlot_Type(slot)));
      }
      break;
    case ST_TRANSPORT:
      slot = GetFirstUsedSlot();
      if ( slot < 0 || GetSlot_Type(slot) != UnloadType ) State = ST_NEXTVOXEL;
      else
      {
        x = UnloadXYZ[UnloadType][0];
        y = UnloadXYZ[UnloadType][1];
        z = UnloadXYZ[UnloadType][2];
        if ( GetY() < y )                                 ok = Move(4);
        else if ( GetY() > y )                            ok = Move(5);
        else if ( GetX() < x )                            ok = Move(1);
        else if ( GetX() > x )                            ok = Move(3);
        else if ( GetZ() < z )                            ok = Move(0);
        else if ( GetZ() > z )                            ok = Move(2);
        else                                              State = ST_UNLOAD;
      }
      if ( ! ok ) display("Robot " + GetRobotID() + " needs help!");
      break;
    case ST_UNLOAD:
      slot = GetFirstUsedSlot();
      if ( slot < 0 || GetSlot_Type(slot) != UnloadType ) State = ST_NEXTVOXEL;
      else
      {
        for ( Dir = 0; Dir < 6; Dir += 1 )
        {
          if ( GetVoxelProp(Look(Dir), 1) )
          {
            ok = PushVoxelTo(Dir, GetSlot_Type(slot));
            if ( GetSlot_Quantity(slot) == 0 )            State = ST_NEXTVOXEL;
            break;
          }
        }
      }
      if ( ! ok ) display("Robot " + GetRobotID() + " cannot unload!");
      break;
    case ST_NEXTVOXEL:
      if ( GetZ() < StartZ )      ok = Move(0);
      else if ( GetZ() > StartZ ) ok = Move(2);
      else if ( GetX() < StartX ) ok = Move(1);
      else if ( GetX() > StartX ) ok = Move(3);
      else if ( GetY() < StartY ) ok = Move(4);
      else if ( GetY() > StartY ) ok = Move(5);
      else                        State = ST_DOCK;
      if ( ! ok ) display("Robot " + GetRobotID() + " needs help!");
      break;
  }
}

// This function is called when robot is loaded from save file or when created

function Voxel_Load()
{
  local name = Get_Save_Filename();
  print("read state file = " + name + "\r\n");
  try
  {
    local save = dofile(name);
    InitDir      = save.InitDir;
    State        = save.State;
    StartX       = save.StartX;
    StartY       = save.StartY;
    StartZ       = save.StartZ;
    CenterX      = save.CenterX;
    CenterZ      = save.CenterZ;
    StepX        = save.StepX;
    StepZ        = save.StepZ;
    StepXBeforeZ = save.StepXBeforeZ;
    FlatSteps    = save.FlatSteps;
    Dir          = save.Dir;
    Depth        = save.Depth;
    Quarter      = save.Quarter;
    CellCount    = save.CellCount;
    RowCount     = save.RowCount;
    StartStock   = save.StartStock;
    UnloadType   = save.UnloadType;
    UnloadXYZ    = save.UnloadXYZ;
  }
  catch (e)
  {
    print("Could not read state file for robot " + GetRobotID() + "\r\n  " + e + "\r\n");
  }
  if ( GetInfo(23) == 0 || GetInfo(23) == 4 )
  {
    print("Robot " + GetRobotID() + " set to initial state.\r\n");
    State = ST_INIT;
  }
  else
  {
    print("Robot " + GetRobotID() + " restored.\r\n");
  }
}

// This function is called when robot is unloaded to save file or when destroyed

function Voxel_Unload()
{
  local name = Get_Save_Filename();
  local save = file(name, "w");
  local slot, xyz, data;
  local code = "return {\n";
  code += "  InitDir      = " + InitDir + ",\n";
  code += "  State        = " + State + ",\n";
  code += "  StartX       = " + StartX + ",\n";
  code += "  StartY       = " + StartY + ",\n";
  code += "  StartZ       = " + StartZ + ",\n";
  code += "  CenterX      = " + CenterX + ",\n";
  code += "  CenterZ      = " + CenterZ + ",\n";
  code += "  StepX        = " + StepX + ",\n";
  code += "  StepZ        = " + StepZ + ",\n";
  code += "  StepXBeforeZ = " + (StepXBeforeZ ? "true" : "false") + ",\n";
  code += "  FlatSteps    = " + FlatSteps + ",\n";
  code += "  Dir          = " + Dir + ",\n";
  code += "  Depth        = " + Depth + ",\n";
  code += "  Quarter      = " + Quarter + ",\n";
  code += "  CellCount    = " + CellCount + ",\n";
  code += "  RowCount     = " + RowCount + ",\n";
  code += "  StartStock   = " + StartStock + ",\n";
  code += "  UnloadType   = " + UnloadType + ",\n";
  code += "  UnloadXYZ    = {\n";
  foreach ( slot, xyz in UnloadXYZ )
  {
    code += ("    [" + slot + "] = [" + xyz[0] + ", " + xyz[1] + ", " + xyz[2] + "],\n");
  }
  code += "  }\n}\n";
  data = blob(code.len());
  foreach ( slot in code )
  {
    data.writen(slot, 'b');
  }
  save.writeblob(data);
  save.close();
  print("Robot " + GetRobotID() + " saved.\r\n");
}

function Get_Save_Filename()
{
  local saves = GetPath(4);
  local sep = GetInfo(20);
  local nut = GetInfo(22);
  local robot = GetRobotID();
  return saves + sep + nut + "_" + robot + ".state";
}

function Init_This()
{
  local yaw = (GetInfo(7) + (PI/4)) % (PI*2);
  StartX = GetX();
  StartY = GetY();
  StartZ = GetZ();

  if (yaw < (PI/2))
  {
    InitDir = 0;
    CenterX = StartX;
    CenterZ = StartZ + QUARTER_SIZE + 1;
  }
  else if (yaw < PI)
  {
    InitDir = 1;
    CenterX = StartX + QUARTER_SIZE + 1;
    CenterZ = StartZ;
  }
  else if (yaw < (3*PI/2))
  {
    InitDir = 2;
    CenterX = StartX;
    CenterZ = StartZ - QUARTER_SIZE - 1;
  }
  else
  {
    InitDir = 3;
    CenterX = StartX - QUARTER_SIZE - 1;
    CenterZ = StartZ;
  }
  Reinit_This();
}

function Reinit_This()
{
  Depth = 0;
  Quarter = 3;
  StartStock = Count_Stock();
  Dir = InitDir;
}

function Count_Stock()
{
  local c = 0;
  for (local s = 0; s < GetInfo(24); s += 1)
  {
    c += GetSlot_Quantity(s);
  }
  return c;
}

function Take_And_Move(Dir)
{
  PickVoxel(Dir);
  if ( ! Move(Dir) )
  {
    display("Robot " + GetRobotID() + " could not move at (" + GetX() + "," + GetY() + "," + GetZ() + "), Dir. " + Dir + ", BlockType " + Look(Dir));
    return false;
  }
  return true;
}

function Probe_And_Move(Dir)
{
  if ( ! GetVoxelProp(Look(Dir), 0) ) PickVoxel(Dir);
  if ( ! Move(Dir) )
  {
    display("Robot " + GetRobotID() + " could not move at (" + GetX() + "," + GetY() + "," + GetZ() + "), Dir. " + Dir + ", BlockType " + Look(Dir));
    return false;
  }
  return true;
}

function Turn_Right()
{
  Dir = (Dir + 1) % 4;
}

function Turn_Left()
{
  Dir = (Dir + 3) % 4;
}

function Init_Steps()
{
  local base0Depth = StartY - GetY() - 1;
  local edgeSize = QUARTER_SIZE * 2;
  local sideSize = edgeSize + 2;
  local sidesCount = floor(base0Depth / sideSize);
  local afterSides = base0Depth - (sideSize * sidesCount);
  FlatSteps = 0;
  if ( afterSides >= edgeSize )
  {
    sidesCount += 1;
    FlatSteps = sideSize - afterSides;
    afterSides = 0;
  }
  RowCount = sideSize - 1 - afterSides;
  CellCount = 0;
  switch ( (InitDir + sidesCount) % 4 )
  {
    case 0:
      StepX = CenterX - QUARTER_SIZE - 1;
      StepZ = CenterZ - QUARTER_SIZE + afterSides;
      Dir = 2;
      break;
    case 1:
      StepX = CenterX - QUARTER_SIZE + afterSides;
      StepZ = CenterZ + QUARTER_SIZE + 1;
      Dir = 3;
      break;
    case 2:
      StepX = CenterX + QUARTER_SIZE + 1;
      StepZ = CenterZ + QUARTER_SIZE - afterSides;
      Dir = 0;
      break;
    case 3:
      StepX = CenterX + QUARTER_SIZE - afterSides;
      StepZ = CenterZ - QUARTER_SIZE - 1;
      Dir = 1;
      break;
  }
  StepXBeforeZ = (StepX > GetX() && StepZ > GetZ()) || (StepX < GetX() && StepZ < GetZ());
}

function display(message)
{
  if ( (GetGameTime() - Time) >= WAIT )
  {
    print(message + "\r\n");
    Display(message, WAIT, 2, 0);
    Time = GetGameTime();
  }
}

Just put the robot on the ground and stand behind it. Open its interface and load the program; it will start immediately to dig a 16×16 “square”, the centre of which is 8 voxels-or-so in front of the robot. The shape is not exactly a square because it is that of what 4 of the game’s robots around a compressor would do.

So:
—1— The robot digs 50 layers of ground.
—2— The robot climbs around the hole, all the while carving a stairway, just for you :-)
—3— When “docked” at its starting point, it will store each voxel at the right place.
—4— It then starts again with 50 new layers of ground, and stops just before reaching the green acid (provided you started at the top of the central blue zone).

When the robot does not know where to put a voxel, it says so. In that case:
—1— Press “L” (learn), and the robot will ask you to stand near a compressor, at the exact place where the robot will be able to transfer the voxels into the compressor (at the level of your feet, not your head!).
—2— When you stand at the right place, press “O” (ok), and the robot will remember.
—3— If instead you prefer to cancel, and go retrieve yourself the voxels from inside the robot, press “Q” (quit), and the robot will quit the learning-mode.

Oh, a few tips, available if you quit the game (or at least the world):
— Each save-file is plain-text, so you can fix mistakes, in case you wrongly taught the robot.
— You can even copy-paste the knowledge of a know-it-all robot, to a newer robot ;-)

Cheers
32
Suggestions / Re: Metalurgy
« Last post by Yves on February 26, 2019, 11:04:40 pm »
This is not the only way.
I have an efficient and reliable production of bronze and stainless steel, taking a ground surface of roughly 10×5 voxels.

Oh, well, let me publish the related article now :-) Here it is:
http://yalis.fr/cms/index.php/post/2019/02/24/Fun-with-Kanban%2C-episode-2
33
Suggestions / Re: The Sequencer
« Last post by Yves on February 26, 2019, 10:57:06 pm »
My two cents:
All other properties non-withstanding, I see 3 main properties to the current sequencer:

— It is first of all a programmable sequencer. And it is important to keep the ability to have a sequence of way more than 5 items, thus allowing sequencer chains. For example, my programmable robot and XTR-1 factories are 100% automated based on this ability.

— It is also a filter: it never absorbs an item that is not part of its programmed sequence.

— And it is a batch regulator: it never absorbs an item while a run of the sequence is still ongoing, and then it only absorbs what is needed for the next run of the sequence.

All those three properties are really useful, and I wish that they are kept. I wrote 2 articles (only one published for now), and they heavily rely on those three properties:
http://yalis.fr/cms/index.php/post/2019/02/20/Fun-with-Kanban%2C-episode-1
34
Suggestions / Re: Extended voxel interface
« Last post by Yves on February 26, 2019, 10:42:53 pm »
I have a wish of the same kind: I created a robot that digs automatically and then also stores each kind of voxel at the right place. So far so good.
My problem is, that storing eg. 5000 black-voxels in a storage takes a lot of time! Each time I see one of my robots stuck to a storage because of such an important stock, I end up taking the remaining voxels from its stock, so that I can put everything at once in the storage.
It becomes even more of a problem when I have several robots working simultaneously: a single robot can keep other robots from accessing a storage :-(
35
General Discussion / Re: Saving variables
« Last post by Yves on February 26, 2019, 08:41:17 pm »
Hello,
This is an old topic, but I thought new players of the game may be interested in some feedback, because the language documentation is very sparse about saving and retrieving variables when quitting and resuming the game.

By trial and error, here is how I ended up saving and restoring my programmable robot:

Code: [Select]
// This function is called when robot is loaded from save file or when created

function Voxel_Load()
{
  local name = Get_Save_Filename();
  print("read state file = " + name + "\r\n");
  try
  {
    local save = dofile(name);
    InitDir      = save.InitDir;
    State        = save.State;
    StartX       = save.StartX;
    StartY       = save.StartY;
    StartZ       = save.StartZ;
    CenterX      = save.CenterX;
    CenterZ      = save.CenterZ;
    StepX        = save.StepX;
    StepZ        = save.StepZ;
    StepXBeforeZ = save.StepXBeforeZ;
    FlatSteps    = save.FlatSteps;
    Dir          = save.Dir;
    Depth        = save.Depth;
    Quarter      = save.Quarter;
    CellCount    = save.CellCount;
    RowCount     = save.RowCount;
    StartStock   = save.StartStock;
    UnloadType   = save.UnloadType;
    UnloadXYZ    = save.UnloadXYZ;
  }
  catch (e)
  {
    print("Could not read state file for robot " + GetRobotID() + "\r\n  " + e + "\r\n");
  }
  if ( GetInfo(23) == 0 || GetInfo(23) == 4 )
  {
    print("Robot " + GetRobotID() + " set to initial state.\r\n");
    State = ST_INIT;
  }
  else
  {
    print("Robot " + GetRobotID() + " restored.\r\n");
  }
}

// This function is called when robot is unloaded to save file or when destroyed

function Voxel_Unload()
{
  local name = Get_Save_Filename();
  local save = file(name, "w");
  local slot, xyz, data;
  local code = "return {\n";
  code += "  InitDir      = " + InitDir + ",\n";
  code += "  State        = " + State + ",\n";
  code += "  StartX       = " + StartX + ",\n";
  code += "  StartY       = " + StartY + ",\n";
  code += "  StartZ       = " + StartZ + ",\n";
  code += "  CenterX      = " + CenterX + ",\n";
  code += "  CenterZ      = " + CenterZ + ",\n";
  code += "  StepX        = " + StepX + ",\n";
  code += "  StepZ        = " + StepZ + ",\n";
  code += "  StepXBeforeZ = " + (StepXBeforeZ ? "true" : "false") + ",\n";
  code += "  FlatSteps    = " + FlatSteps + ",\n";
  code += "  Dir          = " + Dir + ",\n";
  code += "  Depth        = " + Depth + ",\n";
  code += "  Quarter      = " + Quarter + ",\n";
  code += "  CellCount    = " + CellCount + ",\n";
  code += "  RowCount     = " + RowCount + ",\n";
  code += "  StartStock   = " + StartStock + ",\n";
  code += "  UnloadType   = " + UnloadType + ",\n";
  code += "  UnloadXYZ    = {\n";
  foreach ( slot, xyz in UnloadXYZ )
  {
    code += ("    [" + slot + "] = [" + xyz[0] + ", " + xyz[1] + ", " + xyz[2] + "],\n");
  }
  code += "  }\n}\n";
  data = blob(code.len());
  foreach ( slot in code )
  {
    data.writen(slot, 'b');
  }
  save.writeblob(data);
  save.close();
  print("Robot " + GetRobotID() + " saved.\r\n");
}

function Get_Save_Filename()
{
  local saves = GetPath(4);
  local sep = GetInfo(20);
  local nut = GetInfo(22);
  local robot = GetRobotID();
  return saves + sep + nut + "_" + robot + ".state";
}

Of course, this code is tailor-made for my robot’s variables, but you get the idea :-)
36
Hello,
In case the solution above does not work (it happened to me), the Blackvoxel team gave me another “solution”, which is to die (DELETE key), and thus re-spawn at the start-coordinates…
37
Gallery / Learning with Blackvoxel
« Last post by Yves on February 26, 2019, 08:29:55 am »
Hello,

You may have met me already on GitHub. I discovered Blackvoxel in late 2018, and enjoyed it very much.
In addition to being fun to play, with nice in-game programming capabilities, I found it also very educational where self-organization is concerned!

I wrote the following article, and I thought maybe you would be interested:
http://yalis.fr/cms/index.php/post/2019/02/20/Fun-with-Kanban%2C-episode-1
You might even want to plan missions along those lines ;-)

A second article is almost ready, still about Kanban.

And… well, since this place is about showcasing our creations, you can see my factory at the end of the article, producing almost everything.

And of course, I could not have gone so far, so fast, without the program I wrote for my programmable robots! This program:
  • digs a hole equivalent to what 4 regular robots around a storage would achieve;
  • when some depth has been reached, it climbs back up, all the while carving a staiway in case you need to go down;
  • when the top has been reached, it goes in turn to each location where each ore kind should be stored;
  • when an ore is still unknown, it asks where that ore should be stored;
  • when all has been stored, it goes back down the hole, and digs a new series of layers; and so on, until depth 1323 has been reached.
38
Thank you, indeed beter to know! 

I advanced a bit BlackVoxel robots programming, that's quite cool! 

 :)
39
General Discussion / Re: Evolutionary voxel robots?
« Last post by CordellM on January 04, 2019, 12:58:28 pm »
Voxels certainly have a lot of potential in so many industries. Not heard about voxel robots yet, but I'm not surprised.
40
Troubleshooting & Bug Reports / Re: Robot apparently silently fails to compile or edit
« Last post by Enigma on December 30, 2018, 05:02:16 am »
Hi, MUY_Belgium and Welcome to the Blackvoxel Forum  :)

Thanks for your return and comments.

Yes, it appears the manual should be improved about how to start with the programming robot. The Squirrel Robot should have an ingame status display like the assembly language one already have.

In the meantime, here are quick setup instructions :
  • In order to use the programmable robot, you should start the game in windowed mode because you'll have several programs alongside.
  • There is actually a compilation result and error output. These informations are displayed in the standard terminal. A terminal Windows is launched automatically along with the game when you use windows so you should see it when you are in Windowed mode. But if you use Blackvoxel with Gnu/Linux, you must launch Blackvoxel into a command line terminal in order to get it.
  • The choice was made to use an external editor(which can have complete features) rather to a simplified in-game one. When you click "edit", then an external editor is launched. The editor can be modified in the "Settings_Hardware.dat" file.
In the hope we have helped you :)
The Blackvoxel Team
Pages: 1 2 3 [4] 5 6 ... 10