Myrdragor – A massive multiplayer online sandbox game

@tirnithil said: Hey erlend,

thats a good idea. We will try the deform bones in the next days, if they work as intended, we could have a chat with @atomix about this.
Also we have done interesting camera stuff for you, I just had no time to contribute it yet, sry. Time is short these days :smiley:

That’s really nice, thank you both.
Just tell me if you have the solution for modifying the bone, I glad to hear

We made a testcase a few weeks ago and there was apparently no problem. So I think it will not be a great big deal. But, we will see :smiley:

@atomix: Our deform bones are working :slight_smile: If you still want to have a chat about character customization, you can contact me via skype (Tirnithil) to arrange a meeting with me and Agares.

1 Like

@tirnithil : Yes, of course. I will contact you via Skype. I really want to see how your character customization system work. I also have some ideas my self.

Hey folks, there a two little things I have to say:

First, we are still alive, and even if we totally overdid our schedule, we are still straight on course.
Second, since we will reach alpha real soon now, whose soul do I have to sacrifice to get Myrdragor as a JME Project, mentioned in the Projects Overview?

2 Likes

<summon>@erlend_sh</summon>

1 Like

starts the chanting and praising

Well, this looks like a bit of thread hijacking ^^ Especially since we haven’t introduced our character creation system yet. I would have (and still do) loved to discuss this with you via skype, where we could show you some of our stuff and see some of yours (that sounds wierd^^), also I will not show our character customization here in the forums right now. We are a bit … shy on stuff that is that early.

I can tell you, that we have a small amount of everything that is in use in common games. Since our characters will have a rework till beta we stayed low on deformable bones … well, and stuff^^ We can resize the boobs, for sure :smiley:

How did you create the minimap in the first pictures in this thread?

We used a top view camera rendered offscreen. We now use a different approach, but we can give you our old code:

[java]

package de.myrdragor.controller.appstates;

import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.FlyByCamera;
import com.jme3.light.DirectionalLight;
import com.jme3.light.Light;
import com.jme3.light.LightList;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import com.jme3.water.WaterFilter;
import de.myrdragor.controller.MyrdragorApplication;
import de.myrdragor.controller.nifty.screencontroller.MainGame;
import de.myrdragor.controller.nifty.screencontroller.WorldEdit;
import de.myrdragor.model.spatial.node.debug.PieValue;
import java.awt.Color;

/**
*

  • @author Agares
    */
    public class MinimapAppState extends AbstractMyrdragorAppState {

    private Camera miniCam;
    private ViewPort minimapVP;
    private CharacterControl player;
    private FlyByCamera flyCam;
    private WaterFilter water;
    private FilterPostProcessor fpp;
    private FrameBuffer outBuf;
    private Texture2D output;
    private float updateTime;

    /**
    *

    • @param stateManager

    • @param app
      */
      @Override
      public void initialize(AppStateManager stateManager, Application app) {
      super.initialize(stateManager, app);

      this.app = (MyrdragorApplication) app;
      if (this.app.getStateManager().getState(GameAppState.class) != null) {
      player = this.app.getStateManager().getState(GameAppState.class).getPlayer();
      }
      flyCam = this.app.getFlyByCamera();
      initMinimapViewPort();
      initOverlay();
      initFPP();
      }

    /**
    *

    • @param stateManager
      */
      @Override
      public void stateDetached(AppStateManager stateManager) {
      super.stateDetached(stateManager);

      if (fpp != null) {
      minimapVP.removeProcessor(fpp);
      }

      minimapVP.clearScenes();
      minimapVP.setClearFlags(true, true, true);
      app.getRenderManager().removeMainView(minimapVP);
      miniCam = null;
      }

    @Override
    public void update(float tpf) {
    float init = app.getTimer().getTimeInSeconds();
    super.update(tpf);
    if (miniCam != null && minimapVP != null) {
    if (!flyCam.isEnabled()) {
    Vector3f camLoc = player.getPhysicsLocation().add(0, 400, 0);
    miniCam.setLocation(camLoc);
    } else {
    Vector3f camLoc = app.getCamera().getLocation().add(0, 400, 0);
    miniCam.setLocation(camLoc);
    }

         updateOverlay();
     }
     updateTime = app.getTimer().getTimeInSeconds() - init;
    

    }

    private void initMinimapViewPort() {
    miniCam = new Camera(256, 256);

     minimapVP = app.getRenderManager().createPreView("MinimapVp", miniCam);
     minimapVP.setClearFlags(true, true, true);
     minimapVP.setBackgroundColor(new ColorRGBA(0, 0, 0, 0));
    
     // create offscreen framebuffer
     outBuf = new FrameBuffer(256, 256, 1);
    
     //setup framebuffer's cam
     miniCam.setFrustumPerspective(45f, 1f, 1f, 1000f);
     Vector3f camLoc = app.getCamera().getLocation().add(0, 400, 0);
     miniCam.setLocation(camLoc);
     miniCam.lookAtDirection(new Vector3f(0, -1, 0), new Vector3f(0, 0, -1));
    
     //setup framebuffer's texture
     output = new Texture2D(256, 256, Format.RGBA8);
     output.setMinFilter(Texture.MinFilter.Trilinear);
     output.setMagFilter(Texture.MagFilter.Bilinear);
    
     //setup framebuffer to use texture
     outBuf.setDepthBuffer(Format.Depth);
     outBuf.setColorTexture(output);
    
     //set viewport to render to offscreen framebuffer
     minimapVP.setOutputFrameBuffer(outBuf);
    
     minimapVP.attachScene(app.getRootNode());
    

    }

    private void updateOverlay() {
    if (app.getDataHandler().getNifty().getCurrentScreen().getScreenController() instanceof MainGame) {
    MainGame guiCtrl = (MainGame) app.getDataHandler().getNifty().getCurrentScreen().getScreenController();
    guiCtrl.setCharViewDir(player.getViewDirection().clone());
    }
    }

    public void initOverlay() {
    if (app.getDataHandler().getNifty().getCurrentScreen().getScreenController() instanceof MainGame) {
    MainGame guiCtrl = (MainGame) app.getDataHandler().getNifty().getCurrentScreen().getScreenController();
    guiCtrl.setCharViewDir(player.getViewDirection().clone());
    guiCtrl.setMinimapImage(output);
    }
    }

    private void initFPP() {
    DirectionalLight dl = null;

     if (app.getStateManager().getState(WorldAppState.class) != null) {
         LightList localLightList = app.getStateManager().getState(WorldAppState.class).getSceneNode().getLocalLightList();
         for (Light light : localLightList) {
             if (light instanceof DirectionalLight) {
                 dl = (DirectionalLight) light;
                 break;
             }
         }
     }
    
     if (dl == null &amp;&amp; app.getStateManager().getState(WorldTileEditorAppState.class) != null) {
         dl = app.getStateManager().getState(WorldTileEditorAppState.class).getDirectionalLight();
     }
    
     if (dl != null) {
         water = new WaterFilter(app.getRootNode(), dl.getDirection());
    
         fpp = new FilterPostProcessor(app.getAssetManager());
         fpp.addFilter(water);
    
         water.setWaveScale(0.003f);
         water.setMaxAmplitude(2f);
         water.setFoamExistence(new Vector3f(0.25f, 1f, 0.25f));
         water.setDeepWaterColor(ColorRGBA.Brown);
         water.setUnderWaterFogDistance(50);
         water.setWaterColor(ColorRGBA.Brown.mult(1.2f));
         water.setFoamTexture((Texture2D) app.getAssetManager().loadTexture("Common/MatDefs/Water/Textures/foam2.jpg"));
    
         water.setWaterHeight(20);
    
         minimapVP.addProcessor(fpp);
     }
    

    }

    @Override
    public PieValue getPerformanceinfo() {
    return new PieValue(updateTime, Color.CYAN, “MinimapAppState”);
    }
    }

