Jump to content
  • Home
  • Files
  • Docs
  • Merch
Topics
  • All Content

  • This Topic
  • This Forum

  • Advanced Search
  • Existing user? Sign In  

    Sign In



    • Not recommended on shared computers


    • Forgot your password?

  • Sign Up
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • [1.12.2] Replace world renderer
1.13 Update Notes for Mod Creators
Sign in to follow this  
Followers 1
Cadiboo

[1.12.2] Replace world renderer

By Cadiboo, September 21, 2018 in Modder Support

  • Reply to this topic
  • Start new topic
  • Prev
  • 1
  • 2
  • Next
  • Page 1 of 2  

Recommended Posts

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 21, 2018

I'm trying to recreate no-cubes for 1.12.2. How should I go about replacing the world renderer?

I see in these classes in CosmicDan's re-implementation use a core-mod (2 IClassTransformers and an IFMLLoadingPlugin).

Spoiler

BlockTweakInjector.java

Spoiler


package com.cosmicdan.nocubes.core;

import java.util.ListIterator;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;

import com.cosmicdan.nocubes.Main;

/*
 * Original by Click_Me
 * Reverse-engineered and re-implemented (with permission) by CosmicDan
 * 
 */
public class BlockTweakInjector implements IClassTransformer {
       public byte[] transform(String name, String transformedName, byte[] bytes) {
              if(bytes == null) {
                 return null;
              } else if(!"net.minecraft.block.Block".equals(name)) {
                 return bytes;
              } else {
                 ClassNode classNode = new ClassNode();
                 ClassReader classReader = new ClassReader(bytes);
                 classReader.accept(classNode, 8);
                 MethodNode targetMethod = null;

                 for(MethodNode methodNode : classNode.methods) {
                    if(methodNode.name.equals("shouldSideBeRendered") && methodNode.desc.equals("(Lnet/minecraft/world/IBlockAccess;IIII)Z")) {
                       targetMethod = methodNode;
                       break;
                    }
                 }

                 if(targetMethod == null) {
                    return bytes;
                 } else {
                    //Main.LOGGER.warn("~~~ Inside the Block class: " + name);
                    MethodNode injectedMethod = new MethodNode();
                    ListIterator iterator = targetMethod.instructions.iterator();
                    int varCount = 0;

                    while(iterator.hasNext()) {
                       AbstractInsnNode instruction = (AbstractInsnNode)iterator.next();
                       
                       if(instruction.getOpcode() == 165) {
                          JumpInsnNode jumpInsnNode = (JumpInsnNode)instruction;
                          targetMethod.instructions.insert(instruction, new JumpInsnNode(154, jumpInsnNode.label));
                          targetMethod.instructions.insert(instruction, new MethodInsnNode(184, "com/cosmicdan/nocubes/Main", "shouldSmooth", "(Lnet/minecraft/block/Block;)Z"));
                          targetMethod.instructions.insert(instruction, new VarInsnNode(25, 24));
                          //Main.LOGGER.warn("~~~ Inserted instructions extra check");
                       }
                       

                       if(instruction.getOpcode() == 21) {
                          VarInsnNode varInsnNode = (VarInsnNode)instruction;
                          if(varInsnNode.var == 19) {
                             ++varCount;
                             if(varCount == 2) {
                                targetMethod.instructions.insertBefore(instruction, injectedMethod.instructions);
                                //Main.LOGGER.warn("~~~ Inserted instructions render hook");
                             }
                          }
                       }
                    }

                    ClassWriter writer = new ClassWriter(3);
                    classNode.accept(writer);
                    return writer.toByteArray();
                 }
              }
           }
        }

CorePlugin.java

Spoiler


package com.cosmicdan.nocubes.core;

import java.util.Map;

import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;

@IFMLLoadingPlugin.Name(value = "NoCubesCore")
@IFMLLoadingPlugin.MCVersion(value = "1.7.10")
@IFMLLoadingPlugin.TransformerExclusions(value = "com.cosmicdan.nocubes.")
@IFMLLoadingPlugin.SortingIndex(value = 1001) // How early your core mod is called - Use > 1000 to work with srg names
public class CorePlugin implements IFMLLoadingPlugin {
    @Override
    public String[] getASMTransformerClass() {
        return new String[]{
          WorldRenderInjector.class.getName(),
          BlockTweakInjector.class.getName()
        };
    }

