*miner "clone?" (probably not), jme2 or 3? advices please!

Hi !!!



I am going to create a Minecraft,Infiniminer,ManicDigger (anyone know more?)… well, not a clone, everything will go different, but the basis is the same (a cube matrix world, I will probably release this as a basis for other ppl projects).

I need to know if jme3 is capable of handing its requirements, or I will have to use jme2 until something show up in jme3 to handle it.



The main requirements are:

  1. you have a huge lot of cubes that can be removed one by one (think of at least 300x100x300 = 9.000.000 cubes, I know I may have to lower this cuz of mem reqs etc…).
  2. all cubes must affect the physics environment while being removed or added (jbullet can handle it?)



    As far I read, jme2 can be used to code it:

    My idea was to create a single mesh to each terrain, water and vapors, each non conected material (with different behaviours) in the world; then add/remove vertices to it (trimesh?).

    But this must also affect the physics, it would be like add a vertice to jbullet physics object, and as far I know it is not possible. I wonder I will have to implement basic physics (even if initially crappy) for this :(. I think the collision can be handled by jme, just not sure if the collision update on vertex changes will be fast enough, wont lag…



    Looking for advices and tips!



    PS.: I read something about "exposed API" would be solution to many non standard things, no idea how hard/problematic it is to expose so much API :).



    EDIT: where I said "clone", and just after said "not a clone", I removed the "clone" (subst by "…") to avoid confusion. I dont think it is ok to change the subject tho, I would like to remove the "probably" also, as I have my own gameplay ideas…

Well the cube amount is far to much, realistic is maybee 3000 renderd objects (renderd!) so you have to think about a intelligent management system  (Combining cubes to larger cubes for rendering where possible?, only rendering the ones not coverd ona ll sides with other cubes ect)



JBullet for static collision is very good optimized I think there will not be the real problem and you can just use the boxcollisionshape for it.



I suggest tryig a testcase, decide wich requirements are the minimal, and figure out how much you can render there, also test if the collisionworks.

thx Empire,

I tried with 800 cubes (20x2x20), it worked fast, but when I up that to about 2000 to 4000, the application freezes :(  (dual core 3GHz).



Sure, all hidden cubes (surrounded by others) will be removed, remaining only the light weight cube info.

Also, load by regions, so I can have less cubes at a time on memory, and other regions cubes can also become a simple mesh seen far (I think…).



I am thinking on alternatives already, may be I should post this code below on JME3 section?

I am trying to modify a mesh (I will work with collision later, 1st I need to dynamically modify the mesh :)).



I am trying these two functions to set a vertex, but they are not working, and I cant understand what I am missing.



I create a Box and I try to move one of its vertex to see what happens, but always nothing happens, and I always get this kind of output:

Existing buffers: 0
(b: 0  f: 0  i: 0  s: 0  d: 0)
Total   heap memory held: 7557kb
Total direct memory held: 0kb
(b: 0kb  f: 0kb  i: 0kb  s: 0kb  d: 0kb)



this method I get the vertex (vertex 20, at top of the box as seen at Box class JME3):

private Vector3f getVector(Geometry geom, int iVectorIndex){
    VertexBuffer vtbuf = geom.getMesh().getBuffer(Type.Position);
    FloatBuffer fbuff = (FloatBuffer)vtbuf.getData();
    Vector3f v3f = new Vector3f();
    for(int i=0; i<3; i++){
      v3f.set(i,fbuff.get((iVectorIndex*3)+i));
    }
    return v3f;
}



this one I set the new vertex (ex.: y axis +2.0):

  private void setVector(Geometry geom, int iVectorIndex, Vector3f v3fNewPos){
    VertexBuffer vtbuf = geom.getMesh().getBuffer(Type.Position);
    FloatBuffer fbuff = (FloatBuffer)vtbuf.getData();
    for(int i=0; i<3; i++){
      fbuff.put((iVectorIndex*3)+i,v3fNewPos.get(i));
    }
   
    geom.updateGeometricState();
    geom.updateModelBound();
    ((PhysicsNode)geom.getParent()).updatePhysicsState();
  }