[/java]

And perhaps you’ll need those two methods from our nifty screen controller:

[java]
//Links the Rendered Offscreen Texture to Nifty Image Element
public void setMinimapImage(Texture2D output) {
if (output != null) {
minimapImage = new NiftyImage(nifty.getRenderEngine(), new RenderImageJme(output));
}

    Element imgMinimap = screen.findElementByName("imgMinimap");
    if (minimapImage != null) {
        imgMinimap.getRenderer(ImageRenderer.class).setImage(minimapImage);
    }
}

//Displays the correct Arrow Overlay for the View Direction
public void setCharViewDir(Vector3f clone) {
    clone.y = 0;
    clone.normalizeLocal();
    float angleBetween = clone.angleBetween(Vector3f.UNIT_Z.mult(-1));

    float dir = 0;

    if (clone.x &gt; 0) {
        dir = angleBetween * 180 / FastMath.PI;

    } else {
        dir = angleBetween * 180 / FastMath.PI;
        dir = 360 - dir;
    }

    float over = dir % 5;
    dir -= over;

    int id = Math.round(dir);

    if (id != actPlayerDirId) {
        actPlayerDirId = id;
        Texture2D arrow = playerArrows.get(id);
        if (arrow != null) {
            RenderImageJme newImage = new RenderImageJme(arrow);
            NiftyImage img = new NiftyImage(nifty.getRenderEngine(), newImage);
            playerDirArrow.getRenderer(ImageRenderer.class).setImage(img);
        } else {
            Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Playerarrow with ID : {0} was not set.", id);
        }
    }
}

[/java]

Thank you.

What made you change approach - what is your new approach ? (no need for code, just the concept/idea)

The main reason is, that we want a dynamically drawn map, instead of a live map for our game. Also, there were some trust issues regarding the performance using an extra camera.

@nehon said: <summon>@erlend_sh</summon>
wuh... what? Who dares wake me from my slumber! Oh hi Nehon, sup.

To be honest with you @tirnithil , the Projects section has been scheduled for deprecation (or re-purposing at least) for quite some time now, as I could never get it to work quite how I wanted it to.

If you want more eyes on your project you could write a guest article/tutorial for this site. A lot of people are interested in MMOs/Networking for instance.

@erlend_sh said: wuh... what? Who dares wake me from my slumber! Oh hi Nehon, sup.
Dude....this is a friggin long cast time for a summon... Hopefully I wasn't wrestling with a mountain troll or i'd be dead long before you showed up... ;)
@nehon said: Dude....this is a friggin long cast time for a summon... Hopefully I wasn't wrestling with a mountain troll or i'd be dead long before you showed up... ;)

Dead, respawned, acquired new equipment, snuck back to death-site to see what of your original equipment is still lying around… repeat a few times. :slight_smile:

Well thanks @erlend_sh for clearing that up. And … while we wanted to share parts of our code for some time now, we lack the time to do so. Times are hard and busy the last month and … maybe in the future :slight_smile: