Giter Club home page Giter Club logo

Comments (44)

Willard21 avatar Willard21 commented on July 29, 2024

Starting from the top, the fill thing is fine, but I'm not a fan of chaining assignment operators like that, since I feel it less obvious what the code is doing.

The big ugly blocks array was a last minute addition by someone else a couple days ago. It was initially in 1 line, but that broke the fold code button on Khan Academy, so I threw in a bunch of random line breaks to fix it, and never fixed the styling. As far as performance goes, that's only executed on page load and on page resize events, so performance isn't a huge concern there, but feel free to optimize anything you like.

All of those GLSL variables are used, and need to be global, so don't mess with them. All of the attributes and uniforms are passed in from the JavaScript via WebGL functions, and the varyings are set in the vertex shader, then interpolated between vertices in the fragment shader automatically. I've made several edits to the shaders locally, so I'll go ahead and remove the voids myself to avoid merging conflicts.

I'll see if GLSL has a method for interpolating between colors. That would probably be useful.

Feel free to update syntax wherever you see fit. This was originally written in ES5 on Khan Academy, so I didn't have access to most of the fancy ES6 syntax. Since var was the only option, the only way to contain random variables was with IIFEs. I did a find-and-replace from var to let when I started updating to ES6, then fixed a few random variables that broke from that. I've been updating bits and pieces here and there, like converting the ES5 classes to ES6 classes, but there's still plenty that uses old syntax.

I initially had a hacked eval version of all the typed arrays to get them to work in the ES5 KA environment. I think it looked something like eval("new Uint16Array([" + arr.join(", ") + "])"); or something like that. It didn't always result in the fastest code. I've made a meager effort to clean it up in places, but haven't gone through it line-by-line. So again, feel free to optimize anything you like.

I'll go ahead and push my current changes to a dev branch for you to work with to try to reduce merging conflicts. I don't want to push to master yet since it auto-deploys to https://willard21.github.io/MineKhan/Minecwaft.html where a few people play it, and it's missing a couple key features for an actual update.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

GLSL has an interpolating function called mix.

from minekhan.

 avatar commented on July 29, 2024

...but I'm not a fan of chaining assignment operators like that, since I feel it less obvious what the code is doing.

Oh, that explains why some people had a hard time understanding my code... (I use chaining assignment freely)

function fib(n: u64): u64 {
	let old_1: u64 = 1n;
	let old_2: u64 = 1n;

	for ( let i: u64 = 3n; i <= n; ++i ) {
		old_1 = old_2 + (old_2 = old_1);
	}

	return old_1;
}

As far as performance goes, that's only executed on page load and on page resize events...

It's not that I particularly care about over-optimizing everything, but where simpler, more optimized code can be used, the optimization really just comes for free.
But then again, resize events fire multiple times a second, so that might be harsh on the GC or the client's memory.

Regarding the GLSL, do you know of any good apps that can validate or help with writing GLSL? I had never found anything good.

...in the ES5 KA environment...

I've never used KA for coding, seriously, how do they do that stuff? Do they just parse all of your code and reject it if the parser can't understand it... or what? What do they even parse for?

I'll go ahead and push my current changes to a dev branch for you to work with to try to reduce merging conflicts.

Would you prefer that I update the dev branch instead of directly targeting master too?

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

You can use VSCode and install some extension that highlights the GLSL syntax. One I found highlights the syntax if the file was saved with extension of glsl.

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

I only know the bare bones basics of GLSL. That's why my shaders are so small and simple. You can log compiler errors to the console in JS for basic validation, but beyond that, I don't know.

KA uses JS Hint to enforce ES5, and they also use an old library called Slowparse to parse the user's code. They apply AST transformations to the code to insert infinite loop detectors, and store references to every variable created with new (which obviously leaks memory). The webpage environment + a type attribute on the script tag disables all of that though. There's still a couple things to beware of though. All the scripts are executed multiple times, so let and const can't be used in the global scope, and loops need to be stopped before they're started to avoid multiple game loops. That's also why I use canvas.onmousedown = ... instead of addEventListener(). Accessing global variables seems to be slow, which is why I cache Math inside the closure.

I dunno how pull requests work on branches, but if you know how then sure. At least use the branch as the starting point for your changes though. Merging conflicts are the bane of my existence lol.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

If you really want to know everything about GLSL.

from minekhan.

 avatar commented on July 29, 2024

If you really want to know everything about GLSL.

That is the spec, specs are for implementation, not learning the language.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

That is the spec, specs are for implementation, not learning the language.

