Experimental proof of concept: Map tools in web browser

Discussion, updates, modifications, etc for the various map editors...
Post Reply
User avatar
Zehra
Survey Champion 2024
Survey Champion 2024
Posts: 972
Joined: Sun Oct 18, 2015 3:36 pm
Location: Within the BZFS API and Beyond it
Contact:

Experimental proof of concept: Map tools in web browser

Post by Zehra »

Years earlier I mentioned some outlines of an idea: Web based map editors
Zehra wrote: Wed Jul 24, 2019 12:23 am Looking through the code of a few map editors, it seems that porting them to web technologies would offer some promise.
While there is some performance loss, this will very likely not be an issue, unless with using much older computers.
Examples of tools or editors which could benefit greatly from this would be: Modeltool, Anim8orToBZW, BZWorkbench..etc
Taking advantage of web technologies can turn command line tools into user-friendly drop and load interfaces.
So later some time I decided to see a bit of a proof of concept:

Code: Select all

<!DOCTYPE html>
<html>

<head>
    <title>Anim8tor To BZW</title>
   <style type="text/css">
    body {padding-left: 10%;
        padding-right: 10%;}
    h1 {text-align: center;}
    h2 {text-align: center;}
    textarea {
      width: 95%;
    }
    p {text-align: center;}
    </style>
</head>

<body>
    <h1>Anim8tor To BZW</h1>
    <h2>Convert your Anim8tor Cubes to BZW Boxes:</h2>
    <p>
        Default code has been
        loaded into the Editor.
    </p>
    <textarea id="texttoparse">
  cube {
    name { "tel rot_45_cube02" }
    base {
      origin { (0 5 0) }
      orientation { (0 0.38268 0 0.92388) }
    }
    material { "material03" }
    scale { 0.13000 10 15 }
    divisions { 1 1 1 }
  }
  cube {
    name { "cube02" }
    base {
      origin { (-20 10 -20) }
    }
    material { "material04" }
    scale { 10 20 10 }
    divisions { 1 1 1 }
  }
  cube {
    name { "cube03" }
    base {
      origin { (20 10 20) }
    }
    material { "material04" }
    scale { 10 20 10 }
    divisions { 1 1 1 }
  }
    </textarea>
    <button onclick="converttobzw()">Try it</button>
    <script>
    
function convertrot(din) {
  return ((2) * ( Math.acos(din) * 180 / Math.PI ));
}

// Yeah, we're handling it this way.
function objtype(btype) {
  if (btype == 1) {
    return "pyramid\n";
  } else if (btype == 2) {
    return "teleporter\n";
  } else {
    return "box\n";
  }
}


function objname(bname) {
  let objnamestr = "    name " + bname + "\n";
  return objnamestr;
}

function objposition(x, y, z) {
  let objposstr = "    position ";
  return objposstr.concat(x, " ", y, " ", z, "\n");
}

function objsize(btype, x, y, z) {
  let objsizer = "    size ";
  if (btype == 2) {
    return objsizer.concat(".125 ", y, " ", z, "\n    border 1\nend\n\n");
  } else {
     return objsizer.concat(x, " ", y, " ", z, "\nend\n\n");
  }
}

function makeobject(otype ,oname, opos, orot, osize) {
  let bzwobjs = "";
  if (parseFloat(orot) == 0.0) { 
    return bzwobjs.concat(otype, oname, opos, osize);
  } else {
    return bzwobjs.concat(otype, oname, opos, "    rotation ", orot, "\n", osize);
  }
}
// For parsing numbers
function getF1(s1) {
  let l1 = s1.indexOf(" ");
  l1 += 1;
  s2 = s1.slice(l1);
  return s2;
}

// We're just assuming things won't crash and burn.
function getasymmquotes(text, start, end) {
  let findstartnum = text.indexOf(start);
  let findaddnum = start.length;
  let startnum = findstartnum + findaddnum;
  let endnum = text.indexOf(end);
  let textwithin = text.slice(startnum,endnum);
  return textwithin;
}

amarray = [];

bzw=[];
//function amArrayToBZW(item) {
//  console.log(item);
//}
let tasklevel = 0;
let bzwType = 0; //By default it is a box.
//Types: 0 = box, 1 = pyr, 2 = tel
let rotation = 0.0;
let xPos = 0.0;
let yPos = 0.0;
let zPos = 0.0;
let xSize = 0.0;
let ySize = 0.0;
let zSize = 0.0;
let names=[];
  
