Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Need help with an improved Voxel Editor

edited December 2021 in Codea Craft Posts: 1,799

Hey all, @John is considering using this Dual-Joystick Voxel Editor to officially replace the current Voxel Editor in future Codea updates.

In that case I’d really love to make sure it’s very solid, and to implement two last missing features, and I could really use some help.

I’d love help with three things specifically:

  • finding bugs
  • understanding how to implement a fill feature (converting all contiguous blocks of one color into the current selected color)
  • understanding how to implement a feature to bump the model in any direction by one pixel, and to wrap it around to the other side of the editor if it’s bumped past an editor boundary

(…and if anyone wants to pitch in with cleaning up/refactoring the code to remove extraneous bits and identify code smell, that wouldn't be bad either)

I’ve made GitHub repositories for both the editor and the Voxel Player, and any and all are invited to join:

…but there’s no need to do any of that—it’d be a ton of help if you just played with the things and let me know if anything went wrong.

So, for the sake of a better, more fully usable Voxel Editor for all Codeans, please take a look and see if you can lend a hand!



  • Posts: 2,690

    @UberGoober - this is a bit off the wall but I find the left hand zoom a little annoying. I think what it needs is a simple vertical rectangle for up down with no right/left input what do you think?

    Also, it would help if you have a mini 3D map, say in the top left corner reflecting the 3D World so you know where your model is if it flies out of the viewing window. It may also be worth considering putting limits on your model and drawing the 3D axes up in the mini map.

  • edited November 2021 Posts: 1,799
    @Bri_G I like how you’re thinking! If you want to take a stab at any of those things, I’d love to see what you come up with.

    ATM personally I’m very focused on debugging and on adding the final two features it needs to be fully usable.

    There seems to be some confusion about the dual-joystick system. The left stick isn’t a “zoom”.

    This was originally called FPS Voxel Editor because you’re intended to feel you’re a *player*, not an impartial editor. You’re not just looking at it, you’re *in* it. I think the reason it feels so off is that people are expecting it to be a camera, but it’s not. The left stick isn’t supposed to feel like it’s moving a camera, it’s supposed to feel like it’s moving *you*.

    I'm probably not going to implement ideas about that paradigm itself, but I’d be very interested in ideas about making it *clearer.*
  • Posts: 1,799
    @Bri_G having said that, can I talk over your ideas one by one?

    1 - left hand controls - as mentioned, I’d rather clarify the current ones than replace them, but ideas to that end are welcome if they occur to you

    2 - a mini 3D map seems hard for me to pull off easily, but if you think you know how to do it I would love to see your approach - OTOH the problem the mini-map would solve might be more easily addressable some easier way - like perhaps an arrow on screen pointing in the direction of the model if it’s out of view?

    3 - I’m not sure what you mean by “putting limits on the model”, can you clarify?

    4 - 3D axes on mini-map - again I’m intimidated by the task of making a mini-map at all, and I’m also not sure there aren’t easier ways to solve the same problems a mini-map would solve
  • Posts: 2,690

    @UberGoober - I'll have a play with your code and try to add a little to it.

    On the point of dual joypads I have always thought the following (wrt Minecraft/Voxel terrains):

    1. There are two ways of viewing - first party and third party.
    2. First party is from your own eyes ie you are not visible in the terrain.
    3. Third party is usually offset, can either be locked behind the players character (always looking at their back and following their motion at fixed offset) or just offset fro the character can see the character turn and moves with a fixed offset in the same direction.

    On that basis you have no control over up or down - you just follow the terrain and fall or climb (unless you provide a 'grip' function for ladders etc). So the right hand joypad rotates the character with the left/right (X axis on pad) and the up/down function provides motion forward or back.

    The left hand joypad can be used for a camera looking at the world by rotating together with the right hand left/right movement but it should be a temporary motion whilst engaged - on release the view should return to straight ahead. The camera mode is only really of use in the first person mode.

    If you set up a flying camera roving over the terrain your best bet is to use the right hand joypad for movement - forward/backward and rotation with a rectangle elevation up/down to move the camera in an arc around the Worlds core centre.

    You could set up different modes but it could get very complicated.

  • Posts: 1,799

    @Bri_G left hand for ‘body’ control and right hand for ‘head’ control feels more natural to me—I think maybe it’s the standard on console games, but I wouldn’t claim that definitively.

    It’s directly from @John’s Basic Player code, which is basically Minecraft, and specifically from the flying mode of the Basic Player.

  • Posts: 1,799

    Oh, but actually tbh I did reverse the motion/look controls on John’s player. They felt wrong to me from the start.

  • Posts: 1,350

    Some issues in VoxelPlayer:

    1. asset error messages, lots of them.

    2. On a fast iPad, there's no controlling it. Control needs to be related to processor speed somehow. The .speed member in VoxelWalker defaults to 10. On my iPad, setting it to 1 is almost usable.

    3. If there is a dead area in the left joypad, so that you can stop moving without lifting your thumb, I can't find it. Either it's not there, or it's too small.

    As for look direction, people's taste varies. Some products even allow an easy way of choosing.

    Finally, a question, and I think it is a tough one. Do we mean for the examples provided to be good examples? I assume we would answer "yes", and then we need to decide what we mean by "good". Some aspects of good to consider:

    1. To what extent should it be easy to understand how the examples do what they do?
    2. To what extent do we want the examples be easy to modify to get something similar but substantially different?
    3. To what extent do we want them to have easily extra title bits that are useful as part of programs people write?
    4. To what extent do we want them to include tests, to show people how they work, what to expect, and, almost accidentally, how to test their code?
    5. To what extent should they show good Codea/Lua coding practices?
    6. To what extent should they reflect overall good coding and design practices?
    7. To what extent should they be object-oriented?
    8. To what extent should they demonstrate interesting capabilities like fluent design, passing functions, pluggable behavior, ...?

    I think these just scratch the surface, but they begin to address things we might think about. Personally, I find the questions daunting, because I feel like the answers should be "to a great extent" for most of them, and I frankly do not know whether I am up to the task of meeting the standards for examples I'd like to see.

    The most important thing to me in viewing an example is that I want to understand quickly "how it works", because I am probably looking for a specific answer to some question like "how can I figure out what object my finger has touched", and if the answer to that question is hidden deep inside, my needs are not met.

    As an example, I did finally discover the .speed variable in VoxelWalker. It was the fourth tab I looked in, out of four, and until I found it, there was no possibility of trying out the program at all.

    Examples are so valuable. How can we best provide them?

  • Posts: 1,350

    First experience with the new Voxel Editor.

    Somehow a little dude appeared. I'm not sure what I did to make that happen. I was never able to control the view to get a decent look at any desired side of him.

    The buttons x|x y|y z|z. What are they? I tried all the other buttons and they did nothing because I was touching where the dude wasn't. Finally noticed that the bomb was deleting. That clued me in on adding and selecting color to the patch.

    I guess that wedge thing is a brush? It seems to color boxes.

    It's possible that I am a complete noob fool who doesn't understand the simplest things, but I wasn't able to have much success with the program. I'm not sure what I needed, but I sure needed something.

  • Posts: 1,799

    @RonJeffries wow great feedback, thanks so much. Not gonna be able to address that all at once (at least not by myself) so let’s start with the first thing: speed.

    (I know that’s actually the second thing but the asset warning messages aren’t mine to fix, they come from the dependency on the built-in Block Library.)

    Not only haven’t I the foggiest idea how to address the speed, I have no way to test it, because I don’t have a fast enough iPad to reproduce the issue. Does a setting of 0.1 feel less like a runaway train?

  • Posts: 1,350

    1 wasn't bad. 0.1 will prob be too slow.

    i guess what one wants is to move x number of blocks per second? so maybe speed is some number times the time since the last touch or update?? but i haven't figured out how it actually works yet. anyway somehow i think we need to keep delta time in the equation.

  • Posts: 1,799

    @RonJeffries: on the question of what makes a good example project (let’s distinguish between projects and voxel models, because the first time I read that post I thought you were talking about models and I was confused), I think there’s another criteria that actually applies to the Editor more than anything else: does it make it more likely that people will use it to create voxel models for other projects?

    When I got the editor working, specifically after I got mirroring working, I had a lot of fun making models. Having fun making models made me want to make projects that used models; it was a minor thrill, for example, to take my little sword-and-shield fantasy dude and put him in the froggy project and see him hop around.

    So for me I’d like to see the Voxel Walker meet as high as possible a standard for helping people code things, I’d like the Voxel Editor to meet as high as possible a standard for helping people make things.

    (btw the x|x, y|y, z|z buttons are the mirroring buttons, when you make or color a Voxel they make or color a Voxel on the flip side of the x, y, or z axis of the grid. For me mirroring is what makes it all fun. Mirroring was not implemented in the original Voxel editor)

  • Posts: 1,799

    So the right stick and the left stick react to touch differently.

    The left stick generates a physics-engine force that’s applied to a craft rigidbody to create motion.

    The right stick rotates the camera based on a direct calculation of the x and y position of the current relevant touch.

    I’m assuming the speed is an issue with the left stick more than the right one, is that correct?

  • Posts: 1,350

    yes correct

  • Posts: 1,799

    Ok so I think we’re in a pickle there because doesn’t that mean the physics engine runs at different speeds on different devices? So we have to somehow calculate an amount of force to apply based on the resulting rate of travel depending on the device currently running it. Or is there another way?

  • Posts: 1,799

    @RonJeffries can you try running the built-in “voxel player“ and see if it has the same problem?

  • Posts: 1,799

    * now text appears on startup explaining the dual-stick paradigm
    * Editor now loads with an empty editing area and a much larger grid; some of Ron’s trouble came from not being able to tell what the editing tools did because the grid was so small and there was no indication that he should tap on it—now it’s hard not to tap on.

  • Posts: 1,350

    built in doesn't;t run at all:

    Main:26: BlockInventory:155: attempt to call a nil value (field 'button')
    stack traceback:
    [C]: in field 'button'
    BlockInventory:155: in method 'slotButton'
    BlockInventory:47: in field 'init'
    ... false

    setmetatable(c, mt)
    return c

    end:24: in global 'BlockInventory'
    BasicPlayer:21: in field 'init'
    ... false

    setmetatable(c, mt)
    return c

    end:24: in function <... false

    setmetatable(c, mt)
    return c

    [C]: in method 'add'
    Main:26: in function 'setup'
    stack traceback:
    [C]: in method 'add'
    Main:26: in function 'setup'

  • Posts: 1,799

    Editor Update

    • All buttons now cause a tool-tip text to appear mid screen. Tip text vanishes on next finger drag or after a set time.

    @RonJeffries this should clear up at least a little confusion, I hope.

  • Posts: 1,799

    @RonJeffries There are three example programs that use the voxel player: the player itself, the block library, and the Voxel terrain. Can you see if any of them work?

  • Posts: 1,799

    @RonJeffries Also, unless you’ve made any modifications to the examples that you’d like to save, could you try the “reset examples” button and see if the problem persists?

  • Posts: 1,350

    I did do a reset, but still only tried the player. I'll try the others too.

  • Posts: 1,350

    I think the issue is that BasicPlayer is not getting added, the player = is returning nil. BlockLibrary fails right away, terrain fails when you try to spawn player. I don't think I have the time/energy to dig into it just now. I'll let you know if I find anything.

  • Posts: 1,350

    This is so broken. Clearly no one has run these for ages. What is the correct new formula for:

        grass.setTexture(ALL, "Blocks:Dirt Grass")

    I can at least get rid of the asset problems and see what happens next.

  • Posts: 1,350

    Tried this:

    grass.setTexture(ALL, asset.builtin.Blocks.Dirt_Grass)

    Got this:

    ...73BDE4/ bad argument #3 to 'value' (string expected, got userdata)
    stack traceback:
    [C]: in upvalue 'value'
    ...73BDE4/ in field 'setTexture'
    Basic:47: in function 'basicBlocks'
    Blocks:3: in function 'blocks'
    Main:23: in function 'setup'

  • dave1707dave1707 Mod
    Posts: 9,988

    @RonJeffries In one of my projects, I use this.

        grass = scene.voxels.blocks:new("Grass Top")
        grass.setTexture(ALL, "Blocks:Grass Top")
  • Posts: 1,350

    don;y you get asset warnings from those?

  • Posts: 1,350

    they have started to work on the ipad i tested on last night. does it take time to refresh or something? i'm quite confused now.

  • Posts: 1,350

    OK. I guess restoring examples just takes a while and doesn't tell you that or when its done. All the example @UberGoober asked about run on both my iPads.

  • Posts: 1,350

    Isn't there some way to type asset and then tap it to get the asset browser open? I can't make it work in setTexture, which is where I tried it.

  • Posts: 1,799

    Ron, now that they are running, can you tell me if they have the same speed issues as the voxel walker?

  • edited November 2021 Posts: 1,350

    next time i'm on that ipad.

    The original voxel player is not too fast on my iPad. But the new one moves at direction normalized * speed, which is 10. I think the original moves x = x + 1 or y = y + 1.

    That's less. :smile:

  • edited November 2021 Posts: 1,799

    Using the “rigs” approach I tried out here I’ve pretty much entirely re-structured the Dual-Joystick Voxel Player (née Voxel Walker).

    As a result I got a little clearer on how the parts fit together, and I was able to make the camera jump between a third-person and a first-person point of view, as seen in the video.

    It’s kind of cool, but it’s not really usable in a game, because I don’t know how to turn the player-model to always face the direction it’s moving, and I don’t know how to smoothly swivel the camera around as the player moves so that the camera is always looking at the player-model from behind.

    @dave1707, @West, @Bri_G, anyone else who’s fiddled with Craft—can you give me tips on how to swivel the body and the camera around so they face the right direction at all times?

    [project updated and moved below]

  • dave1707dave1707 Mod
    edited November 2021 Posts: 9,988

    @UberGoober Here’s something I have that moves the camera around. There’s an invisible joystick, so move your finger in the direction you want to go. Up to move forward, down to move back, left or right to turn left or right.

    function setup()
        scene = craft.scene()      
        ground.model = craft.model.cube(vec3(1000,1,1000))
        ground.material = craft.material(asset.builtin.Materials.Standard) = readImage(asset.builtin.Surfaces.Desert_Cliff_Normal)
        cam = scene:entity()
        cam:add(, 60, .1, 1000, false)
    function update(dt)
        cam.eulerAngles = vec3(0,180+dir,0)
    function draw()
    function joyStick()
        if show then
            if d<50 then
    function touched(t)
        if t.state==BEGAN then
        elseif t.state==MOVING then
        elseif t.state==ENDED then
  • Posts: 1,799

    @dave1707, thanks, this looks promising — and so the idea is that if the camera is a child of the rotating model, it will just swivel as the model swivels, automatically keeping it in the right place behind the model (assuming it’s in third person view)?

  • edited November 2021 Posts: 1,799

    @RonJeffries pointed out that my “rig” system, because it adds properties and functions directly to craft entities, risks blundering into conflicts with other code, and also makes it hard for readers to distinguish between properties I’ve added to entities and properties that are baked-in.

    I think it’s a darn good point and so I’ve moved almost all the custom properties into a separate table, entity.rig.

    I made two kinds of exceptions:

    • The whole point of the cameraEntityThing is to be able to treat the camera and the entity as one object as much as possible, so I’ve left in place the entity’s getter/setters for camera properties.

    • Any customizations of standard cycle-update functions (like draw, update, touched, and touchHandler-related functions) remain as direct modifications on the rigged entities. Customizing these specifically seems like a very standard Codea design pattern, and one that’s even expected in some cases, so that feels right.

    Ron, could you tell me if this helps make it easier to understand? We may not agree on teasing this code into separate objects and classes, but I very much agree that it should be easily understood.

    [file moved to lower post]

  • edited November 2021 Posts: 1,350

    I'll have a look as time permits. I might take my tutorials down a camera path, and it'd be interesting to see what I'd do.

    But now, remain aware that while I do have a good sense of "good code", a lot of it is subjective, not necessarily so. It's just what I like, seasoned with a lot of history. That doesn't make me right. :smiley:

  • Posts: 1,799

    You make good points, as always, and you are generous with respecting other approaches, also a good thing I think.

    Your interrogation of the qualities a good example project needs is very valuable to me, and I also very much appreciate your perspective on how well or poorly these projects meet those standards.

    So I guess all I’m saying is: thanks. :)

  • Posts: 1,350

    thank you for paying attention, and more for getting something out of my ravings :smile:

  • edited November 2021 Posts: 1,350

    i think since joystickView is a child of entity, its update will get called when the parent's is. is that not the case?

  • Posts: 1,350

    sometimes the code says = function(blah) and sometimes function might want to be consistent. i prefer the latter, i think.

  • Posts: 1,799
    I don’t know about child updates—that’s a good thought. I agree consistency is good, I usually wait until everything’s working to clean stuff like that up though.
  • edited November 2021 Posts: 1,350

    ah. if you pass a class to entity:add, it will create an instance, and scene: update will auto-call the instance's update.

    to me, that's a pretty good case for making our entities with classes.

    anyway that's what i was thinking about.

  • edited November 2021 Posts: 1,350

    @John why is entity:add(type,...) restricted to one instance of a given type? and is that one per entity, or one for all entities? that is could i add a Mover to several entities? tests say yes.

  • JohnJohn Admin Mod
    Posts: 764
    It’s one instance per entity, but you can put one on as many entities as you like
  • edited November 2021 Posts: 1,799
    > to me, that's a pretty good case for making our entities with classes.

    To me it’s entirely neutral—in the context of this thread, how something works may be outweighed by how easy it is to understand how it works.

    In which light, the fact that it took you to here to understand is at least somewhat of a good case against classes used in this way, to me.
  • Posts: 1,350

    as you wish.

  • edited November 2021 Posts: 1,799
    So I’m having a problem with rigidbody: the camera has to be a child of the entity with the rigidbody, so that it automatically moves when the rigidbody moves, but whenever it’s a child of the entity with the rigidbody, it looks like it’s vibrating—there’s a double-image as it moves.

    If the camera is not a child of the rigidbody, there’s no visible vibration at all.

    I’m trying to make a stripped-down project that isolates the problem code, but for now if anyone wants to take a look at the effect in the regular project it’s attached here.
  • dave1707dave1707 Mod
    Posts: 9,988

    @UberGoober The only time I see anything wrong is when the object hits the wall and jumps over it. It’s not a smooth motion, but not that bad. I don’t see any vibration as the object moves around the floor so I’m not sure what to look for.

  • JohnJohn Admin Mod
    Posts: 764

    @UberGoober this is due to the physics timestep not matching up exactly with per frame update loop. I've never really noticed it much when I've used the rigidbody attached camera. There are ways to mitigate this (physics-interpolation) but I haven't put those in as of yet

  • Posts: 1,799

    @dave1707 I tried to screen-record it but, funny enough, it doesn’t show up on screen recordings.

    So it must be happening faster than the screen recording FPS I guess.

    I’m using an iPad Pro (12.9-inch) (4th generation)

    The vibration doesn’t show up on my iPhone.

    Anyone else seeing it?

Sign In or Register to comment.