MineKhan icon indicating copy to clipboard operation
MineKhan copied to clipboard

MineKhan Modders Wiki ! (MMW)

Open SnehasishCodez opened this issue 3 years ago • 29 comments

Here you can post step-by-step instructions on how to add new blocks to MineKhan or new items to MineKhan , how to work around the hundred of lines of code that MineKhan runs on.

Possible Questions: 1.How to add new blocks 2.How to mess round with the lighting / where. 3.How to style buttons in the code or which lines you should look around the edit. And Plenty More!

SnehasishCodez avatar May 04 '21 19:05 SnehasishCodez

How to Make new blocks, although it can take a bit of time. Here are instructions:

  1. Get the image for the block. For the blocks, googled the block name "steve minecraft face" and "pig minecraft face" or whatever you are looking for. If you have Minecraft, for blocks that are in the game you can go to the .jar folder and open the textures/blocks for the images. (DISCLAIMER: I don't actually know if that works, not having Minecraft myself, but Willard said that is where he got the textures so I'm trusting him :D )
  2. Size the image. Because the blocks are 16 by 16 px, the image that we use also needs to be 16x16px. Use a photo editor or something to rescale the image to 16x16px, and export it as a png.
  3. Convert the png to base64. I just googled "png to base64" and it provided a ton of great sites that you can upload your pictures to and get them converted to base64. The converted image will be a string of numbers and characters that you should copy.
  4. Convert the base64 to base36. For this, I used Willard's program that he actually created for making the MineKhan blocks: https://www.khanacademy.org/computer-programming/base64-png-to-base36-pixel-converter/6732846272692224 . Plug the base64 data string into the program code where it says, and it will provide a string of letters and numbers in the println. Copy this.
  5. Putting the new texture in. On MineKhan (v 0.6.1), the textures start on line 132. Scroll down through all the textures listed, until you get to the last one (currently polished granite.) Following the same format as the other textures, put your texture string in the end right after the polishedGranite. Give it a nice descriptive name (like smileyFace or lava).
  6. Listing the block. Now go down. Below where the textures are listed, starting on line 299, is the block data. Go down to the end (again, the last block should be polishedGranite) and follow the same format for listing as the other blocks. Make sure the name you put in the block data is the same thing you called your texture!
  7. Enjoy your block! At this point, the block should show up in your inventory. Create a new world or something and check it out!

Not all blocks work. If you look at my code (which I recommend doing to see examples of what I did), you will see a couple of block textures commented out, like creeperHead. Those textures don't work and break the program because they have too many unique colors and the encoder I use has a limit of 36 colors. Usually if the program isn't working, it's because you made a mistake in spelling or formatting.

made by 🍉 Sally the Great 🍉

Hacker1254 avatar May 04 '21 20:05 Hacker1254

You could also use this to make textures: https://www.khanacademy.org/computer-programming/minekhan-block-maker/6681656548605952/embedded?editor=no

ghost avatar May 20 '21 21:05 ghost

How To Add TNT Back:

  1. push ctrl+f
  2. type tnt
  3. push the down arrow until you see the line that says
// I swear, if y'all don't stop asking about TNT every 5 minutes!
  1. uncomment the lines below until they look like this:
{ 
    name: "tnt",
    textures: ["tntBottom", "tntTop", "tntSides"]
}
  1. there should now be TNT!

sauron65 avatar May 25 '21 19:05 sauron65

I know this may be an older issue, but I may start working on a mod loader for this. That way we can make adding stuff easy to add. I probably will make a fork if this gets open sourced under some permissive license (This version, the KA Version already is MIT)

MicrolemurDev avatar May 26 '21 15:05 MicrolemurDev

