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    2093

Draco18s

Draco18s    2093

  • Reality Controller
  • Draco18s
  • Members
  • 2093
  • 14027 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    2093

Draco18s

Draco18s    2093

  • Reality Controller
  • Draco18s
  • Members
  • 2093
  • 14027 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    2093

Draco18s

Draco18s    2093

  • Reality Controller
  • Draco18s
  • Members
  • 2093
  • 14027 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    2093

Draco18s

Draco18s    2093

  • Reality Controller
  • Draco18s
  • Members
  • 2093
  • 14027 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

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

      By DaemonUmbra · Posted 17 minutes ago

      Where are you looking in the launcher? I suspect you are looking at Profiles/Installations rather than Versions
    • Simon_kungen
      [1.14.4] Sync ItemStack Capability Data + Multi-Capability Provider casting error

      By Simon_kungen · Posted 27 minutes ago

      So yeah... looks like none of my questions has been answered lately. Should I give up on capabilities for now?
    • TheGreenSquarez
      Forge 28.1.10 won't show on launcher + 28.1.0 fails to work

      By TheGreenSquarez · Posted 1 hour ago

      here's the screenshot.
    • TheGreenSquarez
      Forge 28.1.10 won't show on launcher + 28.1.0 fails to work

      By TheGreenSquarez · Posted 1 hour ago

      I'm quite sure it just updated to the latest version.
    • DragonITA
      [1.14.4] How to get Minecraft Horse model/texture to make a custom unicorn?

      By DragonITA · Posted 1 hour ago

      Ok, i want try Something, pls wait.
  • Topics

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

      By TheGreenSquarez
      Started Yesterday at 11:21 AM

    • Simon_kungen
      1
      [1.14.4] Sync ItemStack Capability Data + Multi-Capability Provider casting error

      By Simon_kungen
      Started 23 hours ago

    • DragonITA
      33
      [1.14.4] How to get Minecraft Horse model/texture to make a custom unicorn?

      By DragonITA
      Started Monday at 10:06 AM

    • jun2040
      1
      Game crashing when the block is activated

      By jun2040
      Started 2 hours ago

    • Prasodym
      7
      produces unregistered item minecraft:wooden_door

      By Prasodym
      Started April 28

  • Who's Online (See full list)

    • ShyAlpha22
    • Legenes
    • Simon_kungen
    • DaemonUmbra
    • Cerandior
  • 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