function amArrayToBZW(item) {
  // vars
  

  //let name;
  //if (item.length > 0) {
    if (tasklevel == 0) {
      bzwType = 0; //By default it is a box.
      //Types: 0 = box, 1 = pyr, 2 = tel
      rotation = 0.0;
      xPos = 0.0;
      yPos = 0.0;
      zPos = 0.0;
      xSize = 0.0;
      ySize = 0.0;
      zSize = 0.0;
      found = item.includes("  cube {");
      if (found ) {
        console.log("********** Found an object. **********");
        tasklevel = 1;
      }
    } else if (tasklevel == 1) {
      found = item.includes("name"); //find the name!
      if (found) {
        tasklevel = 2;
        console.log("Found the object's name line.");
        console.log(item);
        let fPos= item.indexOf("\""); //finds first quote mark
        fPos += 1;
        let linevar = item.slice(fPos);
        let fPos2 = linevar.indexOf("\""); //finds second quote mark
        let length = fPos + fPos2;
        let name = item.slice(fPos,length); //copies the name into name
        console.log("Name: " + name);
        names.push(name);
        // find object type
        pyrtest = item.includes("pyr");
        if (pyrtest) {
          console.log("Object is a pyramid.");
          bzwType = 1;
        }
        teltest = item.includes("tel");
        if (teltest) {
          console.log("Object is a teleport.");
          bzwType = 2;
        }
      }
    } else if (tasklevel == 2) {
      found = item.includes("origin");
      if (found) {
        tasklevel = 3;
        console.log("Found the origin line.");
        console.log(item);
        let linevar = getasymmquotes(item, "(", ")");
        // Get coordinates/positions
        let data = linevar.split(" ");
        xPos = parseFloat(data[0]);
        console.log("x position: " + xPos);
        yPos = parseFloat(data[2]);
        console.log("y position: " + yPos);
        zPos = parseFloat(data[1]);
        console.log("z position: " + zPos);
      }
    } else if (tasklevel == 3) {
      found = item.includes("orientation");
      findscale = item.includes("scale");
      if (found) {
        console.log("Found the orientation line.");
        let linevar = getasymmquotes(item, "(", ")");
        data = linevar.split(" ");
        let rotString = data[3];
        console.log("orientation: " + rotString);
        let rotDouble = parseFloat(rotString);
        console.log(rotDouble);
        rotation = convertrot(rotDouble);
        console.log(rotation);
      } else {
        if ((findscale) && (rotation == 0.0)) {
          console.log("No orientation.");
        }     
      }

      if (findscale) {
        console.log("Found scale (size) line.");
        console.log(item);
        let linevar = getasymmquotes(item, "{", "}");
        console.log(linevar);
        // get sizes
        data = linevar.split(" ");
        xSize = parseFloat(data[1]);
        console.log("x size: " + xSize);
        ySize = parseFloat(data[3]);
        console.log("y size: " + ySize);
        zSize = parseFloat(data[2]);
        console.log("z size: " + zSize);
        
        tasklevel = 0;
        console.log("** Fixing bzflag's stupid object size to coordinate ratio. **");
        zPos += zPos;
        xPos += xPos;
        yPos += yPos;
        console.log("** Fixing bzflag's stupid height ratio. **");
        zSize += zSize;
        console.log("** Fixing bzflag's stupid object height/position thing... **");
        zPos = zPos - (.5 * zSize);
        console.log("** Fixing bzflag's stupid Y pos/neg flip thing... **\n\n");
        yPos = yPos * -1;
        //get object settings
        console.log(rotation);
        let bobj = objtype(bzwType);
        let bname = objname(names[names.length - 1]);
        let bpos = objposition(xPos, yPos, zPos);
        let bsize = objsize(bzwType, xSize, ySize, zSize);
        // make object
        let bobject = makeobject(bobj, bname, bpos, rotation, bsize);
        //fileOut.write(bobject)
        console.log(bobject);
      }
    }
  }