    @Override
    public String getModContainerClass() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getSetupClass() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void injectData(Map<String, Object> data) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public String getAccessTransformerClass() {
        // TODO Auto-generated method stub
        return null;
    }
}

WorldRenderInjector.java

Spoiler


package com.cosmicdan.nocubes.core;

import java.util.ListIterator;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;

import com.cosmicdan.nocubes.Main;

/*
 * Original by Click_Me
 * Reverse-engineered and re-implemented (with permission) by CosmicDan
 * 
 */
public class WorldRenderInjector implements IClassTransformer {
   public byte[] transform(String name, String transformedName, byte[] bytes) {
      if(bytes == null) {
         return null;
      //} else if(!"blo".equals(name)) {
      } else if(!"net.minecraft.client.renderer.WorldRenderer".equals(name)) {
         return bytes;
      } else {
         ClassNode classNode = new ClassNode();
         ClassReader classReader = new ClassReader(bytes);
         classReader.accept(classNode, 8);
         MethodNode targetMethod = null;

         for(MethodNode methodNode : classNode.methods) {
            //if(methodNode.name.equals("a") && methodNode.desc.equals("(Lsv;)V")) {
            //if(methodNode.name.equals("func_147892_a") && methodNode.desc.equals("(Lnet/minecraft/entity/EntityLivingBase;)V")) {
            if(methodNode.name.equals("updateRenderer") && methodNode.desc.equals("(Lnet/minecraft/entity/EntityLivingBase;)V")) {
               targetMethod = methodNode;
               break;
            }
         }

         if(targetMethod == null) {
            return bytes;
         } else {
            //Main.LOGGER.warn("~~~ Inside the WorldRenderer class: " + name);
            MethodNode injectedMethod = new MethodNode();
            Label label0 = new Label();
            injectedMethod.visitLabel(label0);
            injectedMethod.visitVarInsn(21, 20);
            Label label1 = new Label();
            injectedMethod.visitJumpInsn(154, label1);
            Label label2 = new Label();
            injectedMethod.visitLabel(label2);
            injectedMethod.visitInsn(4);
            injectedMethod.visitVarInsn(54, 20);
            Label label3 = new Label();
            injectedMethod.visitLabel(label3);
            injectedMethod.visitVarInsn(25, 0);
            injectedMethod.visitVarInsn(21, 17);
            //injectedMethod.visitMethodInsn(183, "blo", "b", "(I)V");
            injectedMethod.visitMethodInsn(183, "net/minecraft/client/renderer/WorldRenderer", "preRenderBlocks", "(I)V");
            injectedMethod.visitLabel(label1);
            injectedMethod.visitFrame(2, 1, (Object[])null, 0, (Object[])null);
            injectedMethod.visitVarInsn(21, 19);
            injectedMethod.visitVarInsn(21, 17);
            injectedMethod.visitVarInsn(21, 2);
            injectedMethod.visitVarInsn(21, 3);
            injectedMethod.visitVarInsn(21, 4);
            injectedMethod.visitVarInsn(25, 15);
            injectedMethod.visitVarInsn(25, 16);
            injectedMethod.visitMethodInsn(184, "com/cosmicdan/nocubes/renderer/SurfaceNets", "renderChunk", "(IIIILnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/RenderBlocks;)Z");
            injectedMethod.visitInsn(128);
            injectedMethod.visitVarInsn(54, 19);
            ListIterator iterator = targetMethod.instructions.iterator();
            int varCount = 0;

            while(iterator.hasNext()) {
               AbstractInsnNode instruction = (AbstractInsnNode)iterator.next();
               if(instruction.getOpcode() == 165) {
                  JumpInsnNode jumpInsnNode = (JumpInsnNode)instruction;
                  targetMethod.instructions.insert(instruction, new JumpInsnNode(154, jumpInsnNode.label));
                  targetMethod.instructions.insert(instruction, new MethodInsnNode(184, "com/cosmicdan/nocubes/Main", "shouldSmooth", "(Lnet/minecraft/block/Block;)Z"));
                  targetMethod.instructions.insert(instruction, new VarInsnNode(25, 24));
                  //Main.LOGGER.warn("~~~~ Inserted instructions extra check");
               }

               if(instruction.getOpcode() == 21) {
                  VarInsnNode varInsnNode = (VarInsnNode)instruction;
                  if(varInsnNode.var == 19) {
                     ++varCount;
                     if(varCount == 2) {
                        targetMethod.instructions.insertBefore(instruction, injectedMethod.instructions);
                        //Main.LOGGER.warn("~~~ Inserted instructions render hook");
                     }
                  }
               }
            }

            ClassWriter writer = new ClassWriter(3);
            classNode.accept(writer);
            return writer.toByteArray();
         }
      }
   }
}

 