But that's the only place that you can get everything. GLSL is a quite simple language. It is a simplified version of a simple language called C. The reason that the GLSL code for this project is so simple is that you only need simple shaders for Minecraft and you don't know how to make effects not how to use them.

from minekhan.

 avatar commented on July 29, 2024

You can use VSCode and install some extension that highlights the GLSL syntax. One I found highlights the syntax if the file was saved with extension of glsl.

Well, highlighting is really just the bare minimum, like, I found this site online, but it's incredibly outdated, I think the newest version of WebGL is 4.5+.

...You can log compiler errors to the console in JS for basic validation, but beyond that, I don't know.

Yeah, but that sounds so hacky, I'm sure that someone has set up a whole environment for properly using it, then again, I haven't found one.

KA uses JS Hint to enforce ES5, ...

Do they literally use it for that purpose? Do you know why they do it?

... The webpage environment + a type attribute on the script tag disables all of that though.

Okay, good.

There's still a couple things to beware of though. All the scripts are executed multiple times, so let and const can't be used in the global scope, and loops need to be stopped before they're started to avoid multiple game loops.

Can you elaborate on this? There is only one (major) script, how and why is it run multiple times?
Could wrapping the entire script in a lexical scope fix that?

...Accessing global variables seems to be slow, which is why I cache Math inside the closure.

Are you sure that it's accessing global variables... or accessing global properties? Math itself is normally a property, using this:

const { Math } = self;

Makes it a global variable instead, which should be much faster to access than normal window property accesses.

But even worse is that you still do lookups to actually get the function properties before calling them.

Math.random() * foo
Math.random() * foo
Math.random() * foo

vs

const { random } = Math;
random() * foo
random() * foo
random() * foo