/*
if (tasklevel == 1) {
  gotoend("Error while finding object's name.")
} else if (tasklevel == 2) {
        gotoend("Error while finding origin.")
} else if (tasklevel == 3) {
        gotoend("Error: while finding orientation.")
} else if (tasklevel == 4) {
        gotoend("Error while finding scale (size).")
} else {
  console.log("\n*** At end of file. ***")
}*/

    function converttobzw() {
      let texttoparseinput = document.getElementById("texttoparse").value;
      amarray = texttoparseinput.split("\n");
      //alert(amarray.length);
      amarray.forEach(amArrayToBZW);
    }
    </script>
</body>

</html>
Now this doesn't yet really work, it outputs a bit of stuff to the console.

To give some context with the all this: UPDATED 3-13-10: Anim8or to BZW Converter and Anim8orToBZW - Now in lightweight Python script

Originally this was a C++ app which was compiled, but later I converted it to a Python script. (And this is converted to JavaScript.) (So the license for the codeblock is GPLv3.)

The possibility of converter applications working within the browser is something I'll possibly be exploring further. It offers some promise, but I think it may be one of the best ways to "optimize" maps, from being "easy" to use (in terms of accessibility, it's just a link/click away). Especially if we can get in either drag and drop or copy and paste functionality working well and reliably.

-Zehra
Some useful references:
Map editor and tool list (summary)
Prefab and BZW help threads index
Map releases index
Some of my BZFlag related stuff.
BZList.net Modern HTML5 server stats site.

BZFlag has a cycle every 1-3 years. Activity drops/stops and resumes some time after. It returns to 90% of what it was.
We see late in 2013, the following thread: Why are there only like 30 people playing BZFLAG at one time.
Let's say 2014 starts with 30 players:
With a cycle length of:
3 years: 2017=27 players, 2020=24 players...
2.5 years: mid-2016=27 players, 2019=24 players, mid-2021=22 players.
I think the cycles get shorter as time goes along, but the bigger issue is eventually that activity will not be able to sustain itself in the long run, as nobody waits an hour for people to show up.
User avatar
Loymdayddaud
Survey Champion 2024
Survey Champion 2024
Posts: 7
Joined: Sun Oct 15, 2023 2:55 pm
Location: Saudi Arabia

Re: Experimental proof of concept: Map tools in web browser

Post by Loymdayddaud »

I assume you've seen allejo's map editor?
https://web-bzedit.allejo.org/
The best flag is Stealth.
User avatar
Zehra
Survey Champion 2024
Survey Champion 2024
Posts: 972
Joined: Sun Oct 18, 2015 3:36 pm
Location: Within the BZFS API and Beyond it
Contact:

Re: Experimental proof of concept: Map tools in web browser

Post by Zehra »

I have, it's probably the one with most promise. (It's possible to create maps on macOS, Windows, and Linux, without installations needed.)

I have the idea of small utility "tools" running in the browser as a way of complimenting existing means of map making, since there has been some issues in terms of "ease of use" compare to some of the command line tools/converters/scripts. Especially more likely for new map makers and users, as in general, a lot of stuff is done via graphical user interfaces these days. (TUI/CLI are being less commonly used compare to GUI interfaces). It's way less efficient and limited overall, but you'd be able to run it on recent web browsers on the other hand.

-Zehra
Some useful references:
Map editor and tool list (summary)
Prefab and BZW help threads index
Map releases index
Some of my BZFlag related stuff.
BZList.net Modern HTML5 server stats site.

BZFlag has a cycle every 1-3 years. Activity drops/stops and resumes some time after. It returns to 90% of what it was.
We see late in 2013, the following thread: Why are there only like 30 people playing BZFLAG at one time.
Let's say 2014 starts with 30 players:
With a cycle length of:
3 years: 2017=27 players, 2020=24 players...
2.5 years: mid-2016=27 players, 2019=24 players, mid-2021=22 players.
I think the cycles get shorter as time goes along, but the bigger issue is eventually that activity will not be able to sustain itself in the long run, as nobody waits an hour for people to show up.
User avatar
allejo
Breaker of Builds
Breaker of Builds
Posts: 814
Joined: Sun Feb 17, 2008 10:01 pm
Location: /dev/null
Contact:

Re: Experimental proof of concept: Map tools in web browser

Post by allejo »