I don't know anything about ASM, and I've heard its a massive pain. Would I be able to do this with reflection (or even better with registry events, though I don't think this is possible).

I just want to get a working world renderer (my one one) that works exactly like vanilla before trying to do anything with block smoothing.

  • Quote

Share this post


Link to post
Share on other sites

Animefan8888    677

Animefan8888

Animefan8888    677

  • Reality Controller
  • Animefan8888
  • Forge Modder
  • 677
  • 5746 posts
Posted September 21, 2018
1 hour ago, Cadiboo said:

I don't know anything about ASM, and I've heard its a massive pain. Would I be able to do this with reflection (or even better with registry events, though I don't think this is possible). 

To be honest with you, ASM might be easier, but I believe that it can be done with reflection. The world renderers(BufferBuilder instances) are stored in an instance of RegionRenderCacheBuilder within an array that is mapped to BlockRenderLayer(its an enum). Which are then stored in ChunkRenderWorker and ChunkCompileTaskGenerator. The former is stored in ChunkRenderDispatcher, and I believe this is where it is mainly stored. Not sure where you can/should access these with reflection. The instance of ChunkRenderDispatcher is stored in RenderGlobal, which has a public instance in the Minecraft class.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 21, 2018

I want to do it without a core-mod for increased compatibility (haha its changing the entire rendering engine) and so that I don't have to use ASM. Can you explain in detail how the renderer works or tell me somewhere that does? As I understand it every time a block state in a chunk (16x16x16) is changed the renderer builds 1 big thing that can be passed directly to the GPU out of all the baked models in the chunk & caches this thing until a block state changes again. How it does any of this I have no idea.

  • Quote

Share this post


Link to post
Share on other sites

Animefan8888    677

Animefan8888

Animefan8888    677

  • Reality Controller
  • Animefan8888
  • Forge Modder
  • 677
  • 5746 posts
Posted September 21, 2018
4 minutes ago, Cadiboo said:

I want to do it without a core-mod for increased compatibility (haha its changing the entire rendering engine) and so that I don't have to use ASM. Can you explain in detail how the renderer works or tell me somewhere that does? As I understand it every time a block state in a chunk (16x16x16) is changed the renderer builds 1 big thing that can be passed directly to the GPU out of all the baked models in the chunk & caches this thing until a block state changes again. How it does any of this I have no idea.

I don't believe you will have to worry about when it is rebuilt, but I can't quite tell you how it works as I have not even looked at this. Though I believe you will just need to handle the building aspect of the rendering. The "one thing" that is passed to the GPU is just all of the vertex data, texture ids, texture uv mappings, etc. But it is done in mass to reduce the amount of times it has to do this.

  • Quote

Share this post


Link to post
Share on other sites

jabelar    591

jabelar

jabelar    591

  • Reality Controller
  • jabelar
  • Members
  • 591
  • 3266 posts
Posted September 21, 2018

No offense but it is kinda weird to be aiming to "replace the world renderer" and then asking questions about what the renderer even does...seems a bit ambitious versus your understanding.

 

What are you trying to accomplish specifically? There are a lot of render events to hook into, plus as mentioned it is possible to use combination of public instance fields and reflection to actually replace things (could just replace the RenderGlobal I guess). But it is a "big hammer" to apply.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 21, 2018 (edited)

This is what I'm trying to achieve.

maxresdefault.jpg

@jabelar No offence taken, this is a pretty big project and I'm out of my depth.

In 1.7 (which is the MC version the old mod was ported to (not written for - theres a good story there)) there was an actual WorldRender class that was modified with ASM (I think, as I've said I've never used ASM, but that looks like what I expect it to be)

Edited September 21, 2018 by Cadiboo
  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 21, 2018 (edited)

Oh and another thing I don't want to just change the graphics I also want to make the all the blocks (collision at least) bounding boxes change with the terrain, but this should be much easier than the graphics. (Once I've learned the ASM I'll need to edit wherever block#addCollsionBoundingBoxesToList is called)

Edited September 21, 2018 by Cadiboo
  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018
On 9/22/2018 at 1:23 AM, Animefan8888 said:

To be honest with you, ASM might be easier, but I believe that it can be done with reflection. The world renderers(BufferBuilder instances) are stored in an instance of RegionRenderCacheBuilder within an array that is mapped to BlockRenderLayer(its an enum). Which are then stored in ChunkRenderWorker and ChunkCompileTaskGenerator. The former is stored in ChunkRenderDispatcher, and I believe this is where it is mainly stored. Not sure where you can/should access these with reflection. The instance of ChunkRenderDispatcher is stored in RenderGlobal, which has a public instance in the Minecraft class.

I’ve never used ASM before and only used really basic reflection, could you provide any examples of code that modifies a vanilla field / replaces vanilla code? I just need to replace whatever renders blocks as squares (with their models)

  • Quote

Share this post


Link to post
Share on other sites

Draco18s    2096

Draco18s

Draco18s    2096

  • Reality Controller
  • Draco18s
  • Members
  • 2096
  • 14031 posts
Posted September 25, 2018

Please do not instruct how to use ASM on the forums. Doing ASM wrong leaves your code fragile and prone to breaking unexpectedly, especially when other mods get involved, and when Minecraft crashes there will be no evidence that its YOUR code that caused the problem.

 

If you do not know how to use ASM already, then you should not be using ASM.

  • Like 1
  • Thanks 1
  • Quote

Share this post


Link to post
Share on other sites

Animefan8888    677

Animefan8888

Animefan8888    677

  • Reality Controller
  • Animefan8888
  • Forge Modder
  • 677
  • 5746 posts
Posted September 25, 2018 (edited)
1 hour ago, Cadiboo said:

I’ve never used ASM before and only used really basic reflection, could you provide any examples of code that modifies a vanilla field / replaces vanilla code? I just need to replace whatever renders blocks as squares (with their models)

I agree with draco18s, so to tell you how to do the reflection part, ReflectionHelper has a setField or setValue. No replacing vanilla code just the instance that houses it.

Edited September 25, 2018 by Animefan8888
  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018
17 minutes ago, Draco18s said:

If you do not know how to use ASM already, then you should not be using ASM.

So as a programmer, I should never learn ASM even when writing other applications as I should never have to use it if I’m writing decent code?

 

10 minutes ago, Animefan8888 said:

to tell you how to do the reflection part, ReflectionHelper has a setField or setValue.

I’ve used such methods before for small replacements in ItemRendering & similar stuff, I was looking for an open source mod (off the top of anyone’s head) that overwrites some large part of vanilla’s code while still maintaining compatibility with other mods and using good code practices. (I realise that there might not be any mods that meet these requirements)

 

13 minutes ago, Animefan8888 said:

No replacing vanilla code just the instance that houses it.

I assume I’m going to have to make my own chunkRenderDispatcher (and build all the rendering from the ground up), replace the instance stored in RenderGlobal as you said, and make an API for mod interoperability. 

 

My first priority is just replacing the renderer so I can start testing.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018

I was massively overthinking this aha, thanks so much @jabelar for your comment on some old thread that I was reading for no reason about how Minecraft.renderGlobal is public.

What I've done is massively overkill but I've just made a new RenderGlobal called ModRenderGlobal that is an exact copy of RenderGlobal (with all the methods and variables changed to public). I also had to make a copy of ViewFrustum because of it having a package method required by my RenderGlobal.

Here is my final code

@EventHandler
public void init(final FMLInitializationEvent event) {
	try {
		Minecraft.getMinecraft().renderGlobal = new ModRenderGlobal(Minecraft.getMinecraft());
		LOGGER.info("Successfully replaced Minecraft's RenderGlobal");
	} catch (final Throwable throwable) {
		LOGGER.error("Failed to replace Minecraft's RenderGlobal");
		// This should only happen rarely (never honestly) - so printing the Stack Trace shoudn't spam any logs
		throwable.printStackTrace();
		// TODO: throw the throwable? Maybe, keep it commented out for now
		// throw throwable;
	}
}

Which can be reduced to

@EventHandler
public void init(final FMLInitializationEvent event) {
	Minecraft.getMinecraft().renderGlobal = new ModRenderGlobal(Minecraft.getMinecraft());
}

And here is the final result - I'll probably post my results of the actual rendering here if I get it to work

1004207894_ScreenShot2018-09-25at4_06_37pm.thumb.png.2a6b394679f42c720087ce8fd5c7d056.png1771091692_ScreenShot2018-09-25at4_06_53pm.thumb.png.4d9cbebd9205b817be81685569696136.png

Thanks everyone for their help!

  • Like 1
  • Quote

Share this post


Link to post
Share on other sites

V0idWa1k3r    386

V0idWa1k3r

V0idWa1k3r    386

  • World Shaper
  • V0idWa1k3r
  • Members
  • 386
  • 1773 posts
Posted September 25, 2018

Unless you want your mod to be client-side only you can't do this

4 hours ago, Cadiboo said:

Minecraft.getMinecraft().renderGlobal = new ModRenderGlobal(Minecraft.getMinecraft());

in the FMLInitializationEvent.

And you do not want your mod to be client-only since you are planning to have dynamic collision boxes for your non-cubes. And the server needs to know about those.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018
12 minutes ago, V0idWa1k3r said:

Unless you want your mod to be client-side only you can't do this

in the FMLInitializationEvent.

And you do not want your mod to be client-only since you are planning to have dynamic collision boxes for your non-cubes. And the server needs to know about those.

Yeah, right now its client side only - I want to recreate the original NoCubes before I add any features. Obviously I'll change this once I start adding stuff. Thanks for pointing it out though!

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018

I've had to copy & paste pretty much the entirety of Minecraft's rendering code (10 11 12 classes so far) just to add 2 hooks (Events) in RenderGlobal & BlockRenderDispatcher which is exactly 5 lines of modified code, should I learn ASM or make a PR to forge?

  • Quote

Share this post


Link to post
Share on other sites

V0idWa1k3r    386

V0idWa1k3r

V0idWa1k3r    386

  • World Shaper
  • V0idWa1k3r
  • Members
  • 386
  • 1773 posts
Posted September 25, 2018

If you think that these events will be usefull in any other scenario for modmakers then make a PR. New usefull events are always welcome.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018
3 minutes ago, V0idWa1k3r said:

If you think that these events will be usefull in any other scenario for modmakers then make a PR. New usefull events are always welcome.

Do you think anyone else will ever want to change how a chunk renders?

  • Quote

Share this post


Link to post
Share on other sites

V0idWa1k3r    386

V0idWa1k3r

V0idWa1k3r    386

  • World Shaper
  • V0idWa1k3r
  • Members
  • 386
  • 1773 posts
Posted September 25, 2018

I am not sure. With custom BakedModels, resourcepacks and RenderWorldLast event it is not something I can easily make a case for. If you can think of any other use case apart from yours then go for a PR.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 25, 2018

I can see a use-case where someone wants to modify how terrain is rendered but not with the same rendering algorithm that I use. This is basically just a cancelable & block-exclusive version of RenderWorldLastEvent

  • Quote

Share this post


Link to post
Share on other sites

Draco18s    2096

Draco18s

Draco18s    2096

  • Reality Controller
  • Draco18s
  • Members
  • 2096
  • 14031 posts
Posted September 25, 2018
10 hours ago, Cadiboo said:

So as a programmer, I should never learn ASM even when writing other applications as I should never have to use it if I’m writing decent code?

ASM is java code that lets you modify java code while it's running. It's literally dangerous if not done correctly.

 

But in the vast majority of situations you ever find yourself in, ASM is not needed. The order of things to try first goes:

 

  1. Own code (extending, implementing)
  2. Events (handle existing hooks)
  3. Reflection (access private values)
  4. Making a PR to Forge to insert new events (and then doing #2)
  5. Not doing anything at all (stop touching it)
  6. Starting a new project (I said stop)
  7. ASM
  • Like 2
  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 26, 2018
9 hours ago, Draco18s said:

Starting a new project (I said stop)

I found this youtube clip https://www.youtube.com/watch?v=Yek5Fu1cX7I

9 hours ago, Draco18s said:

Making a PR to Forge to insert new events (and then doing #2)

I'm trying to do this, but it probably won't get accepted (The way about going about the actual rendering inside the event is very technical & not straight forward) hence my questions about ASM.

Also am I allowed change protected Vanilla Minecraft methods to public in a PR?

  • Quote

Share this post


Link to post
Share on other sites

Draco18s    2096

Draco18s

Draco18s    2096

  • Reality Controller
  • Draco18s
  • Members
  • 2096
  • 14031 posts
Posted September 26, 2018
51 minutes ago, Cadiboo said:
10 hours ago, Draco18s said:

Starting a new project (I said stop)

I found this youtube clip https://www.youtube.com/watch?v=Yek5Fu1cX7I

And? Not sure how that's relevant to what I said.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 26, 2018
1 minute ago, Draco18s said:

And? Not sure how that's relevant to what I said.

Its not exactly - If you watch the video its a clip of development of a game that uses Marching Cubes to make their voxel terrain render smoothly - Exactly the same thing as I'm doing to MC

  • Quote

Share this post


Link to post
Share on other sites

Draco18s    2096

Draco18s

Draco18s    2096

  • Reality Controller
  • Draco18s
  • Members
  • 2096
  • 14031 posts
Posted September 26, 2018

Great! That doesn't explain how they replaced the renderer.

  • Quote

Share this post


Link to post
Share on other sites

Cadiboo    277

Cadiboo

Cadiboo    277

  • Reality Controller
  • Cadiboo
  • Members
  • 277
  • 3303 posts
Posted September 26, 2018
5 hours ago, Draco18s said:

Great! That doesn't explain how they replaced the renderer.

They didn't. You said "Start a new project". Someone made their own game with their own renderer.

  • Haha 1
  • Quote

Share this post


Link to post
Share on other sites
  • Prev
  • 1
  • 2
  • Next
  • Page 1 of 2  

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Insert image from URL
×
  • Desktop
  • Tablet
  • Phone
Sign in to follow this  
Followers 1
Go To Topic Listing



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • AdieCraft
      Japanese Style Temple Base

      By AdieCraft · Posted 11 minutes ago

      Hello there!   Check out my latest tutorial in my Japanese Builds series, building a Japanese Temple base.   Make sure to Subscribe, so you don't miss any future videos.   Thanks   Adie   Japanese Style Temple Base    
    • DaemonUmbra
      Forge crashes on start

      By DaemonUmbra · Posted 51 minutes ago

      Forge for 1.13+ requires Java 8-10 Forge for 1.12.2- requires Java 8
    • GttiqwT
      [1.12.2] Multiple Structure Generation

      By GttiqwT · Posted 1 hour ago

      Yeah I get where you're coming from. I also watched harry talk's tutorial and at first it worked but then I got the problem that it wont spawn more than one structure otherwise it'll overlap and only spawn the latest one added. I tried to follow this tutorial again and it just didnt seem to work at all now. When I get more time ill have to do it again and then afterwards try and fix the issues with spawning more than one structure. I'm currently trying to fix the issue where it causes cascading gen lag but I dont know how to fix that quite yet either.
    • Draco18s
      Distinguish singleplayer vs. multiplayer

      By Draco18s · Posted 1 hour ago

      No. Your client code is sending information to make the server do things. Your server code is telling the server to do those same things (again).
    • solitone
      Distinguish singleplayer vs. multiplayer

      By solitone · Posted 1 hour ago

      This isn’t an issue but normal behaviour, is it?
  • Topics

    • AdieCraft
      0
      Japanese Style Temple Base

      By AdieCraft
      Started 11 minutes ago

    • bitman
      1
      Forge crashes on start

      By bitman
      Started 1 hour ago

    • Merthew
      7
      [1.12.2] Multiple Structure Generation

      By Merthew
      Started November 7, 2018

    • solitone
      24
      Distinguish singleplayer vs. multiplayer

      By solitone
      Started December 5

    • TheGreenSquarez
      5
      Forge 28.1.10 won't show on launcher + 28.1.0 fails to work

      By TheGreenSquarez
      Started Wednesday at 11:21 AM

  • Who's Online (See full list)

    • thinkverse
    • AdieCraft
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • [1.12.2] Replace world renderer
  • Theme
  • Contact Us
  • Discord

Copyright © 2019 ForgeDevelopment LLC · Ads by Curse Powered by Invision Community