I print the resulting vertex before and after the change, collecting directly from the object, and the values are correct! But nothing changes on screen.

Any idea?

PS.: the collision can be worked by checking if the entity is over a collidable (stoping its movement) or over a non collidable cube (when gravity and etc apply...); may be a way to skip jbullet if needed.

Maybe you can post a test case?

Normen might be able to help with how to change a MeshCollisionShape in real time.

Hi!



Ok, here is a test case to change the mesh (not adding, just moving "a" vector).

I thought that change should make the cube look different and also affect physics.

I am new to JME3, so much I cant even make the 2nd cube hit the one below it :(.

(I am using this jME3_08-18-2010.zip on eclipse.)

import java.nio.FloatBuffer;



import com.jme3.app.SimpleBulletApplication;

import com.jme3.bullet.collision.shapes.BoxCollisionShape;

import com.jme3.bullet.nodes.PhysicsNode;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer;

import com.jme3.scene.VertexBuffer.Type;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;



public class TestCaseModifyMesh extends SimpleBulletApplication{

  Geometry modifyMe;

  int iBoxCount = 0;

 

  public static void main (String args[]){

    TestCaseModifyMesh tcmm = new TestCaseModifyMesh();

    AppSettings settings = new AppSettings(true);

    settings.setResolution(320,200);

    settings.setFullscreen(false);

    //settings.setAudioRenderer(null);

    tcmm.setSettings(settings);

    tcmm.start();

  }



  enum eActions {

    ModifyMesh

  };

 

  @Override

  public void simpleInitApp() {

    msg("hit space to attempt to modify mesh!");

   

    inputManager.addMapping(eActions.ModifyMesh.toString(),

        new KeyTrigger(KeyInput.KEY_SPACE));       

    inputManager.addListener(actionListener, eActions.ModifyMesh.toString());

   

    // static

    float fMass = 0; //static objects has mass=0

    modifyMe = createBoxAt3DPos(new Vector3f(0,-1,5),fMass);

   

    // falling over, why doesnt work/hit ?

    fMass = 1;

    createBoxAt3DPos(new Vector3f(0,1,5),fMass);

  }

 

  private ActionListener actionListener = new ActionListener() {

    public void onAction(String name, boolean keyPressed, float tpf) {

      if(!keyPressed){

        eActions e = eActions.valueOf(name);

        switch(e){

          case ModifyMesh: {

              int iVectorIndex = 20; //is at top of box, see Box class

              Vector3f v3f = getVector(modifyMe, iVectorIndex);

              v3f.addLocal(0,1.25f,0); //1.25f arbitrary...

              scanGeomSetAllMatchingVectors(modifyMe, iVectorIndex, v3f);

            }break;

        }

      }

    }

  };

 

  private Geometry createBoxAt3DPos(Vector3f pos, float mass){

    iBoxCount++;

    float size = 0.5f;

    Material matDefault = new Material(assetManager, "Common/MatDefs/Misc/SolidColor.j3md");

    matDefault.setColor("m_Color", ColorRGBA.Gray);

   

    Box box = new Box(Vector3f.ZERO,size,size,size);

    Geometry geomBox = new Geometry("Box:"+iBoxCount, box);

    geomBox.setMaterial(matDefault);

    geomBox.setLocalTranslation(pos);

   

    Vector3f halfExtents = new Vector3f(size,size,size);

    PhysicsNode physnodeBox = new PhysicsNode(geomBox, new BoxCollisionShape(halfExtents), mass);

    getPhysicsSpace().add(physnodeBox);

    rootNode.attachChild(physnodeBox);

   

    physnodeBox.updateGeometricState();

    physnodeBox.updateModelBound();

    physnodeBox.updatePhysicsState();

   

    return geomBox;

  }



  private Vector3f getVector(Geometry geom, int iVectorIndex){

    VertexBuffer vtbuf = geom.getMesh().getBuffer(Type.Position);

    FloatBuffer fbuff = (FloatBuffer)vtbuf.getData();

    Vector3f v3f = new Vector3f();

    for(int i=0; i<3; i++){

      try{

        v3f.set(i,fbuff.get((iVectorIndex*3)+i));

      }catch(IndexOutOfBoundsException e){

        return null; //end of array

      }

    }

    msg("vec="+iVectorIndex+";pos="+v3f);

    return v3f;

  }

 

  private void scanGeomSetAllMatchingVectors(Geometry geom, int iVectorIndex, Vector3f v3fNewPos){

    Mesh mesh = geom.getMesh();

    VertexBuffer vtbuf = mesh.getBuffer(Type.Position);

    FloatBuffer fbuff = (FloatBuffer)vtbuf.getData();

   

    Vector3f v3fRefVector = getVector(geom, iVectorIndex);

   

    // set matching ones

    msg("lim="+fbuff.limit());

    msg("cap="+fbuff.capacity());

    msg("pos="+fbuff.position());

    //msg("arlen="+fbuff.array().length); ???

    for(int i2=0; i2<fbuff.limit(); i2++){

      Vector3f v3f = getVector(geom, i2);

      if(v3f == null)

        break; //end of filled up array

      if(v3f.equals(v3fRefVector)){

        for(int i=0; i<3; i++){

          int iFloatPos = (i2*3)+i;

          fbuff.put(iFloatPos,v3fNewPos.get(i));

          msg("vec="+i2+";axis="+i+";val="+v3fNewPos.get(i)+";valSet="+fbuff.get(iFloatPos));

        }

      }

    }

   

    geom.updateGeometricState();

    geom.updateModelBound();

    ((PhysicsNode)geom.getParent()).updatePhysicsState();

   

    checkVector(geom,iVectorIndex);

  }

 

  private void checkVector(Geometry geom, int iVectorIndex){

    VertexBuffer vtbuf = geom.getMesh().getBuffer(Type.Position);

    FloatBuffer fbuff = (FloatBuffer)vtbuf.getData();

    Vector3f v3f = new Vector3f();

    for(int i=0; i<3; i++){

      v3f.set(i,fbuff.get((iVectorIndex*3)+i));

    }

    msg("posCheck="+v3f);

  }

 

  public static int iDebugLevel = 1;

  public static void msg(Object obj){

    msg(obj,-1,1);

  }

  public static void msg(Object obj,int iLevel){

    msg(obj,iLevel,1);

  }

  private static void msg(Object obj,int iLevel,int iIncStack){

    StackTraceElement[] ael = Thread.currentThread().getStackTrace();

    String methodName = ael[2+iIncStack].getMethodName();



    if(iLevel >= iDebugLevel || iLevel == -1)

      System.out.println("DEBUG "+methodName+"(): "+obj);

  }

 

}



I am thinking on using JME2 with MetaBalls ScalarField etc. to render the outside mesh.
I think MetaBalls can be ported to JME3, not sure. I need to see if it will work fast enough with my requirements, before doing another step.

Another thought was to make a copy of com.jme3.scene.shape.Sphere and change it in a way that each triangle could be added arbitrarily before creating the mesh (not being a Sphere of course). And also allow modifying in runtime. Too difficult to me yet, this is just a guess anyway.

If someone could explain or point to me a link explaining why nothing happens when I modify the FloatBuffer, would be cool :). I think that if I replace the mesh with the modified one (modified FloatBuffer) and reinitialize the object (or destroy it and create a new one) it will work.

So, my next try will be with MetaBalls code at JME2. And I know it may be slow with the ammount of cubes I plan for it :(. Submeshes may work great tho! (several 5x5x5 or 10x10x10 cubes).

After changing the FloatBuffer, you have to call updateData on the VertexBuffer you changed, otherwise you won't see your changes.

By the way, why do you need metaballs? You said you wanted to make a Minecraft clone- that doesn't have metaballs.

updateData() worked perfect, thx!!



I found also this post on how to set each triangle on a mesh!

http://www.jmonkeyengine.com/forum/index.php?topic=14020.0

so I will play with it b4 trying metaballs style (too complex to me yet, need more time to understand all that…) someone knows if metaballs/scalarfield is already in jme3? I couldnt find…



My idea is to create a matrix computed "cubic" world, in the style that was done at Infiniminer, Minecraft and Manic Digger; but, I want to break with the cubic theme! thats one of my main goals ;). I dont know what will happen, if it will look good, I need to give it a try. I have also my own gameplay ideas.

This sounds like a cool project. I always wanted to recreate MineCraft in my own way. I look forward to seeing your progress and the source. Cheers.

@teique

Cool idea! Some ideas to get you started:

Minecraft, I believe, uses a voxel data structure. Read about voxels and oct trees and see how they can help you cull occluded data. Occlusion will be key for performance in this type of game.