The latter is shorter, simpler, and avoids that weird caching that you had done. If you can confirm that it doesn't reduce performance, I'll probably do this where I see functions looked up multiple times and called (it's also how I normally write my scripts and/or code).

Now, in reality, I feel like your global property accesses are slow because you are mutating the global object!
I really want to try to remove all window mutation, that just looks terrible leaving it.

Merging conflicts are the bane of my existence...

Merging conflicts are the best type of both, merges, and conflicts, lol.

from minekhan.

 avatar commented on July 29, 2024

[GLSL] is a simplified version of a simple language called C.

Honestly, I know advanced C and C++, and am used to systems programming, but C is way simpler than GLSL, and quite different too. They have plenty of similarities, the preprocessor, the main function as the entry point of control flow, but beyond that, they are completely different.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

...C is way simpler than GLSL

It seems that way because you're not used to the idea of attributes, uniforms, and varying. If you think those are global variables that are going to be magically filled with information you need then it's quite simple. You also have to understand the rendering pipeline to completely understand it.

from minekhan.

 avatar commented on July 29, 2024

...C is way simpler than GLSL

It seems that way because you're not used to the idea of attributes, uniforms, and varying.

I'm not saying that GLSL is complex, just that C is simpler. C is barebones and has so few instructions.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

I guess.

from minekhan.

 avatar commented on July 29, 2024

@Willard21 Can I get a response to #10 (comment), particularly the part about global let/const?

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Can you elaborate on this? There is only one (major) script, how and why is it run multiple times?
Could wrapping the entire script in a lexical scope fix that?

I already have basically the entire script wrapped in that MineKhan function for that exact reason. There's just around 10 lines above and below the function. And it does need to remain a named function since I check the number of characters in it to identify spin-offs on Khan Academy.

from minekhan.

 avatar commented on July 29, 2024

Well, I was thinking about dropping the use strict, and the application/javascript MIME in favor of making the JS a module.

<script type="module" ... />

But, it would implicitly create a lexical scope around the entire script, so I was wondering if that would cause a problem with executing on Khan Academy?

If you're unsure, could you test this idea?

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

https://www.khanacademy.org/computer-programming/new/webpage you can test code here pretty easily. Just copy/paste it in and see if it runs. You can refresh the page after pasting it in to see if it runs on first load, since the live reload can cause bugs. After briefly googling what a module is just now, I'm not entirely sure how it applies to a single-file project, so I'm not sure how to test it.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

00ff0000red is saying that just put the code inside a module so it creates a lexical scope around it which means you don't have to put giant IEFE around everything, which works.

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Ah. Well that's why I said

And it does need to remain a named function since I check the number of characters in it to identify spin-offs on Khan Academy.

In other words, I'd like to keep the giant function because it's useful for easily identifying modified copies. There's no other way that I'm aware of to check if a program is the original or not. document.referrer worked until about 2 months ago when it broke on Chrome. window.top.location.href throws errors since it's sandboxed. parent.location.href returns the url of the sandbox rather than the containing page, which is the same on every page from what I can tell.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

I think you can add another script that gets the code and checks the length with document.getElementByID.

from minekhan.

 avatar commented on July 29, 2024

Guess what, you can keep the big function!
Although, of course, a better solution would be... well, better, a module would just scope everything, even global var, but it won't scope the window modifications, those window.x = ..., actually, nvm, it probably will; I'll check on KA tomorrow when I have the time.

But, these are roughly equivalent:

<script>(() => { "use strict";
...
})();</script>

vs

<script type="module">
...
</script>

Except, the following will be deferred, likely more optimized, and is shorter and/or simpler.

(also, what if someone were to rename the big function?)

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

If they renamed it then it would crash, and they'd most likely find the exactly line number to remove it. It's not really intended to stop malicious plagiarizers though. A lot of people (generally kids) brand new to coding will copy/paste entire projects because they don't understand that it's plagiarism. I just add a little message on the pause screen saying that it's a spin-off so that newbies don't get crucified. Also so I get more upvotes when their spin-offs end up on the hot list lol. A better method for stopping plagiarizers would just be a random array of "important data" in the middle of the code that can be decoded into a link to this repo or something. But that just seems like overkill.

Most of the window.x = ... modifications aren't necessary, but several of them are useful for executing code from the console. Like those random commented out functions in the bottom of the file in this dev branch can be copy/pasted into the console and used like World Edit commands. It's fun lol

from minekhan.

 avatar commented on July 29, 2024

I just add a little message on the pause screen saying that it's a spin-off so that newbies don't get crucified.

Oh, I never renamed it and tried.

... but several of them are useful for executing code from the console.... used like World Edit commands.

Why not allow users to use them? The game is offline, the source code is JavaScript text (lol, try to hide it), and it's always in creative mode.
Otherwise, it sounds like you want a "proper" dev tools API for this. All you would need is a way to enable/disable the API.

Btw, KA can run the modular JS script tags, but, we'll need to be a bit more extensive testing for this app.

(Also, I hate KA's webpage, it's some sort of pseudo-XHTML.)

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

While it's not too big of a deal for local saves, but a single command can generate a save string a million characters long. Since people tend to share save strings in chat (to my great annoyance), I'd be stuck scrolling forever if I added those commands for all users. Even the replit post has 2 massive save strings in the comments already, and that's just from a house.

from minekhan.

 avatar commented on July 29, 2024

Sounds like some simple compression algorithm can help.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

A better solution for spin-offs would be to add ID to the module script and get the length of that script by document.getElementByID(ID of script tag).textContent.length.

from minekhan.

 avatar commented on July 29, 2024

Why check the script's length? Imho, document.referrer was a better solution, I can't think right now, but there's probably a "proper" way to do this.

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

Checking the script's length is shorter and a little bit cleaner than checking functions length, I believe.

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Sadly document.referrer broke in Chrome 85, which was unfortunate since that was like, a week after I started using it lol

from minekhan.

 avatar commented on July 29, 2024

Checking the script's length is shorter and a little bit cleaner than checking functions length, I believe.

It's that both methods are really hacky and liable to faults.

Sadly document.referrer broke in Chrome 85...

Dang; Chrome using sensible defaults and protecting user privacy. lol, but there is probably a better way, I'll see how I've dealt with situations like this before.

from minekhan.

 avatar commented on July 29, 2024

(Since we're really just using this issue as a general chat about MineKhan)

	To-Do:
 * A lot. Check out the GitHub repo if you'd like to collaborate on this. Must use Discord.

Sorry, I'm not a Discord user, but could you give part of what you have planned for this app?

from minekhan.

Phi-001 avatar Phi-001 commented on July 29, 2024

=== Bugs ===

  • Able to run up slabs that you can't fit through
  • Hitbox indicator has extra lines on stairs
  • Can't place bottom slabs under yourself while standing on them
  • Can place full blocks under yourself while between Y7 and Y15 due to rounding errors
  • Can sneak under a 1.5 block section, then unsneak to xray
  • Arrow keys cause the page to scroll
  • Stairs and slabs still sometimes cause incorrect culling, as can be seen in this guy's world https://www.khanacademy.org/computer-programming/world/4841711753183232

=== Menu ===

  • Controls menu

=== Blocks ===

  • Add uniform for switching between opaque and transparent mode
  • Add second render pass for semi-transparent blocks
  • Add support for animated textures
  • Add support for blocks with no collision hitbox
  • Add torches and jack o lanterns

=== Lighting ===

  • Add sky lighting
  • Add block lighting

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Err that's my short term to-do list anyway. Long term plans are basically just "make it more like Minecraft."

from minekhan.

 avatar commented on July 29, 2024

...basically just "make it more like Minecraft."

Well for one, Minecraft has online multiplayer, and online multiplayer requires a server... you know where I'm going with that.

Add uniform for switching between opaque and transparent mode
Add second render pass for semi-transparent blocks

What blocks are semi-transparent? Slime blocks come to mind, would they classify as such?

Arrow keys cause the page to scroll

I have not observed this. How can I reproduce?

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

If I was going to do multiplayer, I would have the world hosted on 1 of the clients, and just use the server for redirecting packets. But there's a ton to do before that would even be reasonable to start on. Especially since I have absolutely no intention of spending money on a dedicated server for this.

Water is the big one. Stained glass is the other one. Slime and honey blocks too I guess, but I have no plans to add those 2 until I start working on redstone.

The scroll thing only happens in non-full screen environments, such as on KA. It's a simple fix though. Just have to cancel the key events for arrow keys (I'm already doing it for the space key). Most people just use their mouse to look around, so it's not super high priority.

from minekhan.

 avatar commented on July 29, 2024

Especially since I have absolutely no intention of spending money on a dedicated server for this.

Well, you claim to know Node.js... these two places are good starts:

Water is the big one. Stained glass is the other one.

I forgot these existed, lol.

The scroll thing only happens in non-full screen environments, such as on KA. It's a simple fix though. Just have to cancel the key events for arrow keys (I'm already doing it for the space key). Most people just use their mouse to look around, so it's not super high priority.

