Comments (44)
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 void
s 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.
GLSL has an interpolating function called mix
.
from minekhan.
...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.
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.
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.
If you really want to know everything about GLSL.
from minekhan.
That is the spec, specs are for implementation, not learning the language.
from minekhan.
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.
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
andconst
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.
[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.
...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.
...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.
I guess.
from minekhan.
@Willard21 Can I get a response to #10 (comment), particularly the part about global let/const?
from minekhan.
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.
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.
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.
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.
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.
I think you can add another script that gets the code and checks the length with document.getElementByID
.
from minekhan.
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.
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.
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.
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.
Sounds like some simple compression algorithm can help.
from minekhan.
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.
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.
Checking the script's length is shorter and a little bit cleaner than checking functions length, I believe.
from minekhan.
Sadly document.referrer
broke in Chrome 85, which was unfortunate since that was like, a week after I started using it lol
from minekhan.
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.
(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.
=== 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.
Err that's my short term to-do list anyway. Long term plans are basically just "make it more like Minecraft."
from minekhan.
...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.
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.
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.
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.
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.
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.
Something that has a route that accepts POST requests and then updates a list of links?
from minekhan.
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.
Lines 975 to 989 in dc6f223
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.
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.
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.
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)
- [Question] Web Hosting HOT 2
- Backspace bug HOT 6
- How to fix lighting bug HOT 2
- Generation issue HOT 3
- The Far Lands??? HOT 2
- Suggestion: Better UI HOT 7
- Texture encoding HOT 5
- Iframes No Work HOT 1
- Mods(maybe i can create them?) HOT 1
- Armor NOW HOT 3
- A MOD adding music feature to the game, and a few useful commands HOT 1
- Website not updated to most recent version HOT 1
- hii HOT 3
- Banned from multiplayer HOT 1
- "Real Willard" HOT 1
- MineKhan Wiki! HOT 7
- Suggestion: 3rd Person View (edit: oops this already exists sorry) HOT 2
- Lighting Bug HOT 1
- How to know if banned HOT 2
- Banning question HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from minekhan.