I find it real annoying that people are adding unexplodable tnt, so here is the code.

		{ // I swear, if y'all don't stop asking about TNT every 5 minutes!
		  name: "tnt",
		  textures: ["tntBottom", "tntTop", "tntSides"],
		  lightLevel: 15,
		  onclick: function(x,y,z){
			if(y>=30){
        explode(x,y,z,5)
			}
      }, 

Also, this in the hitbox.pos if ( you should put it inside the if (block) if tag)

let onclick = blockData[block].onclick
        if(onclick){
          if(!onclick(x, y, z)){p.lastPlace = Date.now(); return} //if it doesn't return true
        }

and

function explode(x,y,z, radius){
  world.setBlock(x,y,z,blockIds.air);
  for(var i=radius; i>0; i--){
    sphereoidAt(x,y,z,i,i,i, blockIds.air)
  }
}

at the end of the code..... as we know it.... and I feel fine.

ghost avatar May 26 '21 15:05 ghost

All it does is that it replaces blocks with air, once it's clicked.

ghost avatar May 26 '21 15:05 ghost

And if there is anyone that doesn't understand this, just contact me.

ghost avatar May 26 '21 15:05 ghost

I find it real annoying that people are adding unexplodable tnt, so here is the code.

		{ // I swear, if y'all don't stop asking about TNT every 5 minutes!
		  name: "tnt",
		  textures: ["tntBottom", "tntTop", "tntSides"],
		  lightLevel: 15,
		  onclick: function(x,y,z){
			if(y>=30){
        explode(x,y,z,5)
			}
      }, 

Also, this in the hitbox.pos if ( you should put it inside the if (block) if tag)

let onclick = blockData[block].onclick
        if(onclick){
          if(!onclick(x, y, z)){p.lastPlace = Date.now(); return} //if it doesn't return true
        }

and

function explode(x,y,z, radius){
  world.setBlock(x,y,z,blockIds.air);
  for(var i=radius; i>0; i--){
    sphereoidAt(x,y,z,i,i,i, blockIds.air)
  }
}

at the end of the code..... as we know it.... and I feel fine.

That code looks like my code. If you use that explode function, you also need this at the end of the code:

function sphereoidAt(X,Y,Z,w, h, d, id) {
  let w2 = w * w
  let h2 = h * h
  let d2 = d * d
  let w3 = (w - 1.5) * (w - 1.5)
  let h3 = (h - 1.5) * (h - 1.5)
  let d3 = (d - 1.5) * (d - 1.5)
  for (let y = -h; y < h; y++) {
    for (let x = -w; x <= w; x++) {
      for (let z = -d; z <= d; z++) {
        let n = x * x / w2 + y * y / h2 + z * z / d2
        let n2 = x * x / w3 + y * y / h3 + z * z / d3
        if (n < 1 && n2 >= 1) {
          world.setBlock(X + x, Y + y, Z + z, id)
        }
      }
    }
  }
}

ghost avatar May 26 '21 17:05 ghost

@GuineaPigBridge

Also, this in the hitbox.pos if ( you should put it inside the if (block) if tag)

what do you mean by that?

sauron65 avatar May 26 '21 22:05 sauron65

It's just the friggin place you put the code in.

ghost avatar May 27 '21 12:05 ghost

How to add new block shapes (beds, torches, plants, etc...)

We will be using plant shape for this tutorial 1. First you need the block shape plant:

{
			verts: [
				[objectify(8, 0, 8, 1, 1, 0, 0)], //bottom
				[objectify(8, 16, 8, 1, 1, 0, 0)], //top
				[objectify(16, 16, 8, 16, 16, 0, 0)], //north
				[objectify(0, 16, 8, 16, 16, 0, 0)], //south
				[objectify(8, 16, 0, 16, 16, 0, 0)], //east
				[objectify(8, 16, 16, 16, 16, 0, 0)]  //west
			],
			cull: {
				top: 0,
				bottom: 0,
				north: 0,
				south: 0,
				east: 0,
				west: 0
			},
			texVerts: [],
			varients: [],
			buffer: null,
			size: 6,
		},

2. Next, you add it to the shapes object Press ctrl + f and type "shapes = " add the plant shape object to the shapes object

let shapes = {
	//other shapes
	plant: {
		verts: [
			[objectify(8, 0, 8, 1, 1, 0, 0)], //bottom
			[objectify(8, 16, 8, 1, 1, 0, 0)], //top
			[objectify(16, 16, 8, 16, 16, 0, 0)], //north
			[objectify(0, 16, 8, 16, 16, 0, 0)], //south
			[objectify(8, 16, 0, 16, 16, 0, 0)], //east
			[objectify(8, 16, 16, 16, 16, 0, 0)]  //west
		],
		cull: {
			top: 0,
			bottom: 0,
			north: 0,
			south: 0,
			east: 0,
			west: 0
		},
		texVerts: [],
		varients: [],
		buffer: null,
		size: 6,
	},
}

3. Block constant Search for "const cube" You will find the constants. Add const PLANT = 0x300

	const CUBE      = 0
	const SLAB      = 0x100 // 9th bit
	const STAIR     = 0x200 // 10th bit
	const PLANT     = 0x300

4. Initializing the shape Search for "let baseBlock" add these:

			let baseBlock = blockData[i]
			let slabBlock = Object.create(baseBlock)
			let stairBlock = Object.create(baseBlock)
			let plantBlock = Object.create(baseBlock) //add this
			baseBlock.shape = shapes.cube
			slabBlock.shape = shapes.slab
			stairBlock.shape = shapes.stair
			plantBlock.shape = shapes.plant //add this
			blockData[i | SLAB] = slabBlock
			blockData[i | STAIR] = stairBlock
			blockData[i | PLANT] = plantBlock //add this

5. Add plant block shape option Search for "if(k === "enter")" Add this: (blockMode === STAIR ? PLANT : CUBE)

		if (k === "enter") {
			blockMode = blockMode === CUBE ? SLAB : (blockMode === SLAB ? STAIR : (blockMode === STAIR ? PLANT : CUBE))
			updateHUD = true
		}

6. Block icon Search for "function genIcons" Add this to the function (it uses the cube icon):

			data = []
			for (let j = 11; j >= 0; j--) {
				data.push(-hexagonVerts[j * 3 + 0] * scale)
				data.push(hexagonVerts[j * 3 + 1] * scale)
				data.push(0.1666666)
				data.push(textureCoords[textureMap[block.textures[texOrder[floor(j / 4)]]]][(j * 2 + 0) % 8])
				data.push(textureCoords[textureMap[block.textures[texOrder[floor(j / 4)]]]][(j * 2 + 1) % 8])
				data.push(shadows[floor(j / 4)])
			}
			buffer = gl.createBuffer()
			gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW)
			blockIcons[i | PLANT] = buffer
			blockIcons.lengths[i | PLANT] = 6 * 3

And now you have a new block shape!

ghost avatar May 27 '21 20:05 ghost

If you dont want to make your own block shapes, go here: https://khanacademy.org/profile/monsterred/projects EDIT: you also need to click "Recent", its at "Recent Top <--"

ghost avatar May 27 '21 20:05 ghost

function sphereoidAt(X,Y,Z,w, h, d, id) {
  let w2 = w * w
  let h2 = h * h
  let d2 = d * d
  let w3 = (w - 1.5) * (w - 1.5)
  let h3 = (h - 1.5) * (h - 1.5)
  let d3 = (d - 1.5) * (d - 1.5)
  for (let y = -h; y < h; y++) {
    for (let x = -w; x <= w; x++) {
      for (let z = -d; z <= d; z++) {
        let n = x * x / w2 + y * y / h2 + z * z / d2
        let n2 = x * x / w3 + y * y / h3 + z * z / d3
        if (n < 1 && n2 >= 1) {
          world.setBlock(X + x, Y + y, Z + z, id)
        }
      }
    }
  }
}

This was already in the code at the bottom. I just presumed that you took out the // when you downloaded minekhan.

ghost avatar May 29 '21 07:05 ghost

The version that was already in the code used p2.x, p2.y, p2.z for the X, Y, Z since I was using it from the dev console while I played. It doesn't work in multiplayer unless you're the host (thanks to a bug, but it's for the best lol). Personally if I was going to add it as an actual mechanic, I'd use the more efficient carveSphere() method, which is what I use for carving out caves in a "tube" shape.

Willard21 avatar May 29 '21 13:05 Willard21

i'm actually quite familiar with modding MineKhan, check out my latest mod it shows new block implementation, and includes several of my new block shapes, and also shows playing with lighting (although night/day cycle is messed up, so i turned it off)

RedMonster2 avatar Jun 03 '21 04:06 RedMonster2

I mean, it looks amazing. Just the block icons are messed up a bit. But still. Pretty good.

MicrolemurDev avatar Jun 03 '21 15:06 MicrolemurDev

yeah i know the icons are messed up, it would be nice if the icons were presented by the actual block shapes, rather than making a whole new model for it that works on completely different rules. so for now i just do random shapes and try to remember what is what (i'm looking at adding auto shape change, so when you place a lantern, even if your on cube, it will place the correct shape). oh, and thank you for the compliments

RedMonster2 avatar Jun 03 '21 18:06 RedMonster2

@Hacker1254

How to Make new blocks, although it can take a bit of time. Here are instructions:

  1. Get the image for the block. For the blocks, googled the block name "steve minecraft face" and "pig minecraft face" or whatever you are looking for. If you have Minecraft, for blocks that are in the game you can go to the .jar folder and open the textures/blocks for the images. (DISCLAIMER: I don't actually know if that works, not having Minecraft myself, but Willard said that is where he got the textures so I'm trusting him :D )
  2. Size the image. Because the blocks are 16 by 16 px, the image that we use also needs to be 16x16px. Use a photo editor or something to rescale the image to 16x16px, and export it as a png.
  3. Convert the png to base64. I just googled "png to base64" and it provided a ton of great sites that you can upload your pictures to and get them converted to base64. The converted image will be a string of numbers and characters that you should copy.
  4. Convert the base64 to base36. For this, I used Willard's program that he actually created for making the MineKhan blocks: https://www.khanacademy.org/computer-programming/base64-png-to-base36-pixel-converter/6732846272692224 . Plug the base64 data string into the program code where it says, and it will provide a string of letters and numbers in the println. Copy this.
  5. Putting the new texture in. On MineKhan (v 0.6.1), the textures start on line 132. Scroll down through all the textures listed, until you get to the last one (currently polished granite.) Following the same format as the other textures, put your texture string in the end right after the polishedGranite. Give it a nice descriptive name (like smileyFace or lava).
  6. Listing the block. Now go down. Below where the textures are listed, starting on line 299, is the block data. Go down to the end (again, the last block should be polishedGranite) and follow the same format for listing as the other blocks. Make sure the name you put in the block data is the same thing you called your texture!
  7. Enjoy your block! At this point, the block should show up in your inventory. Create a new world or something and check it out!

Not all blocks work. If you look at my code (which I recommend doing to see examples of what I did), you will see a couple of block textures commented out, like creeperHead. Those textures don't work and break the program because they have too many unique colors and the encoder I use has a limit of 36 colors. Usually if the program isn't working, it's because you made a mistake in spelling or formatting.

made by 🍉 Sally the Great 🍉

if you don't have minecraft, the easiest way to get the textures is to go here: https://github.com/InventivetalentDev/minecraft-assets and click branches then click the latest version of minecraft (1.17.1 as of Wednesday, September 15, 2021) to get the texture string in bas256 (MineKhan now uses base256 on willard.fun) and more easily go to https://willard.fun/minekhan/textures

sauron65 avatar Jun 11 '21 19:06 sauron65

How to make broken saves work again

Go to Chunk.load (above "class Contacts") and you will see this:

load() {
	let chunkX = this.x >> 4
	let chunkZ = this.z >> 4
	let load = null
	
	for (let i = 0; i < world.loadFrom.length; i++) {
		load = world.loadFrom[i]
		if (load.x === chunkX && load.z === chunkZ) {
			let y = load.y * 16
			for (let j in load.blocks) {
				world.setBlock((j >> 8 & 15) + this.x, (j >> 4 & 15) + y, (j & 15) + this.z, load.blocks[j])
			}
			world.loadFrom.splice(i--, 1)
		}
	}
	this.loaded = true
}

Just change it to this:

load() {
	let chunkX = this.x >> 4
	let chunkZ = this.z >> 4
	let load = null
	
	for (let i = 0; i < world.loadFrom.length; i++) {
		load = world.loadFrom[i]
		if (load.x === chunkX && load.z === chunkZ) {
			let y = load.y * 16
			for (let j in load.blocks) {
				if(blockData[load.blocks[j]]){ // if a block doesn't exsist, they won't be generated
					world.setBlock((j >> 8 & 15) + this.x, (j >> 4 & 15) + y, (j & 15) + this.z, load.blocks[j])
				}
			}
			world.loadFrom.splice(i--, 1)
		}
	}
	this.loaded = true
}

And know if you load the broken save, it works!

ghost avatar Jun 18 '21 21:06 ghost

Can someone help with this? I added a scaffold hack, except it constantly places blocks in the wrong spot (usually a block too far either left or right), leading you to fall. image

AppleBob avatar Oct 05 '21 00:10 AppleBob

Use p2 instead of p

if(p.scaffold){
  if(!world.getBlock(p2.x,p2.y-2,p2.z)){
    world.setBlock(p2.x,p2.y-2,p2.z, holding)
  }
}

ghost avatar Oct 05 '21 00:10 ghost

tysm, that fixed it

AppleBob avatar Oct 07 '21 03:10 AppleBob

wait however, you now move super fast when sneaking, and scaffold is on

AppleBob avatar Oct 07 '21 03:10 AppleBob

nvm, I found the error

AppleBob avatar Oct 08 '21 01:10 AppleBob

haha missing texture go brrrrr 0g0g2000006o1jkw9o01111111100000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000000000000111111110000000011111111000000001111111100000000111111110000000011111111000000001111111100000000111111110000000011111111

ImaginaryNeon avatar Oct 23 '21 14:10 ImaginaryNeon

There is also a wiki at: https://github.com/Willard21/MineKhan/wiki/Modding

ghost avatar Dec 01 '21 02:12 ghost

how do i add vegitation to minekhan and im using the old khan academy code in notepad to make my mods please help and i need working doors

runbobfun1 avatar Feb 18 '22 17:02 runbobfun1

Plants have been added by many mods but doors are more complex as they require you to have "states" for the block and custom models. You can try, but it would probably be pretty complex.

MicrolemurDev avatar Feb 24 '22 14:02 MicrolemurDev

How To Add TNT Back:

1. push ctrl+f

2. type tnt

3. push the down arrow until you see the line that says
// I swear, if y'all don't stop asking about TNT every 5 minutes!
4. uncomment the lines below until they look like this:
{ 
    name: "tnt",
    textures: ["tntBottom", "tntTop", "tntSides"]
}
5. there should now be TNT!

the good thing about that is that if you try and understand the object literals you can learn to make custom blocks yourself

harsha7addanki avatar Apr 15 '23 12:04 harsha7addanki