This wouldn't be too difficult and could benefit from a greater effort. Think about it this way: if you build a framework or website that provides a REST API, you can apply the transformations of these tools running on the same machine as the web server or in cloud functions. Then, you can help design a plugin system for a map editor like WebBZEdit and write a plugin allowing you to apply transformations from an API.

You mentioned "proof of concept," but all I see is brainstorming. Why don't you try making the proof of concept?
User avatar
Zehra
Survey Champion 2024
Survey Champion 2024
Posts: 972
Joined: Sun Oct 18, 2015 3:36 pm
Location: Within the BZFS API and Beyond it
Contact:

Re: Experimental proof of concept: Map tools in web browser

Post by Zehra »

REST APIs would be much easier/intuitive to do for a proof of work/concept. The need for infrastructure dropped this from consideration. (But would have enabled it to run even from small devices rather easily.) I can't say I have enough knowledge to properly comment on cloud functions. Related to API systems and plug-ins, I can see some form of it being built and with various plugins which perform various conversions/transformations via the API.(Duplication of items, merging into meshes, convert into DrawInfo..etc)

It's understandable, I perhaps worded things rather poorly when saying it's a bit of a proof of concept. The code within the (code)(/code) blocks barely does anything, except convert cubes into boxes from the anim8tor format, and merely dumps the results to console.log, which has been less compare to previous works I've worked on.

But overall, I've mostly seen it as a stepping stone to creating a sort of toolbox/toolkit of some sorts to provide a lot of "utilities" for working on maps. But nothing is set in stone yet.

-Zehra
Some useful references:
Map editor and tool list (summary)
Prefab and BZW help threads index
Map releases index
Some of my BZFlag related stuff.
BZList.net Modern HTML5 server stats site.

BZFlag has a cycle every 1-3 years. Activity drops/stops and resumes some time after. It returns to 90% of what it was.
We see late in 2013, the following thread: Why are there only like 30 people playing BZFLAG at one time.
Let's say 2014 starts with 30 players:
With a cycle length of:
3 years: 2017=27 players, 2020=24 players...
2.5 years: mid-2016=27 players, 2019=24 players, mid-2021=22 players.
I think the cycles get shorter as time goes along, but the bigger issue is eventually that activity will not be able to sustain itself in the long run, as nobody waits an hour for people to show up.
User avatar
red rider
Survey Champion 2024
Survey Champion 2024
Posts: 15
Joined: Tue Sep 17, 2024 5:40 am
Location: In a tank

Re: Experimental proof of concept: Map tools in web browser

Post by red rider »

I use Allejo's map editor, and I would appreciate it if someone would add something that allows me to add meshes, it's getting annoying to have to copy code from other maps.
red rider,
User avatar
Zehra
Survey Champion 2024
Survey Champion 2024
Posts: 972
Joined: Sun Oct 18, 2015 3:36 pm
Location: Within the BZFS API and Beyond it
Contact:

Re: Experimental proof of concept: Map tools in web browser

Post by Zehra »

I'm currently time constrained.

It may sound easy. There's around 3 "sub-projects" this feature would need:
  • Mesh importing
  • Mesh transformation
  • Prefab index
From what I see: It's check to see the client handles meshes to import then. Mesh transformation requires some form of being able to rotate, scale, move, and merge/split meshes. (Order of difficulty from easiest to most difficult: Move, Rotate/Scale, Merge/Split). The prefabs being indexed, should have author (bzid/username), license, date created as basic info. (It's small enough to store on a normal device).
Some useful references:
Map editor and tool list (summary)
Prefab and BZW help threads index
Map releases index
Some of my BZFlag related stuff.
BZList.net Modern HTML5 server stats site.

BZFlag has a cycle every 1-3 years. Activity drops/stops and resumes some time after. It returns to 90% of what it was.
We see late in 2013, the following thread: Why are there only like 30 people playing BZFLAG at one time.
Let's say 2014 starts with 30 players:
With a cycle length of:
3 years: 2017=27 players, 2020=24 players...
2.5 years: mid-2016=27 players, 2019=24 players, mid-2021=22 players.
I think the cycles get shorter as time goes along, but the bigger issue is eventually that activity will not be able to sustain itself in the long run, as nobody waits an hour for people to show up.
Post Reply