Also, you just need to store the blocks that are exposed to the world. For instance, if you have a 3x3 cube of boxes, the very middle box is not visible, so it does not have to be rendered, or even created.

If you clip through the walls in minecraft you can see that there are no blocks underground. Only once they are exposed to the “air” are they generated. That will be a great way to cut down the number of objects you have to manage and traverse when rendering/colliding.

I recently started playing minecraft and was pretty enchanted. I didn’t think I would be able to put it down at first, but when I realized, there is only so many objects you can build, I’m by myself(although I realize there is a way to play with others in the same world), and the big killer is that there are no milestones. There is nothing to really accomplish, and I know minecraft doesn’t claim to be a goal oriented game. It states that it is a “sandbox” game. And I appreciate it for that, but I realize I could have just as much fun playing with legos.



What I would like to see, maybe develop(after I learn 3d programming, which could take awhile), is a multiplayer game, simple in graphics like minecraft, simple in mechanics, simple cubes and all that, but with a purpose, crafting different types of weapons, armor and vehicles/devices, building castles, joining teams and having battles to control land and resources. I’d also like to see maybe a currency and trade system, character development/crafting+fighting skills.



I think I want too much out of a game. When they can combine the action of Halo, with the economy and character development of Runescape/WoW/Eve, maybe I’d be content.

Hi again!



@monkeyBrainz, it is a bit stalled, I am not having much time to look at this anymore :frowning:

Tho, the good point is new things show up, like the new jme terrain system, and I thought that if it get a few tweaks, it can be dynamically changed by player actions (like an explosion to the ground that makes a hole, throw debris up and after it falls and stops moving, it reintegrates into the terrain with collision!). When I have time again, “fortunately?” on my vacations, I will see what I can accomplish considering the new technologies that will be probably available :D.



@Sploreg, yep, the performance is the biggest issue, that promptly hindered me as I have very little already acquired knowledge on how to improve performance, your clue can help but I have to research on that yet xD, thx!; Anyway, sometime later I saw the new jme terrain system and I am changing my plans a bit, like I said above :); anyway I still want precise mesh cut (boolean operations); so I created another thread for that subject.



@flcoder, that must be the reason I give up playing it for now; I miss challenges and goals, as just to survive, in the hardest mode, is still too easy…, so I will wait Minecraft to evolve; at 1st I think there wont be possible to add codified functionalities/modifications (even scripted) to it, in a way you can expand its gameplay modes; so, to create a new game would be the right way I think, that must have been my fuel to begin coding this :D. Btw, on cool ideas, take a look also at Savage and Savage2, you will see that a player can be elected a commander, so he can send orders to other players and actually draw them (point arrows etc) in the game map!!

The funniest thing in games I think, is that when it allows us to create while playing, I think the world is awakening to that from some time now…; but also demand self survival caring (take a look at Fallout3/Fallout New Vegas mods, there is one named Imps More Complex Needs, that forces us to “eat and drink” but in a way you get proper real life nutrition! those calories stuff you read on juice boxes for ex.; Also mods that dont let you jump from too high or you break your leg, and mods that make you bleed, affecting also the NPCs, changing the whole tactics of a game!, resources management, even some micromanagement becomes cool!; on this “bleeding subject”, take a look at UrbanTerror also, the most addicting free action game EVA! :), very outdated graphics tho… :(, but I still play almost all days :>, mmm… that may be the reason I dont have much time xD, D: ).