Easy fix though, I'll go do it right now.

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Yeah normally I use Heroku for my back-end web apps, but the free version isn't very reliable for persistent websocket connections, as I discovered from my last project. I'll try out repl.it next time that's a project requirement.

from minekhan.

InterestingBrainPoops avatar InterestingBrainPoops commented on July 29, 2024

If you can create a aws account then you get a year free of a t2.micro instance. Ive done that for some of my more useful projects.

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Oh neat. Well I have a server and a domain now that I could use. https://willard.fun (the server is courtesy of a friend on Discord). Either way, multiplayer isn't something I'm interested in pursuing at the moment. Though I'm thinking of including some form of world sharing support. Something like, people submit a world to the public, then it goes into a big list of online worlds that people can view, maybe with a url to share the link to it.

from minekhan.

InterestingBrainPoops avatar InterestingBrainPoops commented on July 29, 2024

Something that has a route that accepts POST requests and then updates a list of links?

from minekhan.

 avatar commented on July 29, 2024

Unrelated to the recent server ideas, I'd been helping someone out with some Perlin Noise algorithms in JavaScript, I compared what they had to what is used here as a reference, and realized that both can be much simpler.

MineKhan/Minecwaft.html

Lines 975 to 989 in dc6f223

// fill 0x0..0x100
for (let i = 0; i < 0x100; ++i) {
perm[i] = i;
}
for (let i = 0; i < 0x100; ++i) {
const j = rnd.nextInt() & 0xFF;
const t = perm[j];
perm[j] = perm[i];
perm[i] = t;
}
// copy to avoid taking mod in perm[0]
// copies from first half of array, into the second half
perm.copyWithin(0x100, 0x0, 0x100);

Currently, the permutation generation used rnd.nextInt() to generate random numbers, but if it doesn't matter which algorithm the numbers are generated from, Crypto#getRandomValues can be used to do the same thing.

I think it would be equivalent to using this:

const perm = new Uint8Array(0x200);

// fill first half with randomized values
crypto.getRandomValues( perm.subarray(0x0, 0x100) );

// copy first half into second half
perm.copyWithin(0x100);

I have no clue what the swapping loop was for in the original.

from minekhan.

InterestingBrainPoops avatar InterestingBrainPoops commented on July 29, 2024

The swapping was probably a randomizer, so if you have something that can output to the datastructure without swapping, then I think thats a much less computationally expensive solution. Go ahead! @00ff0000red

from minekhan.

Willard21 avatar Willard21 commented on July 29, 2024

Worlds have seeds. When a world is generated with the same seed, it has to produce exactly the same output. World saves only save the difference from the originally generated world, so if the world is generated in a different way, your build is basically ruined.

I don't mind if you want to change the algorithm, but you can't do anything that can't be reproduced exactly the same way next time.

from minekhan.

 avatar commented on July 29, 2024

Ahh, I see thanks; that explains the current algorithm. Seeds, I almost forgot about those. Minecraft allows sharing seeds and has reproducable worlds via seeding, so this wouldn't work here.

from minekhan.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.