Transcripts
1. Skillsahre into: Hello, I'm Nico caught me
on Master's student for computer science and an
avid Minecraft player. You might know me
from my YouTube channel tutorials by Cotton joe, where I am making microwave
modeling tutorials. Well now we're going to go
even bigger because this is my Minecraft modeling
118 class with forge. Here you will learn everything
you need to do to make an awesome and amazing
Minecraft mod with the most used Minecraft
morning API, forge. Absolute beginners
can start by going through the provider
Java introduction, which is really
going to help you understand some of
the fundamentals. In the beginning, we'll
learn some simple concepts such as adding an item, adding blocks, recipes,
and even custom tools. Then we'll continue by looking
at custom block models, custom crops, and so many other cool and
interesting features. In the end, we'll even
tackle advanced topics such as block entities and
world generation. So what are you waiting for? Sign up for this class now, and who knows maybe your MOD is going to be the
next great hit. I will see you in
the first lesson.
2. (Java) Installation & Download: Welcome to the fabric 118 course and here to the
Java introduction. So we're basically starting off with a little bit of
a Java introduction. Either if you haven't
used Java at all, this is going to be very, very useful to you. Otherwise, if you
already have worked with another programming language
or with Java itself, then this is a very
smart idea to have this as a good refresher
here in the beginning. So I highly recommend going through the entire
Java introduction. There's gonna be some assignments
along the way as well, which you can do to
further basically solidify the concepts that
we are going to be discussing in this
introduction here. And there's going to be a few prerequisites that
we're going to need. The first one is
going to be a JDK. Jdk is a Java Development Kit, and they come in different
flavors, so to speak. But what we're going to use is the one from adopt him here, and we're going to
need to use 16. So JDK 16 in this case, this is called tamarin 16. And I have linked this in the resources basically
that you can download this. This makes sure that you select your operating system
and your architecture. So for me, this would be Windows
and 64 bit architecture. I highly recommend
downloading the MSI here because that's
basically just installer, which then installs the JDK onto your machine like basically
any other program, really. Well, just install that normally like you would
any other program, and then we can proceed. Once you've installed the JDK, we will also need an IDE. And IDE is an integrated
development environment, which in our case we're going
to be using IntelliJ idea. This is, I found absolutely a great tool
to be using for this, we can use the community
version which is free and built on open source, which is pretty much
includes everything that we would could
ever want or need. So definitely make sure that you choose the community
version here. Once again, also just download the EXE if you're on Windows, and like you've maybe seen here, you can also Trick check here
if you're on Mac or Linux, basically switch over and
install them as well. And also just install this like you would any other
program as well. And then once that is installed started and then we can proceed. When you open intelligence
for the first time, a window similar to this
will appear for you as well. Now it's gonna look a
little bit different, but it will have
these three buttons, The New Project button with the Open button and the
get from VCS button. Upon clicking the
New Project button, you can see a new
window will appear. What's important is
we want to select the new project right here. Here we can just name
it whatever we want. So for example,
Java introduction, you can choose a location
right here using the language Java Build
System intelligence and the JDK being 16 for our purposes here for
the Java introduction, the sample code has to
be checked by them. With this done, we can click the Create button and then
a new window will appear. Now firstly, what we
actually have to do in the newer versions
for intelligence, they changed some stuff. I'm unsure why that is the case, because they actually
do tend to change a lot of stuff which
is kind of annoying. But our main class right here, so you can see this main, if I double-click on
this, it will open. You might have opened
for you already. That's fine as well. Now, in going forward, it's actually going to
be in some packages. So we actually have to
do this manually for our case here in this case,
but that's gonna be fine. But we just right-click the
source folder so you can see source right-click
new package. And then we're gonna,
I'm gonna call this net. And then on this
net I'm going to right-click new packet and
I'm going to call this help. And Joe, now you just gonna call it whatever your name is. Basically you're going to have net and then your
name, for example, I'm going to drag the
main class into it, say Refactor, and then
we're gonna be fine. Then you have this
package up here as well. This is very important because there's an upcoming lectures. We're going to
have this as well. Now if this displays
differently to you, it might be the case that it actually looks
kind of like this. I'm going to show you
just for a second that it sort of compacts here, net dot count Joe,
all in one line. If that is the case, you can
go to this gear right here. To tree appearance, height,
MT, middle packages, you can de-select that and also flattened packages
also deselected. And then you're going to
have exactly the same thing as we have right there as well. Now we're going to
continue with Pascal and Joe for the rest
of the lectures. So in this case, what we're going to have is the, we're gonna have
something called main here and another main here. And then this is
a common where it says write your code here. Now we're not going
to write code in this first In lecture right here. We're going to start basically immediately in the next lecture. This is really just the setup. So overall, this is pretty
much all that we need to do. All of the code is
always going to be available in each lecture. So in each lecture
you're going to find a resource link
or you're going to find this basically linked somewhere where you can have either the
GitHub repository. So all of this is going to be saved in a GitHub repository. And each lecture is going
to be a individual, basically an individual
branch there. Or you also have individual jurists where
each of the different, each of the code,
everything of the code of this lecture is also
linked there as well. So no worries there. Everything can be accessed before you can even take a look at this
because of course, some people, they
would rather have the code in front of them and then change it a little bit. Some people just
want to code it, like while I'm coding it.
And that's totally fine. Both approaches are absolutely basically valid in this case. But for the time being, this is basically it. So all of the code
will be available and hopefully you've
made it to this point. And then see if once the
next lecture starts, you can see whether or not
everything has worked there. But that would beat for
this lecture right here. And I'll see you in
the next lecture. So, yeah.
3. (Java) Java Datatypes: Welcome back to the
Java introduction for a Minecraft modeling. And in this lecture, we're going to be
talking about datatypes. So we're starting
very, very slow. The idea is that in programming, we can save things in variables. Now, what those
things are, right? There's different types of data. And basically in this
lecture we're going to go through what types
of data they are, basically meaning the datatypes. So there are a few
different types of data types like
even going further. And the first one would
be the numerical types, basically how to save numbers. There's a bunch of
different datatypes here. So there's an integer, there's a float and the double. So those are the ones
that are mainly used. I'm going to talk
about those in a bit. So you can see first of all, when you create sort
of a new variable, which is, you can
think of that as a container that contains
a certain value. And the type of value is determined by, in
this case here, the first word, you
can see that it's actually even marked in orange. That is not always
going to be the case. This is only going
to be the case with primitive data types. But what those are
we're going to see in a little bit in a later
lecture basically. And you can see that
this is called a number. This is the name of the variable and then the value is 42. Now, an integer, like I said, is A's particular
type of datatype, a numerical data type, which is a whole number. So this can only save
whole numbers or integers. And the actual range
that it can save, it goes from negative 2 billion to plus 2
billion as you can see. So this is basically the
numbers that you can save that can be stored in
one integer. That's the idea. And then there's float,
or when you need a comma. Now, what's very
interesting with floats and doubles that are
almost the same thing, not quite, but almost
the same thing. They're both floating
point numbers. And the idea is that this is actually not stored like this, is actually stored like
scientific notation. You might have seen
this before somewhere. And this is something like 1.412 times ten to the
four would then be 14,120. And basically in
this notation here, the floating point
numbers are stored. And what's important with
a float when using those, they have seven decimal
point precision, meaning that you can
have seven numbers. It doesn't matter whether or not they're left or right
of the decimal point, but seven numbers and then
they're going to be precise, and after that it's
going to get rounded. This is also why usually you
don't want to save very, very, very precise
things in floats. So for example, if you have like ten thousands or a 100 thousands of Bitcoin, something like that. That should definitely
not be saved in a float because that could be very
easily get rounding error. So those are floating-point
rounding errors. Those are very common. Now a double is a little
bit better in that it has 15 decimal point precision. However, still they might be, it might still lead to
some rounding issues. So that is something
to be aware of. Usually in most
cases, for example, in our case, this
really doesn't matter. So if you have a float, usually that can
represent, for example, you have certain
block positions in the world written this
something between those block positions
because of course a block is not like a single
point in space, has like a little bit
of a gradient there. And then there's a little bit of a rounding thing that's
going to be totally fine. And that's also probably one
of the reasons why if you go like millions of
millions of blocks in one direction at some point, the world gets really
messed up because floating point errors
and stuff like that. So that is probably also
one of the reasons. Now there are some
other numerical types which are not used as often, at least personally, I've
not seen it as often. A lot of people might say, Well, I mean that's
not quite right. Of course, you need
to be aware of these. But usually I have not seen
those used as often anymore. So a byte is eight bits
and it can store numbers from negative 128 to 127. So this, I'd call this a
tiny number because it can basically only store a
certain amount of values. Basically here in this case, a short is a small
number which can store between negative
32000 and plus 32000. And then on the other hand is a long which as you can see, can store from negative
nine quadrillion to positive quadrillion
nine quadrillion, which is pretty, that's
pretty staggering. That's a lot of like
that's a very big number, usually, very rarely used. Like I said, from
what I can tell, an integer is the most common
number for a whole number. And then floats or
doubles are used for, well, basically decimal numbers or something like that, right? The next data type of bracket are going
to be the Booleans. This is sort of the logic. So what you can think about is, well, we have a boolean. A boolean can either
be true or false, so it can either be one or 0. This can be represented
in one bit because a bit, if you know or not know, can either be 0 or one, That's the only two possible
values that it can take. So this is pretty much the same. It can either be true or false. So are these great videos, will I do hope so.
So that's true. And it's this HTML. Well, that is,
hopefully you didn't think that because
that's false actually. So that's sort of
the Boolean stuff. And the logic is actually incredibly powerful like
the entire logic field. Because of course, the entirety of all of our computers and operating systems and
all of that is all based on binary code. And in theory, booleans are nothing but binary code, right? Because a true is a one
and a force is a 0. So sort of the same laws
apply in that sense. You can think of it as
that, but overall Booleans, likewise with integers,
we're going to take a look at those in a little bit
more detail in the future. But I definitely wanted to
introduce you to those. In the third and last
sort of big bracket here, our characters and
strings to a character, as you can see, score a char. And this is a single character, so this is marked
with these single, single quotation marks here. And this can store
a single character and special characters,
regular comma. So I can put a comma
in here, that's fine. I can put a dash in
here, like a hashtag, the plus symbol star,
that's all fine. Oh, well, I can even put
in a space and it works. However, what I
can't do is I can put two characters in here, then it's not going to work
because two characters or multiple characters next to each other is called a string. To a string, like I said, is basically just a
sequence of characters. And this is marked with a
normal quotation marks. So double quotation mark here and double quotation mark here. And as you have probably seen, the end of every line
always has the semi-colons. Those are also very
important here. And that's sort of the idea. So you have characters
which are singular, singular characters and an, a, a string of characters
is a string. So that's sort of the idea here. And then at the very end, I wanted to mention something
that we're going to definitely see in
the future as well, which is null, the null keyword. So you can see that
this string test is equal to the value of null. And what's very important
is that null is not 0. It's literally empty,
like it has no value. Though. This is sometimes
in the beginning, especially a little hard
to really get across the distinction between what I don't understand, no value. What does that mean?
Well, it just has no value is undefined,
so to speak. It is non-existent. Write this test like while
it sort of is defined here, it's not, it doesn't
have a value, it's null. And we're definitely going
to look at that and see that in a later lecture as well. So no worries there if that is a little bit
confusing, no worries. The rest should be at least fairly understandable in
the sense that, okay, we have some buckets, we
can think about that, some containers in which
we can save some values. And depending on what
type of value they are, we have to write different
things in front. So that's sort of
the general idea I wanted to get across here, but the data types, otherwise, I hope that this was useful to you and you'll learn something new and I'll see
you in the next lecture. So, yeah.
4. (Java) Java Syntax: All right, welcome back to the Java introduction for
Minecraft Martin. And in this lecture
we're going to take a look at how to read code. Or I'm also going to call
this maybe Java syntax. So the idea is first of all, and this might, some of you might have already
been like wait a second. It's been ignoring
all of this up here. What is this? First of all, we're
going to calm down as we're going to have
to start building up some more fundamentals before we talk about everything
that happens up here. For the time being, what I recommend is you
just ignore this. The only thing that
we really care about is that this early bracket here. And then if I actually
put my cursor there, you can see that this one
lights up everything. First of all, right, now has to happen between
these two curly brackets. That's all that we're
going to care about. We don't care what this means. We don't care what this is, what all of those public, static, void, main, string, all of that, no worries at all. We're going to figure
all of this out in the future lectures that are
to come for the time being. We're going to figure this
basically inside here. That's our main prerogative
at the moment, though, first of all, code is
read from top to bottom. And that's interesting. Well, yes. So this is also why we
have these lines here, which is very
useful, can be very, very useful in
determining arrows. We can say, Hey, you
have an issue there in line 18. You look at it online. 18, There it is. Okay. Fair enough. That's very useful. And usually there are, of course, exceptions
to the rule. But in general, you read
from top to bottom. Now if you have a
two slashes here, then you have a
single line comment. And if you have this slash, star and star slash, and you can have
multi-line comments. So that's also something
to be aware of. And The, There's a few different things that you can do when you
have a variable, right? So we're back to variables. And we've seen those
of course, right? Different datatypes. And variable was sort of like a bucket or a
container in which we could store a value of a certain type and we
have to specify this. So when you declare a variable, then declaring a variable
means that you declare the data type of that variable and the name of the variable. And note once again that all
lines end with a semicolon. This is normal. So every line, every instruction
ends with a semicolon. This is by the way,
also very interesting because I could in theory,
right? Another one. So in x and I could
just do this. Well, this doesn't
quite work because we're all using this day 0. So y, for example, I could do this as well. This also works because this
is a single instruction, so it doesn't necessarily
have to be every single line. And basically doing this also would work even though
there is a two lines. And by the way, this is
like a horrendous thing. This is like formatting
that is of the devil. Don't ever do
something like that. But whatever the case may be. So it doesn't necessarily
be lines always, but it's in single instructions.
That's sort of idea. And you will usually saying that every line has to end with a semicolon is a good start. Basically that's a good start. It doesn't always be the case, but it is usually the case. Now, this is declaring a
variable and then we can also assign a variable
a certain value. And this is what
we're doing here. We've already declared this. So if I now exists somewhere
in the ether of the program, let's say, and now we
say I is equal to 30. So we have now assigned a
value to this variable, okay? Now we can do both
at the same time, declaring and assigning a value, which is then index equals 10. And this would be called
initialization or initializing this
variable in this case. And that's very interesting. Usually people don't throw these terms around necessarily. It's just something to be
aware of a little bit. Okay, I've declared
this variable, now I've initialized it here, I've assigned this variable, so it's just something sort
of the terms here should be, at least store it in
the back of your mind. That's the most
important bit here. And then there's a possibility of accessing
variables or methods. We have talked about
methods yet of certain variables or objects. We also don't quite know
what objects are yet, but we're going to figure that
out in the future as well. But for example, if
we have a string, we can actually get the
length of the string. So how many characters
are in that string by doing dot and then
something after it. So if I put this in, you can actually see
that enormous amount of stuff is thrown at
me as a suggestion, knowers at wall, we're
going to look at those things in a
future lecture as well. For the time being,
we just know that the dot operator also makes us able to access certain variables or methods
of a, another variable. That's sort of what we should
store for the time being. And then the actual
application of this we're gonna see in a later
lecture to a far, far, for greater extent and
in way more detail than this. But for the time being, this is sort of the general gist on how to read code here. Like I said, this is of
course not exhaustive. This is not everything, but those are sort
of the main things I wanted to get across
for the time being. So you have the idea of declaring a variable,
assigning a variable, and then doing both at
the same time and then accessing something
with the dot operator. And most importantly, that this year school should
be ignored and all this should be ignored and
everything just in between those curly brackets
should really be paid attention to
for the time being. But like I said, we're going
to venture out of this, these curly brackets avenged, but that will be it for
this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in the
next lecture. So, yeah.
5. (Java) Output & Input: All right, welcome back to the Java introduction here
for microwave modeling. And in this lecture, we're going to be
taking a look at outputting things and
inputting things. So this is both
outputting something to the console as well as reading something
in from the user. So we're basically storing to supercharge our ability
to actually do something. And the first thing
that we're going to do is we're just going to output Hello world because
this is something that every programmer learns
at the very first time. And this is what we're gonna do. So we're going to
type in a system. And you can see that some things are actually being
suggested for us. We're just going to
write it this out system with a capital S, very important out, all lowercase and then
print line, print LN. And then we're going to make
a first open parenthesis. The closing parentheses should
generate automatically. And then we can just go here
and put in a semicolon. Now this is Oregon. We're going to be fine here. However, we now want
to put something into the parentheses and that
is going to be output. Now we have to make
this a string. Therefore, we're
going to type in the basically
quotation marks here. And then the second
quotation marks should generate
automatically as well. And then we can type
in hello world. So as simple as that. And now to actually
start this program, we go up here, ensure
that this is all fine. This should look pretty
much exactly the same. And we're just going to
click this Run button. And then after a few moments,
you have helloworld. If this was the first time
you have ever run a program where you have first
literary starting to program in this moment. And this is the first
time you've run this. And everything here says hello world and this says process
finished with exit code 0. Congratulations. I'm not even being
like I'm not being, I don't want to be
patronizing here because this is actually a step that every
programmer goes through. At some point, they're
going to write a helloworld program and they're going to be
like wait a second, I can make things
display that I1. So I could, for example,
say hello students. And you're going to be like, way that can't be the case. I can just do that. Yes, I can just run this. If I actually run this
properly, There you go. All right, so run
this Hello students, and now it says Hello
students, no worries at all. So as you can see, this
is actually really, really freaking cool and this is going to be supercharged even more because now let's say we
have an integer variable x, which is equal to 10. Well, why don't we just output once again system and
I can start writing this and you can see that
this is sort of like has sort of the selected rate is sort of highlighted,
so to speak. And when I press the tab key,
it actually auto-completes. So I can write
this very quickly. So you can see out
as also already, basically is a
suggested here and then dot print line as well. And I can just put the
x in and look at this. Everything works and
sometimes goes very quickly. So you can look at
this like this, well, that's so much
for that, right? So a system out print line, you can see how fast
that sometimes works. No worries though. I'm going to try to make this, especially in the
beginning here, a little bit slower so that everyone can be
basically keep up. And well, we can just
put in the x here, so the variable inside
of these parentheses and then the value is being output. That's really cool, isn't it? Where you have the ability to actually output something
that's in a variable. And now we're going
to go even crazier. So once again,
System.out, print line. Once again, just auto
completing it with the Tab key. And now I can say something
like outputting some value. And now look at this. I can go beyond the string. Make a plus x. No errors whatsoever. Everything looks fine. What is going to happen now? Well, look at this now. Outputting some value and then the value of the variable is
going to be output there. So that is pretty frequent, sick if I do say so myself. That's actually really cool. Another question comes in, well, how can we read something
in from the user? Now this is a little
bit more complicated. Usually, this is
something, you know, it's sort of a, I would say, semi
limitation of Java. It's kind of a bummer
that it is complicated, but no worries to what we're going to
write is the following. We're going to write
scanner and then just space everything when something turns red here, no
worries at all. We're going to keep calm. Everything is fine. Then Scanner in equals a new. And then once again
scanner in with a big S with a capital S inside
of the parentheses. So we're going to
make parenthesis System.in and ending
this with a semicolon. Now both the scanner here and the scanner here
should be ready. That is totally fine. What do you have
to do is you have to click on this and press Alt and Enter to
import this up here. So like I said, usually we
want to ignore all of this, but we can make one
little peak up here. So you can see import
Java util scanner. This is basically imported. So that's no worries at all. You can, if this is important
while you're writing this, because when you
press the Tab key, when you write
scanner, this might be important automatically,
no worries at all. Just making sure that
this is the correct, well, phrase, so to speak here. And that this is
written like this. We're not going to worry
about what this means. What are we doing here? None of that, we're just
going to know, okay, we need this in order
to read something in. So then we're gonna say
system out dot print line, type in your username,
something like this. And then what we're gonna
say, we're gonna make a new string variable
called input. And we're gonna make this
equal to scanner that. Next. There you go. Okay, So next, as you can see, has to be written like
this so enough to put in next and then open and
closing parenthesis. And then that's fine. So this is now going to save
whatever we're going to type in to the console in
this variable here, and then we can do
something with it. For example, we're just going to immediately outputted again. So system out print line, your username is, and then
we're just going to say input. So just for the, for
testing this basically, so let's store this. And what we should
see is a lot of students tend
outputting some value. And you can see
that first of all, the program doesn't end automatically because it's
waiting for our input. So let's just say this. Well, my username
is count Andrew. I'm going to press
Enter and then you can see your username is true. So that is a pretty cool like
when you think about it. And this really
also starts where you can just play around
with this a little bit. You know, you have some
intractability with the PC. You can now actually
talk to the PC, so to speak, which is
really freaking cool. So this is one of
the first step. I very much a, basically would just advise you to try out a bunch
of stuff here, just typing some stuff in, typing some stuff out. It actually can be really fun. But we're of course
going to use this in future lectures and the
coming assignments as well, where we basically are
going to read stuff in evaluated and then do things depending on
what the input is. So that's all pretty cool. But this, for now, is it for this
lecture right here. I hope you found this useful
and you learn something new. And I will see you
in the next lecture. So, yeah.
6. (Java) Errors & How not to panic when you get them!: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture, we're going to be looking
at some errors and how you can ask for help when
you get these errors. So first of all, we're
basically starting with some pre-done code
again right here. But no worries. This is of course, all
available to you in the GitHub repository or as
an individual just as well. And this is very interesting. So first of all,
we're basically can uncomment some lines
to find some errors. The first error we're
going to have is the java cannot
find symbol error. And that basically how you're
going to see this is hey, something is red
inside of the code. For example, I'm just
going to uncomment this and you're going
to see that a2 31, basically a variable
we're trying to access or reference is
not actually existing. So this is going to be red. Now, this might be something
that you haven't noticed. So red is also going to
be like underlined here and in the main class
appear and you're going to have a problem
symbol and a problem there. So there's going to be
a lot of signs here, but you might actually
just not notice this, which is totally fine. So if you then still
run your program, what you're going to be
greeted with is this. So the first thing to say
is when you get an error, don't worry at all. Honestly, getting an error
in the beginning might seem very daunting and you
might be getting nervous. Let's say, Don't
be nervous at all. Getting errors is
actually something that is sort of expected when you're programming to have
something work the first time around actually
gets you very suspicious. Because it's very rare that
when you're working on some code that it works at
the first time running it. So please, first of all, always remained calm
when you get an error. Is nothing like this. No shame in that whatsoever. You haven't done anything wrong and you will always
be able to fix it. So this arrow, in this case, it says, like I said, java cannot find symbol. It actually says to us what the variable here is and
where it is located. And if you take a look
at the very top here, you can actually see this 1128. And that actually means
this is at line 28, at character or other
line 11, character eight. So this is actually
really freaking cool. So we can immediately find
where this arrow is in. Can say, Okay, I've
made a typo there or I forgot to make a variable,
something like that. This would be this
arrow right here. The second thing that you might
run into at some point is exception in thread main, Java, Lang,
NullPointerException. So this means that
something is null, meaning that it
doesn't have a value. For example, we have a
string variable right here. And we set the value to null, which I already told
you about is does, means that it
doesn't have value. It doesn't pretty much exist. Now if we were to now try
to call the length on this, this of course doesn't
make any sense because the length of nothing is also nothing like you can't call a length on something
that doesn't exist, meaning we're going to get
a NullPointerException. So this looks kinda like this. And this would be
called the stack trace. So a stack trace in like
layman's terms just in general. So you know, what it is about is basically what code has been
called up until this point, until the error has occurred. And you can see
that this happened at cotton domain
main and then 16. So we can actually click on
this and it will give us the exact line and sometimes even the exact piece of code
where this has happened. So this is the
NullPointerException. This is something that happens routinely even with
advanced developers, that sometimes you forget
to initialize something. Sometimes you just call
something in the wrong order, you forget to call
a method that is something that happens
all too often. Once again, nothing
to worry about, but that is the null exception. You can usually fix this by properly assigning
a variable. And then the last
thing that's not really like an exception, but we've seen
this here as well. So this is this process
finished with exit code one, or sometimes it might
also say finished with non-zero exit value one,
something like this. Or it could also be
something different than 1, 13042, whatever. So it could be some
number that is not 0. That's the most important thing. That means that
there is an error. You should never post only this. If you only post, hey, I got an error and you
post-process finished with exit code 0 or finished
with non-zero exit value. Everyone knows that
you don't know Java. Now that's not an
issue of course, because you have to
start somewhere. But this just if someone
wants to help you, right? So for example,
if you were to go into the Q and a
and you're like, Hey, my you know, I have an arrow
and it says this. If you post this, first of all, I'm going to know
that you probably haven't watched this
Java introduction, which is of course finds
your own decision. However, what I also will
notice that this is not, this doesn't give me
any value at all. This just tells me there has
been an error. That's it. That's all that this says. If the exit value is not 0, then that's just means there
was an error somewhere. I don't know what the error
is. I don't know what the exception was. I
don't know anything. Meaning that I will
actually have to ask again. It can just be a
little bit frustrating because then you
have to ask again, Hey, can you show
me the error log is there are some output there. Just put the arrow
in there as well. Usually when you have an error, It's better to give too much information
rather than too little. So that's usually the case.
It's not always the case. Like don't just drop like
80 different files on someone that wants to help you or in the Q&A,
something like that. But usually you should have
something like this, right? And exception and error, some type of log something which says a particular thing
like this exception. You might have an exception somewhere, something like that. So that should be like the thing you
want to look out for. Let's just something that
I wanted to give you, which can be very
important, right? But that is already it. So this is sort of the, just a general overview
of those errors. And of course, don't hesitate
to ask if there are errors. If you get errors along the way and ask for help,
that's totally fine. I just wanted to
mention especially this year because it
can be frustrating, not only sometimes for
me because of course, then have to ask a
follow-up question. And then depending on
how long that's going to work and maybe you
just look for that. And another answer didn't
come in like 20 minutes, so you have to go do something else and then
it takes a long time. So that can be sometimes
a little bit frustrating. Well, whatever the case may be, this is it for this
lecture right here. I hope you found this useful
and you learn something new. And I'll see you in the
next lecture though. Yeah.
7. (Java) Integers & Arithmetic & Math Methods: Or I will come back to the Java introduction here for the Minecraft modeling course. And in this lecture, we're going to be
looking at integers. We're going to be
looking at math, and we're gonna be looking
at arithmetic operators. Now those are all
very big words. However, I am sure
that we will manage. The first thing that we're
gonna do is we're going to initialize two integers. This is going to be int x
equals 100 and int y equals 20. So up until this point, everything should
be fairly clear. Overall, this is just, these are two
variables, x and y. They have the value
120 respectively. They are both integers. So we started with
the board int. So that should be
fairly straightforward. And we will also have an
integer called a result. Now we're going to
actually just declare this variable without actually
assigning any value to it, because we're gonna be using
that in the following ways. The first thing
that we're going to take a look at is addition. So those are basically
arithmetic operators, addition, subtraction,
multiplication, division, and then
there's a fifth type, which we are going
to be taking a look at in just a moment. So the result here of addition is of course
going to be x plus y. So that shouldn't be too crazy. We're just going
to in x in here. And this operator,
x in from the left. A, an integer could
also be a float. So that also would work. So both of those, both of these, if X and Y, when both the
floats would also totally work. Now this, of course
then the result would also have to be
afloat. Very important. Think about that.
We're gonna see one example in a future
lecture of that as well. Like if you start to mix those, but that should
be fair sensible. We simply put in
the plus symbol and then basically we're
going to add x plus y. So let's do system out, print line and then print the result just so
that we're going to see, well, this should be a 120. Let's see. And of course it is a 120. Everything working
perfectly fine. We can of course, also
use a subtraction by n. What I'm going to do
is I'm actually going to let all of this right? So I'm just going
to drag my mouse over here and then press control C to copy all of
this for my mouse here, control V to paste it in. I usually do something like
this just so that, you know, it's a little bit easier
because this is of course very much
duplicate in this case. Now for subtraction, you
probably guessed it. We just have to put a
minus sign in here. And then all of a sudden
we're subtracting y from x, meaning that this should be 80. And of course it is
AD totally fine. And let's actually copy off
of these like completely. Once again going to
select this control C and then Control V right here. And then we're also
going to take a look at multiplication and of course, the vision as well. So multiplication is going
to be a star right here. And then division
is just a slash. So this should be
fairly sensible, nothing to be too crazy. Overall. Those are just the
normal ways that you basically would well
calculate stuff. So that's pretty much it. Let's just go through C 2005. That is actually all fine. And now the question
becomes, well, what is the fifth type? Well, the fifth type is
actually the remainder. So this is also sometimes
called the modulo operator. That's in like actual
mathematical terms. But for us, it's the
remainder operator and that looks like
a percentage sign. So for example, we could
say 20 remainder two, which would of course be 0. So if we're just going
to copy this once again, Control C, control V, This is going to be 0 because
when we divide 20 by two, then there is no remainder left. So this is a very good way
actually of taking a look at whether or not a particular
number is even or odd. So that's actually pretty cool. And those are the five
arithmetic operators. A fairly straightforward
all things considered. How often are they use? Well, I mean,
you're going to use some math inside of the
entire programming thing. Whether or not be in modeling or in
programming in general, there is some math associated
with it, of course. So these things are definitely important
to have seen before. And then the last thing
we're going to look at here is going to
be the math methods. Now, first of all, we're not going to worry
about too much trouble. Well, it's a method.
Well, you can think of that as a particular function. So for example, Let's
make a call this math. So you can see if
I type in math, you can see Java Lang and
get that suggests it. And then if I put
in a dot, I have, I get suggested a whole bunch
of things that I can call. And there are
things, for example, like the max method right
here, where absolute, right. So I can call max here
and I can say x, y. And then it's going to return me the maximum value
of each of these, which of course in this case
it's going to be a 100. So we should see at the very end here a 100 pop-out they ago. So actually fairly
straightforward. And then let's just
actually duplicate this for the sake of arguments or
Control D to duplicate that. And let's get the absolute
value of, for example, let's say minus 500,
which would be 500. So In Math, like a mathematics, it is written like this. So maybe you've seen something
like that before with these like absolute
lines, so to speak. And that then turns into
500 because we don't really care about the sign
that is in front of it. So we're going to
see as 500 as well. And as I've said, there are
a bunch more stuff in here, like as you can see, this seal. So you can basically
round up, round down. You can get the cosine, you get some exponents. So you can put something to
the power of e logarithm 10. Like there's some
crazy stuff in here, rounding random Even,
even at random, there's even like
constants like e and pi. So there's a bunch
of stuff in here. Usually, It's very rarely
that you need to use. A lot of them are especially
something like the max and the Min method and
the absolute method sometimes are actually
quite useful. And it's good to have
seen this before, this so that you don't like
when you run into this, when you may be looking at
some GitHub repositories of other modes or just cold in
general from other people. And they use
something like this, then you're not completely
caught off-guard. But that would be it for
this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
8. (Java) Assignment Operators: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture
we're going to be looking at assignment operators. Now we've seen the normal
assignment operator, which is the equal symbol. And there's actually a very
interesting thing for this, because this is actually sort
of a sided operator, right? So we're going to assign the right value that
the left variable. So we couldn't just
type in something like, for example, 30 equals y. That doesn't work, right? We actually have to have it in a particular order in that case. Now that well, is that
going to be the lecture? Is that it? No, of course not. There are some specific, very interesting
assignment operators that, well, you know, you require the arithmetic operators
to sort of understand. But what we can do is
of course we can say x, for example, equals
x plus y, right? So we're just adding
y to x in this case. And then writing that back into the variable x,
that totally works. That's not going to be an
arrow, that's totally fine. However, we could also write this in a little
bit of a nicer way, and that is going to
be x plus equals y. So that also works right here. And that's actually
really cool thing. So this is where
this is amazing. Oh, this is very much
like easier than this. And usually it's also a little
bit easier to understand. Now if this does actually confuse you more than
this, that's totally fine. You will, however, have to take a look at the
assignment operators, especially if, for example, if you take a look at
other people's code, they just might use
only these and not this long way of writing it so that you have to
be aware of that. So even though you
might not be using some tools that we're
talking about here, is all of this are basically
tools, rights to program. You still have to
know about them to read code that other
people might, right? So let's actually
just print out the, the variable x here, and then let's just go through
the rest as well, right? So we're going to select this, copy it and then let's just, you know, just paste
it in like five times. So what can, of course
do a minuss equals. We can also of course
do times equals. We can also of course do like
Ned, like divide equals. And then at the end we can
even do remainder equals. And that I've never seen
before like that is really something that is
probably a very, very specific like moment
where this is, has to be cold. But let's just see
if this works. Of course it does work
totally fine to start with a 140 because we've
added 20 here, right? So we're starting here with 120. An adequate again is a 140, and then subtracting it
is a 120 and then times 20 is 2400 and then divided
by 20 is 100120 again, and then dividing or
remaining it is of course 0 because we can divide a
120 by Wendy perfectly, which would of course
be takes exactly. That's very good,
Very well done. So if I however, now just wanted to
add one to it, right? So maybe I just want to
do something like this. X equals x plus 1, right? But just want to add it by one. This would be
called incrementing or an increment x by one. Well, I mean, of course we could just write this as well, right? We can just do this. Yeah, of course, that would
also work totally fine. But there's even an easier
way that we can do this. And that will be x plus plus. Look at this. This is pretty crazy. So we go from here to here, but that's actually
how crazy that can be. And let's just print this out. And then of course, you know, x minus minus, of
course also works. That would be decrementing it. So this is, let's just
keep it for a bit here. Platelets, so increment,
incrementing, and then also this
would be decrementing. So basically we're just adding one or we're subtracting one. Let's just take a look. We start at 0 right here. Adding one, adding two is two or adding another
one, right is 23. And then we're
printing it out and then decrementing it, and
then we're back at 2. So that's sort of the
general idea here. Those are the assignment
operators and then also incrementing and
decrementing Europe, which is kind of
important as well. But those two are going
to be seeing a lot, especially these X plus
plus and x minus minus. Those are things that
are definitely used very often in
certain capacities, let's say inside of the code. But that would already be
for this lecture right here. I hope you found this useful
and he learned to the New. And I will see you
in the next lecture. So, yeah.
9. (Java) Booleans & Comparison Operators: All right, welcome back to the Java introduction here
for Minecraft morning. And in this lecture, we're going to be looking at a Booleans and
comparison operators. Last time we looked at integers, and now we're going to move
on and look at Booleans. So the Booleans in general, we can remember this
from the second lecture, are basically a
datatype that can either save a true or a false. Well, for example,
we're going to make a new boolean here. For example, likes the lectures. Lectures, made sure that
this is written correctly and this is of course
true, Let's hope so. And let's also make a boolean, which is, for example,
asked question. And let's just make this
false for the time being, maybe that turns true later, but for the time
being, that is false. So we remember
Booleans, like I said, a true or false, 1 or 0, that is the idea. And we can even print
this out, right? For example, we
can say you have, or you like these lectures. Let's say you like
these lectures. Who likes these lectures? And then I can press Control
D to duplicate this. And for example, you can say, you have asked a
question in the Q and a. So I could, for
example, take this. And then instead of
like the lectures, I can say ask questions. If I were to do this, then
what we're going to see is just true and false, basically just like a string outputting,
they're totally fine. Okay, so that's the sort of
idea of Booleans, right? True or false, Fair enough. But now, what are
comparison operators? Well, let's think about this
comparison operators, right? Well, there's a few of them. And the idea of comparison
operators that of course, well we're going to compare two different values
to each other. And that is going to return
a Boolean because of course, if we compare something, for example, we could
say bigger than right? So we have something that's
bigger than something else, then of course, it's either going to be
true or false, right? If I'm going to say, hey, I have an apple that's like
the size of a baseball. Like okay, fair enough.
And then I have an apple as a sizable
like a football. Well, obviously the size
of a football is bigger, so there's going to
be like a true under this is also a bigger or equals. There's also equals,
there's not equals. They're smaller than and
smaller or equal to. So those are the
comparison operators. We're not going to look at every one of them individually. And we're going to take
a look at a little bit. So the actual example we are going to be looking
at is, for example, you have a score at, or maybe you made
an exam, right? You wrote an exam and
your score is 98. Well, thank you very much. That is a very good
score and it's actually actually your score
day, you go in. Then you can say, well, we could write in a Boolean that is called
past class, right? And you pass this
class when exactly. We can think about this. Well, of course you need
at least 50 points. Let's just say for the
sake of argument here, you need 50 points
to pass this class. Well, it's very easy. You can just say
your score has to be bigger or equal, 50. Does that make sense? So that should make
intuitive sense. All things considered this, this would be true in our case, of course, but if
your score changes, then the answer here
changes, right? Because as soon as this is
no longer like if it's 49, you no longer pass
the class, right? So that should be thought
of fairly self-explanatory. So we can even just
print this out. So just system out, print line, let's
say for example, you asked, let's just put this in so and then
pass class, right? So we're gonna get
a true if it's true and a false if it's not. And we can even say
something like with your score plus points,
something like that. We can say this.
And if I now run that and see you pass
true with 98 points. If I were to put this to 49, which of course, in this
case now is no longer true. So no 49 is no longer
bigger or equal than 50. Well, this now will
return a false. You will see, there
you go. You passed false with 49 points. Let's keep this as 1998 DOE. And let's think
about this as well. So let's took another idea here. So we can also have a boolean, for example, has
perfect score, right? And this could be
then be equal to your score is equal to a 100. This is the equals operator. Very important that those
are two equal signs. And that's something
that sometimes people get confused
on knowers at all. One equal sign is the
assignment operator where we're assigning a
value to a variable. And two equals signs is the comparison operator where
we're comparing whether or not this value of this variable here is equal to the
value of this one. That's very important. And here of course,
this is false. As of course 98 is
not equal to a 100. That should also be fairly
straightforward overall. And we can even do something like this
that's very interesting. We can even negate something. So this is basically this
the declamation mark here. Though. We can also say
something like, hey, we pass the class here, and then we can make
another Boolean that's called failed class, failed us. And this can be equal to, well, not pass class, right? So we just negate whether
or not we pass the class. And of course that makes sense. So if this is a
little confusing, you're write it out, like actually write
a writer text. If failed class is true, as class is false, of course. So those always need to be
opposite of each other. So we can always
just negate this. This could also be an idea. So negating year is of course, negating basically meaning the two put the exclamation
mark in front, means that true turns to false. And then if it is false,
it turns to true. Where it returns
true then right? That's sort of the idea. Comparison operators. You can also think of this. They return a
comparison operators. You can think of it like this. When we had a plus rating, we took in an
integer on the left, plus integer on the right
and returned an integer. Again, it makes absolute
intuitive sense. You don't even think
about it when you're, when you're working on mathematics
and calculating stuff. When you do 5 plus
5, like of course it's going to return it
to 10, which is a number. Well, the comparison operator
is pretty much the same. You just put in, for example here an integer and an integer, and you return a Boolean. That's, that's all
there is to it. But the only thing
that really changes is the return type, so to speak. Thinking about this
and that's it, something to keep in mind here. And that would be the
comparison operators. I highly recommend just playing around a little bit with this. It shouldn't be too crazy. It really is just comparing two different values
to each other. And that is then
expressed as a Boolean, which should actually make
sense is that there are only is ever a one right answer
in this case, right? If either the score is bigger or equal to 150 or
not, implies that. But whatever the case may be, this is it for this
lecture right here. I hope you've found this useful and you learn
something new. And I'll see you in
the next lecture. So, yeah.
10. (Java) Booleans & Logical Operators: All right, welcome back to the Java introduction here
for microwave modeling. And in this lecture
we're going to be looking at a logical operators. So I have prepared a few
Booleans right here, watch lectures, asked question, finished assignments
and engaged review. Those are of course related to a course like
scenario, let's say. And we're now going
to take a look at the logical operators. And there are three of them, basically which we're
going to take a look at. There's the end, there's
the OR and the not. So we've seen previously
where we were able to negate something and the AND, and the OR are also
very interesting. So the logical operators take in two Booleans and give
you a new boolean. So for example, for the
end of the Booleans, you have to give it,
have to be true, and then it returns true. Otherwise it returns false. And for the, or either
one of them has to be true and then it returns a true. So this only returns false
if both of them are false. So for example, you could
think of it like this. So Boolean finished
course, right? So if you want to
finish the course, you have to have
watched the lectures and finished the assignments. That should make
sense. That sort of a good concrete example here. And then you could also
say, well, a fan, right? So, so let's say
it's fan, right? So someone who is a fan
would finish the course. So finished cores
and Eva review, that also should
make sense overall. And now someone who
might be learning, like maybe learning a lot, they watched the lectures
or they asked the question. So this is something someone
who's learning, right? Either watching the
lectures or ask a question. So either of them could be true and then learning
would be true as well. Let's sort of a
general idea here. And there's one more
thing that I have and that is going to be
this right here. So this is just a
general overview of what basically happens. You can also download
this as a cheat sheet. This is available
in the resources. And the idea here
is that it just shows you what the
different types of outcome, that's basically what
the results are. So you have a and B. And then depending
on what they are, this is the return
that is given, like I said, both
of them have to be true for the answers
to return a true. And here, if either
of them is true, then this returns a true. Otherwise it's false. You can also think of it,
write a or B towards sort of, it's sort of really
baked into the language when you think about the
negation, like I said, we've already talked
about that is sort of the general adjust when it comes to the logical operators. There is, of course
a little bit more there as well over that, is this really a good
beginning for this? And then of course, the real thing that
you can think about is that when you have one of
those which returns a Boolean, you can of course, then
chain those together. So you can then also say, for example, end ask
question, right? So you can see that because this of course
returns a Boolean, we can now use the
AND operator again. So this pretty much works very similar to like the
arithmetic operators were. Of course you can also
plus, plus, plus. You can have 5 plus 8
plus 7 plus 9 plus 15. That works totally fine. In a similar way, you can chain the
logical operators together as well, right? But that would be it for
this lecture right here. I hope you found this useful
and you learn something new and I'll see you
in the next lecture. So, yeah.
11. (Java) If and Else Statements: All right, welcome back to the Java introduction
for Minecraft morning. And in this lecture, we're going to be looking at
the if and else statements. Now in this lecture, basically we're going
to start really having some interaction
with the computer. A lot of the previous lectures
were very theoretical, is sort of showing
some concepts. But in this lecture, we're going to be really well interacting
with the computer. Let's just start by
making two integers. Exam 1, Let's say for
example 65 and exam 2, which is going to be
51 for the time being. And we could imagine
that, let's see, we have to write a program that evaluates those values
of those two exams. And basically says, Hey, you have ailed or past exam 1, you have failed or past exam 2. And then at the end, maybe when people have passed both exams, maybe something is printed out Like you have passed the
class or something like that. So how can we do this? Well, what we can do is we
can make an if statement. And for that we literally just
like right if, right here. And then we can
do the following. We can put in a parentheses. And if you put it in
an open parenthesis, the closing parentheses should
automatically generate. And inside of those
parentheses we have to put in a Boolean value. So we remember back to the previous two lectures where we had
comparison operators. So what we can say
is that, well, if exam 1 is bigger
or equal than 50, then we know that
we've passed the exam. And then when we put hidden here is after the closing
parentheses, we put in a curly bracket. And if I put the open curly
bracket in and I press Enter, the closing curly bracket should automatically
generated for you. And now what we can do is we
can write as something else. So we can say system
out, print line. And then for example, you
have a past exam one. Though, this all of the code between these two curly brackets here is going to happen
when whatever is inside of the if statement. So inside of these
parentheses, true. So if this is true, then this is going to happen. So that's pretty cool actually. And then we can
sort of supercharge this by adding an
LLC or at the end, and also putting in
a curly bracket. And once again, we put the open curly
bracket in any press Enter a closing curly bracket should automatically
generate here. And then for example,
we can just select this control C control
V to paste it in. And then we can say you
have failed Exam 1. So this year, right? For the else actually
happens when this is false. That actually works
out very well for us. So we can basically
use this to, well, take a look at
whether or not Exam 1 was passed or failed. So let's actually
run this and we should get a past exam one. And of course we
are getting this because in this case
exam 1 is bigger than, bigger or equal than 50. So this is being called.
So that's pretty cool. Now we can basically do exactly the same thing
for the second exam. So let's just copy all of this selected Control
C, Control V. And then here we're
going to say Exam 2. Here we're going to say Exam 2, and here we're also
going to say Exam 2. That's actually pretty cool. All things considered. And then the question
becomes in, well, I mean now we want
to outputted when you have actually
passed both exams. So how can we do this? Well, now we're
getting pretty crazy. So the last two
lectures will seem a little more coherent,
so to speak. We're gonna say exam 2. Exam 1 is bigger or
equal to 50, right? So that's still passing
this End Exam 2, 0, right? This exam 2 right here
is bigger or equal 50. And then if this, if both of these are true, then we know you've passed
the class so we can copy the system out here
and then we can just say, you have passed, let's say the class just for the
sake of argument here. So that is really
freaking cool, right? We have now if statements
and if else statements, and what you can
also do by the way, when you have an else
statement that you can put another if statement
on here, right? So you can just put
this one in there. Basically if this is false, then else and then
put another if statement is basically just
for the sake of argument, just say true here. Of course this would also
work, but, you know, and then we can say
else and basically chain those together so
you can make if else, if else, if else, and then the last one is
always going to be else or you can also just not have
an else here as well. That also works. I wanted to mention
that as well. But now the really
cool thing is, well, let's think about this. Let's say this is
actually a program where the professor comes in and actually writes in
the results of your exam. Oh what? Well, we remember
how can we read something in we have
to write in scanner, scanner, scanner
equals new scanner. And then system.out.print. And then this sort of
just works for us. We remember that we don't want to worry about too
much what this means. Then we can say something like
system out print line and say results or exam one. Right? And then let's
just duplicate this. Make results for an exam 2. And then we can just say that
Exam 1 is actually equal to scanner dot next int
right here, right? So we're going to read
in an integer and then save it in the
exam one variable. And the same thing we're
gonna do for to go. Now what's going to
happen is really cool. Now we start this and
now it's actually expecting us to put in an exam. Well sadly, 32, actually
not 320 but 32. Well, and then the
results for exam two, they were actually
very much better. They were 68, sadly, just a little bit, not
quite enough for 69. And then you can see you
failed exam 1 and exam 2. So now we're really starting
to go into a sort of part of this java
introduction where you are able to really do
something with the computer. And you're really
going to see this in the first assignment as well for the next lecture is going to be a sort of a alternate
version of the if statement, which can also be
very important. And then the first assignment, I highly recommend doing the assignments here for
the Java introduction, especially when you're
just a beginner because they can be
really, really useful. And with this, of course, the core is available it up
repository or a just as well. But take a look at
those in the resources. And I highly recommend playing around with
this a little bit, just reading some numbers
in comparing them, doing some if statements, just making a whole
bunch of cool stuff. With this, you can already pretty much make a
really cool game. So, but for the time being, this would be it for
this lecture right here. I hope you found this useful and you learn some of the new. And I'll see you in
the next lecture. So, yeah.
12. (Java) Switch Statement: Or I will come back to the Java introduction here
for Minecraft modeling. And in this very short lecture, we're going to be looking
at the switch statement. The switch statement
is sort of like the little cousin to the
if statement, so to speak. So it is very similar. Let's just take a look. So we're going to
make an integer called a metal placement, which is for the time
being just one in. You could imagine this one
representing the placement in, for example, the
Olympic Games, right? So one would be the gold
medal, silver, bronze. So two is silver and
bronze is three. And then anything else
as records, no metal. And we could do this by just
making some if statements, whoever we could also
make a switch statement. You can see if I
type in switch here, then inside of the parentheses, I put the variable that
I want us to evaluate. Then once again make
the curly bracket or the second one should
generate automatically. And now I have to
actually specify in each, inside of these curly brackets, each of the cases that
this variable can take. So I can say case 1. So this means that it
has taken on value one, system out print line and then for example, say gold medal. And then I can say case two. And then I can say system out
print line, silver, metal. And then once again, at the very end here I can
say case three, system. The system out print
line. There you go. Bronze medal. However, it is formatted,
that's totally fine. And then we can
also say default, meaning that this is
going to be called if it's neither this case,
this gets more this case. So we have predefined
cases here. And then in the default case, it's actually going
to be called if it's anything else that
we can say no metal. And the first thing
that you will notice is wait a second. We have to define
every single case. Yes, here, the issue
is that you can use something like
bigger or equals, which immediately makes it much easier to narrow something down. If I wanted to make the
exam evaluation here, I would actually have to
go through each case. So I have to go
through cases one through 50 or one
through 49 for saying, hey, you failed and
then the other ones for you succeeded or you passed. So the switch statement isn't
always the best choice. It can be however, sometimes. So let's just take a
look at this list. Should of course, actually
print out gold medal. But the first thing you're
going to say is wait a second. It's actually printed
out everything exactly. Because there's one more thing that we actually need to do. And that is when
you have the case, the very end, you have to
end with a break right here. We have to put in this break. Otherwise, it will just
basically go preserved. It will just go through
the switch statement is just going to continue along and just pull
out all the cases. And if we have the break here, then you will see that
only the relevant one is actually going to be taken. Let's just put in three just for the sake of argument here. So as you can see,
that now works. So this is very important for the break keyword here has to be used with the
switch statement. This sometimes can be
a little bit annoying. So the switch them usually for integers is okay, can be used. It's usually used
for enums because enums have defined
values that they can take and that usually
is easier for the cases then what is very rare or
which is basically impossible. You shouldn't use floats
in switch statements because here you of course
have to define the exact case. And because of the
floating rounding or errors that can occur, this might actually
just never work. So never use floats
and switch statements. Basically, that's a very
important thing to remember. Otherwise, a switch statement, even if you are not going
to use it yourself, might of course come up
in someone else's code. You will have, at least have to have seen this before, right? But that would already be it
for this lecture right here. I hope you found this useful
and neurons and the new, I'll see you in
the next lecture. Oh yeah.
13. ASSIGNMENT 1: Trivia Game: All right, welcome back to
the Java introduction for Minecraft modding here
with the first assignment. In the first assignment
is going to be a create, a simple trivia game. I will explain shortly
what that entails. Though the idea is
that you should define at least three questions. I recommend doing
three questions, three answers, that's
going to be enough. Otherwise, the code will get
very cluttered very fast. And what I want you to
do is I want you to prompt the user to
type in their answer. You can use the
scanner for that to basically get what
they typed in and then evaluated with an if
and else statements to check whether or
not the answer that the user typed in was correct. So I recommend rewatching the output input lecture is that was very important
in that case. And the if else statement
lecture might also be very interesting to
look at it one more time. So if they were correct,
output that they were, and if they were wrong, then tell the user
that they were incorrect and also output
the correct answer. Another thing you
should do is basically just increment a points total, meaning that when the user has a correct answer that
appoints increased by one, then at the very end, you just have a unique output for each of the
different point totals. So basically three,
basically saying, hey, you've done everything correct to something like 0 minutes, okay, one mistake, one
and so on and so forth. So basically from 0 to three, having some if else if
statements at the very end, there are two things
to keep in mind. So those are some tips that
you will have to keep in mind when you are reading
in a string from the user, please use scanner dot next and not scanner
dot next line. Because if you're using
scanner dot next line, that sometimes messes up the
way that this is read in. But I highly
recommend doing this. And then when you're reading
in an answer from this, ended up next, we have a string and you want to
compare that to a string. Don't use equals, equals, but use the input dot equals
and then put the answer, the correct answer inside
of parentheses here. This will also return
a Boolean value, and it will make this
a little bit easier. So otherwise, because there's sometimes does not work and
this will definitely work. So that's keep that in mind. And that is pretty much
the assignment right here. This is also written in
as text here as well. And I suspect that
for a beginner, this is something around
about 45 to 60 minutes. I would definitely recommend
taking your time with this. Probably going back
to the old lectures, taking a look at the
output input lecture, if and else statements lecture. And with that, you should
almost be completely done. Basically, that is pretty
much what you need. And then once you're done, you will have access to the, to the solution, of course, and I will also step through the solution in another video. So that would be it. N, Good luck.
14. SOLUTION 1: Trivia Game: All right, so you've
made it through the first assignment and here is the step through solution. So you've probably
already seen how it looks like an hour just
going to go through. So of course, the questions
here in this case are actually done as strings. That of course makes a
lot of sense, right? Otherwise, you can really save
the questions in any way. And the one answer is actually in an integer, that does work. However, I do also see
the point in making this a normal string as well. Over answers would be
correct. So no worries. There. We have an integer
points and then a scanner, and then we just start, we
output the first question. We then say the user
input number 1. We're just going to
put this in here. We're going to see if that is
equal to the first answer. If it is, we're going to
increment the points, output that it was correct and
you have that many points. And then otherwise we're
going to say incorrect and output the correct answer. After that, we're pretty much doing exactly the same thing. I'll putting the
second question, getting the user input again and equalling
it or saying, Hey, is this equal to
the answer here, incrementing the points
if it's correct, outputting that and
then saying no, it's incorrect, this is
actually the correct answer. And then the third time again. And then at the very end
here you can see that it basically goes through
sort of a cascade here. So points going
through three to 0. Then I also have sort
of an Easter egg here. When you have less
than 0 points you get, how do you even get
negative points? Because there's no
way to get those. You could of course also
something where you get some negative points
if you make a particularly like stupid
answer or something like that, that would also work. But I've not implemented
anything here. It was just an example. So that's actually
how that might work. So this is one example. Once again, if the actual
program works right? So if this works for you and you can play this
game and it works, but it looks different to this. That's absolutely fine. Like No worries at all. So that's the beauty here. There's multiple
ways to do this, and we'll see this in the upcoming assignments
as well as we are going to basically always use
this trivia game as well, sort of a template. And we're going to redesign this next few assignments
basically in a different way. And that's, I hope that you
will be able to see that it gets easier and different, let's say in the future lectures and the
future assignments. But that will be it for
this solution right here. I hope you found this assignment useful and you learn
something new. And I'll see you in
the next lecture. So, yeah.
15. (Java) Strings and String Methods: Or I will come back to the Java introduction here
for Minecraft modeling. And in this lecture, we're going to be
looking at strings and some string methods. Well, basically all around
the string so to speak. And we're going to first of all, start by making a new string
variable called sentence. And this is going
to be equal to, it's a wonderful
Dava introduction. Well, let's hope that
that is also true. But whatever the case may be, this is what the value of
our string variable here is. And we're just going
to print this out. So sentence right here, system out line sentence. And now the question is, what else can we do here? Well, the first thing
that we're gonna do is we're going to
actually duplicate it. Let's align. And
what we're going to say this is done by
Control D by the way. And what we're gonna do is
we're going to say length is, we're going to say
something like plus. And then we can say
sentence dot length. So as you can see, I can call the dot length with
the parentheses here, meaning this is a method call. We're not a 100 percent
sure yet what that is, but we've seen this
before a couple of times, and this is basically just
returns us the length. And if I ever actually
hover over this, you can see in an integer returns the length
of the string, length is equal to the number of characters in that string. So this is basically
Unicode units. Let's not worry about that. It's just basically equal to the characters in that string. Let's see. Length is 35. So that's
interesting here. And then also of course we output the actual
string as well. But what else can we do? We have to be able to do
some interesting stuff. Of course, we can. Let's actually get
this output here. Let's actually just
duplicate it three times. Why not? And the first thing
is going to be shouting. So that is going to mean
that everything here, I'm going to turn into
uppercase. How do we do this? Well, we can do sentence dat
to uppercase right here. This actually already suggested. And then of course
the same thing just would be whispering, right? And then we're going
to do sentence that to lowercase right here. So that's just going to first of alternate uppercase
and lowercase. And then just for the
sake of very middle, that's also just output the
sentence one more time. Let's also add a
commentary, right? So this is upper and lowercase. So fairly straightforward. We can just turn the entire
string to uppercase, an entire string to lowercase. And then here, well,
we should just get the lowercase
string as well, right? So if we just put this out, you can see shouting
everything in big letters, so everything in uppercase,
then everything in lowercase. And then here it's,
it's the normal string. That's strange, isn't it? Well, here is the very
interesting part about this. These methods actually return a copy of this
sentence variable. They don't change the
variable in themselves. So when we had things
like x equals x plus 1, we actually changed x is
0 or x plus equals 1. That changed the x variable. In this case, we're
returning a copy. So that's very important and you have to really
keep that in mind. But onto the next
thing, Let's say, I'm telling you,
Hey, what position is that Java found
the word Java. You're gonna be like, I don't
know, it's like exactly. So what we're gonna do
is we're going to just copy over the print line again. And we're going to
say the following. We're going to say the
word Java or something like this is found at position. Now we could count, we're
not going to call just yet. We're going to count
in just a moment. We're going to say
sentence dot index of, we can see there's a couple of different types
of index of here, but we want this string 1. It doesn't actually
matter by the way, which one you choose
here you can see that as soon as the cursor is inside of the
parentheses is actually going to suggest which
ones you want to do. We're going to take basically, and I'm going to say Java here. So Java, Let's just
see when is that? Like where does it happen? 17, okay, let's just count. So I'm going to start here. So my cursor is
always going to be on the left side of the character
that I'm counting on, 123456789, 10, 11, 12, 13, 14, 15, 16, 17, 18. And everyone's gonna
be like Wait a second. But that said 70, didn't it? Yes. It did say 17. Now why is this 18 though? Aha, see, this is a very
interesting thing because in Java or in most
programming languages, we're actually counting
starting from 0. Now this might be
absolutely crazy to you, especially if you were
very much a beginner. That's totally fine. Don't worry about it.
The thing about it is that you get used to it
very quickly actually end. There's a few other places
where we have to use this. But if we start counting at 0, you can see it's 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17. All of a sudden, the j is
exactly the 17th character, or rather it's the character
with index 17, right? So because this is
of course the index, the index of this, the index of this word. And we're basically looking
for the first character here. That's very interesting indeed, when we really think about this. And well what if
will actually we're, we're, we're not,
this is not correct. Where we're at is actually we
want to replace something. So system out print
line and we want to say a sentence that replace, and we want to replace Java
with, let's say C Sharp. But why not? Right? So you can see the target that we want to replace as Java, and what we will replace
it with is C sharp. So if I were to run this now. We'd see it's a wonderful
C-sharp introduction as not right, That's not okay. But in this example, of course, that's totally fine. So this is the replace method and that's also
very interesting. Once again, this is not
replaced it in the sentence. It has returned a new string, a copy of this that
basically replace this. Very important. It, maybe
we want to see whether or not a certain sentence
starts or ends with something. That's very easy actually, we're just going to duplicate the replace your once
again with Control D. And what we can just
say it starts with, you can see, and
I could just say, hey, I write and that would
be true in this case. And then we can also, can you guess what
the other one is, of course, ends with,
which would be, let's say an uppercase a, which is of course
false in this case, this would be true,
this should be false. So let's just see for
the sake of argument. And there you can
see true and false. Very easily done. Now what is if we have an, a string and we're just going to call this
S for the time being, and it's just going to be
an empty string, right? So a string with nothing in it. How can we check
that this is empty? Well, we can make
a Boolean empty. For example, we just
say S is empty. And there you go. That's pretty much
all that we need to. And if we were to system out, print line that is empty, we could of course also put S dot is empty inside of your, why bother, that's totally fine. And they go, this is
actually where is it true? It's true. Of course
it's true. Sorry. There you go, Right? Of course it's true
because this is empty. And there's one more thing that's really
interesting when it comes to sort of the Boolean
methods for the strings. And that is the contains, one. That's very interesting. So system out print
line sentence that contains, let's say Java. And this is of
course true, right? Because this contains Java, we should see r2 here
as well. Beautiful. What about the other way around? When we think about
index overhead? What about a certain character
at a certain position? Absolutely no issue whatsoever. System out print line, sentence, char at what position? Let's say 17. So we know
that it's going to be a. So they know that
it's going to be a j. That's going to be very
important and there is a J. Easy enough. Once again, we start
counting at 0. Therefore, while this
is the 18th character, is the character with
index 70, very important. That's, it might be hard, but after a little
while using it, I'm sure that you
will get used to it. And let's just do
one something else. And that's going to
be the substring. Interesting substring.
What does that? Well, let's do system
out print line, and let's just say
sentence dot substring. And where do we begin? Well, let's begin at index 17. But what it's now
going to happen is it's going to take
everything starting from like 17 and it's just going to return
everything afterwards. So this now the substring 17-year should say Java
introduction, exclamation mark. And of course it does as
well. That's very nice. So if we take another look sentence that you
can see that there are of course a bunch more methods
that you could call not, this is not an exhaustive
list that I've shown. I've just shown a few that
might be interesting here. I always recommend
trying out a little bit. You're trying out
a bunch of stuff. This great thing here is that it really is only typing
out a bunch of stuff, clicking the Run button and
just seeing what happens. And if something happens, that's cool, even better. And if not, if there
is an arrow by the, work through it and see
if you can't fix it. But that would pretty
much be it for the strings and these
strings method lecture. I hope you found this
useful and you'll learn something new if you did our very much
appreciate a review from you. Otherwise, I will see you in the next lecture though. Yeah.
16. (Java) Casting: Or I welcome back to the Java introduction here
for Minecraft modeling. And in this lecture, we're going to be
looking at casting. You can also think of that as converting datatypes
between each other. What does that really mean?
Well, let's take a look. So for example, we want to have an integer loan, which is, let's say $750 Euros, whatever the case may be. And then we have
a interest rate, which is of course
in float, right? And this is going to
be 0.0525, let's say. So this would be equal to 5.25% interest rate
at this point, should all make sense. So now we want to actually
calculate the interest. Now the interest, we should calculate that as a float
for the time being. And I'm going to show
you why in a second. So interest is equal to the loan rate times
the interest rate. That should also make sense. You can see that even
though I'm taking a, an integer times a float, it all works because we're saving this in a
float. Interesting. Okay, Let's do system out, print line and just print
out the interests, the sea. And it should be something
like 39, that's okay. Then of course,
if you sense here as well, That's totally fine. Now the question is, how
can we just make like multiply an integer and a float and get a
float out of it. That's pretty crazy, isn't it? Well, what happens
is basically that this integer in the background
is converted into a float. We can make this
explicit by typing mode in parentheses in front
of the actual variable. And then we have
this explicitly. So this is an explicit cast before it was an implicit cast. Now, the thing about
it is that we're going here from an
integer to a float. What happens if we make the
actual interests in integer? First of all, what's
going to happen is that this is going to show an error because as soon
as we have one float in a, in a mathematical
expression here, everything is going to
be turned into a float because flows have more
information, right? Because everything after the decimal point is
more information, therefore, everything gets
converted into a load. Now, let's actually explicitly
cast this to an integer. Now let's know Mori,
the background here being yellow
means that this is a, is basically a warning. We're not going to worry about this because I actually want to show you basically
what the warning is, warning us because
all of a sudden it's a big fat 0 and
you're going to be like, wait, how did they
turn into a 0? Well, when we cast a
float to an integer, what's going to happen
is that everything after the decimal
point is just cut off. So basically it's like this. So all of a sudden, interest
rate is going to be 0 when we cast it
into an integer, meaning that you're
just going to say loan times 0 is of course 0. And you can see that this is also what the warning here says. That's why we want
to get back to the float right
here. So they go. And then instead of
making this an integer, we're just going to keep this at the interest rate and normal. And that's going
to be fine though. This is sort of
the idea when you go from integer to a float. So from a, basically from less information to
more information, that's usually fine. Go from flows to integer. So for more information
to less information, that can have some
consequences, let's just say. So that is always what
you have to keep in mind. And this is also a thing. So basically this
idea of writing a different datatype in
front of a variable to cast it into a different datatype is something that we are going to see a little bit later
in a later lecture as well. So that is something to
basically also keep in mind. Well, but that would
already be it for this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in the
next lecture. So, yeah.
17. (Java) Ternary Operator: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture
we're going to be looking at the ternary operator. Now the ternary operator at first glance sounds like
something completely crazy, really complicated, but in
fact, it actually isn't. So we're going to
make two integers. One of them is going
to be the exam. This is just going
to be the exam result as an example here. And then an integer
called gift for this is, let's say our Father wants to
give us a gift of X amount. We're going to specify that when we actually pass this exam, though, how we could do
this as the following way. We can say if exam is
bigger or equal to 50. So basically we're
passing the exam, then we're going to
say gift is equal to 10 and then else
gift is equal to 0. Now we wouldn't necessarily
need this else here, but I'm just going to
add this just in there. And then we're just
going to system out print line if two. So no worries there. This should all make sense. But now what we can
do is we can actually write all of this
year in one line. And what we can do is we
can say gift is equal to. And then the first thing
that we have to do is write a Boolean expression. So for example, exam
is bigger or equal 50. Then we're going to
write a question mark. And then what we
want to return if the Boolean expression
here is true. So 10, then a colon, and then whatever we
wanted to return if the Boolean expression
is false, so it was 0. And this is the ternary
operator, question mark colon. And that pretty much is the
exact same thing as this. So what we can do is we can basically just copy this over. Let's just comment
out both of those so that regardless of
what happens here, this isn't assigned to. We're going to first have
a 0 output and then a 10. Let's see. There you go. So the 0 is of course this 0 right here that we've
assigned up here. And then the 10 here is
the ternary operator. So that's actually pretty cool. Now usually the ternary
operator is used. I wouldn't recommend using
it too much basically, but sometimes with like fairly
simple things like this. You could also think of maybe taking this Boolean expression, making a Boolean out of it
saying like asked exam. And then this reads a little
nicer right past exam, are that it's 10,
otherwise it's 0. So you can think
of this as well. So I probably wouldn't
keep it like this because this is something like
this not to redouble rate. There's too much
brain power that goes into looking at exam equal, little bigger equals 50. Okay? Okay. Oh, I get it. If you have something
like an is, does pass exam or
something like that as a Boolean that makes
sense in this case. But whatever the case may be, this is the ternary operator and basically the same
thing in if statements. Now, just because this
is all in one line doesn't mean that it's
necessarily better as well. Line count is no indication
of quality code at all, okay? And I want you to, I want
this to be very, very clear. It doesn't matter. A great
program can be 1000 lines. If it has to be 1000 feet long, it has to be 1000 night long. Just because you can
make that program 800 lines doesn't necessarily mean that it's better.
That's very important. Because the most important
thing when writing code is that you can read it and
someone else can read it, which includes you
six months from now. Because you're in six month is going to be
a different person because you will have forgotten everything you
wrote in your code. Therefore, you have
to make your code readable or other people, that's the most important bit. And if a ternary operator makes sense in that
case, that's great. I would never, I would
definitely advise you to never put multiple terminal
operators in the same line. Because of course
you could put in another ternary operator
on the true or false here. Definitely don't do that
because then it gets very, very complicated, very fast. Stick to if statements. In that case, whatever
the case may be, this would already be it for
this lecture right here. I hope you found this useful
and you learn something new. And I will see you
in the next lecture. So, yeah.
18. (Java) Java Arrays: All right, welcome back to the Java introduction here
for microwave modeling. And in this lecture, we're going to be
looking at arrays. Arrays are definitely
the, let's say, most complicated topic we're
going to be looking at, you know, up until this point. However, what I first
want to tell you is that if you struggle with this, no worries at all. This is totally normal. I also struggle with is, when we learned this. And at the end of the lecture, I'm actually going
to tell a little bit of a story about that. But for the time being, Let's remember back we
had E3 strings, right? We are at question
1, question 2, question 3, and answer one,
answer to answer three. Now, granted, the first answer
was actually an integer, but in this case it's a string. That's totally fine
because that's for demonstration purposes. It's a little bit
easier to show. And what we had here
was the idea that, well, we had those questions. Let's just say, I tell
you, you know what, your trivia game that was
in the first assignment, you should actually make
this have a 150 questions. Now you're going to be
sitting there going to be like, excuse me. Yeah. A 150 question. Well, okay. Then you start duplicating this and then
changing every one of them. Now, then maybe, you know, I, I know thing you can keep all
pressed and and, you know, change multiple things
at the same time, but then they all change
to the same number and it's all sorts
of just screwed up. It's not very good. So that doesn't
quite work. Okay. How else might we
be able to do this? Well, what we can
use is an array. Now an array, you can
think of that as a list. It's not a 100 percent
of list, right? It's a little bit
different because there is actually something called
a list in Java as well. However, we're going to
think of it as a list. And you were going to
make a string array of questions and a string
area of answers. And we're just gonna
take a look at what that basically entails. So how do we make an array? Well, we just type in
the type that we want. So the data type that we want, and then these brackets here, and this is going to be questions
and it is equal to new. So we have to take the
new keyword and you can see that this is already
being suggested to us. I'm going to type this out
string and then once again, the angle of the brackets here and then ending
with a semicolon. Now this is not done yet because inside of these brackets, we actually have to supply
the length of this array. So how many elements are
going to be in there? In our case? Well,
that's pretty much it. So that's pretty cool. Now. That's it. It's like yes, that's
pretty much it. And now of course we need
to assign something. So what we can say is questions. You can see that I basically autocomplete that with
the Tab key, right? The brackets again
and then assign, for example, one equals two. And then let's just take
this right here, right? So something like this. And I can just continue
with this, right? 23. And then let's just, well, how can I
output this right? How, how is this possible? Well, system out print line, and then we can
just say questions, no questions, there you go. And then for example, three-year now at my mean is
all the same, right? Now, let's just change this,
actually copy this over. So select this
control C control V, like this Control C Control V. And let's just bring
out the three here. That's just C and O know
what happened here? Well, what happened here
is that we maybe forgot. Now, I didn't forget, I actually
wanted to show you this. But what happened here is that we have to start counting at 0. So this is where we
get back when we saw the strings where we
start to count at 0 year, we counted 0 as well. But this means that when we have three elements in
this questions array, the first element is of index 0, the second is of index one, and the third is of index 2, meaning that three
doesn't exist here, and then we get an exception. We're going to see this at
the end of the lecture again, because I want you to like see the exception and I want you to understand what that means. But for the time being, this is how you assign
different strings, in this case, different
values to the array. And you can also read it
out pretty much like this. But that's actually
what all it takes. And let's also just
copy this over for the sake of
argument and call this the answers, right? And then we're going
to copy the swell. So I'll select this RP
here, here and here. And then we're just
going to change this to the answers here. So this is going to be 50. This is of course
going to be London. And then the last
one is going to be F e. Very interesting indeed. And then what we can
do is, for example, we can output the answers here. So we're just going to see
answers one in questions 1. And then all of a sudden
it says something like, well, what is the capital
of the United Kingdom? London? Very easy. And let's actually
change this to, actually, we don't need
to change this to a 0. That's totally fine. All we can do is
now, well, okay, Then can we just like reassign this so her
so we can take this. I'm just gonna take this. Actually, I'm going to write
it out those questions. Once again, bracket 0 equals, for example, how old is Ian? Msc, Gregor, right in 2020. That's just let's
date ourselves. Why not? That's totally fine. And then we just
output this again. Now the 0, let's
say, and the 0 here. The question. We've reassigned here, and then the answer is still
going to be correct. By the way, that is
something I have checked. By the way, as I did
want this to be correct. That's pretty cool. All things considered. The really cool thing is that here everything is sort of
in one data type, right? So questions now has
all of the questions. Instead of having three
different strings, we actually have everything in this questions string
array. That's pretty cool. We can also get the size of
the length of this array, of this list, so to speak, by doing questions that
length as you can see here. And we can just take
a look at this. This is of course
3 because this is what we have supplied
right here, right? So in this, we had to
supply the length. Therefore, this is
pretty much it. And you might have also seen
a lot of suggestions here. We're not going to worry about
any of those at the time being because all of those
are very, very complicated. And we then also
have is I'm actually going to copy over just
the tiniest bit here. So this is the array index out of bounds exception right here. It's pretty much what
we've already seen, but I'm going to show
this one more time. So if we put a number into the bracket that
actually does not exist, we're going to get
an array index out of bounds exception. So you can think
of it like this. Well, this is an array and it has a certain bound,
okay, fair enough. Like an index. So the index
that we're passing in, this is the index rate three. I want the question
with index three. Okay, fair enough. But that
is out of bounds because this area only has three elements and we
start counting at 0. So therefore, the index or the element with index
three does not exist. And once again, you get the really nice stack
trace here so you can get the exact location
where the issue has occurred. So that is also something
I wanted to mention here. Otherwise, that
would pretty much be the general gist of arrays. And now of course, the sort of thing I told
you at the beginning. So when I learned
areas in university, the interesting thing was that I didn't understand them fully. So I said, You know what, I don't need areas. I'm never going to use areas, ever. It doesn't matter. I'm just going to
stick with this. I'm going to make
individual variables. But of course, you're
going to run into very hard issues as soon
as someone says, well, then make like 20
different ones and then just like give
me get them out, put them in a random order. It's not going to work because these things
definitely have to be learned. This is also not the
right approach, white. Oh, I don't understand it. Therefore, I don't
have to learn it. Therefore, it's not
important, none. And of course, if it exists, there has some merit to it in that sense in the
programming here. So I definitely highly recommend taking
another look at this. Just staying calm, trying a few things out to sort
of understand this. And also once again, if you get any errors, no worries at all. Errors are totally normal
to get when programming. There's nothing like
there's no shame, doesn't like it's
totally normal, genuinely it every programmer, it gets multiple arrows
every day when they program. Even veteran programmers
still get arrows every day. So never feel bad
about that at all. And yeah, so that's sort of the general idea of areas here. I hope I was able to
sort of get the idea across that this is really
much like a list, right? It's not a 100 percent ellipse, but you can think
of it as a list. You put different elements into, basically with different
indices or indexes, you know, something
like that, right? But otherwise, this would be it for this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
19. (Java) Loops: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture
we're going to be talking about loops. What we are going to
need for this lecture are both of these
string arrays that we've made previously for the questions and
the answers anyway. But before we do
anything with the areas, first of all, I want you
to do the following. Output. Every number from
0 to 99, right? You're going to be like, Okay, system out, print line 0, then you might be like
duplicate one, duplicate two. Now you're going to
be sitting there all along time like that. Let's just be honest, that's
gonna take a long time. Well, and then come loops. So loops are something
where you can execute a piece of
code multiple times. And the first type of loop we're going to be looking
at is the for-loop. For that we're going to type in four and then parentheses. Once again, the
closing parentheses should generate automatically. And then we're going to
type in int I equals 0 semicolon I is smaller
than a 100 semicolon I plus, plus closing parentheses and
then an open curly bracket. Then the closing curly bracket should generate
once you hit Enter, when you take the system
out print line and put it inside of the
curly brackets here. And I'm going to change
the 0 to an eye and now see the wonders
of programming. As you can clearly see, everything is output from
0 all the way up to 99. But what is happening
here? Well, in a for-loop, the idea is that what we're doing is we're defining,
as you can see, we're initializing a, an
integer i e to the 0. And then we're saying
we're having some sort of Boolean expression here
and then an increment. What happens is
that I is set to 0. What is being checked
is whether or not I is smaller than a 100. If this is true, we are continuing
with this loop. So if this is true, everything inside
of you happens, then we're going to increase I and then this
is checked again. And then we're doing this
again, increasing I, check increasing i and
so on and so forth. So this is basically done
forever until this year. This Boolean
expression is false. And once it's false, meaning that I is no
longer smaller than a 100, which happens once i is a 100, then this is no longer executed and
everything afterwards, after the curly bracket
here starts to happen. This is why it stops
at 99 and not a 100, because when I is 99,
this is still true. 99 is smaller than a 100. Everyone agrees, yes. But as soon as it's a 100100
is not smaller than a 100. It actually is in
fact equal to a 100. Therefore, this no longer
basically is true. Therefore, this is no
longer executed for a 100. And that's sort of the idea. And that's really
cool, isn't it? Like we can very easily do this? And now I'm going to
absolutely blow your mind. Do now I'm going
to tell you, well, output all of the
questions and answers and you're just going to
occupy system out print line. Now question 0, answer 0, just like we had before. Well, this is going to be
easier for int I equals 0. I is smaller than questions
dot length I plus, plus. And then what I'm
going to do is I'm actually going to
copy this one twice. And then instead of
this, I'm going to call questions I oh, that's interesting,
isn't it? And answers I. Now this, that's pretty cool. So you can basically
pass in the integer here into the
brackets and access, well, whatever index you want and whatever index
this integer takes on. Another really crazy
thing is because we are actually looking at the
length here, right? Because we have the length, this immediately saves
us from any errors. Now the only error
that might occur is if we all of a sudden make
this four here, right? Because we're taking
the length of the questions while the
answers is not the same. So then we could
run into an error. Once again, the area out of bounds exception or the array index out
of bounds exception. But for the time being, when we use the lengthier, that's going to be totally fine. And if I just run this, you can see it prints
out everything. Harmony sits at the
US AIR 50 capital of United Kingdom, London. And then chemical
symbol for iron is Fe. So that all works. So that's pretty, that's pretty insane, right?
That's pretty cool. Or loops insanely valuable and can be used for all
sorts of stuff. There's another
type of loop which is very similar to the for-loop, which is the for each loop. Now you can see if I can
actually type that in and I could press the Tab key
to autocomplete this. However, I will not, because the formatting is
a little bit weird for me. I don't know, quite know
what that is the case. We're just going to write
in for that I can say string Western Poland questions. And the way to read this is for each string question in questions, this is how
you would read it. And then you can just do a system out, print
line, question. And I can just print out each
individual question here. Once again, that's
just going to work. So as you can see,
there you go, uh, basically now have access to what the individual elements inside of that list or
array in this case, and I don't have to specify
it via the index here. I'm actually getting all
of them well individually. So this is the for each loop
and this for each you go, That's another type of
loop that's interesting. And then the last
type of loop that I want to show you
is the while loop. Now, I have a personal
preference to very rarely used the while loop
simply because of the fact that it can be, well, it can get
you into trouble. So we can say
something like while true and then curly brackets. So what happens is
that everything inside of here is going to
happen while this is true. Now obviously, when you think about this for a
second, wait a second. If I put in true, then this is always going to be true exactly. This is now a while loop and a while loop and endless, right? So this is an endless
loop and this is the danger you might run
into with a while loop. You could run into the issue with for loops as
well in theory, but it's very rare that
are actually happens. But in while loops, it's very often the case or it can be the case that you
have an endless loop. Now everyone has to go
through that at some point. I'm just saying that my bias is that I don't really
like while loops. But what we can do is, well, let's do the following. Let's actually add an
input for the person. So Scanner here, scanner equals new scanner system.in
and then done. But what we're gonna do is we're just going
to say something like the following
system out print line. Do you want to continue? But so we're just
going to say, Hey, does the person want
to continue to use? We want to continue. And then we're just going
to say, hey, if scanner dot next, right? If that equals yes. Then what we're gonna
do is we're just going to continue, right? So continue the actual keyword
else we're going to break. This is an example here of the Continue and
the break keyword. The continue keyword basically ignores everything that
comes after it inside of the loop and jumps
back to the top of the loop where the break
keyword breaks out of the loop. So basically it goes
to the end of year and everything afterwards
is then executed again. This would be the same if this all of a
sudden turns false. In this case, this is of
course an endless loop, right? So, so as long as
I type in, yes, this is going to continue and as soon as I type
in anything else, it's going to break out of it. So that's sort of the idea
of this while loop here. Let's actually take a look
at this so I can type in. Yes. And I can type in, yes.
And I could type in. Yes. And then I'm going to make
a mistake here and an OH, no, All of a sudden
the code is stops. That's sort of the idea. So this could be an endless loop with sort of a braking system. Now what's very important
is that the continue and the break keyword
should probably only be used sparingly because there are a lot of developers
who don't like this. Because if you have like, let's say a longer FOR
loop or longer while loop and you have a lot of
Continue and breaks in there. Sometimes can be a
little bit confusing. Like to read it, right? Because you're going to have
more branches so to speak. So you can think, if you can
think of way of doing it in a little bit of
a different manner that usually is better. Whatever the case may be. Those are the loops that
I wanted to show you. Really pretty cool stuff. And we're really starting
to get some very, very cool tools in
our toolbox to really work with code and to just program something
that's really cool. So, but for the time being, this is it for this
lecture right here. I hope you found this useful and you'll learn something
new if you did, I would very much appreciate
a review from you. Otherwise, I will see
you in the next lecture. So, yeah.
20. (Java) Java Methods: Welcome back to the
Java introduction for Minecraft modeling. And in this lecture, we're going to be taking
a look at a methods. So first of all, we once again require
the string areas here. We don't necessarily
require them, however, we are going to use
them in this lecture. And well, methods. What are methods? Well, we've seen
this word thrown around a few times before
with the string methods. And also something like system out print line is also a method. And I might have said once
or twice before main method. So there is something to this. We've seen the math
methods as well, so we've definitely
heard that word before. What is it really? Well, in theory, a method, you can think of it as
a few lines of code, one line of code or a 100
lines of code in theory, that are executed when
you call that method. So you call a method
like for example, when we type in a system, system out print line, right? And I say Hello, read this. It's something in the
background, happens, right? So this print line,
when we call this, this method here, something
in the background happens. Now we don't, in this case necessarily know what
exactly happens. But something happens to
that this hello, right? Once I run this, so
that when this happens, something happens in the
background that this hello is now being displayed
in this Run window. So we don't really know what, but something in the
background happens, so some code is executed. So if we have a piece of code that we might
want to reuse, let's say a 100
times in our code. Then you might say, well, we can just make a for-loop,
you know, a 100 times. Well, but what if I want to do this at different locations
in my code, right? So maybe I want to ask a
question in this case, right? And an output and answer and
then check for the answer. Then I want to ask
questions again. It's like, well,
I mean, you could do a for loop, but well, maybe we want to make some
if statements in there. It's going to get a
little bit complicated. So this doesn't always work. So let's say, for example, what I wanna do is I just want, I wouldn't just
something that I can type in that I can give, let's say a, an array here, red. So the string array
of questions, a string area of answers, and that just outputs meet all of the answers and
all of the questions. So all of the questions,
answers just in enroll. So I could of course write
something like this. Right eye for loop
int I equals 0. I is smaller than
questions that links, Let's say I plus, plus. And then I could just say system out, print line questions. I write something like this and then duplicate this
and then say answers. I could do that. Well, let's say once
again, I want this to be done a 100 times
throughout our code. Now the observant of
you might say, well, why don't we just put this for-loop into another for loop. And you would be
absolutely correct. You could do that as well. However, let's not
get too clever. Let's just think about this
and make this a method. Now, what we're going to
do is I told you before that we are only operating between these two
curly brackets. We're, we're expanding our world now and moving outside
of these curly brackets. Because now our
new curly brackets are those two basically. So now this is our new home. And this, you might have
sort of thought about this. Well, this is the main
method that is basically being executed when we
press the Run button, then the main
method is executed. Now we're going to
add a new method. And first of all, going
to write this out. And then I'm going to
explain what happens here. So we're going to write
public static, void. And I'm going to call this
output questions and answers. Then I'm going to type
in a parenthesis, the closing parentheses should
generate automatically. And then I'm going to
make a string array here. So this is going to be
the questions and then a, another string array
answers, right? And then I'm going to
make a curly bracket. And you see that the
second curly bracket has already generated. I can just press the
Enter key and then the formatting should
also be complete. And with this, a newer
method has been created. So for the time being, we will ignore is this
public and static. We don't quite know
what that is yet, but we're very close
to figuring this out with in a future lecture. We're going to actually
figure out what that means for the time being. We just know this is
an access modifier. We don't know what it does yet. We just know that we
need to have public static written here and then everything is
going to be fine. There's void here is actually the return type of this method. So some methods return something and we'll see
this in just a moment. So after we've done this method, we're going to make
another one that actually will return an integer. Then we're going to have
the name of the method. Now this is something that
you can decide yourself. Usually, naming variables and naming methods should
be very expressive. So even though this
might very long to you don't shy away from long method names or
long variable names. If they exactly describe
what they are doing, that is going to
be the best thing. Then after the name, come, the parentheses here. And inside of the parentheses, we basically also define
a variable sort of speak. And those are called parameters. So we have two parameters here, and both of them are
of type string array. And overall, this
entire thing here. So all of this, right, the access modifiers,
the return type, the name of the method, and the parameters is what's
called the method signature. So because we need to know this, method signatures have to be. Unique meaning I can't
have the same thing. So I'm going to
select all of this. And then I'm going to say
Control C and then Control V. And you can see that
if I hover over this now we're going to say is
already defined right here. So this is exactly
the same thing and it's already defined. That doesn't work, right? So that's very important. However, if I change
the method signature, meaning for example, I make one less, I put one less parameter
in here that works. You will, they have
the same name, they have a different signature. So this, in this case, would now be called method overloading because we
have the same name, this with a different
signature off. So for example, different
number of parameters, different types of parameters,
different return type. That's sort of the ways you can alternate year for having
methods of the same name. This is going to
get interesting, maybe later down the
line for the time being, we're going to delete
this one and we're just going to keep the one
method right here. And what we're just going to do is we're actually
just going to take this Control X to cut it out, Control V to paste it in. And all of a sudden you can see everything is working totally
fine because of course, we are having the parameters
here, Westerns and answers. And the idea is that we're
going to pass those in. So because right now of
course this questions, this answers, those are
not the same as these two. I can call this, let's say Q0, Q, Q u, e, just for
the sake of argument. And I'm going to call this E&S just so that there's
no misunderstanding. This year is not the same as this because I could
call this with, of course, a different
string array of questions in a different
string area of answers. So this is going to
be very general. This is just going to do this for any area
I'm gonna put in. So that's the really cool thing. Then what I can do is I can
call this, I can say output. And you could see as
soon as I type in out, the actual method is being
recognized by the program. It actually suggested here. So I can just put
in the tab key. I can press the tab key and
it automatically generates your and I can just
say Q0 and ANS. So now I've passed in the
questions string array as the question perimeter and the answer string array
as the answer parameter. You might, what you've also
might have seen is that the method turned
from gray to yellow. This simply means
that this method is actually being
used, so being called. And that's also a,
an important idea. And if I now run this, you will see that it actually works. You
can see how many sets. The US, they have 50 capitals, United Kingdom,
London, and chemical symbol for iron is F, e. So it outputs this and it just basically calls all of the
code of this inside of here. And now of course,
methods can call methods, and methods can
call other methods. So this, of course, does get quite complicated
at some point. However, for the time
being, this is really cool. Now, we're also going to
make a method which is, might be very complicated. So what we're going to
have as one's going to public static int. So we're now going
to be returning an integer and we're going
to sum two numbers together. So for that, what do we need? Well, of course an integer
x and an integer y. Now, once again, the
names of the parameters, by the way, also can be
whatever you choose to. Usually you want them also to be very expressive in general. Now we have this sum
method right here. And what we're going to
do is we're going to type into the return
keyword x plus y. There you go. So we're just going to return x plus
y because that's of course the sum of
these two integers in that case, nothing
too spectacular. However, what I did want
to show you is basically the return keyword
and that you can return different types as well. So the SAM method in this case, we can just take a
look at this, right? So system out print line, and then we're going to say
some ten and let's say 12. And then if I run this and it should say 22, there you go. So no worries at
all, that all works. And that sort of the general idea here that
you have with methods. So it can either
return something or it can nab return something, then you have to
write in a void. But that's sort of a
tentative look at methods. Of course, once again, you really have to
also apply this a little bit to really get
the understanding here. However, that is a great segue to the assignment which
is going to be up next. I highly recommend
making like doing the next assignment because that's going to be
basically methods. And even if you don't get Sue will basically do
everything in there, at least looking at
the question and then the solution to
it will hopefully illuminate also the way that you can use methods
in your own code. But for the time
being, this is going to be it for this
lecture right here. I hope you found this useful
and you'll learn something new and I'll see you
in the next lecture. So, yeah.
21. ASSIGNMENT 2: Trivia Game with Methods: All right, Welcome to the second assignment of
the Java introduction here. And in this short video, I basically want to
explain the assignment. So overall, the assignment
is not actually that complicated over I still want to basically walk
you through this. So the idea is that you should recreate the trivia game
from the first assignment. So basically pretty
much the same thing. But this time you should have five questions and five answers. And the way that you should
save those is in two areas. One for the questions
and the answers. And what you should also do
is you should at least create two methods to make the code more readable
and easier to follow. And basically as a hint, you're going to think
of it like this. When you have some
duplicate code, you should probably make
that into a method. We'll think about that. Think about where you
might be calling something twice and then you can basically make a
method out of that. And what you should also
do is you should make an endless loop and then some if statements in there
in some capacity. So some logic, who make
the user to prompt the user to keep playing or not if they don't
want to anymore. I highly recommend
taking another look at the loops lecture
again because they are actually had a very
similar use case that they are aware we
had an endless while loop that you can stop with
them IF statements and the break and the
continue keywords. So those might come
in very handy here. Otherwise, overall, this should be fairly
straightforward. The game in and of
itself should play very similarly actually
than the first one. It should just look a
little bit different. So overall, that would
be the entire idea. Of course, don't forget things
like the points as well. Also the, you know, add those as well. Otherwise, this is pretty much all that you
really need to do. I suggest round about another hour or so
for this assignment, depending of course
on your level, you might also do it
in like 30 minutes, 45 minutes, who knows? But don't stress yourself. Take yourself some time
to really dig into this. Watch a couple of lectures
again, the loop lecture, I highly recommend
methods lecture was very nice areas if you don't quite fully
understand those, I highly recommend this. And otherwise, of
course, the solution will be available
to you as well. So no worries there. Otherwise, I wish
you the best of luck for this
assignment, though. Yeah.
22. SOLUTION 2: Trivia Game with Methods: Or I welcome back to the
second assignment and the solution to the
actual assignment here. So once again, the code is
of course available for you. And as a, well, basically
disclaimer here, if your code doesn't a 100 percent match the
code that I have, that is of course totally fine. There's no shame in that because there's always multiple
solutions to this. And I do think that my solution may be uses a few,
too many methods. Actually, interestingly enough,
but for the time being, we're just going to
step through it. So of course, the string arrays, questions and answers should be fairly self-explanatory here. Same with the scanner once
again to read stuff in, and then a points total
here, just core points. So that's fairly
straightforward. We have a while loop
that is always true. So you can see this is basically the entire
while loop here. And let's first of
all take a look at the very bottom here. So this print play again, method prints out, Hey, do
you want to play again? If you put in a y here, then it basically resets the points and then continues
with this while loop again. Otherwise, it just breaks
out of the while loop. And then prince de goodbye here. That's sort of the idea. Otherwise you can very
easily actually follow this. Does the names of the
methods almost entirely describe what they are doing and then see Print
title, Fair enough. And then we're gonna
go through for each of the questions here
for this for-loop, very, fairly
straightforward as well. And we have the print question here for the question
that currently is basically being asked BY then
read in the user answer. And then we have an if statement that calls another method here. So is correct answer
from this user answer. And it basically compares this to the answer that is
correct for this question. If this is the case, so if
this method returns true, we are then printing out, you had a correct answer
where then increasingly points total and writing that back into the points variable. And then here we're
also printing out the current points
total basically. And if this was not
the correct answer, then we're printing out that
you had an incorrect answer and we're also printing out
the actual correct answer. That pretty much is all
that we really need here. And you can see then at the end here we're just printing out the point total and then asking the player to basically whether or not they
want to play again. So that's the entire logic here. And then if we go down, we can see that there are
a lot of methods in here. And all of them are very,
very simple, right? Almost all of them
just one light, basically all of them
just a one line. Now, you can make a
very good case that, that might be a little
too much of a good thing, can also be a bad thing
in this case, right? Or too many methods
might be too much. However, this definitely is
very easy to follow here. There's also points in saying, well maybe we could just take this entire IF statement
and make a method. Are that as well, we could maybe take the entire for loop, make an entire
method out of that. We can take this part and
make a method others. So there are multiple ideas that you can follow
and you could still, of course make more methods
out of this or fewer. That's totally fine and
that's totally okay. As long as it works, you
have a few methods you made, then it's going to
be absolutely fine. So once again, if this is
not exactly your solution, do not worry about
that in the slightest. Once again, the
beautiful thing about programming is that
there are always, I mean, there's a million different ways that
you can do this. Of course, some of
them are going to be more optimized than others. But at the end of the day, when we really think about it, this is totally going
to be fine usually. So if this isn't a 100 percent correct like you have
it, that's okay. If it works, I'm already
very happy with that. Otherwise, this pretty
much is my solution. This code is of course, also available to you. Otherwise, I hope
that this assignment was useful to you to dig a little deeper into the idea of methods and how to use them. I can always, of course, also just suggest playing around with it in your own time, just trying out a
bunch of stuff. At this point you have a
lot of different tools. You have if statements, you have loops, you
have methods, arrays. So there's a lot of stuff that
you can play around with. You can read stuff
in from the user. You can write out
stuff to the console, which at this point actually just opens up a whole
bunch of stuff to you. So if you want to make sort of like a choose
your own adventure, just a little tiny thing, right? Go ahead, right, just try
out a bunch of stuff. I highly recommend just
being experimental with it. You, you can't break
anything here, right? As long as you write your
code in here is just for you, it's all going to be fine. Like I've already said in the
lecture about the errors. If you get some errors,
no need to worry, this is not the end of the world and everyone gets arrows, right. I get arrows anytime, like when I program, of course, there's going to be arrows
and that's totally fine. As long as you
work through them, you try to understand
why did I get this error? How did that happen? And sort of something like that. But this would be it for
the solution right here. I hope you found this
useful and you'll learn something new and I'll see
you in the next lecture. So, yeah.
23. (Java) Java Collections: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture,
we're going to be taking a look at collections. This will include a
realist maps and sets. Though especially sets is
something that is used quite extensively in Minecraft
modeling in general, but in the Minecraft codebase. So sets are very
interesting things, but we're going to first of
all start with an ArrayList. Though. We will think back
to the string array, which we were able to
define like this, right? So questions for example, here, with a new string array, let's say of size two. And then we were able to assign those questions
kind of like this. How any states, no States? Does. The USA half goes
something like this. And we could
duplicate that line. The other one as well. For example, making this a
little shorter capital of UK. So that works totally fine. No issues whatsoever rate. However, one of the things you might ask yourself is right, but what if I want to
change the number of questions inside of this area? Well, you have to change
this number right here. And that can be a
little annoying, right? Because then you have to go
in here, have to change this, makes sure that if you then
have a area that has answers, you also have to change the size of that, and
so on and so forth. So kind of not the best thing. And for that we're going to
take a look at a list now. So we're going to
type in lst, so list. And you can see that it already basically suggests
us at this one. And we're just going
to press the Tab key, which is now going to import
something at the top here. If that doesn't happen,
I'm going to show you in just a moment how
you could fix that. And then you're going to put in the angle bracket right here. So angle bracket and the other one should
automatically generate as well. And then we're gonna put
in a string right here. And then afterwards we're going to call this the question list. And this is equal
to a new ArrayList. You can see that this is already being basically suggested to us. Once again, I'm going to press the Tab key to
automatically generated. And we're going to end
this with a semicolon. And the first thing that you're
going to see is that we, we have not defined any
length for this list. And this is exactly
right because there's no need to define
a length for a list, because a list is sort of dynamically while
Lengthen solar speak. So basically we can
just add stuff to it, add elements to it and the list we'll just
expand dynamically. So that's really cool. That's the first
very cool thing. So we can say question list, dot, add, and then put a string. So for example, what language
is spoken in Germany? As a question here. And then I can just
duplicate this. And for example, say, what is the capital of Canada? And then at the end here maybe
something like, you know, let's just say in
what hemisphere? Hemisphere is Brazil. But just for the
sake of argument. So those three
questions examples, just add it to the list, and this will now be the
element with index 0. This will be the
element with index one, and this will be the
element with index two. So that's really cool. And the first thing
that we can basically say is that lists, right? They are basically add entries
or elements dynamically. So that is really
freaking cool, right? So we can add and well,
even remove stuff. How would you remove stuff? Well, that's actually
fairly easy as well. We can just say question
list dot remove, and then either I can put
in the index that I want to remove or I can put in the actual object that
I want to remove. So I could also pass in
the actual string here, or I could just say one. And then it's going to
remove the question, what is the capital of Canada? That's pretty cool.
Now, the next question you might have is, well, how are we able to basically
get the length of this? Well, we can say
question list dot. First of all, you're
going to get a lot of things suggested here
as you can clearly see. A lot of things most of which don't interests
us at the moment. We actually have to use the
size method right here. So size with the parentheses, meaning of course that
this is a method call. And this returns as the length
or the size of this list. And how can I get a, an element out of this list? Well, we can just
type in system out, print line to print this out. And then we can say
question list that GET. And then here we have
to pass in the index. So in this case 0 for example. And if I just run this, you will see that
we're going to get two for the size
because of course we have removed the first question or the string with index one. And then the element
with index 0 is still going to be what
language is spoken in Germany. So that's pretty cool. All things considered. Now, let's take a look
at something else. And that's going to be a list of integers, for example, right? So numbers is equal
to a new array list. And what you're going to see is that this some issue here. So ArrayLists rates
something like that. And then you can see
that it's sort of, you know, it doesn't
behave quite right. There's like a red
underlines here. What is going on? Well, if we hover over this, you can see type argument
cannot be of primitive type. That means that
we actually can't use in Boolean and
stuff like that. However, before you. This may and say, Oh my god, that's the worst thing ever. No worries. There are wrapper classes
which you can use so you can actually
see replace it with Java Lang integer. Well, I can either click on this or I can just type an
integer right here. So this one, in this case. And if you use that, then everything works fine. So these are this list and these angle brackets are
what's called generics. And the idea is that you can
put any datatype into here, except for the primitive ones. That's very important for those we need those a wrapper classes. So there are wrapper
classes, right? We can use, can use
instead of the primitive, a primitive datatypes the u. So this is very important to remember here there are
wrapper classes and they should exist for every one
of the primitive datatypes. So no worries there at all. And here we can very easily
just say numbers at, you know, were 20 for example. And numbers add
something like 42. No worries at all. As you can see, we can
just add those numbers in here and they're normal integers and we can basically use o. That is totally fine. But I did want to mention
this that you can't use the primitive data types in these generics as
they are called. Like I said, generics are these tour of these
angle brackets, right? These angular brackets. And everything that's
inside of it is called a generic because, well, it is generic in the
sense that we can put in any other class
or any other object, any data type that
we want into here. And it will just work. This by the way, includes
a list as well, right? So we can have a list of a list. Of course, why not? Right? We multiple lists
that would also work. But for the time being, that
will be it for the lists. Let's take a look at maps. So maps are very interesting. Read, a map is the
following thing. A map contains a
key and a value. And the key, the
key actually maps, right key maps to a certain value that
all should make sense. This is called a key value pair. Okay, fair enough. What can we see? Well as just type this in
map as you can see, and we have two different things in the angle brackets this time. So let's import this, right? So you can see that this
is also imported here. If those aren't
important automatically, you can see that things turn red and you can very easily
do this yourself. You can just click on this
and press Alt and Enter, and it will import this class. You can see I have
also had to do the same with the ArrayList. And then down here for the map, actually don't have
to do this just yet because I'm not done yet, but we will see this
in just a moment. We're going to have
a map that maps a string to another string. And we're going to call this
the country to capital map, which is going to be equal to
a new HashMap in this case. And then what we
can do is we can just press Alt and Enter. And then it's going to be
important here as well. But those are very important,
those imports basically, so that the program knows that we are using these
datatypes, right? So the list, the ArrayList, the map, and stuff like that. And what we can do
now is we can add to this country to
capital MAB as well. So we can just say put and
that puts in new values. So for example, Germany
would be Berlin. Hopefully you knew that one. Let's do another one. So let's actually just duplicate
this a couple of times. And we're gonna say France. You know that one that
is Paris, of course, early straightforward, Italy, Wu now it gets interesting
Rome of course. And then we're going
to have a USA, and that is going to
be Washington DC. So very straightforward. All things considered here, as you can see, I can put
in two strings, right? Because this is what
I've defined here. Those do not have
to be the same. I could put in an integer
year, a float here, I could put in a string here, a list here.
Anything would work. This does not have to
be both of the same. That's very important. I also wanted to mention that. And how do we now get
a value out of a map? Well, let's say system
out print line. And then we're going to say
country to capital dot get. And you can see I have
to supply a string. And what I'm going to get out
is of course a string here, but this is what
I have to supply. And then this is what
I get out of it. So the return type
and I put in Germany, and then Berlin
will be output as Germany is the key to
the key-value pair, Germany, Berlin should be
fairly straight forward. I can also ask whether
or not the map contains a certain key or
contains a certain value. So I can say system
out print line. And then just so
that everyone knows what we're asking here
contains key Germany. And then we're going
to say, country to capital dot contains key, Germany, which of course
is going to be true. Then we're just going
to duplicate this. Then we're going to
say contains a value. So we can also ask for
values, London for example. And then we can call the contains a value
method right here, pass and London right here. And then if we just run
this, we should see. First of all, right here, Berlin rate is the capital of Germany and
then contains key. German is going to be true because it does contain that
key and then contains value. London is going to be
false because of course we don't have London
urine here as a value. We can also remove
things from a map. So once again system out, print line and connect to say, I can say country to
capitalize, dot remove. And the cool thing about
the Remove you can see is that I can either pass in the key or I can also pass in both the key and of
the object as well. And then it's going to return a true if that has
been removed because maybe those don't
match and you want to a specific
functionality here. Otherwise you can just pass
in the key and then you will actually get
the return as well. So you will get a last, last store of value year. So this should now say Paris. And after that, brands is
actually, as you can see, and after this is basically
removed from this map, that's a very interesting
idea of maps. They can be incredibly useful. However, it is, of
course sometimes it's hard in this
abstract sort of ways when I just show those where you can really use them. Using these data types, sometimes can be, well, it's not an exact
science, right? So sometimes you want
to use something. I'm not sure if this fits. Once again, just try it out. Steve works and then
you're going to be fine. And then last but not least, what we're going to
take a look at sets. What sets, as I've mentioned, are things that are used heavily in the
codebase of Minecraft. And a set is just a collection, a collection that
contains no duplicates. Well, that's the most
simplest definition of a set. It just is a, well, a list or a collection that
doesn't contain duplicates. So a set, for
example, of string, we could have this as
usernames, for example, with each issue which is equal to a new
HashSet in this case, then you can see this has also been imported
and now this has turned into a story here
because all of those are in, under the util package. So it actually doesn't have
too many imports here. It's sort of does
that on its own. That's very nice. So now we have a
set and we can of course add to that
user names dot add, for example, cotton job. Or we could say
usernames dot add, nano tech right here. And then we can say, well, okay, fair enough, This
is really cool, but what else does a set do? Well, once again,
if we now want to add something twice, so you can, for example, say something
like usernames add, let's say FV, right? And then I duplicate this, and I want to add it the
same name twice, right? We're actually going to
get returned eight faults. Here we get a true,
here we get a false because this is
already in there, the string is already
inside of the collection. And because it contains
no duplicates, we can only ever have it once. If I actually all this, you will see that the
first one is true because of course F or V
was not added yet. And then after it has been added and we try
to add it again, we're going to get
a return false. So that's a very interesting. Over all the sets, you can't really call individual things
inside of the set. The set is really a collection that should be used
sort of together. And I just wanted to just gently introduce the sets here just so that you've
heard about them. So once we see them inside
of the game basically, or inside of Minecraft code, then you're not going to be
completely caught off guard. So the last section here, arrows you might
run into, right? So that's always a, an
important thing though. You can just, let's
just do this. Uncomment were arrows. I just saw where errors, please, not for terrorists
that, that would not be good. Lets actually copy this over for the sake of
argument and we're just going to change this C to a small c and n are
going to be fine. So the first one is the index
out of bound exception. So let's just do the following. Let's uncomment this. And first of all, this
is the question list. There you go. No worries at all. And if we do this, then you will see we get an exception here, the index out of
bounds exception. So this is a very, very similar exception
to the array index out of bounds exception
is just with a list. That's pretty much all there is. So we tried to pass in an index into the getMethod that
doesn't exist for lists. So of course, when we
only have two elements, the first one is of index 0, the second one is of index one. So very important
here that of course, passing any two would
not work, right? So that's the first exception. And then, well, the other thing is not
really an exception, but it is going
to return a null. So if we pass in a key into
a map that doesn't exist, we're going to get a
null returned, right? And that might lead to
an arrow down the line. So if I do this, then you
will see that if I do that, we'll get a null at
the bottom here. And this is basically
right, of course, Malta, we don't have that in our
country to capital Mab. This is actually going to
get us returned a null. Therefore, it might be
very valuable to see if it contains a key before
you actually try to get it was great. Getting returned a null is
not the end of the world. Of course not over if you then, if you don't expect
this to be null or you don't handle this to
be null possibly, then you might run
into some issues. Well, those are some of the
errors that I definitely wanted to mention here as well. So those would be, well, the sum of the collections. Of course, there's plenty more, there's plenty more datatypes
that you could use. You know, there's
not only list's maps and sets, There's plenty else, but for the time
being is going to be enough to basically
get you started. So this would be it for
this lecture right here. I hope you found this useful
and you learn something new. If you did, I would very much appreciate a review from you. Otherwise, I will see
you in the next lecture. So, yeah.
24. (Java) Object Oriented Programming Explained: Or I welcome back to the Java introduction here
for Minecraft modeling. And in this lecture, we're going to be talking about object oriented
programming. And as you can see, we are
actually on PowerPoint. In this case. We're
actually going to have a little bit of a PowerPoint
presentation here. So let's actually
just start with the idea of what is this
object-oriented programming? Well, in this lecture,
we're going to go through a little bit of the
theory and some of the terms that you
will well basically need to familiarize yourself with in order to know what is going on and to
understand the parlance when talking with
people that know programming and when I
continue along with this, so especially in
the Minecraft part of this lecture or this course, you're going to see that
I'm going to basically always use the terms that
are necessary to use. So classes, methods, objects, stuff like that, and you
should know what those are. So the first thing that
we can think about is everything is an object. Okay, let's, let's store
that as an information, as a piece of information
and we can create custom objects with
custom functionality. Interesting, Okay, and these
would be called classes. So a class is, we can create an object from
a class, okay, Interesting. And in classes can
inheritable functionality, which would be methods,
variables from other classes. And we're going to see two basically Theory
examples of this. And then in later lectures, we're going to take a look at some practical examples as well. Well, first of all, let's go through the very
important terms here. So a class, or classes are custom or
user-defined data types. But now we get actually
to the point where you can make your own datatypes. And those classes then
can basically be used as templates to create objects. And these classes include methods and fields which
are called members. Let's take this one
step at a time. So a class is a custom or user-defined data types
that pretty cool. And those include
methods and fields, which we're going to
talk about right here. These are members and how they can be used to create objects. Now what is an object? An object is nothing else than an instance of a particular
class with defined data. We're going to see an example
of that in just a moment. So this will get a much clearer. But first of all, let's
talk about the members. Those should be fairly
self-explanatory or way easier than the objects. So members of a class is
either a method or a field, and you can also call
methods functions. Now, people who are a
little bit more into Java might know that this
is not strictly necessary. So functions are tiny bit
different than methods. For our purposes,
it's totally fine. Some people still say functions, even though there are methods, it's going to be fine
and no one's going to go crazy with this. We don't have to be too
pedantic on this, right? So methods or
functions basically define specific
behavior for an object, and methods can be called
for specific objects. So one example of this, which we've already
seen is something like the size method for
a particular list. Of course, every
list is going to have the same size method. What is going to be returned is specific to a specific list. So for that object, but that's sort of
the general idea, fields or attributes as they're also called our
variables that are defined in the class that store some data related to that class. So for example, if
we were to have a person class that might
save a string called name, that should also make
sense and should be fairly self-explanatory
as this example here. And once again, all of
this we will of course, also see live in action, I believe next lecture
we're immediately going to start to jump in to
classes and objects. So no worries there at all. So let's first of
all take a look at the idea of inheriting stuff. So this, I want to, first of all preface
with the idea that if you don't fully get this,
that's absolutely fine. Inheritance is very complicated. I just wanted to mention this so that you have
heard it once before. But the idea is
that we might have an animal class, right? And that actually
basically inherits all of its functionality and all of its variables down
to two classes. So the two-legged animal and the four-legged animal class, and these are related
in the following way. The animal class is
the superclass of the two-legged animal and the superclass for the
four-legged animal. While the four-legged animal and the two-legged
animal classes are subclasses of the Animal class. You can always only
have one superclass, but as you can see, you can
have multiple subclasses. And then here we can
even go further down and inherit even a more stuff
and add more functionality. So you sort of go
from a very generic or very abstract,
very specific, right? Animal is a very
abstract category. Two legged animal. We're starting to really get
into more specific stuff, human and an ostrich. Now we're very, very specific. So that's one idea you
can think of, right? So let's think of a
dog class now, right? So we have a class
which is called a dog, and that might have
some attributes or some are fields, right? Which is going to be a picture, a name, and an age. And we're gonna be like,
Okay, that's fine. That's okay, that there's good enough to describe
a particular dog. And well now we want
to create a new dog. So we want to create a new
instance of the dog class. We want to create a new object. Well, let's just do that. There we have it. Right now
we have created a new dog. Benji was seven years old, and here is a very
cute picture of him. Isn't that just nice? Yes, if I do say so myself, I think that this is a
very cute picture here, and this is a
particular dog, right? We haven't really
changed anything here. The only thing that
we've done is we've basically created an object. When we go back here once every dog has a picture, a name, and an age, and this is a particular instance or a particular object
of the dog class. Now let's just
create another one. For example here, Gracie with five-years old and also has a very cute picture right there. There is, you can see those are two different objects or two different instances
of the Dog class. However, they are both dogs. So this is sort of the separation
that I sort of want to get across when it comes
to classes and objects, that the class is the template. And then once you create
a particular object, that then becomes an
instance of that class. So that's sometimes
can be a little weird, especially for beginners. But no worries at all at once. We're actually going to start programming with this
eerie or when we actually put this
into practical use is going to be way more clear. I'm sure of it, right? What would already be
the end of the lecture? Actually, the most important
thing of this lecture, let me just quickly go back here is this one right here, right? So this slide is probably
the most important one. The slides actually
are also available to you as a resource so you
can download this as well. So no worries there. So you do have access to both of these cute dog pictures as well. So that's actually going to
be a very big plus of course. Otherwise, this would be it for this lecture right
here, like I said, a little bit more
theory and the next lecture we're going to put
all of that into practice. So that will be it for
this lecture right here. I hope you've found this useful
and neurons are the new. And I'll see you in
the next lecture. So, yeah.
25. (Java) Java Classes and Objects: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture
we're going to basically apply the theory that
we've learned last time. In the last lecture, We're gonna be talking
about classes and objects. So first of all, of course, we need to create a new class, a custom class now. And for that, we're
going to go into this project window right
here inside of our package. So this is the package, right? Net helped Monroe was the package that we created
or other I created. Hopefully this is your name. Then in your names package, you right-click new Java class. And then you're going to
call this the dog class, making sure that
the class here is selected and then press Enter. Now this year this window only appears for
me because I have a GitHub repository
associated with this project. If you don't have that,
that is absolutely fine. Don't worry about that at all. So I just wanted
to mention this. And now instead of these
curly brackets, oh, add members to this class. So for example, we could
add some fields, right? So we can say
something like adding, adding some fields, right? And then let's think back to the PowerPoint presentation
that we've seen, right? We had a public String picture. We were thinking
about a picture. We're just going to
say that a string that's totally fine
for the time being, a public string name. And then let's say
a public integer, which is the age variable. Now that's all fine
for the time being. We're once again going to
ignore the public here. We just have to set
this to public once again in a very,
very short time. Actually, we're going to
see the access modifiers. So that's literally the
next lecture as well. And then we will understand what this means for
the time being. We have to set it to public. And what we can also do is, for example, someone
like a public void. And then we'll for example, so we can make of fields
and also methods, right? So this is a method
here, and this is, of course this was fields here. Then I can do something
in that method, which is just for the
sake of argument. I'm just going to say just
at that, at this time. Okay, So now this is all set up. Now, what are we doing
with his dog class, right? How are we making a
new object out of it? Well, we can do the following.
You could say dog, right? Logo. And now this might at first we can say something
like this, for example. Now this might, for the first
time be a little confusing. Maybe like wait, but I mean, I thought of you sort of
should recognize this, right? This is just a normal variable that we have declared
here, right? Is just a type of dog. Now, like I said,
because you're now starting to use custom classes. So custom basically datatypes. This might be a little weird, but this is just the same as
if I were to do this, right? Really when we think about it, it's just a variable. This time of type dog. And another way I can actually initialize this is I can say new dog and you can see that it actually generates this
automatically for us. And now I have
created a new dog. So this is the general idea of how you can
create a new object. So you need to use
the new keyword, which we've actually seen
previously a few times. For example, with the scanner, we had to create a new scanner. And now that also makes sense. Scanner is just
another object or another class which
we can instantiate a new object or a new instance of an inch
can basically use that. That's sort of the idea. Now, the real question
though is that okay, Like I have this dog here, but like i the fields, what are, what are they now? Well, let's just try it out. Write system out, print line, Togo, dot name for example. Let's just see, well, what is that dog was named as a dog? No, actually the
name is null because we have not assigned
any of those values. Therefore, they are all null
because here we have used, right, used the default,
default constructor. So what does that mean? Well, the constructor
is another part of a class which
is very important, and this is actually
not classified as a member in this case,
this is something else. So the constructor,
as the name suggests, is something that constructs an object from this template, from this class, right? But the default constructor, every class that you create
has something like this. So it is written like this
with an access modifier. And then the name of the class immediately followed
after by parenthesis, which have nothing in them. And then basically just
almost like a normal method, just without a return type or rather the return type
is the same as the name. You can also think
of it like this. And this year is the
default constructor. And this is what
we've been using for this doc here, right? So this is the default
constructor now. And the real issue here is of course you can see that
nothing happens in it. So none of those things have
any value assigned to it. We can, however, also create
our own constructors. Right now we can create
a custom constructor. So for example, public
dog, string, picture, string name, and age, write something like this and
then we can assign those. So this picture equals picture, this.name equals name, and
this dot age equals age. And you will see,
all of a sudden, everything still
works totally fine. Now the first thing
you might ask, what is this, this keyword? Well, this refers to the object
that we're creating rate. So for example, you can think of it when
we call those Wolf method. If we were to call this, we would have to call this
on a particular object. So every time I use this
inside of this method, that particular object is
basically being referred to. So you can think
of it like this. Same way with the constructor. When I use this, that particular object we're just
now creating is being referred to because the parameter name here has
the same name as the field. They don't necessarily have to, but in this case they do. Then we want to use this
tool very much specify, hey, this is the field
and as the parameter. And now what I can
do is instead of creating one with the
default constructor here, I can actually do something
like, for example, dog and Benji, let's say
equals new dog, right? And then you can see if
I wait a second here, can basically take
a look at this. There it is. So now we actually get
a suggestion here, either no parameters or string, picture string, name,
string or int age. So we actually get
the suggestion here. Let's say Benji dot PNG, right? Let's say Benji for the name
and then seven for the age. And you can see this is
pretty much almost the same as just a
normal method call, but in this case it actually
creates a new object. And then we can do
system out print line. Now Benji dot name, and then let's say Benji dot h. And now this will output is Benji and a seven
as you can see. So that's actually
really freaking cool. There's one more thing. Let's just say for the
sake of argument here, when we have a lot
of fields, right? Sometimes it can be a
little tedious to put all of them in here
in the constructor. So what we can do is we can also right-click
generate constructor. Then you can just select all of the fields that you
want to initialize, you'd see by the constructor
and we say, okay, and this generates
exactly the same thing that we've done previously. I wanted to mention
this because that can be sometimes very useful, right? So there's a lot
of things in here that can be generated
automatically. So keep that in mind as well. But let's also
make another dark. So just to illustrate this, so dog Gracie is equal
to a new dog, right? This is the greasy
dot PNG, Gracie, and I believe Gracie was
five or five is fine. Now let's actually
output that as well. So I'm selecting this Control C, Control V to paste it
in and then changing the variable here and
sort of Benji to Gracie. And this, of course now also works and it's going to
have different values. So once again, those
are both dogs raid, but they are a two
different dogs. So there are two
different objects. And I hope that the theory
from last lecture sort of carries very easily over to this illustrative
example here, once we're actually using it, it hopefully becomes very clear. And we will also do is we'll just change this
wolf you're actually to this dot name, just waft. Then what we can see is also that when we call this method, once again, this
method in particular, we actually have to call on
a particular object, right? So we actually have
to save Benji dot, WAF or racy dot. Should all make sense. And now what's going to
happen is that it's not going to be the same for each
one of them, right? So Benji just moved
or Gracie just Swift. So this once again refers to the actual object where this is being called
on so to speak. So that's the idea. And then one last
thing that might be a little bit different
or a little weird. It's like, well, wait a second. Benji dot age, right? Okay. Can I just like assign this to something? Yes, I can. Well, that's very
interesting, right? All of a sudden, right? Benji has become 10 years
old and you might be like, Wait, that's not, that doesn't
make any sense, right? Is only seven them. That's not right, Is that yes, this has now saved. And this is something that
we're going to look at the next lecture when it
comes to access modifiers. Because all of this being public basically
means that, well, you can change this and access it from
anywhere in the code. And that is sometimes
not what we want. You sometimes want to restrict the access to certain fields, variables, methods, all
of that jazz basically. And like I said, we're gonna take a look at
that in the next lecture. However, this would be it
for this lecture right here. I hope you found this useful and you learn some of the new. And I'll see you in
the next lecture. So, yeah.
26. (Java) Access Modifiers: All right, welcome back to
the Java introduction here for Minecraft morning
and in this lecture, we're going to be looking
at access modifiers. So you will need all of the
code from the last lecture. No worries, of course, this is available to
you as a resource. So definitely take a
look at that and then, well, we'll just jump right in. So the idea was that, well, we had all of our fields
here as a public, right? So everything here was public. And we were thinking,
well, okay, so how are we going to use this? Or how will we be able
to not make some fields changeable or like modifiable
here outside of this class. Well, let's just go
through all of the, well, let's say
access modifiers. So there's public, There's protected, and there's private. Then there's two more things
that we're also going to see which is static and
the final, well, it's not really
access modifiers, but they're also sort of
modifiers that you can put in front of fields and, or methods. So when it comes to making
the name, for example, protected here, this
actually will do nothing. Now the reason why
it does nothing is that a protected field or a protected method can be
called in the same package. And because the dog and the main class or in
the same package, we can still refer to this field here in
the protected keyword also works or classes
that extend from this. So basically, acids that
inherit from the dog class would now also be able to
use the name variable. What about the age variable? Well, let's do the following. Let's make this
private. And all of a sudden we can see
related problems, right? Everything's going crazy. Everyone is freaking
out because all of a sudden we can
actually access this because a private variable and only be accessed
in the same class, meaning that we can't
directly access this. However, we can do
something which is going to be a method, returns this value. So this is what's
called a guitar. And what we can do is
we can right-click Generate and you
can see that we can actually generate
getters and setters. Setters are pretty much the same thing where you
set the variable rate. So where you can
basically set this and a getter is just very much
the thing where you get this. So I can select the age
variable and say, okay, and see it generates
a method for us public integer because of course that's the return
type here, get age. So this is the way
that you would phrase this or the
name of this was usually get and
then just the name of the variable or the field. And then we return
age in this method. And then instead of
calling it directly, we can say get age at age, age. And now here's the very
interesting thing. Of course this does not work. We can't assign
something to a method. Therefore, this does
not work, right? So we can say doesn't work. So we can't assign a new
value to this age variable. So that's really the cool thing. And then we can also have a
static and a final keyword. Okay, What is that? Well, static is going to be very interesting. So when I have a
public static int, and I'm going to
call this the dog to human ear multiplier. Multiplier, which is equal to seven
if I'm not mistaken here. And this is what we can
think of it like this. Does every dog have to have
a specific field to them, which is this multiplier. I mean, if we're really honest, not really, right, when
we think about it. The doctor here, dr. Human year multiplier really is something that works
for every dog. Exactly. That's why it's static. Is static variable or a static method and actually
be called only class and it doesn't require a specific objects
to be created. So what I can do is, for example, instead of
calling Benji that HE, I can say dog, dot, dot, human, doctor, human
year multiplier. You can see I call this on the actual class
and not the object. So that's a very
interesting thing. And that might be breaking
your brain a little bit here, because first of all, getting into static is a
little weird and it seems very counterintuitive
at first glance maybe, but no worries at all. When we're really using this, It's going to be fine. And the general gist
is that, you know, if something static
usually is something that is the same for all of
the objects, right? Because once again,
you Dr. human year multiplier doesn't
change from dog to dog. Now, let's ignore the
fact that maybe it changes if there's different
breeds and stuff like that. Let's just ignore that. It's just an example
here, of course, right? And then the question also
is, well, wait a second. This really doesn't need
to change it because now we have the same issue
once again rate so dogs, your multiplier and all
of a sudden equals ten. We can just change this
and it's like that's not really smart, right? That doesn't have to happen. Well, luckily there's the
final keyword as well. And that makes it
so if I actually press Control Z to go back, you can see that cannot assign a value to
a final variable. Because when is a
final variable, then the value can never change after it
has been assigned. That's also very interesting. However, there is of course, a distinct difference between a private and a final
variable rate. Because a final variable we could in theory
change, right? We could say something
like, for example, let's just make a
public, public void. Public void birthday, right? For a dog, where we
say age plus plus. But that still works even
though it's a private, we can change this variable. We could never change this
variable once it's final. So that's the difference there, which is hopefully understandable
in that sense, right? So let's actually take another look at the
following, right? So we can also then say
something like, Well, I mean, let's just add a, let's
just add one more thing, something like a public int. So getAge in human years, right? Where we can use the multiplier
here that we're going to return the age variable
times the doctor here, human doctor, human year
multiplier right there. Now we can just call this usually you can of course
also say dog dot this. We don't have to do that because we are inside
of the dog class, so we can just call
it without that. That's very much
personal preference, just whether or not
you want to do that. But what we can then
say, for example, is we can then say Benji
dot get age in human years, and that will then
be, what is that? 49? Yeah, 49. There you go. So easy enough. That's sort of the general gist. We have public, protected and private for the
access modifiers. And then there's also
static and final. And we will definitely be, we're going to encounter all
of those in future lectures, especially when we get
into microwave modeling, that's going to be
very relevant here, especially something
like the final keyword and the static keyword, those are going
to be used a lot. Once again, if they are a little bit unclear, that's
absolutely fine. No worries at all. Once you start
working with them, it's going to get way clearer. And once again, I
can very much just advise you to try out
a bunch of stuff. Just fire up intelligence. Make a bunch of classes, and just try out
a bunch of stuff. Make a few classes, make a few fields,
whole bunch of stuff. You can't break
anything. Not really. So it's just really a matter of being open to
experimenting basically. So that's very much an
advice that I can give you. But otherwise, this would be it for this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
27. (Java) Inheritance & Polymorphism: All right, welcome back
to the Java introduction here for Minecraft modeling. And in this lecture we're
going to be talking about inheritance
and polymorphism. Well, first of all,
a polymorphism and inheritance for very
large words, right? But overall, they're concepts
are fairly straightforward, especially polymorphism
isn't that crazy of a concept actually? Now, another disclaimer
I want to say right out of the gate is that
because this is an example, the actual sort of concept might not be a
100 percent transparent, which is absolutely fine. By the way, this is
something that once again, has to be built with just trying out a
bunch of stuff, right? I usually have about the
same Here. I forget. I see. I remember. I do. I understand. So there always has to be some doing that goes along with it. Whatever the case may be. Let's say, for the sake of argument that someone
says, You know what, I really want a
cat class as well because I'm not a dog
person, that's fine. That's totally okay. Well, let's add a cat
class in here as well. So a new class, cat. And there you go. Now, what you will quickly
realize is that, well, like let's be honest,
the cat renal should also have a picture
and a name and an age. And you might be like,
well, I mean let's just copy those fields over. And then you might be like,
well, I also need to get age that the getter
and then the wolf, maybe the baby and Mimi
Chao and you come to a point where you're
copying over a lot of code and usually
tabbing over a lot of code is a sign that you
can optimize something. Now, premature optimization is the road to hell.
I understand that. However, sometimes this just makes a lot of sense where you have like this copied over, this copied over, this
copied over, and it's like, let's just make a method or a class out of it
or something else. And that something
else is actually going to be a superclass for the cat and a dog
being the animal class. So we're going to make a
new class called animal, and that is now
going to store this. So I'm going to
cut that out with Control X and Control V to
paste this in right here. And now all of a sudden, what we can do is we can extend the dog class by
the Animal class, meaning that the, let's
just do it right? So we're going to inherit everything from the animal here. We're going to say
extends animal, and this now is inheritance. So the dog class is now
the subclass of animal, and the animal is now
the superclass of dog, meaning that everything
here has been inherited. Now I can actually
literally delete this. The only thing that
is going to turn red is going to be the age, because I actually have
to make this protected here so that it can be
accessed in the subclass. But we've seen this in
the last lecture where I said that when it is
a protected variable, and then you can
actually access it from the subclass as well. So that's sort of the idea. Let's actually get
rid of a few of these comments here as well. We can also get rid of
the default constructor that is also no
longer necessary. So now we have this
animal class, right? And that's pretty cool. Now you can see that b-a, this Dog class, everything
here is being set. However, we want to make
sure that everyone, that every class that actually inherits from the Animal
class also works. So we're just going to make
a new constructor as well. So right-click,
generate an instructor, making sure that
everything here is selected and then press Okay. And then we're
immediately going to be greeted with an
arrow right here. Because if we hover over this, you can see there is
no default constructor available in a net
com zoo animal. What does that mean? Well, when you actually add
a specific constructor here, that is not the
default constructor. The default constructor
no longer works. So once you have one
constructor that is, isn't the default constructor, you have to add it
like manually again. So I could, for example, say public animal, right, with nothing in it, right? So something like this. However,
of course that doesn't. Now, you know, that once again, we don't
actually want that. So this is going
to be deleted and then the default constructor
no longer works. And now what do we
have to do here? Well, what we can do is we
can call the superhero, and this basically
calls the constructor. So we can actually
put in PI as you can see it actually
already to just say, let's just take all
of the parameters here and put them into year. And now this super is now calling the Animal
constructor right here. So this is actually
perfect in this case. Then something else,
maybe for example, the, both the get age and
the birthday could also be in the animal
class, for example. That would also
work totally fine. And the rest here is
actually totally okay. I'm going to adjust, make
this a little bit different. So I usually want
the constructors at the top of the class, right? So first-come the fields and then the constructors and then all the methods and
stuff like that. Although the order of
course is something that is completely up to you, but this is usually
the convention 0. Now what would happen if
I now were to say, well, the cat now also extends
the animal class. We'll, we're gonna
get an error here, which is there is no default constructor available in animal. And then we have this
were possible solution, which is the create
constructor matching super, which is something we're
going to see a lot of times. Because if you click this, you will simply get a new
constructor here with all of the needed parameters
that you need in order to call the constructor
of your superclass. And that's pretty much it. That's really freaking cool. And now we can actually
create a new class. You can see everything
here works. So we can say cat whiskers
is new cat, right? So new cat here. And this is, for example, then whiskers dot PNG. And then the name is going
to be whiskers, right? And then maybe, maybe there were like 12 years old or
something like that. And then we can simply
call, for example, whiskers dot and you can see I can call everything get age. Now I actually have access
to the age variable here. This is simply the case because we are in
the same package. This usually should
not be the case. I just wanted to
mention this because usually when you actually are extending a particular
class is very unlikely that you are
in the same package. So just wanted to mention this. And that is a, well, I wouldn't say a limitation, it just is a reality basically. But now the real
question, communicating, but now what is so interesting
about having this? Well, let's think
about this, right? So we have the wolf
method here, right? Let's just delete
that or actually let's be even smarter rate. Let's just copy this
or cut it out, right? And then add this to the animal. Now first of all, you're
going to say, wait a second, not every animal, Wolf's right.
Yeah, that's fair enough. So let's just call
this makes sound. And then we can say this name, just, let's say
just made a sound, but we can't do this. And other really
interesting thing is this is defining
the animal class. However, I can still
say something like whiskers, Adamic sound, right? So because whiskers is a
cat and a cat is an animal, I can call all of the
public methods here still. And if I call this, you can see whiskers just made a sound. So that's pretty cool. But now we're going
to supercharge this because while every
animal does make a sound, a cat makes a different
sound from a dog, right? So what we can do is we
can actually override the implementation of this
method in the subclasses. So that's pretty frequent, cool. But what we can do is we
can either start typing the actual name of the
method as you can see, or we can write an
override, right? We can start to write that. And then you can see all of the possible methods that we
might be able to override. We're going to of course,
choose the mix sound method here and it will get
this annotation added. This is not strictly
necessary, however, it is very valuable
for you if you have this and I definitely
recommend keeping it, because if you go through
the actual classes, you can very clearly see, okay, So this was overridden from one of its superclasses. So that's very important. Then I'm actually going
to just take this one. So I'm actually going
to take this and just modified a tiny bit, right? So I'm going to say
this, Just me out. Let's say I'm gonna do the same. Copy this over to the dog here. And I'm going to say this name, just waft the slow, we have something
different here. And what you will then
see if I actually call, for example Benji
dot make sound. And I'm then also going to
Gracie, don't make sound. What will happen now? Well, very interestingly enough. Meow, woof, woof. So as you can see, the overridden methods
are now being called instead of the one by
the actual superclass. So that's really frequent, cool. And now this is sort of the
idea of inheritance, right? We can inherit both
methods and fields Europe in this just makes
it so first of all, everything is a little
nicer separated, and then also we don't
have duplicate code. Now the real question is,
what is polymorphism? Polymorphism is a
big word for a very, very easy to understand concept. Actually, in the very easy to
understand concept is that a dog is simultaneously a dog and an animal
should make sense, right? So you have a dog class is both a dog or an object of type? Dog is both the dog
and animal are enough. Okay. What does that mean? Well, I can save this
in an animal, right? So I can save animal, animal
is equal to a new dog. Let's just save Jenny dot PNG. Jenny, maybe Guinea is like 15, all dark, but that's okay. And now what would
happen if I do this in a mole dot make sound. What is going to happen now? Well, I mean it's an animal. So obviously it should say Jenny just made a sound, right? Because that's the
most logical thing. Wait a second in the background,
it's a dog. Exactly. Then he just moved. Because even though we
save this in an animal, polymorphism makes it so that the dog object can take
on multiple forms, or any object really can
take on multiple forms. That's what basically
polymorphism means. Multiple forums in a very
loose translation, let's say. And the great thing
what I can also do is I can make a
list of animals, for example, rage, cool animals. And I can make this
a new ArrayList just for the sake of argument.
Let's import this. And then I can just
say animals, not add. And I don't only have to add an animals because of
course Benji is a dog, but the dog is also an animal. And then I can also add Gracie, and then I can
also add whiskers. So as you can see, even though they are all saved
as animals, right? If I want to get
those back, animals, dot get one, for
example, make sound. So it makes them
their job, right? And the get method here
gets you back an animal. But once again, we've seen that calling a method on this
actually caused the, say, the most specific
method that it can. So even though this is
being saved as an animal, Gracie is being saved
as an animal here, the mic sound is going to make it so that
Gracie just moved. So that is pretty cool. Once again, if you don't clearly see the application for this,
that's absolutely fine. This is a very abstract
just introduction for this, of course. However, this would,
for the time being, be it for this
lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
28. (Java) Interfaces & Abstract Classes: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture we
are going to be taking a tentative look at interfaces
and abstract classes. So we're actually going to start with the abstract class first because that's a very
illustrative example actually. So what we can think
about is the following. What is a dog? Well, I mean, you've seen
have you seen a dog before? Yes, of course. I mean, either as a picture or somewhere in the world you might
have seen a dog. Have you seen an animal before? Now you might say is that well, I mean, I've seen a dog
before it but no, no. Have you seen an animal before? And you're going to
meet and fuse, right? Because it's like, what is
an animal at the moment, what we can do is
we can say animal, let's just say a is equal
to a new animal, right? With, for example, just like x, p and g x and that just like 10 years old or
something like that. And then you might be like,
what is an animal like? What does that represent
really rate in animal is a very, very
abstract concept. And abstract classes, right? See the congruence there, right? So really we shouldn't
be able to create new objects from
the Animal class because what really
is an animal like? Things can be classified
as an animal, but the object animal
doesn't exist, right? So what we're gonna do
is we're gonna make a public abstract
class out of this. And you immediately
going to see that we have a related problem, which of course is
exactly this right here, because we can't create a
new animal if it's abstract, you can see animal is abstract, cannot be instantiated,
meaning that we can't create objects from in abstract class in
the cat and the dog. Literally nothing has
changed because of course, the animal is still at
everything here, so works. Now what we can also do and
that is really cool for an abstract class is that we can make certain methods abstract. For example, the mic
sound method right here. So we can just basically
just, let's delete this. And then what's
going to happen is that we can say public, abstract, void,
make sound, right? And now look at
this, we just ended. So we still have to have a
normal method signature year. However, the actual
implementation is left to the subclasses. And if we were to
not override this, what you can see is
also would find that class dog must either
have declared abstract. So either this has to
also be an abstract class or we have to implement
the abstract methods from animal that can just
hover over this into the implement methods and then this will get
added as well. So I'm just gonna go
back with Control Z here and then everything
just works fine. So that's sort of the idea
of an abstract class. And a interface is amine, something that's very
related to this as well. So what we're just
gonna do is we're just going to add an interface, so a new class here, and then we can
select interface. We're going to call this
the petal interface and the IP edible interface. You're in interfaces. We also just define
a method signatures. So void, pet For example, rates of symbol like
this, and that's it. So no access
modifier, just this. And if this interface is
implemented now for example, in the cat right implements, we have the right,
then I palatable than what you will see is a very
similar error than before. Implement methods, the
method and the ego. And now I have to
have some kind of implementation in
this cat class. Why do we have
interfaces and classes, you know, couldn't I
just make another class? Edible animal and
stuff like that? Yeah, of course,
that also works. But the limitation
here is that you can always only extend
from one class. You can't, however, implement multiple different interfaces. So that's really the
interesting thing here. And then also the interface basically is what
the name suggests. It's an enables you to interface with something
in a particular way. So when something
implements an interface, you sort of have a, I mean, you could think of it as
like an unwritten contract that everything inside
of this interface is definitely has a
certain implementation. So for example, I could say
something like, you know, just this name was pet,
something like that, right? And then I can just copy this over just for
the sake of argument. I'm going to also implements
this in the dog here. So I pedal and I'm just going to add this
and then we're going to say something like
was scratched and scratched behind the
ears, for example, right? And now what I can do is
instead of, for example, making a list of
animals, now I could, for example, also make a
list of iptable, right? So now we have these pets
rate new ArrayList of that, and we can add those
as well, right? Pets dot add. And then let's just say Benji, and then let's just
say whiskers, right? And now we can make a
petting zoo if we wanted to. That's really cool. And it doesn't matter. Once again, with polymorphism, it doesn't matter if
they're saved as I petals. Once again, their actual
real implementation is being called When
we were to call, for example, Pets dot get one. Then what would
happen is that of course the actual
implementation is being called whiskers was
patched instead of whiskers was scratched
behind the ears. That's sort of the
general idea here. Once again, interfaces
abstract classes. Sort of in the same vein as the inheritance and the
polymorphism in general. Where it might be a little weird because in these examples, it sometimes it's hard to
really get across the idea. Once again, trying
out a bunch of stuff really can help or
following the assignments, also a worthwhile endeavor. But otherwise, for
the time being, this is going to be for
this lecture right here. I hope you found this useful
and learned something new. And I'll see you in the
next lecture. So, yeah.
29. ASSIGNMENT 3: Trivia Game with Classes: All right, Welcome to
the third assignment here for the Java introduction. And this is actually a fairly
straightforward assignment. As you can see,
it's not that long. Over once again,
the time it takes it and make this
might be round about an hour or so as usually a very conservative
estimate as well. So there's a little bit
of wiggle room they are you might be able to do
it in 30 minutes, right? No worries at all. But for the time being, let's just go through here. So trivia game with
classes and objects. So once again, we wanted the
same trivia game that we've been making in the last
two assignments as well. I basically want you to modify the trivia games that it
uses classes as well. Now this can be in any way, shape, or form that
might be the case. Think about like
how you could make some custom classes that, you know saves the answers and the questions
may be together. Maybe you can use a list,
something like that. It really is up to you how
you want to structure this. But just think about
how you can make this way easier with
classes and objects, and then just try that out. Of course, once again,
the solution will be available to you
once you're done, I highly suggest really taking a crack at it and
really trying this out. And I guess I'll see
you in the solution.
30. SOLUTION 3: Trivia Game with Classes: All right, Welcome
to the solution for the third
assignment right here. And well, I mean, I guess let's just take a look. You can see I have
actually only two classes, a trivia game class
and a trivia class. And the trivia game
class basically contains all of the
logic and the game loop. And the trivia class contains the questions and the answers. So let's take a look
at the trivial class. First of all, let me
zoom in a little bit here so we can see I
have a string question, a string answer, and just a constructor that passes in both of these shrink
variables here. And then I have a
bunch of methods here, right is correct answer
would basically puts out a Boolean and also makes sure that everything is in lowercase. So the input as actually being
put to lowercase, though, that you can basically put in uppercase letters and it still counts as the
correct answer. Here we have the print
question, the print answer. We also have validated answer
which then brings a, Hey, this was a correct answer, or this was an incorrect
answer as well. And this is pretty
much the trivia class. Once again, if this
doesn't look exactly like yours, that's
absolutely fine. This is just one example
of how to do this. And then same with
the trivia game rate. We have a list of trivia here. So those are all
of the questions basically which are being
populated right here. So this is actually called, sorry, in the start
game method, right? So this is the first
thing that happens, populated trivia list. And this is the doughnut right here where we just have
a new ArrayList and then we add a bunch of those trivial right there to
this actual list here. And this is really cool
because this now could also be done via a reading in, from a file or, you know, downloading
stuff from the internet. So this method here could very easily be replaced
with something else. And this is really
the power when you do this separate
in these classes, right before we had those
individual string variables, there was no way that we could
change this very easily. In this case, we could change this wooden database onto that. You could put, like I said,
something on the internet. You could do almost anything, read it from a file. And that's really the thing that you wanna do with classes. You want to make this sort of generic in the sense that you can very easily add and
subtract stuff from it. Usually add, of course, right? And then there's a bunch of other stuff here as well, right? So the game loop is the
main thing where we have this infinite while
loop right here, right where we just go through
each of the questions, validating the
answers by getting the user input and
then increasing the score if the answer
is actually correct. And then we will just print the score after each
of the questions. Then at the end here we ask, Hey, should we abort the game? And if the user says yes, then we just break
out of it and print the final score at the
end of the game as well. That's pretty cool.
All things considered, this is pretty much
all you really need. Once again, if your
answer differs, no worries at all. But hopefully you have
this answer that you can walk through and sort
of try to understand, okay, well, how would I do this? Why was this done? You know, methods, okay, That's very interesting classes. So that's sort of the idea here. But for this solution,
this would be it. And I hope you found this useful and you learn
something new. And I'll see you in the
next lecture. So, yeah.
31. ASSIGNMENT 4: Bank Management System: All right, Welcome to
the fourth assignment here for the Java introduction. And in this assignment, you are supposed to create
a bank management system. Now overall, this
might first of all sound very complicated,
but no worries. I'll step you through the
idea that I had here. So the bank management
system should have something like
these components, a person, a bank and
a checking account. And then to open a
checking account, you should go via a bank, right in it might require a
certain initial deposit here. And the individual components or classes that you have rights that a person
might have a first, middle, and last name, and age. Maybe it's something like
a social security number is not necessarily required, but you know,
something like that. A bank might have a
list of customers. Their checking accounts may be a maximum overdraw mount,
something like that. And then a checking account might have the current value and the methods for taking out
and depositing money overall. That's sort of the general idea. There's a bunch of ways
that you can approach this. So I'm very interested to
see what you come up with. And of course, the solution will once again be available to you. I think this is probably
a little bit harder. I would imagine something like 1.5 hours is probably
best to set aside for this so that you
can really dig in and try to understand and make something
that's pretty cool. So good luck.
32. SOLUTION 4: Bank Management System: All right, Welcome
to the solution for the fourth assignment. And as you can see, we have three different classes, pretty much like I said
in the actual assignment. And well, let's just go through. So we have a person class which is fairly straightforward, read first, middle
and last name, and an age or private this time, and basically accessible
via ghettos here. And then we also have
a boolean right here, which basically just
returns whether or not a person is older than what
has been supplied here, which is very interesting. And the account here is
also interesting, right? We have a balanced,
we have account ID. At this point is not actually
really used all that much, but it's very possible
that you can do something with this
as well and then an account holder as well. And that is used in the bank to basically get a
specific account here. So we can see ever have a
list of accounts, right? And the way that we
can get an account is get account by person. But that's the way that
I personally right now to get the accounts here. And the rest is pretty much
does the bank account, right? So basically, if you can open this account, is that the case? And it basically validate
whether or not someone is 16 or older than 16, and also whether or not the minimum deposit
has been actually hit. There is actually a little
bit of a bug in here, right? In this method, that's
very interesting. You can try to find
that yourself. Just a little bit of an
interesting exercise as well. But otherwise, you
know, overall, this is once again just
one example of this. We can just take a
look at this, right? So what we're going to have
is I have some code here, so nano tech is
not old enough to open a bank account
and then ten, say euros or dollars
is not enough. We need at least a 150
and then we actually get the balance from Maria's
account, which is 2000. Then trying to withdraw
3000 doesn't work because the withdrawal
amount is actually 500 or the overdraw basically. And that is why
this doesn't work. So that's sort of the
general idea here. Once again, There's
plenty of ways that you can do this if it looks
completely different to yours, but you're still works,
that's totally fine. Regardless of that,
I hope that this was a useful exercise or
useful assignment two, you end and I'll see you in
the next lecture. So, yeah.
33. (Java) Anonymous Classes: All right, welcome back to the Java introduction here
for Minecraft modeling. And in this lecture,
we're going to be looking at the anonymous class. So what is an anonymous class? Well, when we inherit
from something, so we think back the
dog class, right? That had a name, right, and inherited from
the animal class. And now what we can
do is for example, we can make a
person here, right? So I still have the person class from the last assignment. So for example, personnel
is equal to a new person, but it's so nano attack
and eight years old, let's say just for the
sake of argument here. Now, this is all fine. If now I wanted a class that extends this person class,
which is a manager. Now the only thing that we're
going to do is actually just make it so that when
you get the full name, you're gonna get the name like Manager printed
out as well. Okay, So, so how
would we do this? We'll make a new class, right? And all of that. Well, let's just say that we actually only
really need this one. So what we can do is we can
make an anonymous class. So we can say person manager
is equal to a new person. But let's just say
John Smith, right? Let's say 42. And then we end this. Now what we could do
instead of ending this with a semicolon,
after we're done, we're actually going to
make a holy bracket and end the ending curly
bracket with a semicolon. You can see that
there's no arrows here. Because inside of here
now we've created this anonymous
class because it is a class that extends
the person class. However, it doesn't have a name, therefore
it's anonymous. And when we can do
is, you can see if I start writing
an override here, I can actually override
everything that is inside of the person class
that is over writeable. Prefer example, I can say fullname and then I can say
something like Manager, and then plus get the full name. So this is now what this
particular anonymous class does. And then I can, if I
system out print line, for example, nano
dot get full name. And then I can also
do the same for the manager dot getName. You will see that nano is
just going to be nano attack. And then it's going to
be manager John Smith because we've added this
manager right here. This example might not be
the most illustrative. I find it very hard to really show you a very
illustrative example of anonymous classes. It's usually the further
in you go, you know, with interfaces and inheritance
and stuff like that, it becomes very hard if
you're not in a very, in an actual
environment where you actually have some classes
and some functionality. But this is definitely
something that we will see in the modelling section
of the course as well. Because there's plenty of stuff here that's going to
be needed for that. But whatever the case may be, at least you've seen
this even if we are not going to go into too
much more detail here, I hope you've found this useful and you learn something new. And I'll see you in the
next lecture. So, yeah.
34. (Java) Enums & Advanced Enums: All right, welcome back
to the Java introduction here for Minecraft modeling. And in this short lecture, we're going to be taking
a look at enums and also advanced enums,
overall, enums, you can think of those as a certain data types that
have predefined values, and you can only assign those values to that
actual variable. So let's just
create, for example, a difficulty enum, right? So we can make it a class and then just change this
to enum right here. And then the way that an enum basically is structured is it has the actual values that it can take it
just inside of it. So for example, easy,
medium, and hard, for example, as the difficulties
of a game could be. And then to create a
new variable for this, it's pretty much just
once again difficulty. Then let's call this the
game difficulty, right? Under like this. And then this is equal to 2. Assign this, you can
see difficulty dot, and then we just have
these three values as possible options. So let's just say
difficulty medium here. And we can then normally
just reassign this right? Again, difficulty equals to 2. Difficulty, difficulty
hard for example. And then two. For example, we can also
make IF statements out of a retro game, difficulty
equals, equals. Now that equals something, for example, difficulty easy. And then we do something here. So that's pretty much all it
really is for normal enums. And there is
something interesting for what I call advanced enums. So for that, we're going to
create a new Java class. Again, that's the tool tier, and that is going to be also
renamed to an enum here, I'm actually going to
copy over some stuff from the other
monitor right here. So this is actually also of
course available to you, a GitHub repository
or adjust as well. You can see that while
this is an enum, it has a constructor here and
we have some fields rate. That's very strange.
Yes. So the idea is that you can
have enums defined. So of course this
is an diamond enum. And just for general
examples here. And the cool thing is that those work exactly the
same as the other ones. So I can say a two
tier tier is equal to, let's say, for example, the
tooltip diamond, right? And what I then can very
easily do is I can say system out print line
tier, for example, git tag multiplier,
which then gets me the attack multiplier
of whatever the tier has been assigned to. So I can basically have a, I don't want to call
it a list necessarily because a list is a little
something different, but you can have predefined values in this enum here,
in this enumeration. So that's the enumeration and you can then
access those as well. So that's actually
really will end, can be really useful. And we will definitely see this example in when
we're making tools, custom tools or Minecraft. That's definitely something
that we're going to see. But otherwise that's pretty
much it for the enums. I just wanted to show
you this and mention is that you have at
least seen this before. Otherwise this would be it
for this lecture right here. I hope you found this useful
in neurons of the new, and I'll see you in the
next lecture. So, yeah.
35. (Java) Exceptions: All right, welcome back
to the Java introduction here for microwave modeling. And in this lecture, we're going to be
taking a look at exceptions and the try
and catch statement. So overall, this is not
the most interesting, or what would you say, the most exciting topic? However, it is, it can be a fairly important
one. Nonetheless. Though exceptions we've
seen a few of those. For example, the something like the IndexOutOfBoundsException and the NullPointerException. So there were a few
exceptions that we've seen before that were
thrown by the actual code. And what we're gonna do
is we're now going to throw our own custom exception. So in our package we're
going to create a new class, which is the test exception, because it just
really requires us to have a test exception here. We're just going to extend the exception class right here. And I'm actually
going to copy over the two constructors that we're going to need here for this. So this is of course,
all available to you in either the GitHub repository
or energised as well. We're going to have is
we're going to have a scanner where we can just quickly scan in some
stuff system in right here. And then we're just going
to save the following. So we're going to say next int, and we're just
going to basically save something in
an integer here. And just for the
sake of argument, what we're gonna do is
we're going to throw this exception when we pass in a number 0 into a
specific method here. So private, static,
void check for 0. That's very straightforward
in the number. And what we're just gonna do is we're gonna say if the number, if the number were
passing any residual, then what we're gonna do
is we're going to throw a new exception.
How do we do this? We're going to write throw
new tests exception, and then we're just going
to say number is 0. For example,
something like this. And that's pretty
much all that we really need to do here. What you see is that this
actually throws an error here because Add exception
to method signature. So we actually have to have
this at this method here. So we have to add the throws test exception to the
method signature, otherwise it doesn't work. And if I call this now, right? So if I check for 0, i, what you will see is that
this also has to be added to the main method as well because this is not
handled properly, so we're not handling
this exception. So what you can do is we're
just going to run this. And if I, for example, type in a one here,
nothing happens. The program ends normally
over if I put in a 0, you can see exception and main thread count and
your test exception, very interesting numbers 0. And then you can even see where this has been called, right? So here first and then here was the exception
that was thrown. So that's very interesting. Let's first of all, a
comment this out and get rid of the artistic
section up there. And what we can do now is
we can say, for example, let's just say z is equal to
the scanner dot next int. Or actually just skip
it the I here for that. That's fine. We can now make a try statement. So this is going to be a try
with the curly brackets. And then here it's going to have an catch with an
exception e inside of it. And this is basically
handling an error, right? So the try and catch statement is there to handle an error. So we're going to
try this right here. Write a check for 0 I. And if an exception is
caught or thrown, right? And we can catch it here. And then we can do
something with it. For example, we can just basically just do
something like this. So GET message
then just for now, basically just print out what is actually
happening here, right? So the actual exception, there's of course other things
that you might want to do or have to do if an
exception is caught. And then you also have
this finally here, which we're just gonna
do the following. We're just going to
basically print out finally, just to see that
this is printed and then we're actually
going to copy the out. And this is going to be,
this happens always. But now the interesting thing
is when you actually handle exceptions properly with a
try and catch statement here, then what happens is
that the program does not just break or it
doesn't just end, it actually continues along. So what you can see
is that first of all, when I call, when I put in
a 1 for example, right? So one day you go finally, and this happens always. So the finally, as you can see, is always cold and then this is always also called, right? And then the
interesting thing is that when the exception thrown, you can see we're
printing out the message. But finally still happens. And the, you know, this happens always,
also still happens. So the rest of the
program continues along. What's very important
is that in general, you want your code to fail
as loudly as possible simply because of the
fact that you want errors to be seen
very, very early on. That's why throwing
exceptions can be useful. Now, granted in
microwave modeling, you're very unlikely to have to, especially in the
beginning, right? I mean, most of this, I'm assuming for
beginners, right? This is not going to be very
important for beginners. This is something way
more for advanced people. When you're really sitting
there, you're like, Okay, I'm going to make like a
giant mode now, right? I want to make it like the
next thermal expansion, Let's say on that level
something like that, then making some
custom exceptions. Very smart idea, definitely. But whatever the case may be, this is it for this
lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
36. (Java) Lambda Expressions: All right, welcome back
to the Java introduction here for Minecraft modeling. And in this lecture, we're going to take
a tentative look at a lambda expressions. So lambda expressions
can be very complicated. I just want to give you a very brief overview of the ones that we have and
what lamda expressions are. So in general, and the veteran people are
going to three methods. They are basically functions
or methods as variables. Now that's pretty cool
when you think about it. And we're going to take a
look at these five just in very, very sparse details. So we're not gonna go
into any detail at all. I just want you to
have seen those n to basically store
that in the future. Because especially
in 4D modeling, this is something that is very important actually in fabric, not so much, well, whatever the case may be. So a supplier, for example,
right here, right, is something that has no
parameters but a return value. And it could be written
something like this, right? So no parameters in
the parentheses and an arrow and then the x could be whatever
is being returned. You can see supplier of type integer means that
an integer is returned. And then this is
how it looks like. The cool thing about
this is that this also means because when we can
make a variable out of it, we could also pass
it in into a method, meaning that we could, we could pass in these
suppliers in there, which might have
different functionality. So that is fairly cool actually, this is also used in afford programming a lot or
enforced modeling, especially because
when the supplier, when you have something
inside of it, this is only called when the
getMethod here is called. So you can sort of delay loading of certain variables
and stuff like that. That's pretty much the extent of my knowledge in
that area as well. So we're not gonna
go too much into it. And then after we've fixed this mistake here per
meter, of course, right? So the consumer sort
of in the name really consumes a parameter but
doesn't return a value. Here is an example for the
consumer for a string, which simply basically
is where you pass in a string and then it does
something with that string. A callable is no perimeter
and no return value. So very similar to a supplier, however, it throws an exception, so a callable, it's
possible for that to call an overthrow
an exception as well. That's the general idea. You can also always hover over this and you can actually find a very nice summary of what
they actually are, right? So here we're calling the
callable in this case, then a runnable is
something that has no parameters and
no return value. Then a function basically is literally like a
function that maps a certain input to
a certain output is just the function
for the circle, basically where I just
have the pi here. But that's pretty much all
that there is really to it. So overall, like I said, I really just wanted
you to step through this once I've seen this before, when I say, Hey,
we're going to make a supplier that you don't
sit there and you're like, oh, I have no idea what that is. No. A supplier basically is
a datatype that has, that sort of more or less saves in a function or a method. It's not quite that, but it's very close to
it so that, you know, especially for beginners, it's enough to think
about it like that. Whatever the case may
be, this is actually it for this lecture right here. I know that this was very
short, but like I said, it's really just a
very brief overview rather than really explaining
every detail of it. But I still hope
that you found this useful and learned
something new. I'll see you in the
next lecture. So, yeah.
37. (Java) Generics: All right, welcome back
to the Java introduction here for Minecraft modeling and for this last lecture of the
Java introduction section, we're going to be making a
tentative look at generics. Generics, of course we've
seen those before, right? A list was a generic,
for example, where we could put in an integer like any class basically, and basically have the numbers, for example, with a
new ArrayList here. So that all worked out
very easily and very fine. That was well, fairly
straightforward. But what if we have generics
that we want to use ourselves for that
we're actually going to create a
new class here. We're just going to
be the pair class. And you will be able to save
two different values in it. So we're just gonna make those angle brackets and then x, y. And the idea is that X and Y are now placeholders for
certain datatypes. So we're going to have a
private x squared first and a private lie
called second, right? And this is, the idea is that you now have to
think of this like, okay, those are generics, meaning that those are just placeholders,
like I said, right? And let's just generate
a constructor for this. So right-click
generate constructor. And then for both of
those we're going to just read the constructor. And then actually
we're also going to do right-click Generate getters and setters for both of them. And there you go. That's basically the
entire class already done. And you can see it
always uses the x and the y because those
are basically just placeholders for
the actual data values or data types that
are being used. Now what's very
interesting, what you can also do is you can say that a certain data type as to
extend from a different one. So we can, for example,
say extends float, meaning that the y now
has to extend the float, meaning that it can
either be a float or any other subclass of that
class that were defined here. That's very interesting as well. It is something that
you can do and that is done in Minecraft modeling
extensively as well. And what you can also do, let's just make a new
pair here, right? So pair, Let's say
are like integer, integer float for
the time being, like this term equal
to a new pair of them. We're going to say
some like 2250.55. Sure, that's okay. Making sure that this is an
f here, then it should work. There you go. This is now working
totally fine. And what you can also do, instead of passing in a certain actual value
or a certain data type, you can also make
this a question mark. And then the generic will
just sort of figure it out. This is what's called
a wildcard generic. We're not gonna go too much
into detail about this. This is something that
you will also see in Minecraft modeling
a little bit as well. However, this is, there's no real need to understand this. It's entirely because generics definitely is something
that is way, way advanced, like very advanced
topic that even like skilled programmers don't like a lot of them don't
even understand this. Like I wouldn't include myself in that description
by the way, like, I know generics good enough so that I can basically
deal with them. However, making like a
real generic class myself, I will be honest, this is very, very hard, right? So this is a very
complicated topic, so no worries there at all. I just wanted to mention this
and wanted you to see that this exists and that you can
also make your own generics. But that would be it for the Java introduction in
this section of the course. I hope you found this
useful and you learn something new if you're
a complete beginner, I hope that you now have the Java foundation that
you're going to need in order to continue
along with microwave modeling. So best of luck to you, and I hope that you will enjoy the microbiotic section
of this course.
38. (Minecraft Basics) Installation & Setup & GitHub: All right, Welcome to
the microbe portion for the forge 118 course. And in this lecture we're going to download everything and set up the development environment so that he can start
microbes model. Well regardless of
whether or not you have watched the
Java introduction, we're going to need to
download the JDK 17 this time. Because, because
Minecraft 118 and up probably it was going to use ready cave and teen right here. So once again, I have
linked adopt him here. You simply download
the latest release, making sure that you are on
tamarin is 17 right here. If you are on a different
one, it should, in theory, detect your
operating system and all that. Otherwise, you can
still always go to the other releases and then choose your operating system and your architecture, and
you should be fine. I recommend on Windows you just download the MSI and then you basically install this onto your PC like any other program. One thing I highly recommend
is saying, hey, yes, we want the Java home variable
to be set right here, because that's
just going to save a lot of issues
further down the line. Because when the Java home
variable is set once, they're basically just
makes our life a little bit easier after
that is installed, we also need an IDE Integrated
Development Environment and we're going to
use IntelliJ idea. I highly recommend using this as well because otherwise
there might be some differences in
either the bands that they have to
press like shortcuts. We're also where you
find certain things inside of your a
development environment. You will choose the
community version because it is free and built
on open source. So it's perfect for us. You won't have to pay
anything for this. It's absolutely free. Simply download this
and once again, install any other
program on your PC before we'll open until
today for the first time, we now have to
download micro Forge, in this case for a
microbe 1800s one. So if you're watching
this in the future, we might already
be at one hundred, eight hundred and two
or even higher version. Who knows? What will definitely be higher is this version right here, right now we're at 39.5
now, that's totally fine. What we're gonna do is we're
going to download the NDK. But before we do this,
a very important notice here from the future. Please use one hundred
eight hundred one when starting the course. I highly recommend this. If you don't do this
and use 1800s two, then some things won't
work like the tags, the advanced item that we're
basically going to use with the tags as well as
the world generation. Now, once I get to it, I want to get to it very soon. But hopefully in the future at the very end of the course, there was gonna be an a
section which is 1820s, if you actually do see this. So just take a look at
all of the lectures. And if you see a
section at the end That's like 1182 updates, then you can go in there and actually go through
the entire course. And then every time there
where there's a certain, a topic that does
not work like tags. It will be the tags lecture and all of the world's
generation lectures. Then you can basically
skip over everything else, go to the end of the course, do those, and then
continue back. I highly recommend the best
choice is staying with one 1800s for the time being and then just going through
the entire course once, then changing it to
182 will also be a lecture that I will do in the future at the very
end of the course. So no worries there. Let's
just a very smart idea. Otherwise, of course you
are free to choose it, but please be aware
of some things do not work the same in 1800s
as they do in 181. I just wanted to say that. Now, let's go back to
setting everything up. In the future. You will probably have
two windows here, one of the ones that is the
latest and then recommended, always choose the
recommended build currently, which has not updated to
a sufficient version yet. So that they basically say, Hey, this is the recommended version, that's gonna be fine,
but it's always gonna be the M-Cdk that we want. And then here we just have
to wait for five seconds until we can download
the zip file. And then we click
the Skip button at the top and then the
zip firewall download. I've already prepared it, so I have my zip
file right here. So I'm going to right-click
and then extract to forge a crazy name here. And I'm also going to
rename this of course, one 1800s, they ago. Then we can delete the
zip file right here. This is the contents of the project folder or that
you're going to have. And what we can do is we
can delete all of those, the credits, the change
lock, the license, and the Redmi because
there are specific to forge were actually
or I personally, I'm gonna have my own
license file and all of that in just a little bit
about after that is set up, we can now start intelligence
for the first time. Now the window that you
will be greeted with will probably look a little
bit different to you. However, what you will definitely
have is three buttons, The New Project button, the Open button, and they
get from VCS button. We want to click the Open button and we want to navigate
to this directory. So I can also just copy it over, put it in here, and then
choose this folder right here, where the source folders inside this one right here say okay, we're gonna, we're gonna
say we trust the project, then a new window will open. Now things will start
happening in the background. You might get errors, you might get
something red in here. Don't worry about it.
We're going to fix all of them step-by-step, same with a warning
here you can see red, this warning right here. That's all fine. Just let this run through. Either we're going to get built failed or a build successful. Either one at the moment
is totally fine for us. All right, look at that. I actually got a build successful here,
that's totally fine. Like I said, if you
get a bill failed, we'll go through this and see what we can
basically change. There are some steps
that we need to take basically regardless
of what's happening. So what we want to
do is number one, you want to go to File and
then to project structure, we want to make sure
that at the project SDK right here it says 17th. So we basically want to choose the JDK that we've
just installed. Same with the project of
language. This should be 17. We're going to hit
apply and say, okay, we will also go to settings to build
execution deployment, in-built tools Gradle,
and make sure that it says project SDK
right here with 17. Those steps are
extremely important. Please make sure that
everything here is correct. After that is done, there's one more modification
that we need to do. You see if I open the
java folder right here, you can see that everything
here is sort of spread out. If intelligence is open
for the first time, it might look
something like this to you to simply go
onto the gear here. Makes sure that both
flattened packages as well as compact middle
packages is turned off. And then it's going to
look exactly the same here as it does
for me right now. Everything here has run through
correctly, That's great. So what we're gonna do
is we're going to open the terminal here and we're
gonna put in dot slash Gradle w Gen Intel
J runs right there. And then we're going to
hit Enter and just let it run through for
this basically just downloads a bunch of more
stuff and just makes sure that everything is
basically done correctly. And then we go build successful. If you've got a first
pill successful, this might not
always be necessary. However, it's great to
do this nonetheless. And now we're onto
changing some stuff. But first of all,
we're going to go open the built-in DOD Gradle file. And then here you see there's a version of group and
an archive name base. But the version, well, let's just put in
something like 0.01. And then usually what
is advisable is to put something in that says the
micro version as well. So I'm going to say
my version of 0.01 and then dash 100,801 because
of course we're in 181 now, the group here is the same as the names of our
package structure. So for me that's gonna be
net out and Joe Mc course. For you, this would be
net or calm your name. And then for example, you
could also choose MC course, or if you have another model, you could also of course
choose a different melody. Here we just take our
model idea as well, and that pretty much sums up everything that we need here. Really don't need to
change that much. What we can't change his right here you can see example mode. It says here, we can just select this press Control R and then
change this to MC course. You can see that a new window
will appear at the top. And then we can basically put example Mater at the top mc
course here and then just say replace all that basically everywhere where it
says example mod in this file it will
replace with EMC course. And what we can do
then is we can load the greatest changes by pressing the little elephant at the
top right corner as you saw. And then it's going to
basically run through again. This should not take as
long as the first time they go Well successful in nine
seconds, that's great. And then we're off to changing some more stuff and changing some more stuff we will
in the example mod class. Because what happens
here is that, well basically we don't
have an example mode. What we have is we
have net cotton rope, MC course or net your
name, MC course. So what we're gonna do is at
the top here in the package, we're gonna say net out
and Joe dot MC course. Of course this is marked with a red underline and
we're going to hover over this and say
Move to package net Cotton joe MC course
I'm gonna say yes. And then you can see a new package structure
here will emerge. So now we can delete
the rest that is empty. Then we want to
rename this class. So what we can do is we can
click on it, press Shift F6, and then we're gonna name this
the MC course mod day ago. Now, it is very important
is that this class, the MC course mock class, it will refer later as sort of the main class
or your main mod class. So if I ever say that
this is what I mean, Then we come to the MOD ID. The ID is something
that is very important. So please listen carefully. The MOD ID can only contain
lowercase characters. Format ID is basically a unique
identifier for your MOD. And it's gonna come in a
lot of times in the future. At this very top
here in the AdMob, you can see that we
have a string here. So what we're gonna do
is we're going to select the entire string with
the quotation marks. We're going to right-click. We're gonna go to re-factor. We're gonna say
introduce constant. I'm going to call this
the mod underscore ID. I'm actually going
to is copy this over to the very top here. This one is going to be used a lot of times in the future. And this is for US MC course. I highly recommend
staying with this and putting in the
same thing here. This is very important MC course all written in
lowercase altogether. This here also has to match
in the resources folder, meta nth mode Stato Mo. And you can see here mod ID, this also has to match. This is incredibly important,
very important here. Display name, let's
just say for example, the Minecraft modern course mod. Something like this offers
how about cotton row? Those are all not necessary, but this is just a Ideally, you don't necessarily
have to put this in. Let's also, let me
change the license to MIT just in case and the ego. So this is the general idea of basically setting
everything up. You will have to change this
intimate star Tom o file. And up here that's
very important. And usually that should resolve almost everything
that you have. Once again, make sure that you check the project
structure in the settings. And then after you've
changed all of that, run, the dot slash Gradle,
Jen intelligent runs. And then after you've done that, we're pretty much set up. This is pretty much all that
we need to do for the setup. Or we can now do is go
to the top right to the Gradle tab here, expand the tasks and the forge rail runs and then double-click on
it, run a client. Let's see if Minecraft
starts for the first time. That's the most important step. Basically, what I am very sure
that this will work fine. There you go. The window has already
opened and let's just see probably going to
hear the sound very soon. And there we are. Okay, Let me first of all, immediately turn
off the music and the volume a little
bit. They ago. In our modes, you can see the microbe modern course model. There is MC course
version at the moment 0 because we've not defined this properly in the
mos dot HTML file. But that's pretty much
all that you need to do. If you reach this point
and Minecraft has opened. Well, welcome to forge morning. It's gonna be a great
and awesome journey, I am sure of it. And the next thing
that we're going to do is we're going to set up the GitHub repository
for this project. I highly recommend not
skipping the step as the GitHub repository will
help me help you in the Q&A. For example, if you just supply me your GitHub
repository will be able to help you way faster than basically if you just
say, Hey, I got this arrow. So it just makes all of our
lives a little bit easier. So I highly recommend also setting up a GitHub repository. We'll go through the
steps right now. What you will need for
that is a GitHub account, but this is completely free and I highly
recommend doing this. This is a tool that is used by, I mean, almost all programmers. There's some different websites, but GitHub in itself is highly reputable and I just highly
recommend using it as well. So after we have made
an account there, what we can do in
intelligent is we can go to the VCS up here and we can
say share project on GitHub. And then you can see
I'm gonna call this the forge course on 18. That's fine. I'm I'm personally going
to make this private. If you want to share it, of course you can't
make it private. And now if I click
the Share button, you can see, hey,
account is empty. We're going to add
a new account. And what I'll say is I
will login via GitHub. I can click this and then
this window here will open, simply say authorizing GitHub. And because I'm already logged
into GitHub right here, this has now
authorized and you can see chair by github.com
slash coulomb joule. Now we'll say Share
and then a bunch of new things will open here you can see Add Files,
furniture, commit. We're gonna say, of course
that is totally fine. And then you can
see it's actually shared on GitHub and that's actually all that
you need to do. I can now click
this and it should open the GitHub repository. And there it is. This GitHub repository will
be available to you as well. By the way, this
is very important. I will have every lecture separated into different
branches so that you can basically very easily see and compare with
what you've written. I'll also have individual
gists for each lecture. So no worries. All of the code will be available in some form that is going to be
very useful to you if you now make a change here. So for example, I'm
going to say something like very important comment. You will see that the file where the change occurs,
it turns blue. And then what I have to
do is I have to go to this commit tab right here, will have to select all of the changes that
I want to commit. I then say added
important element. So this is just a name
of what happened. And I will click Commit. Now usually you
might also get, hey, I got like 63 warnings. Are you sure you want to commit? Usually you do want to commit. Now this just went through,
was very important, is that just because we
have committed something does not mean that
it is online yet, because to make it online, we actually have to push it. So at the very top here, the green arrow that
points to the top right, we have to click this. Then you can see added
the important comment. We can see the
changes basically, who, who did those
changes and all of that. And then we can just
click the push button. And then it says pushed one
commit to origin master. Then if I re-open this
and I reload this side, you can see added
important comment. I don't want this
to devolve into a GitHub or get
tutorial right here. But for the time being,
that's pretty much it. That's pretty much
all that you need. And now you can embark on the crazy and cool journey of modern Minecraft with 4241801. But this is it for this
lecture right here. I hope you found this useful
and learned something new. I'll see you in
the next lecture.
39. (Minecraft Basics) Using Parchment Mappings: All right, welcome back to
the fourth course for 118. In this short lecture, we are going to be changing our mappings to be
parchment mappings. Now, just a little bit
of an explanation here. The idea is that if we use
the normal mappings provided by merging the
official one server go into RI build-up Gradle file. See I have the official
mappings for 180 one here. And while this is totally fine, what does happen is that all of the methods do not
have a map parameters. This means is that every method that we might override
or something like that, the parameter name is
always going to be some, like P underscore some numbers and then underscore
a or whatever. And this is really
fricking, annoying, especially if you have
methods that might have 56, 57 parameters. And they all have
these strange names as they are fremitus. That is why I highly recommend
going with parchment. Now I have two links
in the resources. One is the librarian GitHub repository
here from parchment, and one is the
parchment repository. And what you will find
is that currently the 118 X version
does not exist. So it's not found that
it's not strictly true there is a
nightly snapshot. Now, a nightly snapshot
in this case means that it is definitely not
yet a full release. It's, uh, it works and you
can already work with it, but it's not highly
recommended to, you know, It's not done yet, so to speak now, we
will still use it. And what I will say is that I will be updating this lecture. Or as we go along
through the horse, I might throw in one or two
parchment update guides in their overall, usually updating it pretty
much is only changing. One thing that I will show
you in just a moment. Now what we can do is in
the librarian here you can see it basically says
everything you need to do. So it's very straightforward. For example, the first
thing we need to do is we need to add
this right here. So the parchment from the
Maven parchment repository. Let me copy this. Go to the forage
course right here. And then at the very top, below this, we want
to paste that in. You can see now we have
the parchment there. And then we want to
check the second one. And that is going
to be the librarian though, the class path theorem. So once again copied
Control C and then paste it in below
the Gradle here. So right here on
the dependencies, then we wanna take the
plug-in right here, and this has to be
exactly below this. So right here, right
very important. Don't paste it in here, but below the net
Minecraft Gradle, otherwise it will not work. Very important. And then last but not least, you need to change the mappings. I'll actually copy that over
from the other screen that I have here because I already have the nightly version
basically done. Let's just see they ago. So this would be the 13th of
December nightly version, nightly snapshot in this case, like I said, if newer
versions come out, I will link them here
somewhere or I will have future lectures or
change this lecture. And we're gonna, just
gonna see, we're gonna do this, no worries at all. And overall, this should now be fine if we have
those four things. So the maven, the class
path dependency here, then the plugin and changing the mapping
seer, you'll be fine. So what we can do now is we
can load the Grail changes. Now this actually should
not take too long. Once again, it
depends on your PC, it depends on the Internet connection speed that you have. There's a couple of factors
that might, I'm into this, but once again, it shouldn't be more than maybe a minute or two. But let's just be patient and let this run through, right? So as you can see,
build successful in 55 seconds, that's great. And well now it's
basically done. We have now we're now using
the parchment mappings. And that is going to be great. This is going to be way better. I highly recommend
doing this as well. It really only does change
the parameter names. So there are mapped now it's pretty much
all that it does, the method names
and the class names and all that should stay
completely the same. But that is already for
this lecture right here. I hope you found this
useful in the new, and I'll see you in
the next lecture. So, yeah.
40. (Minecraft Basics) Create a Custom Item: Or I will come back to the
forage course for 118. In this lecture, we're
going to be adding our first customer
item to mind for now, this is going to be a very interesting thing
that we're gonna do. And what we'll do is we'll
actually add two items. We're going to add
one, we're going to basically go through each step. And then I'll show
you immediately after we've seen
the item in game. Or you can add a
second one because sometimes it is a little
confusing for people. Wait, how do I now
add a second one? Do I have to go through
each step again? And no, there are some shortcuts that you
can basically take. Well, the first
thing that we will do and this is very important is in our MC course MOD
or our main mod class, we're going to select
this right here. So everything, including the getMethod event bus
with the parentheses, and we're going to
right-click on this re-factor and then introduce a variable. And then we're going
to say replace all three occurrences. And we're going to call
this the Event Bus. So just double-click
on the event bus. And then we're going to be fine. We'll also do is we
will basically delete everything in here except
for the setup method. We don't want the
registry events, we don't want the server
sorting, none of that. Do we need? And then we'll have
to read things in here so we can then delete
both of those as well, so that our constructor basically left with
just the event bus. You're the listener right here, the bottom of the event
bus register at here, and the setup method, because this is a
method that will definitely have
to use in future. There is another
method that will, that will have to add in
a future lecture as well. But we're gonna do that
once we actually have two. So now on to adding the item. So in our MC course package, we're going to
right-click new package, which is called item. Then instead of there we're
going to right-click again new Java class called
the mod items class. Now the mode items
class is going to follow a sort of schema or a certain template that a lot of different
classes will follow. And that is going to
be the following. So we will have a
deferred register. So I'm just going
to type this out of them and see what this is. This is going to be a
public static final, the third register, very
important one, F2, ours. But this one here from net microforms
registries double-check if you write this correctly
because there have been some people who have
written it wrong, and then that of course leads
to it not working though you can type it in and then just press Tab to auto-complete. And then we need these angle
brackets if you type it in the first one and the second one to generate automatically. And then we need item in here. Very important that we have
net Minecraft world items. We take this one once again, autocomplete and
then it immediately will import the class up here. This is called
items all in caps, very important as well as
this is a final field, therefore it has to
be written in caps. That's just a Java
convention in this case, this will be equal to
a different register. Once again, making sure that
you write it correctly, you can auto completed with
a tab when you actually see the congestion
there that create. And then once again, we can
just autocomplete it in the parenthesis
will then generate. Then we can save
forge registries that items on my
MC course model, that model ID, and then ending all of it
with a semicolon. So you can see that we are
already using the model ID. Here are the different register. In the simplest terms,
the deferred register. You can think of this as
just a list of all of your items that you
with your MOD atom. This is why we need to supply the melody so that forge knows, okay, all of these items are from this model ID,
from this mode. That's the general idea. Of course it's a little
more complicated than this. But just for your
general understanding, you can think of this
as a list of all of your items and we
basically have to register in there when you have
a deferred register basically for every thing that has forged registries here, I can take a look at this. For all of those things. We can basically have a another class and
another deferred register. And every time we have
a different register, what we're going to have
is we're going to have a public static void or the register method
with an Event Bus. Event Bus as its perimeter. We're gonna say items
dot register event bus. Now, if at any point
something here might be red. So for example, it is possible that item here might turn red. What happens is you
simply click on it and press Alt and Enter
to import the class, making sure that you choose net microwave world item here, and then everything should work. Make sure that the
imports you are correct. That's very important as well. And now we have the register
method and we need to call this back in our
MC course mod class, our main mod class inside of
the constructor right here, we have to say more items dot register with the Event Bus. So we have to pass
in this event bus into the register
method right here. And then the actual
different register will also be registered. So we have to register, well, our lists, so to speak, of all of our items. And now how do we, how are
we starting to add an item? Well, we need a public static
final Registry object. Once again with the angle
brackets of type item. And this is going to be the
cobalt underscore ingot. Now you can see once again, I have something
that's marked in red Registry object. I
can just click on it. And enter, and it will then import the correct class
that we're going to need. And this is going to be equals
two items dot register. The first parameter is
going to be a string. And this bus, or as
you will soon see, name generates automatically, you do not have
to type this out. Very important for Walt
underscore ingot is the name. This follows the same
rules as the mod ID. Only lowercase
letters, underscores or dashes and numbers,
nothing else. And you can see
after I've added the common now it says name. Once again, this
generates automatically, this is done by the IDE, this is done by intelligent. You do not have
to type this out. And the second parameter
is going to be a supplier. So we have open and
closed parentheses, will by this arrow,
and then a new item. So new item with the
other stuff in here. So new item properties you can see inside of the
item constructor, I'm just going to autocomplete
this and then say dot tab. And then we need to
supply at a tab. So this is the creative
mortality that it takes. And you can see where it's
just the tab miscellaneous. We're just going to
double-click this and then we're going
to be fine with it. We can see this is now all that we need to
register the item. The item would
already be in Game. Of course, it doesn't
have a texture yet, and it also doesn't
have functionality. We're not going to
add functionality in this lecture right here, but in the following lectures
are of course going to see, can basically add that. Now, one important thing is that this item properties here is
actually a builder panel, so you can slap it
on a dot afterwards, after the tab, you can
see that I can also call some other stuff like
Sentinel repair, fire resistance, perhaps
remainder, stuff like this. So there's a few cool things that I can basically call here, and it changed the item
in that way as well. We're going to stick
for the time being to just having the tab and just using the miscellaneous tab for this, and that's
going to be five. Now. Well, what does it mean? Well, it doesn't
have a texture yet. How are we going to define that? No worries at all. Now comes the folder structure, which is very important. So do make sure that you take care and look at
this very closely. There's any spelling
mistake here. Actually is going to have make it so that something
does not work. Instead of the resources folder, we're going to right-click
new directory called assets. And then inside of there
we're going to right-click new directory called MC course. This has to be your
MOD ID, exactly. Very important. Inside of there, we're going to make a new
directory, old models. We're also going to make a new
directory called lang LNG. We're also going to make
a new directory inside of the MOOC course
over cold textures. And once again, please note that these have to be
written correctly. So the models folder, we're going to make a new
directory called item. And then inside of the
models folder, again, we're going to make a new
directory called block. Now, what I can do is because we are going
to need both of those. I can select both of
them and then drag them into the textures folder
while holding control, which will duplicate
those folders. And because, because basically
I need the block and the item folder inside of
the textures folder as well. Now let's start at the top
with the length folder. In the length folder,
the translations are going to be located. So we're going to
right-click new file. And this is going to be the
EN underscore us db.json. Very important that
you add the dot Jason, otherwise it will not
be recognized properly. That's very important.
Also E and underscore us as to be also
written correctly, hit Enter and then
the file will appear. This window will appear. If you have a GitHub repository, if you do not have that,
then you will not see this. That's totally fine. If you do have a
GitHub repository, you basically want to say add, because then it adds it to the GitHub repository for
your next commit basically, and the EN underscore us JSON file will be built as follows. I'm going to start
with a curly bracket, which is immediately going to generate the second
curly bracket for us. In here we want to
translate the item. So the issue is that we're
just going to type this out. Item dot AMC course dot
o ball, underscore, ingot, colon and
then Old English. So the general idea
is that this is the unknown localized name of the item because this
one right here, right. The cobalt underscore ingot is the name that we've
given to this item. It is an item, and it
is, this is our Motet. All of this should make
logical sense, right? It shouldn't be like, why
is that happening here? No, no, this should make sense. This is the, um, localized name. Why do we even have this? Why do we need to define this in sort of like a JSON file? Well, there are
different languages. And if you want to
translate for each of those languages than having the, um, localized name and then a localized name here make that makes
a lot of sense. Actually. This is why we have
to do it like this. Once again, makes sure
the folder names are wrecked and also the
name of a file here. Otherwise, this looks good. Then let's move on to
the item model file. And the item model
is, well interesting. I will type this out ones. So what we're gonna do is
in the models item folder, Right-click new file called the cobalt underscore
ingot dot JSON. The name of this file has to match exactly the name
given right here. This is also very important
and then ends with the JSON. Now, like I said, I will
going to type this out once. We're gonna do this
rather quickly and then I'm going to
explain each part of it. So we're going to
have a parent right here, colon, item slash, generated ammo
textures, fallen open, curly bracket, layer 0. All an MC course, fallen item, slash
or bolt underscore. I might be saying what the
FREC is happening here. No worries. We're going
to go through this. The parent here determines how this particular texture is
displayed in your hand. And also in three-dimensional. Adam generated
basically just is, it's going to make the texture extruded a little bit so that
it has sort of a 3D look. And that's going to
be basically it. So that's just how any
normal item is displayed. We then have to define
all of the textures. And this has to be
textures very important. Make sure that this is
all written correctly. Layer 0, also important. And then this right here
is basically defines the directory where the
texture is located. So this is going to look at
the MC course Assets folder. So assets MC course inside
of the textures folder, right here under item slash cobalt English dot PNG, so item. And then we don't have
anything in there. I'm going to copy over
the extra right now, bubbled in Git dot PNG. And they go, and this
is basically now the texture that it
will display in game. One. Very important detail here for the textures is that please note the credits
file right here. So all textures are done
by nano attack and they are distributed under
this license right here. So if you want to use those in a public repository
of some sorts, then please follow the license, just add this file to your
project or your repository, and then you're
going to be fine. I just wanted to mention this
is quite important though. You can use the textures. Just keep that in mind right now for an item with actually
done everything, we've registered the item. We've added a translation, we've added the item model JSON file and the texture for now, for the first time we can
see for works, by the way, any one of those red arrows that you might be getting
are totally fine. This can sometimes happen
after you basically added arrangement for the first time, but
this is totally fine. You should be able to ignore
this as long as it keeps going and the Minecraft
actually starts, this should be no concern. And this also only happened once or in front of him, Minecraft. So let's see, let's go
to the miscellaneous tab and let's go to the very bottom. And there it is.
The cobalt ingot has been successfully
added to the game. That is a pretty cool All
things considered, right? And so just that you've seen it, let's add the nugget as well. So the basic idea
here is that we do not need a second
more items class. This is sometimes where
people get a little confused. The only thing that we
need to do is we need to copy over this
registry object. I'm gonna do Control
C after selecting all of it and then Control
V, paste it in here. We then just have
to rename this to nugget and then rename
the synagogue as well. For each item that
you register will have a registry object
associated with it. That's the general idea. And of course it
also has a name. So we need a new
item model, JSON, though let's first
of all go into our ear and underscore
us JSON file here. And what we'll do is we'll just duplicate this line by
pressing Control D, then adding a comma here. And then once again,
we're going to rename this to nugget. This nugget as well. And now in our item models, what we can do is we can just
take this JSON file and we can drag it into the same
folder while holding Control, and then we'll duplicate it. And then we can change the
name here, navigate as well. Then inside of here, of course, also changing this nugget. And then I will copy over
the item texture once again. And that's basically the process
of adding a second item. So this is basically always
what you're gonna do. There are going to
be some differences, especially when it comes
to the model files. Maybe they look a
little bit different. But overall, this is pretty much always what
you're going to have to go through at a registry object at the translation to the E And underscore us JSON file
at a item model JSON. And then the texture, that's pretty much
all there is to it. They'll just for
completion sake, let's see if it works or
if I'm such a Minecraft. As you can see, the cobalt also has been
successfully added. The game, though,
as you can see, it actually is a fairly straightforward once
you know how it's done. And this is just a thing that you just have to
get familiarized with and just routinized
basically adding items. And it's going to become basically second
nature to you, right? But that will already be it
for this lecture right here. I hope you found this useful
and learned something new. All of the code is by the way, available to you in the GitHub repository or an
individual just as well, that you basically never have to type everything out yourself. You can also copy some
stuff over if that is more conducive for learning
for your particular idea. Otherwise, I'll see you in
the next lecture. So, yeah.
41. (Minecraft Basics) Create a Custom Block: All right, welcome back
the fourth course for 118. And in this lecture, we're going to be adding
custom blocks to Minecraft. The custom blocks are
a bit more involved. But because we've seen basically one part
of how to add items, the blocks are similar,
but like I said, a little bit more involved
like tiny bit different, but not too much. So in our MC course package, we're going to right-click
new package called book. And inside of there we're
going to right-click new Java class called
the mode locks class. Now this class will be a little bit different,
but first of all, we will have the public static final deferred register
of type of block, making sure that we choose net Minecraft world level block. Very important, not the
OpenJDK oneness sworn eternal, but the level block, block that's very important. And then we say
blocks is equal to the third register dot
create registries, that box with our MC
course model that MID. And whether it's a
different register, we will also need
a public that's a void call register
method with the Event Bus. Event Bus. And this we'll call Box dot register
with the event bus. And before we forget it, we will immediately call it in our MC course mod
class right here, mod blocks dot register with
the event bus. There you go. So now the deferred
register is registered. And now what we
actually need is we will make two helper methods. I'm going to type everything
out and then I will explain after I've done this, the code for you is available in the GitHub repository or an
individual just as well. You do not have to type
out everything here. You can basically
copy it over as well. So when I have a private static
and then angle bracket T extends block void. Actually let's make
this item, sorry, let's make this registry
object of items. Then the name of the method
is the register block Atum, which is going to have a
string name parameter and a registry object of type T, which is going
to be the block. So that's the second parameter. And this is going to
return more items, items that register
with the name. And then a supplier of
a new book item with the block dot-dot-dot
New Item Properties tab. And let's put in
the creative tab, MRTK for the time being. But we will actually
change this. So one of the issues here is that now we're basically
hardcoding, okay, this is always going to be
into the miscellaneous tab, will actually add
a third parameter, which is going to be the
reactive mode tab, tab. And then we're going
to place this right here that we can
basically signify, Hey, we're going to make the
specific creative more tab. And then I'll just format this a little bit
differently. There you go. And then we'll have
another method that's a private static. Once again, angle bracket
T extends a block, which will also return a registry object
this time of type T, the register block method. And this will take in a string, we'll name is supplier type T, and then a block called Brock, and then eight and then
a third parameter, once again, this being the
creative mode tab. Tab. Now this one will
do the following. It will first of all
make a registry object of type T or to return, which is equal to
blocks dot register, the name with the block. Then it will cool at the
register block item method with the name to
return and the tab. And then here we're going
to return to return. Now those methods look
absolutely crazy. However, they are not
actually that crazy. So these are just some
helper methods for us because when we register
a block like this, right? When we just call
blocks that register, what happens is that
it creates the block, but it does not create
an item for the block. And this is kind of an
issue because we need block items for
each of our blocks. Now, doing it like this, in my mind makes lot of sense. If we ever run into a block that does not need a block
item, which we will, we will just make
another method that does not call this register
block item method. And then we'll basically
be fine though. Dear is that what does
this mean, for example? Well, it means that T is just a generic and it just
means that whatever is put into the T here has to be extending the block class. We're basically always going to use the block class anyway, because that's all
that we're really going to need in this case. But yeah, that just makes sure that this is the correct type. Pulling the register
blog item method should also make sense. This basically just
registers the item that is associated with this block here that we're basically creating an Has the same name basically, and that should pretty much be everything
that you need to know it gonna put this into the
tab that we pass in here. So all should be fine. Let's just see this in
action and let's see. So let's make a public static final Registry
object of type block. Will the cobalt
underscore block, which is going to be equal
to register block with once again at the
name cobalt block, double underscore Block
were important this year, generates automatically the
name plate 2, so to speak. And then a supplier
of a new block. And this is gonna take in
block behavior properties, that Material.me. And then if I put in a dot, you can see that there are a few more properties that
we can add two blocks here. What are the ones
that I want to add is the strength properties. So this basically is the time it takes to break this block. And then also very
important that we call requires correct
tool for drops, which will basically does
exactly what I wanted to. Also, this is not
copy this stuff. Oh, I'm very sorry. The ego. And then the third
parameter is going to be the creative mode tab dot. Let's do once again
miscellaneous. But this one does exactly what it says on the tin requires correct tool for drops because we have to define
IT tools later, basically so that the cobalt
block actually drops itself. This is something we'll
see in a later lecture. Actually the block drops, those are done with
Lou tables, knowers. We'll get to this. But this once again
is the block and the associated block item
registered with this. I highly recommend
also just playing around with some of
the properties that you can add here
you can see there are a few here that
you can basically add. Usually, we'll see a few of them going through the lectures. But let's now look at the JSON files because those are very interesting because
we actually need, in the MC course
folder right here, we need to add a new
directory or block states. There's also very important
that is written correctly. And I will once again
a type this out. So we're going to make a
new file in here called the cobalt underscore
block dot-dot-dot Jason, once again, make
sure this is written correctly and has
the ending JSON. So this is the name
that it needs to have. And then I'm going
to type this out. So R1 second curly
brackets, variance, colon, early bracket, empty
quotation marks, colon curly bracket. And then model colon, MC course, colon block, lash,
cobalt, underscore block. What is happening here? Well, the block state
basically defines different variants
of the same block. In our case here we don't have any variance because this is just going to
be a normal block. And this right here now
points to a block model JSON. So in our models broke
file it looks for a cobalt underscore
Block JSON file. So we're going to right-click
on this new file, cobalt underscore blog.js. And this actually
looks similar to the item model that
we've seen before. Curly brackets,
parent, fallen, block, slash cube, all comma
textures fallen. Only record. All colon, MC course, colon block,
cobalt, underscore block. The block model
determines how the block looks inside of the world.
What does that mean? Well, while the block states points to apes with
particular block model, the block model determines
the textures of that block and then basically refers to this
texture right here. And we also need an item
model for our blocks. This is very important. Oh, this is actually
going to be a new cobalt underscore blog.js. This however, looks a
little bit different. This is going to have
curly brackets and then parent fallen MC course all in Brock slash
cobalt underscore block. So this then refers back to this block model
and makes it appear sort of in a 3D way that blocks appear inside of t0 inventory. Let's copy over the
cobalt block texture right here into the book holder. And then also let
add the translation. Also very important. Let's copy this ones. And then we're going
to call this the block MC course cobalt block. And this is of course
a block they ago. Now that is all that we need to sort of recap
force once again, we need to create
the registry object for that particular block here. We then need a block
States JSON file, a bulk model JSON file, an item model JSON
file and the texture. This is a general idea. And after we've seen
whether or not it works, we'll also see a
second block B added just basically so that
you have another example. But for now, let's see if it works or we find
ourselves in mind for it. As you can see, the cobol
block has been added, so let's set it
down and they go, it does look pretty amazing, and it all works fine. So if there are any issues
with this block, right? So if there are any
textures missing, we can basically go through a checklist that you can check. So if the block only doesn't have a texture inside
of the inventory, it is the item model
Jason, that is to blame. Texture does not
work in the world, but it does work
in the inventory. It has to be the block States
Jason, that is to blame. And if it doesn't work in
either one of them, well, then it either is the block
model JSON or all of them. So that's a general
checklist that you can go through and basically check. But now, just for, you know that you
have another example, let's add another block, right? So once again,
this actually does involve just a lot
of copying here. So we're going to copy this,
I'm going to paste it in. This is going to be the cobalt or block and then
this is going to be the cobalt underscore
or instead of metal, this is going to be don't. And this is going to be rather than five strength,
just force, right? That's going to be fine.
Now the rest here is fine. This now has
registered the block. We of course now
need the book says Reason brought model Jason
and the item old Jason. Let's just copy this over by dragging it into
the same folder while holding control and
change the name here to block, to cobalt or theme here. This now points to a block model Jason in the folder right here, that's called cobalt
underscore or dot JSON. We're going to
create that as well into the name year for the
texture that it points to, which we'll add
in just a moment. Let's also add the
translation immediately. But what OR, and
of course the name here who will
underscore the ego. Also copy over the cobalt or
item model and rename it. Or and then underscore
or here as well. And then we just need
the texture for it. I'm going to copy
this over as well. And there you have it. Now the next block is made. And yes, once again, this is just the normal way
of going about it. You will just have to go through this in the next lecture. Basically, you're going to have an assignment on adding
two blocks of your own. This is basically
going to rock cobalt block and the deep state
cobol or block as well. So that's just something
to basically keep in mind. Apart from that, let's just
see if completion seek, whether or not the or
block also has been added. All right, we find those
back and microvesicles. See the cobalt or block also has been successfully
added to the game. So everything work
in great here. That's actually how
easy it is to add a second block as well, right? Like I previously
said, the next lecture is going to include
some assignments. I highly recommend
you go through this because it can be very, very positive and just
a very good idea to basically will do those just so that you get a
little bit of a feeling. Once again, all of the code for the lectures
here is available in the GitHub repository or
an individual just as well. But that would be it for
this lecture right here. I hope you found this useful
when you learn something new and I'll see you
in the next lecture. Oh, yeah.
42. ASSIGNMENT 5: Block & Item: Or I will come here to
the first assignment for the fourth course in
the Minecraft section. And like I have
already said, here, you will basically make
two blocks and one item. This should actually
not be too crazy. So hopefully you will find the assignment in a
written somewhere. So basically you
have the assignment as a written question as well. And the idea is that
you will have to add the rock cobol block as well as the deep slate
cobalt or block. Now, the textures for those
blocks are available. Same with the item. Please do note the
credits file right here for the textures follow
a particular license. So if you want to use them in a public repository
or something like that, and please note that the
creditors file, like I said. And for the item, you are going to add the
raw cobalt item basically, and that would
pretty much be it. Others all shouldn't
be too crazy for you. Hopefully if you've seen
the previous few lectures than it should be fairly,
fairly easy to do. Well, good luck and have fun
on the assignment. So, yeah.
43. SOLUTION 5: Block & Item: All right, let's take a look at the solution for the
first assignment here. And of course, hopefully it
was fairly straightforward. You just added the two
registry objects for the two locks that
we wanted to add. Same with the item
here, the raw cobalt. And then we just needed the
blocks, these JSON files, which simply point to two different block
model JSON files, which in turn point
basically the textures here. And then the translation
that should be at this point hopefully
become routine. And then we just needed the
item model basins as well. And this also includes
the rock cobalt, which then just points
to a texture right here. The overall, hopefully
this was easily done. And that's pretty much
all that you need to do to have this in your game. And we will be using basically the raw cobalt and all of the other things as
well in the future. Oh, it definitely is a good idea to have this
in your game as well. All of the code is of course, also available in the
GitHub repository or in, in, in an individual
just as well. And I'll see you in
the next lecture. So, yeah.
44. (Minecraft Basics) Custom Creative Tab: All right, welcome back to
the forage course for 118. In this lecture, we're
going to be adding our own custom creative
modes tablet to the game. This is actually a fairly easy and straightforward
process. So in our item package, we're going to right-click
new Java class called the model creative
mode, tabs, or tab. This is going to
implement the following. This is going to have a
public static final read of Mode tab called
corps underscore tab, which is equal to a new. And you can see Norris just
the creative mode tab. And if we press the tab key, it will generate the, generate an anonymous
class for us. We'll actually
have to enter this with a semicolon right here. And then instead of
returning null here, and we'll move on to churn
is a new item stack. More items dot cobalt,
ingot, dot get. And then inside of here, we're going to add a string. This label here generates
automatically once again. And this is just going to
be the course model tab. Whatever item you put in here, also whatever block you
put in here is going to be the display image
for the actual tab, and this is needed
for the translation. So I'm actually going
to copy this over. And we're going to go to
our E and underscore us JSON file to the
very bottom here. And we're just going to add the, add the item group dot
CourseMatch tab colon. And we're going to call
this the MC course. Not. That's okay. Now this is an outlier in
the terms of translation here we have a big G for the uppercase G for
the item group. And then of course mod
tab with outermost idea. But that is pretty much all
that we need to do to add it. Now let's also add our
items and our blocks to it. Instead of saying creative mode, tap here we're going
to say more creative, more tab, dot Course tab. Just going to copy this over
selected press Control C, and then Control
V to paste it in here and do the same
thing right here. Basically everywhere where you have the miscellaneous tab. We're now going to put
in the Course tab. And now all of our items
and our blocks will be in the four-step though. Let's see if it works, or we find ourselves
back in Minecraft. And a very good sign
is that we have a second page here
in can see MC cores MOD and everything is in here exactly how you would
expect it to go. That is perfect. And just
everything working exactly how you would want to write it that is already for this
lecture right here. I hope you found this
useful in yurts of the new, if he did our very much
appreciated review from you. Otherwise, I will see you in
the next lecture. So, yeah.
45. (Minecraft Basics) New Recipes: All right, Welcome back
that forage course for 180. And in this lecture, we're going to be adding
custom recipes to Minecraft, or custom recipes are
done via adjacent files. They are not done in
the assets folder, but rather in a new folder. So in the resources right-click
new directory called data or data inside
of their MC course, and then inside
of their recipes. Now what's very
important is once again, this directory has
to be complete, written completely correctly,
otherwise it will not work. And I will basically show an
example of each recipe year. Like I said, these are in
JSON format once again. And what we can do actually is we can go to the external libraries down here. We can expand this. And then you will find
somewhere below here, you know, going down. But finite Minecraft
nine extra 180, one or whatever the
current version is. If you expand this and
go into the data folder, you will see Minecraft and then all of the JSON files
that are in Minecraft. So for example, we
can take a look at each of those JSON files. These are basically all
of the vanilla recipes like pay out. How
does this work? You can see coal from
blasting cool or interesting, but there's, you can already see there's different
types of recipes. How does the composter,
how's the combustor made? You can see this. You see O tag, interesting. Okay, we're using tags here. Cook time could be frayed. We have things like the cookie. So you can basically find
examples of stuff in here. I highly recommend going
through this, going in here. If you ever have
a recipe that you basically want to recreate,
you can just find it. You can then say, for example, for the bone block here, right? Oh, that's like a really
thing I want to do. You can basically press
control C to copy it. Go back to your folders, go in here, control
V to paste it in. And then for example, I
could say cobalt block from ingots where they go
and then I'm going to open this and then you can see now I can of course change it. And the general ideas that well, you have different
types of here, right? In this case we have
a shape recipe. The pattern is filled.
What is the pattern? Will the parent are three
strings of length three. So this represents
the crafting grid. This is the top-left slot and then the top right slot
and so on and so forth. So this should be not
too crazy to understand. We can put in keys here. So you can see that
this hashtag symbol basically represents a bowl
new item in this case, well, we will change this
to our customer items. So we're going to
say MC course colon or bought underscore ingot. And then the result here, of course going to
be MC course colon or bold underscore block. But all of this
should actually make sense at the moment and
shouldn't be too crazy. But this is a shaped recipe, like I said, because it
has a particular shape. Now what also would work
is something like this. Then you would
either have to bill the top two rows or the bottom two rows in
the crafting bench. So they don't always
have to be of length three or three strings. There's also works. So something like this, which would be the
boat, for example, would also work because you
can either put the boat in at the very top or
also at the bottom. So that's very important. And I will actually
copy over all be available to you in
the GitHub repository or an individual just as well. You can see first
of all, this one is a shapeless recipe
because we can basically put the ingredient anywhere into the
crafting bench. And this is basically
a cobalt block, right? And then we will get robot
ingots and then nine of them. So basically, this is the same thing as this one
just in return, right? So in reverse though, you can get the nine
ingots back from a block. And then we have
these two which are the ingots or smelting. So you can see I can smell the cobalt or into
an ingot here. Same with this, but
let's just smelting or blasting will be fairly self-explanatory, all
things considered. And then just as an example, you can also just use,
We'll multiple keys. This is the way
that you use them. And you can also use
Minecraft items either as the result or as a crafting
item that works totally fine. Like there's no issue
with this whatsoever. So this is sort of
a general idea, year end, Well, in not
quite the next lecture, but the lecture after
that, if I'm not mistaken, you're going to be making
your own custom recipes and basically have a few
ideas of what you make. But they all are fairly
straightforward. Though, overall, That's
it. Very important. The external libraries really highly recommend going
through this because there also is the Assets folder where all of the lock states, the Lang, the textures
are also ends right here, the textures are in here. So you can basically take
a look at everything, the model files as well. So I highly recommend going through the external
libraries here because this is
just the best thing that you can like ever look at. If you don't know,
Hey, how can I make a recipe that is exactly
like x in vanilla? Just go in here,
take a look at it. Very easy, No worries at all. But this is a very
straightforward process. But for the time being, let's see if it works or why we find ourselves
back in Minecraft. So let's try the
cobalt inner first and they go and cobalt
block and let's see, I can get the nine
ingots back as well. And what you will find
as well is that it will automatically as those, as recipes in the
recipe book as well. So that's really nice. And let's just see if we can
also smell the cobalt or, and of course we can,
that's totally fine. That works as well. Though
everything here working great. And also just for the
sake of argument, why not try to make the
diamond stack here, the ego 64 diamonds
working as well. Nice wrapper, that would already be it for this
lecture right here. I hope you found this useful
and ignorance of the new. Once again, all of the JSON
files are available in the GitHub repository
or where an individual just as well. And I'll see you in the
next lecture though. Yeah.
46. (Minecraft Basics) Block Drops with Loot Tables: All right, welcome back to
the fourth course for 118. In this lecture, we're going
to be taking a look at adding custom route
tables to Minecraft. Or a loose table basically defines what a
drops from a block. This is also one of the
reasons why we added the requires correct
tools for drops here, this all right there. Because if we don't have that, then basically any tool that you might this block with would then drop the actual Lu table or the rock drops, so to speak. Once again in our data folder, in the MC course folder, Right-click new directory
called loot underscore tables. Once again, make sure that
it's written correctly. Then inside of there a new
directory called blocks. And then I'll actually copy over the loot table for the
cobalt block is to see this. So this is how it looks like. It is of type block. There is one pool and then you basically have a different
entries in this pool. We can see this rod onetime
there is the entry here, one entry of type item. And then we basically drop one cobalt block or all this can sometimes get a
little confusing, especially when I will now
copy over the loot table for the cobalt or
blocked because of course that works a
little bit differently. We will see this is
more complicated than it would be at first odd. But of course what we have
is we only have one entry. What it is is an alternatives
entry, so to speak. And the idea here is that, well, either it's going to
drop this and it going, it's going to drop this if
the condition here is met, which means that the enchantment on our tool has
to be silk touch. And then it drops the
cobalt or otherwise, it will drop between 25 Ra. That's the general idea here. And you can see that
it also applies a bonus when it comes to the fortune
enchantments as well. That's something that is also done in this case
with a function. I highly recommend once again, going down to the
external libraries unit, microwave client extra one 1801, instead of the data folder, you will also find that
the alluded tables folder. And then inside of there you can take a look at all of the loops, tables from all of
the vanilla blocks. I highly recommend. I cannot recommend enough going down here and just
taking a look at this. I will also give you to other resources which
are really important. One of them being the
luge table Wiki entry here from the micro fan and wiki because
here you will see actually all of the
different stuff, all of the different things that you can basically put in. You can see that there's
a lot of stuff in here, highly recommend
taking a look at this, basically how it functions. And then there's another
one and that is going to be misaligned dot GitHub
IO loot table. And this is a luge
table generator. Just make sure that you are
on 118 at the top right here. And then when you have that, you can basically change
all of the stuff in here. You can say, Hey, I want
some specific functions. You can see these are all
of the functions, right? You're going to ask them
specific conditions like a random chance. You can be like, Hey,
I wonder if the, if the entity is
killed by a player, all of that, all of
that, all of that. So there is an insane amount of stuff that you can
basically add in here. I highly recommend being
open to experimentation, trying out a bunch of stuff. This is the best thing that
you can do for loop tables. And I'm sure that at that
point then you will manage to get something really
Lu table that is exactly what you
would want it to be. But this is actually
not all that we have to do because we will actually
have to add something else. And that is once again
in our data folder, Right-click new directory
called Minecraft, the game you might
have heard about it. And inside of there
we need to add a new directory, old tags. And then inside of there, we need to add a new
directory called blocks. And then inside of there, we need to add a new
directory called mineable. Now, why do we need this? Well, we need to define what
our blocks, our mind width. And for that we're actually
go down to the data folder, Minecraft, eggs, blocks, and then we will see the
mandibles right here. What I will do is I will
just select all of them, press control C to copy them. Then I'll go in here, press Control V to paste it in. Have all of those JSON files with all of the
vanilla blocks here. What I can do is
just, I'm going to just also select all of this and just get rid of it or
all of those JSON files. But these are tags. Now tags at the moment
you can basically think of them as a collection of different blocks or items that have some similar
functionality to them. We'll go through what blocks are in a later lecture as well. But for the time
being, what we'll do is we'll just add all over the blocks that we
have to the Pic X Jason. So this would be MC course
colon cobalt underscore block. And then I will just
duplicate this four times. This is then a rock
cobol block wall or and then also the IEP slate. But very important
is that you can only define blocks that are
existing inside of your MOD. Though if I would not have the deep layer cobalt
or if I added here, then I will get an
error when I tried to join a world that's
very important. And then there's three
more things that I need. And those are, well, the level of tool I need
for this different level. So I can basically
look for this. So you can see nice diamond 200 needs
iron to need stone tool. Once again, I'll just copy
all three of those over. Highly recommend doing the same. These are of course, also
all available to you in the GitHub repository or an
individual just as well. And then I will just do this and we'll just
say this and then the stone tool also
just get rid of. And so for example, let's
say, you know what, I think that cobol and
it's iron tools at least. So what we're gonna do
is I'm going to say MSE course colon o
bolt underscore block. And then you realize,
you know what? Let's just take those, copy them over,
put them in here. That is a little bit easier. They go. So we'll only be able to mine those with at
least an iron tool. And up, That's the idea. So iron tool and up, we'll be able to mine those now, every new block that we add, you will have to
add to these tags. I will probably not be doing
that in as we go along. I will definitely
not show it because at this point, you know, if you've seen it once, you should probably
be very easily able to just add them yourself. It should be fairly
straightforward, but that should be all
that you have to do. And now after having
added the tags and the lute tables, Let's
see if it works. Or we found says in Minecraft. So let's see if I can mine this and they go the block drops. And here we should get some
raw for Walt and we did. So that everything
works totally fine. Let's also just try this with
a stone pickaxe and you can already see that it
takes quite a long time, so it probably not work. And you can see it doesn't
same with the diamond aX. It takes so long to
even like starts to see the breaking animation
is not even worth trying. Of course it's not
going to work, right there would already be it for this lecture right here. I hope you found
this useful in terms of the new, once again, all of the JSON files
are available in the GitHub repository or in
an individual just as well. And I'll see you in
the next lecture. So, yeah.
47. ASSIGNMENT 6: Recipe & Loot Tables: All right, welcome back to
the second assignment here for the course for 118. And in this assignment,
you're supposed to add some loose tables
and some recipes. So the recipes that you are
supposed to add is number 1. The recipe for the nuggets. For that I can put in an ingot
and get out nine nuggets. And then of course the
reverse once again, where I can basically
put a nine nuggets into the crafting bench and
then get out one ingot. That is number one. Number two is, you
should also add the recipes for the
deep slate well, or to be smelted as well as the raw cobalt or to be smelted. And then also be able to
craft the raw cobalt block to it and then from it back
again, basically as well. And then one more thing
is that you should add a recipe which contains at
least two vanilla items. So similar to the stack
diamonds from another star. With that we've done here, just has to contain two
Minecraft items here. And then the rest
you can basically fill out however
you would like to. It can result in
anything that you would like to just be
creative they are, and just try a bunch
of stuff out, right? So good luck and have
fun with the assignment. So, yeah.
48. SOLUTION 6: Recipe & Loot Tables: All right, Welcome to this
solution for this assignment. And of course, adding
the luge tables, Let's start with those would have been fairly
straightforward. Year we basically just took the cobalt block loot table and replace it with
the row cobol block. Then same goes for the deep
slate cobalt or loot table, where instead of
cobalt or it drops the deeps late cobalt or row cobalt here should
still dropped normally. So that's the lute tables. And then when it
comes to the recipes, you can see there's quite a few. Now overall, those should also be fairly
straightforward, right? The last thing from the deep slate cobalt or it'll
be fairly straightforward, is the same as the normal one, just, you know, with the
deep state in there. And pretty much same
goes for the rest of it. All of it should be
fairly self-explanatory. All things considered.
If anything, remains unclear or you have
any questions, of course, you can always feel free to use the Q and a that is provided. And I will answer the
questions best of my ability. But otherwise this
would be it for this assignment right here. Hope you found this useful
and leaders of the new. I'll see you in the next
lecture though. Yeah.
49. (Minecraft Basics) Advanced Item: All right, welcome back to
the forage course for 118. And in this lecture, we
are going to be adding a custom advanced
item to Minecraft. Now what I call it an
advanced item is basically an item that has its own
class associated with it. This doesn't always mean that it's necessarily crazy advanced, but you basically have
the ability to add way more functionality
to this item. So let's just see
how to do this. In our item package. We're going to right-click
new package called Custom. And then inside of
there wouldn't make a right-click new Java class
called the dowsing rod item. I highly recommend ending every custom item with the word item so that
you know what it is. This will extends the
item class right here, will hover over this create,
constructor matching super. And then we'll basically take
a look at what we can do. So if we middle mouse button
click on the item class, we will actually be
able to see all of the different methods that we
might be able to override. And you can see
there are a lot of methods that we are
able to override here, which is really cool. And there's even at
the very back here, I forge item which we can also middle mouse
button click on, and there's even more methods
that we can override. You can also see the
methods that we can override if we type
in override here. And then you can see
basically all of the different methods that
are possible for overriding. And this is a lot of methods
as you can clearly tell. So really a lot of this
comes down to once again, trying out a bunch of stuff, trying out a bunch of stuff. And one more time trying
out a bunch of stuff, being open to experimentation, probably the best thing that
I can basically tell you. Now we're going to make
a dowsing rod item. And I want to do with
this is the following. I want to be able to right-click with this
item on a block. And then it will basically
extend down into the ground. Basically take a
look at every block that is below the block
that we just clicked. And if it finds a
valuable block, then it will print out the coordinates.
That's all I wanna do. This is already quite
an interesting idea. All we're going to see the right-click method when
you right-click on blocks because there's
two different methods for right-click Nanoblock and, and right-clicking in
the air so to speak. So we can just put in use, and you can see this
use right here. This is the one that
would be called. This method would be
called if we just right-click in the air so that this is what
you would want. The US on method
here is the method that is called when you
right-click a particular block. But this is the one that
we're going to override here and see it has
a use on context. And what we're gonna do is
we are just going to, well, I'm going to put the
functionality in and I'll try to explain best
as I go along. So we're going to have an if statement where
we're going to ask basically the p context
that get a level. So we're gonna get the world. The level here, we're
gonna say is client side. So in this rare, rare instance, we actually want to do
everything on the client in this case because it is actually a little
more interesting to us. So we're gonna say
block Pause, position. Clicked is equal to
the contexts dot, get position, DIA, get
clicked, pause here. And the modulus is
going to import this by pressing Alt and Enter. Then we want the player. The player is going
to be contexts, dot-dot-dot player that you go. And then once again
click on player and then import this with
Alton into as well. And then last but not
least, we'll have a boolean which is
going to be found book, which is equal to false here. And then we want a for loop. So I'm going to just put this for-loop in and
then we're going to look at what this
basically does. But we're going to start here. I'm going to say I more
equals position clicked that, get y i plus plus. And then what I wanna do
is I basically want to get the block that is below the block that I've
just looked at. So block below, which is
equal to p context dot, once again get level, not get lock, date at
the particular position, which is the position
clicked dot below, by exactly how much
I'm counting up. And then we're just
getting the block from that and import the block by pressing Alt
and Enter once again. Now, what I then
want is I want to output the coordinates
and I also have to check, okay, is this block, you
know, something valuable. So for that we're going to
make two helper methods. Now I'm actually
going to copy over the output of the
coordinates, right? This is the output method here. So we can see we're just
getting the name of the block and then putting out
the coordinates of it. So that's all we're
really doing here. And then we also want
a private boolean, old is valuable lock, which just takes
in a block here. And we'll then just return a true if this is a valuable book, what we're gonna do is
we're going to return block equals blocks dot
poll or for example, or LOC equals, locks up or, or. And then let's just duplicate this ones will have
another orange here. Format this a little
bit differently. Apply this. Yes, and then we'll
also put in diamond or and maybe just iron
ore here as well. And iron block but
iron or they ago. So these are the four valuable
blocks for the time being. If you want more,
you can of course add more in a later lecture. We're also going to
see a more robust way of doing this with tags. But for the time being,
this is going to be fine. Then what we're going
to say is we're gonna say if is valuable, walk a block below. We're going to output the
coordinates in the position clicked that below with I here, though, because this is the
actual position that we just clicked with the player
and the block below. We will then set found
block to be true. And then we'll break
out of the for loop here because
we found a block. And we no longer
need to basically do any checking because we only want to output the
first block that we find. And then once we're done
with the for-loop here, we're going to say,
if not found blocks. So this means that no
block has been found. We're going to say
player datas and message with a new
translatable text component. Item, MC course dowsing, rod dot no underscore value. And then after the parentheses, the second parameter
is going to be player dot get UUID a year ago. So this is of course a way to output a message into the chat. Now, this is a translatable
text components, so we have to take this
right here and add it to the un underscore
us JSON file. So we're going to just
add this and just say no valuables out. I'll recommend using translatable components
everywhere you can, basically making your mark just a little bit more robust or other speaking
countries as well. So basically when
you have another language that just makes it a little bit nicer to read
and to use right now. What is the rest? What is going on here?
Well, first of all, we making sure that
we are on the client. This is usually not the case. Usually we want to be on the
server, but in this case, because we're just
outputting something On the client is fine
because this use on will actually be all twice
on the server and ones that the client will then just
make two variables here. So the position that you
clicked and then the player. And we're then going to go
from the bottom of the world all the way to the actual
position that we clicked. This is going to be y. And, and we're going to start
when we have reached this. Now what we will actually have to do is we will
actually have to change this tiny bit
here in the block state. Because if I put in a negative
number here in the below, we would of course go
above all of a sudden. So I can actually go
into this as well. Let's see. We're gonna go
into the down position to, in this distance. Now the real issue is, of course that is the distance
here is negative. And of course we'll just go
up instead of going down. And we actually want to add a 64 to this because of course, instead of 0 being the
limit of the world, it is now negative 64. This is why we basically
need to also this up by a 64 year and then the rest
should work totally fine, because the first block that we will literally take a look at is the block itself
that we've just clicked. And then as I becomes one, then we're going to go down
one and so on and so forth until all the way to
0 when we reach this. But then the thing about it
is that then we can continue. For below that. That is why we add a 64 here. So overall, this should be
all that we need to do. Let's go to the More Items class and let's create the items. We're just going to copy this, make this the dowsing rod. And then here the
same dowsing rod. Now instead of a new item, this is a new dowsing rod item. This is extremely important
that you do this. Please note that this has to
be a new dowsing rod item. Otherwise it will of course
not get this functionality. Very careful with. Let's add the
translation as well. So there's a dowsing rod, and then here it
is a dowsing rod. Let's copy over the
England item model here for the dowsing rod. And change the name
here, dowsing rod. And then we will also copy over the dowsing rod texture into
the items folder right here. Dowsing rod they ago. And now this should be everything that
we're going to need. Though. Let's see if it works. All right, we find ourselves in Minecraft and as you can see, the dowsing or has been
added to the game. Let's just see if I right-click. Well, that is a
great thing to see. Your, this is of course not
quite what we had in mind. You can see no valuables found
that works totally fine. This just is the actual
output is of course, would be made a little
bit nicer to read, but no worries at all. We can see the actual
position of it. And well, I mean, that's
absolutely perfect. This is seems to be
working totally fine. And all is well. Now there are
actually two things that we should also add, and that is in the
item properties, I should also add the
durability right here. And this would be,
let's say for example, 16, so we can use it 16 times. And then we should
also make sure that we actually
damage the items. So this is going to be done
outside of the if statement. We're gonna say P
contexts, dot-dot-dot, get item in hand
that hurt and break. By one. We're gonna say P contexts,
dot-dot-dot, get player. Then we're going to say make a parentheses where we
put in player here, then a, an arrow, and then we say
player dot broadcast, break event with the layer
dot get used item hand. So this will basically
add or subtract one durability each time
that we use this item. And then this basically
just makes sure that we have some durability. They are something
that we can also not stack the dowsing rod, which of course does
make a lot of sense. Let's also then
just for the sake of argument at this one, instead of doing the getName, let's just do as item and then get the registry name and
then put that to a string. This should also work. This I believe then should
output Minecraft colon, and then whatever
the actual block is, which is totally fine as well. Those are just some
adjustments here. All of the code is of
course available to you in a GitHub repository and
individual just as well. But this would be it for
this lecture right here. I hope you found this
useful in euros of the new, and I'll see you in
the next lecture. So, yeah.
50. (Minecraft Basics) Advanced Block: All right, welcome back to
the forage course for 118. And in this lecture,
we're going to be adding a custom advanced
block to Minecraft. Similar to the advanced item. And advanced block needs
its own separate class. So in the block package, right-click new
package called custom. Sort of there we're
going to right-click new Java class called
the SPD block. And the spirit block will have the following
functionality. If we step on out,
we're going to get an effect applied to us. And that's the
movement speed effects are basically going
to get faster. Now this extends
the block class, making sure that we choose a net Minecraft world level
block. Very important. And then we hover over this creed constructor
matching super. And if the parameter
here is unmapped, can do is we can
just click on it, press Shift F6, and then
choose Properties here, just so that it looks
a little bit nicer. And then the method
that we want to override is the step on method. So we're just going
to type that in and then press Tab two.
Complete this. And once again, we
can right-click on the block class and
we can see, well, a lot of different methods
that we can override, probably even more
than in the item. And this is of course
not it because there's also an I4 each block interface which has
even more methods that you can override this. You can see this
is crazy and a lot of methods I highly recommend. Once again, it just being
open to experimentation. You can see if I started
typing override here. There's the US method which is used for
right-clicking or block. There are methods like add landing effect
at running effects. This is crazy stuff. Harvest block can harvest block. That's like for a
particular item, Canvas harvest the block. We have an insane amount of things as you can
clearly tell all on. There's the destroy method, There's the pen
Hover Text method, and then some of them
which are deprecated here. Now, usually when you have a deprecated method
like for example, the onRemove or the US method. The US method is a
great example of this, doesn't always, necessarily mean that you shouldn't use it. What that means is that
you should not call this method including
the super cool. But that's something
to keep in mind here. But for us, we're just interested
in the step on method. And what we want to check here
is basically We are not on the client or that will
be have to type in is exclamation mark P
level is client-side. Now this exclamation mark
here is extremely important. Okay, Do not do it without this because without
the exclamation mark, we're checking a foreign, the clients that we want
to be on the server. We have to negate
this very important. Then we want to
check whether or not the entity that has stepped on this is instance
of a living entity. This simply means that we can
cast it without an issue. So we can say living entity. And entity is equal
to E entity dot cast. And then it most often will suggest living entity already. So this is great. And then what we can do is
if it's a living entity, we can call dot add effect. And here we just
wanted to basically call a new mob effect instance. Here we pass in a mob effects
that whatever we want, in this case it's
movement speed. And then the second parameter in here is going to be the length. So this is the time
that this effect has. If we put in a 200, this would be 200 ticks. So divide this by 20 to get the amount of time
in seconds basic. And you can also add
a third parameter, and that will be the amplifier. So this basically is
an additive amplifier, meaning that if you don't
have anything in here, it's gonna be, you know, one, this is going to be sp2, this is going to be sp3
and so on and so forth. So that is the
general idea here. Let's put an a one just so
that we can see this as well. And well, that is pretty
much all that we need to do in the realm of the functionality for
the speedy block force. Now we still have
to register it. We're just going to copy
over the deep sleep cobol or here and we're
going to call this the SPD underscore block. And then the name
the same thing, speedy underscore block. Then very important. Once again, this is a speedy block this
time and not a normal block. The other stuff I'm
actually happy with, now it just comes
to the JSON files which I will copy over. All of those are available
to you, of course, in the GitHub repository or
an individual just as well. See this is just a
normal block model. Jason. Then let's copy
over this one right here and say ET
underscore block. And then the name is
going to be speedy block as copy over the
block model as well. Once again, to some
normal block model that, that points to a texture. And the item model
also doesn't own anything crazy or spectacular. It is just a normal item model
like we've seen for a lot of other blocks that simply points back to the block model. Last but not least, of course, let's also add
texture and the ego. Now we have added everything
that we need to add. Though, Let's see if it works. Or offenses back and
migraines can see the SVD broke has been
added to the games. Let's just set it down. And what's very
important is that, that while this arrow
points to this direction, it will always point
to this direction no matter how I place it down. We'll just keep that in mind. Because this texture
basically is always going to point
in the same direction. We're going to see
in a later lecture how this can change. Let's go to school on here and
you can see I already have speed to apply to me
while I am on there. I will have this apply
to me constantly. But then as soon as I step off, you can see now I
have speed too. This could be a really
cool block, for example, for any kind of
adventure map or like parkour map possibly rubber that would already be it for
this lecture right here. I hope you found this useful
in terms of the new force. Once again, all the code
is available to you in the GitHub repository or an
individual just as well. I'll see you in
the next lecture. So, yeah.
51. (Minecraft Basics) Custom Fuel: All right, welcome back to
the forage course for 118. In this lecture, we're
going to be adding a custom fuel item
into Minecraft. Adding a custom fuel item is actually fairly
straightforward. However, we do actually need to make a new
class for this. So in our custom
package right here, right-click new Java class
called the coal sliver item. And this is going to
extend the item class. Let's hover over this create,
constructor matching super. And then really the only
thing that we need to do is we need to override
one particular method. And that is D get burn time. Right here. We'll just double-click on this
and then we will return whatever the time is that this
actual item takes to burn. Now for our purposes, we're gonna do for a 100. Once again, this is
the time it takes, so that's very important. And for example, coal
has a burn time of 1600, so this is exactly 1 fourth, as good as cold sores. Now let's go to our
more items class and let's just copy
over the dowsing rod. This is going to be the
coal underscore sliver. And same year coal
underscore sliver, making sure that we don't
have any durability on this. That's very important. And that we're creating a new coal a sliver
item right here. Apart from that, that is
all that we need to do. Of course we still
need an item model. Let's just copy over
the item model of the cobalt ingot and we'll call this the coal underscore sliver. And then changing
this year as well. Cool, We'll underscores liver. Not forget to add the
translation as well. We will underscore sliver. Worse naming this
the OLS liver force. And then last but not least, as also copy over
the item as well. Right here into our
items folder for intro, the textures item
folder they ago. And that's actually all
that we needed to do. So let's see if it works or
referrals back in Minecraft. And let's just see the
coast of the husband added. And of course it
works totally fine. And you can see that
the fire basically decreases well, fairly rapidly. All things considered, it should be basically 20 seconds
that there's burns, so it should be enough
for exactly two items. The smelt completely,
basically exactly 1 fourth of what the actual core item
is we're able to smelt. So I'd say that's pretty cool. All right, and that's actually
how easy it can be to add the custom fuel
item to Minecraft. And yes, sadly, what you
will have to do is you will always have to make
a new custom class here, what you can also do
in theory is you can make an anonymous class
in the more items here. But I just suggest doing it like this because this is
just way easier to do. Let's just be honest, because this is not too crazy to do. And also it should be fine. You can always
make a new package costumed like fuel items, and then just put all
of your items in there if you really like
annoyed with this, with these classes, That
should also be possible. Otherwise this would be it
for this lecture right here. I hope you found this useful
and he learns of the new. And I'll see you in the
next lecture though. Yeah.
52. (Minecraft Basics) Custom Food Item: All right, welcome back to
the forage Course Room 118. And in this lecture
we're going to add a custom food item to Minecraft. For adding a custom food item is actually not that difficult. You basically just need
a normal new item. So we just need a new item here. And this is going
to be a turnip. And of course the same
goes here, turnip. And then when we need to
do is we need to call the dot food method right here and passing
some food properties. Now instead of adding those
food properties in line, what we're gonna do
is we're gonna make a new class and the item package right-click new Java class
called the mode woods. And then in there, you can
basically create this food. The vanilla example would
be the food's class. So press shift twice
and put in foods here. Make sure that you
tick the include non project items here. And then we can open
this and they go, now you have basically
have access to all of the food properties
that Bonilla also offers so that you basically can sort of know what
you should add there. So we're going to add our
own food property here, so we'll make a public static. Final, good properties
will turn up. And then this is
equal to a new food from parties that builder. And we're going
to add nutrition. But this is the number of AF meets basically that
you get restored. The saturation mode is basically the thing that
happens in the background. And then just so
that you've seen it, you can also add an
effect here as you can see if we can just use here a supplier of a new mob
effect instance of, for example, the mobile effects, that movement speed or
let's say 200 ticks again. And then you also pass in a probability how
often this happens. So if you, for example,
say, you know what? I actually only want it to
happen 10 percent of the time. Then you put in point 1 f. Then at the end, you
always need to end with a dot built here and the ego. And that is basically
the turnip done. And now this year will
be called right here. We're just going to say
mod of foods that turn up. And they ago, that is
all that we need to do to add the custom food item. Now of course, we do still
need both the texture as well as the item
model JSON file ls. Now forget, and the
translation here as well. Turnip is of course a verb. And this is going to be
the turnip item model is a normal item model as we've
seen plenty of time now, that simply points to this
singular texture here. And well, after having
added all of that, Let's see if it works or
offensive back in Minecraft. So let's just eat the turnip. As you can see, it
has been added and it has refilled exactly
one hunger bar. So the idea is that of course, if you put in two, that would fill up two halves, meaning one lake,
one chicken leg, one basically meet
bar right there. Right? So that's how easy can be to add custom food to Minecraft. Right? And that would worry bit for
this lecture right here. I hope you found this useful
and he learns of the new. I'll see you in
the next lecture. So, yeah.
53. (Minecraft Basics) Custom Tooltips: All right, welcome back
the forage course for 118. And in this lecture
we're going to be adding a custom tool tip to Minecraft. And what is a custom tool to? Well, it is exactly
that which you see when you hover over
a particular item. But first of all,
what we're gonna do is we're going to add it to the dowsing rod item because we usually need a custom
item class for this. However, we will also
see how we can do it and basically added
to the blocks as well, because that is
something that a lot of people have been asking
for in the past. So I wanted to
show that as well. So we're going to
start by overriding the append Hover Text
method right here. So we're just going to type
in a pen Hover Text and then autocomplete it
with the Tab key. And then we don't
need this anymore because what we want
is we want to hover over the actual dowsing
rod and then it's gonna say something like Redshift
for more information. And then when we
hold down Shift, then we can basically see the actual Tooltip.
But how do we do this? Well, we're going to see if
screen that as shift down, then we're going to
do one thing else. We're going to do another thing. And the one thing that we're
gonna do is we're gonna say tooltip components dot add. We're going to use a newer translatable
component right here. And the key is going
to be tooltip dot, dot, dowsing, underscore round. About, just say
tooltip, that shift. Once again, very important. These keys just be
consistent with him. That's the most important thing. In this case. I think
that that's fine. We can just copy this. And then down here
we're just going to say without the shift. Now, where do we define
this will once again, just like we've done right here, we just define this inside
of the yen us JSON file. Just like we've done up here. We define this in the
ENR score us JSON file. We're just going to do
this at the very bottom here, this one. And then this is going to look something like the following. So the shift one is the one that actually shows up
when you hold shift. And it's going to be
right-click to find valuables. And we're just going to
duplicate the line by pressing Control D and remove
the shift here. And then this basically prompts
the user to press Shift. And the way that we can
do this is we can put in a paragraph
symbol right here, E, lift and Paragraph symbol r. And this will make this
a different color. I will link in the resources, a great resource for basically
seeing those color codes. I highly recommend
taking a look at that. Basically, they're
the formatting codes that you can also use
any Minecraft books. I highly recommend
taking a look at them because then you can
basically will color in anything that you
want and you can make it pretty cool,
All things considered. But yeah, that's actually all
that we need for the item. Let's then move
on to the blocks. The blocks are a
little bit different, but they are also
fairly straightforward. So we're not gonna do it
for the speedy block, we're actually gonna do it. Well, we're going to override both of these methods, right? So what does that mean? Well, we're just going to
copy them first of all, and then we're gonna get
an error because, well, we have two methods that
match to other methods. But what we can just
do is we're gonna just add a new parameter here. And that's just going
to be a string. And that's gonna be
the tooltip key, then the same thing
is going to happen. So I'm just going
to copy this over to the register block method. And then you can see
all works again. Because then what we're
gonna do is we're going to also pass this in here. So the tooltip, he's going
to be passed in here. And then here, instead
of just creating a normal block item
after this one, we're going to make
an anonymous class. And then here we can just
append the hover text. Then here what we're going
to say is we're going to say tooltip dot add. And then we're just gonna say a new translatable component with the tooltip key that
we've passed in there. And there you go. Now this will only be
called if we actually add a tooltip e to the end
of the block here. So if I don't add it, then it, It's just going to
create the block without it. If I do add it, I
can just do it. So for example, let's do the SPD block because that
doesn't make a lot of sense. Then we can say,
for example, tool, tip, dot, locks or block. It doesn't really matter. Speedy block, let's
say for example. And this will then
add a specific tool tip with the SPD block. We just have to now put
this in here as well. So something like it gets
really speeding over like that. And this will also
then be displayed when we hover over
the SPD block. That's actually how easy
it can be to add this too. Well, specific blocks as well. Now, we will not have the particular functionality
of the holding shift. We could also of course added in a particular way
that also works. But any modifications here, really with a little
bit of Java knowledge, I'm sure that you will
manage those as well, right? So now after we've
added both of those, let's see if they work or we find ourselves
back in Minecraft. So let's see, There you go. Dowsing more press shift
from more information. It of course works either in the no creative tab or
in the actual inventory. And if I hold Shift
right-click to find valuables, exactly how we would want it to. And then here are the SVD block. It gets really speedy,
also shows this. So that's really
awesome and that's pretty much how
easy it is to add the custom tooltips
to Minecraft. All right, and that
would already be it for this lecture right here. I hope you found this useful
and learned something new. If you did, I would very much appreciate a review from you. Otherwise, I will see you
in the next lecture though. Yeah.
54. (Minecraft Basics) All about Tags: All right, welcome back to
the forge course for 118. And in this lecture
we're going to be adding custom tags to Minecraft. So custom tags, those
are not the name tags. These are actually tags that we've previously talked about with the mineable tags
and the needle tool tags. Basically, what we're
gonna do is we're now we're going to make not
only our own custom tag, we're also going to see
how you can add tags to the forge namespace. And that might help with
compatibility between your MOD and other months
MC course package, we're going to
right-click new package called the util
package right here. And then inside of there,
we're going to make a new Java class called
a Veeam model tags. Now the motor tags is
going to look as follows. So this is basically
modeled after the tags from orange here. So they have basically
two static classes, when blocks class and
when items class. And here also very interesting to look
at basically some of the optional tags that they
have already predefined. Basically that you
can add stuff too. So that's very good. I can highly recommend
taking a look at that. So what we're gonna
do is we're gonna say public static class
called blocks. And then below it a public
static class, cool items. They ago and now in the blocks
class we're going to need a private static tags dot optional named
tag of type block. We're just going to call
the method tag with a string name parameter. Let's import the block class, making sure that we choose
the correct one net Minecraft world level
block, block, of course. And then we can return the block tags dot read optional with a new
resource location of our MC course mod, mod ID and the name. That's all that we need to do. And then we're
going to copy this. And we're going to
call the other one, the orange tag is here. We create a forged tag. Instead of r mod ID. We're going to pass in
the namespace Forge. And then we can take both of those methods and just
copy them over to the bottom here and just change this to item, Same
with this one. And then instead of block
tags, we have item tags. The ego, and the classes
are basically built. Now the question is, well,
what do we want here? Well, let's first of all add our own custom tag that's
going to be a public static. Final tags are optional
named tag of type block. And this is going to
be the dowsing rod underscore valuable, equal to a new to tag. And then dowsing underscore,
underscore battle. Now, what does this do? Well at the moment it
doesn't do anything, but we can later reference this and everything
that is inside of this tag will be evaluated
in some way though. To add stuff to the tag, we go down to MC
cores and then we're going to make a new
directory here called tags. And then inside of there, we're just going to make a new file. There's actually this name, so dowsing, rod
underscore valuables. And it's very JSON, very important that
the names here match. My life a little bit easier. I'm going to copy over the, you know, the way that
the thing is structured. And then I will
also actually copy over the entirety
of the contents. Those are all
available to you in the GitHub repository and
individual just as well. This makes it a
little bit easier here you can see
basically I have the cobalt or as well as a bunch of other ores in here as well. And are you still
might be like Yeah, but what does this do like, okay, now we have a tag for it. How can we do something with it? Well, in the dowsing rod item, you remember we have this is valuable block method where we had to pass in blocks
manually so to speak. And now what we could
do is we can say more tags that blocks, that Gaussian or valuables
that contains block. And this will just return whether or not the block
that we've passed in here is contained in the dowsing rod valuables
tag, and that's it. That's all that we need to do. And now we can expand this
pretty much infinitely. Other modes could expand. This is just makes our mod 10 times better in
terms of compatibility. And while we're on
compatibility in the items, let's just add too as well, public static final,
tags, dot-dot-dot, optional named tag, item
or bolt underscore ingots. And this is equal
to a forged tag. Under ingots are bold. And then we're going to
just duplicate this. I'm going to also
put in the nuggets just for show basically, then this would be her vehicle. Now why would we wanna do this? Well, first of all, there's two distinctions
that we need to make. If we create a optional
tag right here in this mode tax class that does not
necessarily do anything. This just allows us
to specify or to reference certain
tags that we've created like this one
inside of our code. This is not always necessary, but it might be
sometimes necessary. So for our purposes,
we're going to create a new folder in the data
folder called Forge. And then inside of there
we're going to create a new folder called tags. And then inside of there, we're going to create a
new folder called items. And then inside of there, we're going to create another
new folder, old ingots. And then finally in there, Right-click new file
called cobalts JSON. Now once again, I will
actually just copy over the contents of this
one right here so that we have the basic tax structure. And then I'm just going
to say MC course, colon or bolt
underscore England. Now I have added
my cobalt ingot, the cobalt ingots forged tag. Now, what the LSAT to write like that doesn't
get us anywhere. Like, why would we do this? Let's look at this. If I have a recipe in which
I used the cobalt English, maybe our 1D or other modes
that add cobalt as well too, you know, for that
to be used as well. But now I can say instead
of item, I say tag, and then instead of this I
say forge, a new namespace. We're under ingots slash cobalt. Now, anything that is
added to this tag can be used right here to
craft this recipe. And that is insanely powerful, especially when, you know, you have a big mod
pack, you know, you wanna make it more
compatible with each other. This is a great thing,
like really cool. Definitely think about
this, take a look at this. And yeah, that's pretty much
the two, well, mean reasons. I would say you might want
to add tags here, right? Let's just add one single
more thing right here. And that's going to be a public that to avoid called
the register method. As we just need to
register both of these classes because they
are static initializers. There's some wonky in US. They are, we're
just going to have a register block tags with
basically nothing in it. That's fine. And the new gear, and
we're going to call this the horse item tags. And here we're just
going to call it blocks, not block tags and items, data register item 10. And that this register method will simply be
called right here. So we're just going
to say more tags dot, which is the ego, right? And there's of course a
little bit of a typo in here. So actually, this
needs to be under the logs category. There you go. And then everything
should work fine. So now let's see For works or finance or
pack and Minecraft. So let's see if the cobol
Ingrid works. And there you go. Of course the
crafting still works. That's great. Let's take the dowsing rod and let's
just see, there you go. I can even find stuff very early on and I can even find stuff
that I couldn't find before, like the, the deep
state gold or, or the deep slayed Redstone war. So the actual tag also works. That's great, right? Once again, all of the
code is available in the GitHub repository and
individual just as well. But this will already be it
for this lecture right here. I hope you've found this useful and you learned something new. I'll see you in
the next lecture. So, yeah.
55. (Minecraft Basics) Custom Stairs & Slabs: All right, welcome back to
the forest course for 118. And in this lecture,
we're going to be adding custom stairs and
slabs to Minecraft. Now this starts a
little section, so to speak, of a
non-block blocks as I like to call them. This will include, like I said, stairs and the slabs,
as well as fences, fences, walls, buttons,
pressure plates, the door and the trapdoor. So there's going to be basically
the next four lectures. And well, let's just start. So in the Modocs class, what we're gonna do is we're
just going to copy over, let's say the deep
sleep or here because that is a little bit easier
for us at the moment. And then we're
going to call this the cobalt underscore stairs. And then here of course as well, cobalt underscores, theirs. Oh, then copy that in and
make the slabs out of it. So slabs, actually
slab, very important, but stairs, it's Laurel and
with the slab, it's singular. And then here this is
going to be a stair block, while this is going
to be a slab block. And the block
actually takes in a, another first parameter
which is going to be a applier of blocks dot cobalt, block dot-dot-dot gets default
or default block state. This is just the block basically that the
stairs are made out of. That's going to be fine in this. Let's make both of them material metal just so that we have this. And then apart from
that, I'm actually fairly happy with this. Now the thing about all of the non-block blocks is that
the actual registration? Well, that's fairly easy year. What is really the most I would say, not
necessarily annoying, but it will get annoying when
we come to the, you know, the doors and stuff like that because there's gonna
be a lot of JSON files. Let's just copy
over the JSON files before the IRS and the slabs. So what you will first of all, notice by just opening
the cobalt stairs one, there is a lot of stuff in here more than there has been before. So the first thing I want
to say is that all of the JSON files are
available to you in the GitHub repository
or an individual. Do not type this out. That is madness, okay, Do not do this
worst-case scenario. If for whatever reason you can't download something for me, you can always go to
the Assets, Minecraft, so basically external
libraries and it microwave client extra
181 and then to the, to the assets microblock states. And then you can just take the freakin Keisha
stairs, for example. You can see they're
basically exactly the same. The only difference here is
the MOD ID and the name. And I will show
you a quick trick. What you can do is you
can select this and then press Control R. And here, for example, just
change the motto De. If you have a
different model ID is Replace All and then it
will replace all of them. Same with the name of
the actual stairs, right, is selected press Control R and
then you can change it. You have titanium, for example, Twitter to titanium and the ego. So that's a very
good thing to have. I highly recommend doing that if you really want
to change something, but definitely don't
type this out, that would be madness. Now, what is all of
these doing, right? So we have particular
variants here, and the variance are defined
by block state properties. Now blocks they properties
we're going to talk about in a later lecture over
for the time being, let's just think
about the idea that certain blocks in the world can have different properties. Okay, that shouldn't
be too crazy. And then depending on
those properties, right, if the facing
properties East and the half property is bottom and the shape
properties in our left, then we're going to show a particular model with a
particular rotation here. And then UV lock,
just basically locks the rotation of the texture so that it doesn't
rotate with the block. That's just, you know, it's not too important in this case. Those are really the
most important ones. And yeah, that's basically then points to a
different model. And what you will see is that we have the cobalt stairs
inner and then here we suddenly have
the cobol stairs outer and here we have
just the cobalt stairs. So what you might have guessed
already is that there are going to be multiple
block model files for, well, the stairs
and also the slabs. But before we add those, let's actually add the
translation first, just so that we don't forget it because that sometimes
might happen. I'm just going to
copy over the order is going to be the cobol stairs. And the cobol slab is going
to be the cobol slab. And here there's white and then I can copy over
the model JSON files. So the block model Jason
files, like I said, all of them are
available to you in the GitHub repository or in
individual just as well. Now, those are only
going to be five. It's not actually that bad. And the thing about it, they themselves are actually
fairly straightforward. Like if you look at this, for example, there's
nothing too crazy, is it? So the parent here that's
different, that's slab. And then we have three
different textures. But actually the OH points to the cobalt block
because of course the cobol slab just basically looks like half
of a cobol block. And when they're on top of each other, which is called a block. So they go and then
same with the top one. It looks exactly the same
except for the parent. Let's also take a
look at these stairs just for completion sake. And you will quickly see
that all of a sudden, it's not actually that crazy. It's just the parent
is different. And the parent basically
just determines the shape of the actual block that
is being displayed. You might have stairs
that are normal stairs. When you add stairs
in a 90 degree angle, you know that they sort
of get a different shape. That basically is just literally what the parent here does. And the textures stay the same. And it comes to the item models. They are actually fairly boring. All things considered, they're
just normal item models. The stairs just point back to the stairs and the slab just points back to
the normal slab. Now what is really
cool is we don't need to add any textures
because all of the textures that the stairs and the slabs use are
the cobol block. So you don't need to
add any textures. And with that, this is
actually well, basically done. Oh, I guess for completion sake, let's see if it works or refer themselves in
microfinance can see both the stairs as
well as these labs have been added
successfully to the game. And everything here
is working great. I can set them down well in
whatever way I would like. So isn't that just great? That's actually how easy
it is to add those to Minecraft or wherever that would already be it for
this lecture right here. I hope it was useful in
the new, once again, all of the code in the
JSON file are available in the GitHub repository
where an individual justs. And I'll see you in
the next lecture. So, yeah.
56. (Minecraft Basics) Custom Buttons & Pressure Plates: All right, welcome back to
the forest course for 118. In this lecture, we're
going to be adding a custom button and pressure
plate to Minecraft, right? So once again, the button and pressure plates are actually
fairly straightforward, or the registration itself is just the JSON files
that are crazy year. But let's just add a button here and then all the save button. This is going to be a
stone button block because there's no metal button
block in this case. And then very important, what we also need a
call is we need to call the no collision
right here. But we can basically
walk through the block without any issues. And then for the cobalt
pressure underscore late. And here, mobile underscore, pressure under script
late is of course going to be a pressure
plate block 0. And that's actually takes in a, another first
parameter, which is going to be the sensitivity. We're just going to
choose everything. By middle mouse button click
on the pressure plate block. The signal strength
method here is basically responsible
for the sensitivity. As you can see,
there's a switch right here, everything and mobs. And a general idea
is that if you really want to have a
different sensitivity, you can achieve this overriding
this method basically, and then changing a
bunch of stuff in here. Highly recommend some Java
knowledge there is definitely required to do this and be, have something work, but it
should be workable, right? So now let's move on
to the JSON files. This first of all actually added the translation because
that's going to be, well, the easiest thing is going to carry this quickly
over so you can see the cobalt button and
the cobol pressure plate and then the crazy JSON files. Now once again, all of those are still available to you in the repository or an individual
just as well as always. And this is going to be crazy. So the pressure plate actually, I mean, that's like, holy fine. Write it in either be false, so power or not powered. And then either we show
the pressure play down or the pressure plate
normal, there are enough. What about the button? Well, the button is
a little more crazy. So the button here,
as you can see, as once again at three different
blocks date properties, and depending on them, we basically change,
first of all, what model it points to and
also the rotation here. So that is pretty
freaking crazy. But luckily, the
button actually only has a three different
block models, while the pressure plate, as we've seen, only has two. So once again work at five. Let's just copy them over and let's just take
a look at them. But overall, the pressure plate, as you can see, once again, just points to the texture of the cobalt block is just
a different parent. So the block model Jason's
here, Not really interesting. Same with all of the buttons. It's nothing too crazy. So this is something that's going to be sort of
a thing that happens for most of the actual different
block model JSON files for the non-block blocks. They're not actually
that interesting. There's just a lot of
them so that you can basically define anything
that you would like. And this pretty
much also extends to the item model JSON files. You can see this to the overall block inventory and this just points to
the normal pressure plate. Once again, we don't need to add any texture is because all of the textures that it points to is always going to
be the cobalt block. Therefore, we're
actually already done. Once again, everything you
can copy over from the gist. So the GitHub, I
highly recommend this. And let's just see if it works or why we found
suspect in micro. As you can see, everything
has been added and it also works totally
fine. Isn't that great? You can see everything working exactly how you
would expect it to. And that would already be it
for this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
57. (Minecraft Basics) Custom Fences & Fence Gates & Walls: All right, welcome back to
the forge course for 118. And in this lecture
we're going to be adding a custom fences, fences, gates, and
walls to Minecraft. So this is once again, a fairly straightforward
exercise. All things considered. There's, Let's just go into the more blocks class
and let's first of all copy over the
button three times here. And this is going to
be the cobalt fence. And then this of course also going to be
the promoter pens. This is going to be a fence. Look, this is going to
be the fence on eight. And this is then of course also the fence underscore gate, which is a fence eight block. And then the last one is
going to be a football wall. Wall here as well. And this
is of course a wall book. Now let's take away
the no collision here. That would be well, not the best thing if the
fences all of a sudden had no collision would kind of
defeat the purpose of them. And the rest is going to
be totally fine here. Now once again, the JSON
files are where it's at. Let's first of all, the
translation just so that we have it then we don't need to worry about this anymore. I'm just going to
copy it over for the cobalt fence decouple fans get in the cobalt wall here. And then let's add the block s3 isn't far
as all of those are, of course, once again,
available to you in the GitHub repository or an
individual just as well. And you will see that this is actually a
little bit different. So let's first of all take
a look at the fence gate. Once again, it has
three different blocks. It perimeters or
boxy properties, and it just points to
different block models. Nothing new that we've not already seen in the
last two lectures. But the fence however
and the wall. Those are different because
those are multipart. Now multi-part. The general idea is that, well, as you can see
that right here, right? And the first multipart we
have applied this model. And this model will always be applied if this is sat down. Now, when a particular
Roxy property is true, in this case, if
something is true, then we apply a,
another property. You're another model here. And in this case
it's going to be the side that you know
that if you set down the fence post by
itself and then you add one fence post to the north. We actually add the
site afterwards. But this is a really
frequent cool thing that this is how it works. And this is actually a very straightforward
way of doing this. Though. This is definitely a
little bit different. I'll recommend just
checking it out, taking a look at this. It shouldn't actually be too crazy to understand
all things considered. We just add different
models depending on whether or not something
is basically a neighbor. Basically the idea. Now this has, however, also the added thing that, well, there's gonna be a
lot of Jason files now. So let's just copy
over all of them because this is going
to be an insanity. We have these all of them. Just copy them over
11 of them total. Now, we're just going to take a very brief glance
at them because honestly they're
all very boring. Basically, it's always going to be the parent
that is different. You can clearly see all of the time we take the point to the same
texture right here. You can see it's just going to be the parent that's different. And basically the same thing
goes for all of the others. We always pointed
at the same texture is just the parent
that's different. I could just once again,
highly recommend if there are any interest in
other JSON files. Just go down to the
external libraries, unit, microwave client,
extra money TIN, and just take a look at
all of the trace and fast right here in the assets
Minecraft folder, you can see all of the
block model JSON files. You'd see all of that,
the block say JSON files. So everything is basically
available to you here as well. This highly recommend copy stuff over and don't type
everything out, especially if you have multiple walls and stuff like that. That would just be
madness, right? Let's also get the
three item model Jason felt over n.
Those are all not too crazy because we have some cobalt fence inventory
and cool wall inventory. Those are basically they
are referenced here. And then this one is just the
normal cobalt fence gate. And once again, because
all of the textures use the footwall block texture, we don't need to
add any textures. Now, there is actually one more thing that
we do need to add in order for the fences and
a waltz to work properly. And that's going to be tags. So inside of the Minecraft tags, blocks tag or block folder, I want to create a new file
called the fences dot JSON. Once again, I'm
just going to copy the structure you're over. And this is going
to be MC course, Boolean, cobalt
underscore fence. Then I'm gonna take
this and I'm going to drag it in here while
holding Control. And I'm going to
call this walls. And this is going to
be the cobalt wall. If I don't have this,
then the fences and the walls will not
connect to each other. But that is very important too. We do need this. But if we've added
that and the rest, then let's see if it works. Or if I was at a migrant asic and see everything
has been added successfully and it all
looks fricking great. You can set it down it
The next to each other. Exactly how what
we would expect. So they ago, everything working fine wherever that will already be it for this
lecture right here. I hope you found this useful
and he learns of the new, and I'll see you in the
next lecture. So, yeah.
58. (Minecraft Basics) Custom Doors & Trapdoors: All right, welcome back to
the forage course for 118. And in this lecture,
we're going to be adding a custom door and
trapdoor to Minecraft. So let's open the mailbox class and let's just get
the cobalt wall. And instead of cobalt, this is actually
going to be Sherry underscore blossom
underscore door. Same of course in the name. So in this case actually we're going to have
a different, well, a different material
here because we won't be making
doors out of cobalt, but out of the wood that we
will add in a future lecture. And what is very important
here is that add the no occlusion coal
and also that we're making the material
would because if we make the material metal than this door will function
like an iron door. If we make this would, then we can open it by right-clicking. Same goes for the cherry
blossom underscore trapdoor. Just going to copy
the name here over and add the trap
here at the front. And this is then a
trap door block. I'm here making sure that
this material that would and then adding the
no occlusion as well. In occlusion cold here is
needed because we have alpha values in the
actual texture. And because of
those alpha values, we actually also need to go
into our MC course mod class. And inside of there we need
to create a new method. So we're going to make
a new private void called the client that up method with a final FML client
set of events or event. And then inside of here,
we're going to call the item block render types, that said render later. For the mode blocks,
dot, cherry blossom, dor dot get with the render type that
adult, duplicate the line. And then here makes sure
that the trapdoors set. Now this is not called
yet because what we need to do is we need
to say Event Bus, add listener, this colon,
colon lines setup. Then after this has been done, now the actual FML clients that have method is called here, the method and then these
render tribes are being set properly before we add
all of the crazy JSON files, let's first of all, add
the translation here. Fairly straightforward,
nothing too crazy. And now let's go on
to the JSON files. So first of all, of course, the block States Jason's. So this would be just the door and the trapdoor that you go. So once again, of course, there are pretty crazy. The door actually has four different block state
properties as you can see. So once again, all of the adjacent files and
all of the code is available to you in the GitHub repository or an
individual just as well. I recommend copying those over when it comes to
the block models. Well, we're in for
a treat because that is going to be
seven of them again. So that's going to
be pretty crazy. Now, these are a
little bit different, like tiny bit more complicated
but also not quite as bad. So you can see once again, that differs most as the parent. Now because doors are
two parter block, so to speak, we have a
top and a bottom texture. You can see a
cherry blossom door top and a cherry
blossom door bottom. And then the hinge here you can see it's just a
different parent. But overall, once again, this take a look at them, just go through them a little bit. You know, how they look like, they're not too crazy overall. The item and models are
also kind of interesting. The trapdoor should be
just a normal item model. But we can see this. This just points back to the block model basin
over this year, the door actually points to
a specific item texture. Does the door actually has a specific texture
for the item as well. So we're going to, first of all, a copy of the item
texture over here. And then of course we also need the three different
cherry blossom textures. So this could be
the door bottom, door top and the
trapdoor textures. Now, that is actually
all that we need to do. Very important is this
client setup here, which we're going to need in
the future lectures as well. But every time we have a block
that it doesn't fill out the entirety of the
x-ray block state space, so to speak, then we basically
need to add this as well. So that's very important. Otherwise, let's
see if it works. Or if I suspect and
microRNAs can see both the cherry door as well as the cherry blossom trapped or have been added to the game. And I can right-click
and open them. Who says I with any other
wood based door or trapdoor? So that's pretty cool. Rubber, that would already be it for this lecture right here. I hope you found this
useful and alerts the New. And I'll see you in the
next lecture. So, yeah.
59. (All about Tools) Creating a new Tool Set: All right, welcome back to
the fourth course for 118. And in this lecture
we're going to be adding a custom tool set to Minecraft. So this will include the sword, the pickaxe, the shovel, the ax, and the whole. We're actually going to
create a new custom class and the item package or
the modern tiers. Because what we need to
define is a custom tier. Luckily, forge makes
it very easy for us. We can just say
public static final forged here called cobalt, which is equal to
a new forged here. And then we just need to
pass in a lot of parameters. The level reduces the speed, the attack bonus and the tag damage bonus,
the chairman value. Then we need to
pass on block tags. Dot needs iron tools, and then just a
supplier of a gradient. And we're gonna
say ingredient of more items, dot, dot get. And I will explain right now. So what is going on here? This is crazy, actually
is not that crazy. The first thing is,
of course, a level. This is just the level that basically this item here
represents this tier. So we can actually
go into this and you can see there's a
bunch of stuff here. And the level
basically represents, you can see right here, basically represents
the idea of, hey, is this stone tools, iron tools, or diamond tools? That's basically
the general level, the general idea
of the level here. And we have the number of users. So this is just how many
uses this item has. Though, the
Durability, basically, the speed should be
fairly self-explanatory. There's just the speed
of the actual item. The attack damage bonus is
just a bonus to attack. This gets, let's
actually put this to 3 and Chairman value
is just channel. This is the block tags. You're I'm not a
100 percent sure, but I believe that
this is once again, narrows down to what this actual forged
tear or this tier of tools can
basically mine here. And then the last
one, the supplier of the ingredient here, is basically just the
ingredient that you can use to repair the items
of this tier width. So now that we have this, we can go to the more
items class and I can start to basically
take the turn appear. Let's just take this one and let's just make this the cobalt underscore sword here as well. Cobalt underscore stored. Let's get rid of the full year. That's kind of important. And this is going
to be a board item. The first parameter is going
to be more tears dot cobalt. Second parameter is the
attack damage modifier. And the third
parameter is going to be the attack speed modifier. And then come the actual properties which are
going to be fine. And we'll duplicate this five times and then just
get the other ones. So we're going to have the wall pickaxe or bolt big
X here as well. This is a pickaxe item. And we have the travel
will travel here as well. And this is a shovel item. Going to be the robot acts. And cobalt acts here as well. Of course, Item. And then last and most
certainly least the cobalt WHO. But of course we have to get
the entire thing in here, which is the cobalt WHO
and a whole item, right? So usually you can of course change these numbers,
right? You can tweak them. So for example,
the homemade have no additional modifiers here. The ACS might have,
you know, this one, but therefore like maybe
a negative ones be modifier or just like
say a 0 modifier here. And the rest is
going to be fine. So this is something that
you definitely have to play around with highly
recommend just playing, being open to experimentation
with the numbers here. Because that's just balancing
basically the model. And overall that's
pretty much the, you know, the registration done. We now only need the, you know, the translation here, but let's
just add the translation. I'm just going to
copy this over. This should be fairly
self-explanatory, right? Just like we've seen a million times, could speak already. And then the item models have a one particular thing that is a little bit
different with them, which I will show you when I
copy them over once again, all of this is
available to you in the GitHub repository or
individual just as well. You can see that the parent
here is item slash hand-held. This is very
important, otherwise, the extra will not
be displayed in 3D in third person views. So that is very
important that you have the parent item handheld here. And otherwise we can now copy
over the textures as well. All five of them
as well, they go. And that's pretty much
all that we need to do to add the custom
tools to Minecraft. So let's see if it works. All right, we find ourselves
back in microfinance and see all of the tools have
been added successfully. So let's just see if I can
actually mine stuff with it. So this year, of course, will not work in this
case because we've defined this as level one. So this should work. However, let's see a go. This works totally fine. So that's a good
sign, of course. The bird should also work. There are definitely
not very fast, but that's totally
fine of course. And then right-clicking
here also works with this right-clicking. The stripping of the logs
should work well-defined, same with the pathing. Everything here
actually going to be only five by the speed of
course is defined here. So this would be, you want
to increase the speed of this no actual tear
and the level here, you can do it like that. And then what you can also
do is in the forged here, if you press on the tier
here and then press Control H and see the tears
from Minecraft itself. And you can basically just
take a look at all of the vanilla values
of the tools here. For that, you can
basically change those up and copy some of
them over, right? But they would already be it
for this lecture right here. I hope you found this
useful and it learns of the new and I'll see you
in the next lecture. So, yeah.
60. (All about Tools) Making a Multi-Tool (Paxel): All right, welcome back to
the forage course for 118. And in this lecture,
we're going to be adding a custom Paxil
item to Minecraft. That's exactly right. We're going to add a will sort of multi-tool to Minecraft. And for that we need
a new class and the custom package that's
going to be the Paxil item, which is going to extend
the digger item right here. And this is going to implement
the venerable interface. Let's just hover over it and create constructor
matching super. Now we will actually have
to change this a little bit because we don't
need either of those. Because these two parameters
actually go right here. We should do
something like this. And then the tagged for the blocks actually
is going to go away because we're
going to add that to our model tags right now. So the way that
we're doing this is we're going to go to
our motor tax class. Then we're just going to copy
the dowsing rod valuables. And here we're
going to make this the Paxil underscore mineable. And then the name of
this is going to be the mineable slash Paxil. And this will now be
referenced right here. So mod tags, dark blocks. And just like that,
everything should be totally fine, right? And now this class should
be completely done. And the great thing is that because we have defined
these tags here, well what we can do
is we can now go into our C corps data folder, into the tags, the blocks, and then right-click new
directory called mineable. And then inside of there
we're going to make a new file called
Paxil, that JSON. And then what we're gonna
do is I'm just going to copy this one over for
the sake of argument just so that we have the
basic structure of the tag. And you might say is, well, do we now have to go
into the pickaxe item and just have to
add all of that. Know, what we can do is we
can also add tags into tags. But what we have to
do is we have to say hashtag Minecraft. So this is the namespace of
the tag that we want to add. And then mineable slash, mineable slash, pick
X, for example. And then we're just
going to copy this. We're gonna do the ACS, add commas here and then
put in shovel here. So our Paxil is going to be able to mine everything
that a pickaxe can, an axon and a shovel. And the greatest thing here is that because we've added it in such a way that we are
referencing the other tags. If a different mode adds
stuff to these tags, well, the Paxil item will also work for those blocks as well. So that's the really cool thing. Now how do we create
the actual Paxil item? Well, very easy. We're just going
to copy the cobalt WHO and we're going to
call this the cobalt Paxil or what packs
layer as well. And then this is just
going to be a Axl item. And that's it. There
you go. Paxil is done. That's actually how easy it is. It actually is not that crazy. So of course you need to know how to basically that you can use different tags in your
own tags and stuff like that. But overall, this is
fairly straightforward. There is one particular, well, that's a limitation
that the packs item has and it has no
right-click functionality. Now you could add the
right-click functionality. If we click on the digger
item and press Control H, we could, for example,
go into the whole item. And you can see here the US on the right-click
use on method. And you could override this, and you could put
different things in there. You could say, hey,
let's do a default, whole action, so
on and so forth. And then do the
same thing for the, for example, if you sneak, then you could right-click
and then it makes the path, you know, somebody like that,
and then right-clicking. And you could also add
the right-clicking with the AKS functionality. We're not gonna do that in
this example right here. This is just going
to be a Paxil item, a multi tool item that
will basically be L2 mine, multiple different
types of walks. Let's also add the
translation here. This should, of course
not be too crazy. It's just the cobalt
Paxil of course. And then same for the item
model, nothing too crazy. It's just going to be
the cobol Paxil that points to the
cobalt Paxil extra, which I of course also have. This is an a, B, a, a cool texture which we'll
see in game in just a moment. And well, that's actually
all that we need to add the backslash
item to the game. So let's see if it works. Or inferences back
and migrants can see the backslash item
has been added and it looks absolutely
Great. So let's see. There you go. I can use it as a shovel, exactly how you would expect. Let's see if I can mine
those blocks as well. They might take a little
bit longer, but overall, I can still mine
them perfectly fine. And then let's actually
find something. But this one should now
work because once again, the cobalt tier is
not high enough. But if we just dig
down a little bit, we should be able
to find stone here. And then stone I
should be able to mine as well and I
should get cobblestone. There you go. I got
some cobblestone. So as you can see,
everything working here. Totally fine. Axl item, absolutely. Amazing, right? But that would already be it
for this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
61. (All about Tools) Weapons that apply effects: Or I will come back to the
forage course for 180. And in this lecture we're
going to be adding a tool that adds an effect to the
map that is being hit. What does that really
mean? Well, let's just go through this and see what this really means
in the custom package. Right-click new Java class, or this is going to be the
levitation sword item. And this will extends
the sword item will hover over this creed
constructor matching super. And then what we'll do is we'll override the hurt enemy method. And the only thing that
we need to do here is we need to say p
attacker dot add effect, new mob effect instance, mob effects, not levitation, let's say for 200 ticks. And then the, after the first parentheses P attacker as the source of basically
the attack here. And that is pretty
much all that we need to do for the
ideas that we're going to add a that
is actually going to be target here or a day ago, the target at Effect. And then here P attacker. So the idea is that
when we hurt an enemy, then we're going to add
the levitation effects to that enemy when we hit it
with this particular sort. That is something that
a lot of people have asked for a previously. But this is why I show this. It actually is very, very straightforward to do this. Now, you will of course need to use this class right here. For example, here
for our cobol sort, we can then say levitation
sort item here. And it now every time
we hit an entity or an animal with the
cobalt sort item, it should get levitation
for ten seconds. That would be really funny, but let's just see if it works. Or your pharmacist
back in Minecraft. So let's just see if I hit
the animal they had go, it gets levitation and it should get that
for ten seconds. Though they're just going to
be floating up in the urine. Then at some point they're going to drop down back to the Earth. And that will actually
result in the dying as well. So that's kind of funny. It is a cool effects of the
levitation sword might not be basically the most
interesting one, but there are plenty of ideas, different effects that
you can basically add on hit with your custom
weapon, right? But that would already be it
for this lecture right here. I hope you found this
useful and learns of the new and I'll see you
in the next lecture. So, yeah.
62. (All about Tools) Creating a new Armor Set: Or I welcome back to the
forage course for 118. In this lecture, we
are going to be adding a custom armor set to Minecraft. Very similar to the custom
tools for the armor set, we actually need to
make a new class. This is going to be
in our item package. Right-click new
Java class called the mode armor materials. And this will implement the armor material interface and it's going to be an enum. What we'll do is we'll middle mouse button click on
this and then press Control H to get to the
armor materials right here. And what I will do is I will basically click at
the very top here, right to the early bracket, go to the very bottom, hold Shift and then
click at the bottom and then press control C
to copy everything, and then Control
V to paste it in. Now let's just get
rid of that one here. And then over all, the only thing that we
need to do is we need to change the name of
the constructor here. And that's going to be fine. Now the only thing that
we don't have is we won't have the parameter
names here mapped. Now you can map them yourself. Basically, you can click on Shift F6 and then rename
it right to name. And then you can
continuously go through, but it's really not
necessarily needed. I will actually copy over the constructor because actually have this prepared
in the mapped way. Materials they ago. And there you go. So the only thing that
doesn't work is this because instead of being
a lazy loaded value, we're just gonna make
this a lazy year. And then everything
here should work fine, but the rest
should be fine. This of course, all
available to you in the GitHub repository or an
individual just as well. So no worries there. And well, what does this do? Well, first of all, we can see all of the
vanilla values right here. And because this is an enum, is pretty cool because
this isn't advanced. You know, even we can define multiple different values here. Let's just say
that, for example, our cobalt is going to be
sort of on the level of gold. But let's say you know
what, it's going to have a little bit more durability is, let's say something like 13. Maybe interoperability is
going to be a little less, but not too less, like maybe like 21, something like that. The goal eclipse on is fine. Maybe it's even going to have like a tiny bit of toughness. I don't know, like 0.5, no
knock resistance though. And the ingredients to repair
it with is going to be more items dot, dot get. And then the rest we
don't need anymore. This is going to be cobalt. And then the name
here of course, also has to be cobalt. And these values
here are interesting because these values you can see that's the third parameter, is an integer array that's
called slot protections. Now slow protections are
basically the protections of each different armor piece. This starts at the bottom. So this is the boots, leggings, chest plate
and then the helmet. That's very important.
And maybe we want to change this a little bit,
maybe something like this. Maybe the Talmud is actually
a little bit stronger. The chest plate as
well and the ego. But once again, when it
comes to the numbers, play around with them, be
open to experimentation. If you want to really
balance your mode, it's going to be,
you're going to have to play around
with this any way. So no worries there,
there is, however, one more modification
that we need to do, and that is in the getName
method right here. Because what we want to
return here is MC course mod, mod a, D plus colon
plus this name. This is a very important
that you do this. Otherwise the texture
will not work the way that we're going to set
it up. So no worries there. But apart from that, the more
armor materials is done, if you ever want to add
another armor material, what you need to do
is you basically need to have all of
these jars as well. And basically then separate
them with a comma. So let's just call this cobalt two for the sake of argument, you can see, long
as they're named differently, That's
going to be fine. They're all separated
with a comma. And then this ends
with a semicolon. That's very important. Just
wanted to mention this as well because a few people have
gotten confused with this. It actually shouldn't
be that crazy. It's just very basic Java
knowledge in this case. But whatever the case may be, Let's go to the More
Items class now. And let's create our
or armour items. Let's just take the axle here
and let's just make this to the cobalt helmet and
then helmet here as well. Underscore element. And this is going to be the
armor item, very important. The first parameter
is going to be the mode armor
materials, cobalt. And then the node has
three parameters. Taken. One of being equipment slot. Equipment slot in
this case had a goal. And then the item properties
allow us just copy this three times and then let's
get the chest plate here. This plate. And then the only
thing we need to change is the
equipment slot here. That's very important
that we change this. Otherwise, we're going
to run into some issues. For what leggings? Leggings here as well. And then last but not
least, the boots. And then boots here as well. Strange this two legs and then this equipment slot to eat. And with that, all of the four
items actually are added. That's how easy it can be. Now what we wanna do is
of course, first of all, before we add the JSON files, let's just add the translation. This should be at
this point trivial. It's just, I just copied it over to be fairly self-explanatory. And when it comes
to the item models, will they are just normal
item models as well. Because of course,
inside of the inventory, well, they just look
like normal items. However, there is one
interesting thing. So first of all, you
can see just points to a texture here. And
that's going to be fine. Let's copy all of
the textures over. But then the question is, well, how do we get this,
the 3D armor? Well, inside of our
Textures folder, Right-click new
directory called models, and instead of their new
directory called armor. And this is the American
spelling that's very important. So you people from
the UK, sorry, but it is just going to be, then let's copy over
these two well PNGs here. This is going to be the
cobalt underscore layer 1 and cool underscore layer 2. This is very important. Please pay attention here. So when we define the
more armor material, this name right here, cobalt has to match this name right here as
exactly the same thing. And then underscore layer, underscore one is
basically going to be the 3D representation. It looks like this. You can change it
up a little bit, but not too much. And this is going to be you
can see the chest plate, the helmet, a little
bit of the other stuff. And then here mostly, I believe the leggings
and the boots, this has to match exactly. It can't be any spaces in there, no parentheses 1 because you copied it over
from somewhere. Exactly like this.
Be aware of this, that this is in the correct
folder name correctly, and they have all
the correct names. Very important. If you ever are wondering where the other textures or
you can go down to external libraries
that microclimate extra 118 one in the
textures folder, and then in the models armor, you basically have access
to all of the vanilla ones and you can change them
in theory if you want to. So that's really freaking cool. But that is actually all
that we need to add. So let's see if it works. All right, we find ourselves
back in mindfulness. Can see everything
here has been added to the game and it looks
frequent, amazing. Oh, this is actually how easy
can be to add the armor. You can see early
armor values as well as even a little bit
of toughness in there. That is really freaking cool, just like we've defined
in our armor materials. That is pretty freaking cool. And it makes pigs fly, right? But that will already be it
for this lecture right here. I hope you found this useful
and he learns of the new, and I'll see you in
the next lecture. So, yeah.
63. (All about Tools) Full Armor Effect: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding a custom full armor effect. Now what does that mean? Well, the idea is that if we
wear our entire armor sets, so all of the entire cobalt
armor materials set here. Then what we want
is we want to add a custom or just normal, basically potion effect
with the player. The way we do this is
I'm actually going to copy over the class that
we're going to need. This is available to you in the GitHub repository or an
individual just as well. Alright, so this is the
entire class and overall, we'll just go through and
I'll explain as I go along. So the first thing that we
have is of course, a map. So this map maps in armor material to a certain
mode effect instance. Now number one very
important thing is that this instance that
we are using in this map is actually
never used itself. We're just taking
the values from it. So you can see that if I put the armor material cobalt on, I'm going to get a luck effect applied to me with
an amplifier of one. So this means that I'm
actually getting the lock 2 and then of course
also 200 ticks. So this would be for 10 seconds. Now currently, this only works
with mod armor materials, so only your custom ones
and not with vanilla ones. That's a very important
limitation here. Now, how does this work well on armor tick is called
this method here. We're overriding this
and this is called every time that a particular
piece of armor, in this case the
mode armor item, is inside of your armor slots. So this is called, we're going to make sure
that we're on the server, and then we're evaluating
whether or not the player has a
full suit of armor. This is a custom
method that I wrote. It is not nothing
too crazy here. We're basically just
getting the armor of slots 0 through three, but all of the forearm
are slots and then just checking whether or not
they are not empty. So if none of them are empty, then we're going to get a true on this and
then we're going to continue to evaluate
the armor effects. For that, we're basically
going through the entirety of the map here of the
material to affect map. And just making sure that hey, does the player have
the correct armor on four, basically an effect. And we're going to go sure that we are
going to make sure. And this one right here. So this one just says, hey, is it the material of
all of those armors, basically the same
material as this. And if that's the case, well, then we can continue even further with basically
adding these satisfactory. We're making sure
that the player does not have the
effect already. Otherwise, you would basically be applying the fact every tick, which might be a
little bit too often. So I just added this sanity
check basically here. Then we're also once
again just checking if the armor is on and
if that is the case, then we're going
to add the effect. So we're going to make
a new effect instance of the actual effect
instance here, get effect iteration
can amplifier, like I said, this small
effect right here, this instance has never used
when we defined up here, this is only used as a template
so that we can basically also put in the duration
and the amplifier as well. Yeah, that's pretty much
all there is to it. It shouldn't be too crazy. You know, if the
question comes up, you're well, how
did you do this? How did you make that? Well, it is just at the end
of the day in Java knowledge that you need and probably a little bit of Minecraft
knowledge as well. And how we can use this class. Now we'll in our mod items, I personally prefer to use the cobalt helmet to make
an MOD armor item here. And what's very important
is you only need to make one of your sets here. So one item in your set, the mode armor item. Like I said, I usually
prefer the helmet. The chess-playing might also
make sense, or the boots, whatever you want,
but only one of them needs to be a
more armor item. And if that is the case, then we can already
see whether or not it works or if firms
as in Minecraft. So let's see, I already
have everything on except for the helmet and let's put it on and there it is. I have luck to now
for ten seconds. And if I take any of
those armour items off, as soon as the effect wears off, it's not going to renew. As you can see, there you go. And then it doesn't
matter basically which when I have on and which
when I haven't read. It, really is basically
checking for every one of the other pieces and they go luck to you once again, right? There are certainly some
limitations with this class, but this should
hopefully will be a cool introduction
for this for you. You can, of course,
always changing all of the code is available in the GitHub repository or in an individual just as well. And this would already be it for this lecture right here. I
hope you found this useful. And in terms of the new, I'll see you in the next
lecture though. Yeah.
64. (All about Tools) Custom Horse Armor: Or I will come back to
the forage cores for 118. In this lecture, we're
going to be adding custom horse armor to Minecraft. For custom horse
armor is actually a fairly straightforward
process. However, there is
one little thing that you need to keep in mind. Well, let's just copy over
the cobalt boots right here. And let's just make them cobalt underscore horse
underscore armor. And same here, Cobalt underscore
horse underscore armor. And this is going to be a
horse armor item, right? This one. And then what we want
is the first parameter, let's say something like 12. And the second parameter
is going to be a string for Bolt. Now the string here is very
important because this is defines the name of the
horse armor texture. So let's first of all add
the translation again. We will underscore
horse underscore armor. For cobalt horse
armor, of course. The ego and then a item model. I'm just going to copy
over the ingot here, and I'm just going
to call this the cobalt horse underscore armor. And then we're going to
change it here as well. Worse, worse underscore armor. And then let's add the, let's say boring item model, as in, this is just
a normal item. And let's add the boring
item texture here. So boring as well, this is just the normal
texture, however. What about the 3D texture? Well, that actually goes
into the assets folder, but into Minecraft for a new folder in the assets
folder called Minecraft. And then inside of
there we need textures. And then instead of the
urn, we need Entity. And then inside of
there, we need horse. And then inside of
there we need armor. Once again, the
American spelling. And then I'm going
to copy this over. You can see horse underscore
armor, underscore cobalt. This is exactly the name
that we're giving it here. So if we middle mouse
button click on the horse armor item, you can see that it basically takes exactly this right here. So it takes detectors, entity, horse, armor, horse underscore, underscore wherever the
identifier's that we put in here. And dot PNG, basically, this is what it points
to 43, the armor. And that is basically all
that you really need to keep in mind for
the horse armor. That the one other thing that might be
interesting is that if we can take a look at
this, that for example, iron as five protection gold has seven and diamond
has 11 with 12. This would actually be a
little bit better than diamond horse armor, but
that's totally fine. You can of course change
this however way you want. But let's see if it works. Or a furnaces back in Minecraft and as
luck would have it, we already have a tamed
horse right here. Let's just give it
the cold horse armor. And there it is. It does look very similar
to the diamond one, but it does look still
a little bit different. Though. That is actually
really awesome and that's how easy it is to add custom
horse armor to Minecraft. Writing that would
already be it for this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in the
next lecture though. Yeah.
65. (All about Tools) Custom Enchantment: All right, welcome back
to the course for 118. And in this lecture
we're going to be taking a look at how you can add custom enchantments
to Minecraft. So Enchantments in
and of themselves are actually fairly
straightforward to add. It is hard is the
actual functionality of the Enchantments. But in the MC course package, right-click new
package called the enchantment packet right here. Then inside of there we're
going to need two new classes. One of them is called the
mod enchant minutes class. And the other one
is going to be our actual and chairman's
that we're gonna do. And that is going to be the lightning breaker in Shenzhen. There's also the class that
we're going to start with. This is going to extend the
enchantment class right here. And then let's just hover over correct constructor
matching super right here. Then this very important that we change the equipment
slide here to three dots instead of being
the actual area here. And then what I also can highly recommend is clicking
on this and chairman and the pressing Control
H to basically be able to see all of the vanilla
enchantments that you have. So for example, there's, I mean, there's so many
different things, right? The thorns of Chairman,
just take a look at this. You can see, Hey,
how does this work? But how is this basically
possible to be done? And you can basically
just take a look at all of them in here. Highly, highly recommend
taking a look at this, because this really
is a great resource to see the possible
functionality here. And for our chairman, what we're gonna do is we're
going to first of all, override the GetMax
level method. And we're going to
return a2 because here, this basically determines how
many books are generated. Because the books, the
books are actually generated automatically for our enchantment is really cool. And this basically determines
how many levels there are. Now, we want to overwrite
the do post attack method, which is basically called after a while the attack on an entity. And we're just going
to go through this. So I'm going to try to explain. So we're going to say
not P attacker level not is client-side. So basically making sure
that we're on the server. Please note the
exclamation mark at the very front that
negates the client-side. Very important that we want
to be on the server for this, we want to say server level, which is equal to, let's just
call it world, that's fine. So a little bit used to
calling the level world. And yeah, he attacker
dot level but cast to the server level actually not the client
level, server level. They ago and then
ended like this. And then we're going to make
a server layer for player, which is going to equal
to the P attacker dot cast to the server
player. Exactly. And then we're going to have
a block pass cool position, which is equal to
the target dot, get. Actually it's just blocked. Position. There you go. That's what it is. We're going to import the
blog posts class as well. Then inside of here, you can
see that we get the P level, which is basically getting
a level here, right? So we're going to get the
level of the Enchantments. So we're gonna say if
P level equals one, this means that we're not
going to swap one lightning. But the idea is that we want to call entity type dot-dot-dot lightning bolt
spawn in the world. Nl player position, mobile spawn type, type dot triggered. And then true and then true. So this is basically a way that you could spawn
a lightening bolt. Very straightforward. And the greatest thing
is that this is not only a way to small
lightening bolt, you're going literally
spawned anything that you want with it, a, b and Ax, little bat, an area, fact Cloud, apparently,
an armor set, whatever you really want to. But for the time being, we're
going to keep it like this. Now we're just
going to copy this, make this level two, and then we'll just small to linings. That's actually all the
functionality that we need. If you want a particular functionality for
your enchantment, it is just a matter of learning Java more and just trying
out a bunch of stuff. Be open to experimentation. Take a look at the, the lunula enchantments,
highly recommended. You can basically can't do
anything better than that. By now, we still need to add stuff to our mod
enchantments class. And this is going
to have something that you have seen
before and it's a public static final
deferred register of type Enchantments. This time we'll enchantments. And this is equal to d
different register that create or registries that
enchantments MC course mod, mod ID, and whether it's
a different register. There also is pours a public static void
register method with an eye event bus or
event bus as its perimeter. We're just going to call
the Enchantments that register with the event bus. And its register
method is of course, be called here right
now under the law, the mock blocks registers, we're going to say
mod achievements dot register with the event bus. There you go. And now this is registered. Now what we're going to
need is we're just going to do basically the following is actually going
to be very straightforward. We simply need a public
static Registry object of type enchantment, of course, which is going to be the
lightning underscore striker, which is equal to
enchantments start register lightning
underscore striker. Then in a supplier of new lightning strike or
enchantment with the rarity, let's do let's do
uncommon though? Uncommon, yes. For rarity and the
Enchantments category is weapon than the equipment
slot is going to be not feed, but we're just gonna
do this equipment Slashdot about mean hand. Yes, there you go. And that's actually it. That is all that we need to do to register this enchantment. This is the functionality, this is the registration done. Now what we do need
to still add is that the translation instead of the e and underscore
us adjacent file, we're used to, you know, I'm going to put this at
the very bottom here. We're going to copy this over. This is nothing too crazy. This is just the basically enchantment
MCQs, lightning Stryker. So this name, of
course, once again has to match with this
name right here. And then this is just
enchantment Vermont ID. And you will only need
this one's even though there's multiple
different levels, this will be translated for
each of those levels, right? So after having
added all of that, Let's see if it works or why we functions back
in microfinance can see the lightning strike or has been successfully added to the
game, the Enchantments. So let's just add it to our diamond sword
here in this case, and let's just use the ones
that is the number one. Then if we use number two, it is not to notice will, but it is something different. So there you go. That's actually how
easy it is to add a customer channeled
to Minecraft. And that will already be it
for this lecture right here. I hope you found this
useful in urine. So the new, and I'll see
you in the next lecture. So yeah.
66. (Intermediate) BlockState Properties: All right, welcome back to
the forage course for 118. And in this lecture
we're gonna be talking about block
state property. So block say properties are
a very interesting thing. And basically we're,
first of all, we're going to cover sort
of the theory behind it. And for that we're going to take out the PowerPoint slides. Let's take a look at
the distinction between blocks and block states. So block, you can think of that as sort of a single pattern. The idea is that for us in our more blocks class or for the Rindler blocks
in the blocks class, we have different fields
for a particular blocks. Now those are created once you remember they are
public static final, so they're assigned once. There ever only exists one field for one
particular block. So you can think of them
as a singleton pattern. While block states are the instances that are inside
of the world or the level, the block states save
a block position, the block properties, those would be the strength
of the block. You know how, how much time it takes to break stuff like that, that We basically assigned
in the mailbox class and then also the block
state properties. So those are the three big ones. Of course there's a lot more
than that is behind there. Those would be the big three. And you can think
of it like this. The block states are saved
by the world and they can only ever be changed
by the world or the level. By, for example, doing level sunblock than putting
in some parameters. That's the general idea. You have a block which
is a single pattern is just the idea of
a block so to speak. Because if I say
Redstone or block, you're like, Okay, I
know what Redstone or block looks like, but if I then have three
different Redstone or blocks in the world, they're all different, but
they're all the same type. That's sort of the idea. So
you can think of a block as a class and the
block state would be the object that is
created from it, let's say in terms of programming language,
so to speak, right? So what are block
sit properties now? Well, the small headline here, or how to store data in blocks is not a 100
percent correct, but it's sort of the idea
of sort of the same. So in the a calcium blocker
class in this case, the general question
might be, well, why don't I just
put in a Boolean there and then it
will work well, once again, think about this. When we are creating a block, write the, this class
here is created once. So if you would have just
a Boolean in there for all blocks of that type,
it will be the same. And then of course, doesn't make any sense because
whether or not this Redstone or block
is lit or isn't lit, has nothing to do with the one like two blocks away from it. Right. And that, of course,
doesn't make any sense. So that is where the separation comes in and that is
where the block say, properties need to be used. We can see here we have a
Boolean property called lit. And what is very
important is that we define this in the block class. And then we always, always have to call the create block state definition method here and basically add the
properties to the builder. That's very important
is that in general, properties can never be null. So they always have
a value above, can have multiple
different properties. And these properties
can then later be referred to in the
block States JSON file to basically refer to different models that we've
seen this already, right? We've seen the stairs within
the doors, all of that. They basically have plenty of different blocks,
the properties, and then the end depending
on their values, they then refer to a
different block model. And he was basically
one example, right? This would be, LET is equal to false and this is lit,
is equal to true. Changing the block state. Well, how is that done? Well, it's actually
done very easily. We just need a level here. So we need a level
variable somewhere, set block at a
particular position. Then we get the current state. We set the value of lit exactly what is inside
of here, right? In this case true. And then the three is just a, basically a flag
which determines the updating behavior of the
actual setting of the block. Usually this is done
in on the server. So if you're just doing this on the client is
not going to work. Basically, always make sure that you are on a server thread when you are changing the
block state was of course, if the client could just
change Bach states, or that could lead to some
interesting issues that say, and yeah, that's pretty
much the idea, right? It happens on a
particular position here. The second parameter
is the new state at that block position. And then third
parameter, like I said, it changes the
updating behavior. We're basically going to
go through with 3 4 Amin, basically the entirety of this course because
three basically just updates all of the
neighbors and updates the way that it looks and
that's going to be fine. So at the moment, I wouldn't worry about this too much if you really
need something else, then at that point I hope you that you are an advanced enough to basically figure this out
on your own as well, right? But that would pretty much
be it for the theory here. So let's go into
intelligence and let's press the Shift key twice
and let's put in a red stone or block. We're actually going to
take a look at this class. And as you can see, pretty
much exactly what we had here, a Boolean property called lit At the very bottom, we have the credo block state
definition method right here, which is called. So both of those are basically
the important things. Now the reason I've chosen the Redstone or block
here is because this is the easiest example of a
single block state property. And it doesn't have too
many other things in here. But there are, of course,
some other things. Attack here would be if you
just left-click to the block, then it starts to search
the Interact method, which basically is right here. And this is very interesting. So if the lip property is false, then we're setting it to true. And you can see this is exactly
the setting of true that we had in the PowerPoint
presentation as well. We set the blog at a
particular position. The state we're setting
the value of LET the true, and then the flag here is three. So I believe that if
we hover over this, you can see worldwide
flags are as follows. One is a block update, two will send it to the
client for will prevent the block from being re-rendered
and stuff like that. And you can basically add them. But if we put in a three, then what's going to
happen is that it will both cause a block update and it will send the changes
to the client because we put 1 plus 2. That's the basic idea. If
you need anything else and they are basically
just take a look at this for the time being. We're not going to worry
about it too much. Well, this is all
fine and well right, we can all take a look at this, but let's be honest, we wanna
do something ourselves, and this is exactly
what we're gonna do. We will create a new class here. So in our custom package, right-click new Java class. And this is going to be
the cobalt lamp black. And this will extend
the block class. Of course, right here, import this picture
that we've chosen, that we've chosen the
correct one over o, the screen constructor
matching super. And if this noise us, then we can just click on it, press Shift F6, and just
choose Properties here. There you go. All right, now we
need, of course, a block, say property. Now I'm going to
make this a public static final Boolean property called clicked, which is equal to Boolean
property dot create. And that's it. And regulations, you've created a custom blocks ID property. That's all that we need to do. And of course we
do still need to override the Create block
set definition method. And then basically call it
P builder dot add, clicked. There you go. If you have multiple
blocks, the properties, you can just add them by basically by separating
them with a comma. Of course, adding clicked twice here doesn't make
a lot of sense, but if you had multiple ones, you can just separate
them with a comma and add as many as you want
with the add code here. Now what we want is we want
to be able to right-click this block and then it basically
turns on and turns off. We're just going to take
the US method here. We're going to override that. So let me just make this
a little bit different. And then of course, because
this is deprecated, you can see we
shouldn't call this. We're just going to
return the interaction result that success,
that's going to be fine. Now the question is, okay,
what are we going to do? Well, we're going to say
if P level is client side. So basically making
sure that we have the, this is very important
that we have the exclamation
mark at the front, basically negating this, right? So we want to be on the
server, not on the client. And I'm gonna say p-hat equals
interaction hand in hand. We're only going to
call this one's ever, That's the basic idea. And this is very important. So exclamation mark, please note this because I've
seen this multiple times. The people have forgotten
the exclamation mark where we want to be on the
server, not on the client. And then we're gonna say
Boolean current state is equal to the state that
we've been passed in. So this would be the
actual block state that we've just right-clicked. And I'm going to say
get a value of clicked. And then what we're gonna
do is we're just gonna say level set block that look like we've seen at this
particular position that we right-clicked
with a state that we've right-clicked and
setting the value of clicked to the current state, negated the first parentheses, orienting, putting into three, which is the flags. And, and that's actually
all that we need to do for this lamp to change. Well, it's blocked state. And we're gonna see how we can basically represent this or how we are going to be able
to see this in just a moment. But yeah, that's pretty much
all that we need to do. You can see everything in here. This shouldn't be too
crazy at this point. Yeah, So let's actually
register the block as well. So in our more blocks class, I'm just going to
copy over the cherry blossom trapdoor and
this is going to be the cobalt underscore lamp for it's the same
here, Cobalt lamp. And this is now a
cobalt lamp block, which is going to take
definitely not wood. Let's take an let's take a metal and then no occlusion
is also not the case. Now what we will actually add is something
very interesting. Let's not strictly necessary, but I wanted to show this. Basically what I want is that if the click property is true, then what I want is I want
this to be turned on there. How do we do this? Well, you can see we have
this lake level here, which is a to Int
function of block state. What does that mean? Well, it basically takes in a state here and then we
have it similar to a. You can see this is similar to a supplier and then we just need to return it so we
can put in 15, for example. Regardless of the state, you can see that it's
just going to return 15. That's not quite
what I had in mind. What I had in mind is that
we're going to say state dot, get a value of cobalt
lamp black dot clicked. So we're basically
getting the value and then we're going to
use the ternary operator. If this is true, we're
going to return 15, which is Max light level, and then otherwise we're
going to return 0. That's the general idea here, is just a, something
to add basically. And also then you,
now you know, hey, this is how you can
very easily just add a light level there to
a block if you want to. And now of course, on
to the JSON files. So let's first of
all actually add the translation just because that's going to be a
little bit faster. I'm just going to copy
over the fence here. The cobalt lamp. They go about lamp. And then I will also copy
over the block states. Those are of course,
all available to you in the GitHub repository or
individual just as well. And here you go. So click this equal to
false cohort lamp off. So we're going to point to this model, they've
clicked is true. Then we're going to point to the cobalt underscore
lamp on block model. So let's copy both of those
blood models over as well. Shouldn't be too crazy, should they? No, of course not. They are actually not too crazy. And see, we just
pointed to cobalt lamp off and then on the other
one, can you guess? Yes, overall, lamb on. So it's very
straightforward, actually. The textures that we're pointing to them with the item
model, you know, it's just going to be
pointing to the off, Let's actually pointing
to the unimodal. Well actually, you know what, let's make this point to the model because that is a little bit nicer in this case. And then of course,
just copy over the textures as we've
seen multiple times. Now. They go and well, that is pretty much all
that we need to do, right? Most of the heavy lifting here done by the Boolean property, and the rest is, well, should be fairly
self-explanatory. So let's see if it works. Or we find ourselves
back in Minecraft. As you can see, the
cobol M has been an unsolicited down
and there it is. It started in the on position. So basically it starts with a Boolean property t being
true, that's totally fine. Of course, there's
no worries there. And what you can
actually see, like let's actually put in time at night here and see
if I right-click it. Now, we can actually see that the light is what being
turned on and off. So that's really frequent, cool. But that's actually how
easy that can be as well. But in just so that we have it, if you maybe want a
different default property, what we can do is we can call
this in the constructor, this dot register default state. And then we can say this
dot default block state, our set value of
clicked will to false. And with that, basically
what we're gonna do is we're setting
this to be false. So the clip property will
now be false by default. But that's sort of the
general idea for an, another interesting thing
is that, for example, if we go into the
Boolean property, so middle mouse button
click, you can see this is a property of type Boolean. If I press Control H here, you see they're also
integer properties as well as enum properties. One of the most ones is
the direction property. So you can also use
integer properties and all of the
other ones as well. And if we actually take a look at Boolean property that
create, for example, we can do this, but we can
then also take a look at, for example, the block state. I think it's blocked. Three properties. Go block, say
properties that class has basically all of
the vanilla blocks, the properties defined
in here, we can see, for example, some integer
properties, ages, max, ages. We have some level
cauldron level, lowing level capacitor. So with basically
some examples here, I highly recommend taking
a look at this if you want to make your own
custom blocks a property. Otherwise this
would be already it for this lecture right here. I hope you've found this
useful in terms of the new, and I'll see you in
the next lecture. So, yeah.
67. (Intermediate) How does NBT Data work?: All right, welcome back to
the forage course for 118. And in this lecture, we're
going to be taking a look at NVT data or as it's now called, compound tags, will
basically MVT tags. So what are those? Well, it's basically a
way of saving data onto, for example, Item stacks. Now, the first
question that comes to mind is wastewater
item stacks. Well, just as Bloc states are the representations of a
block inside of a world, similar item stacks are representations of items
inside of your inventory. So if you have two
different diamond swords, well they are both the
item, diamond sword, but they are both
different items, stacks, That's a general idea. And for this, what we're
gonna do is we're gonna save the result that we had
from the last dowsing rod. Right-click on a well
in, in NVT data. And what we're gonna
do is we're gonna make a new item for this. So in our custom package, right-click new Java class
called the data tablet item. And this will extend
item of course, over all this create
constructor matching super. And then what we're
gonna do is we're going to just add a bunch of stuff. So first of all, we don't really need
to add anything to be able to add
NVT data to this. We can add NVT data to any different item
stack that we want. This is pretty much it. What we are gonna do however, is we're going to have
the following things. So number one, I actually
want the NVT data to be displayed as a tooltip. We're gonna do is we're going
to say append Hover Text. And what I will do is I
will basically say, Hey, if the actual stack
here, right, has tags. So this is the method that
checks whether or not, you know, NVT data or
attack is present here. Then we're going to say
oranges is just a string. And we're going to read
this from the stack. Dot gets tagged, so this gets the NVT tag or
the compound tag. Then you can see there's different types of
methods that we can basically get this
a few different get's. There's also some puts. Well, what we're gonna
do is we're going to get a string with the following key, MC course dot last
underscore or. And then we're just going
to add this to the tooltip. So P tooltip components, dot add new texts
component or an All right, so we've seen now two
of the three important, well, tag methods basically
has tag and then gets tagged. And then you can
basically get any tag via a particular key year. And we'll also do is we're
gonna make this limb. So we're going to basically
have the enchanted glint on this item if there
is a tag prison. So we're gonna say is foil and we're just going
to return the stack, not as tag, but that's
pretty much it. As soon as it has a p tag
component on this stack, then it's going to
start to sort of glitter like it is enchanted. And then we'll also override
the US method right here. And what we're gonna do is we're going to say the following. We're going to say if the
player not get item in hand, he used hand that has tags. So once again, if we have a tag, then we're just gonna
do is we're going to say player getItems in and used hand that tag. So this is the third one
to a new compound tag. Because if we are
just setting this to a new compound tag which doesn't have anything
associated with it, then it's just going
to basically erase the tag and hashtag
will now be false. So basically if we
just right-click the item D data
tablet in the air, then it's just going to erase all of the data
that is on there. That's the basic idea here. And well, that's pretty much
all there is to it, right? We have the hashtag, we have the git tag, and we have the set attack. Those are pretty much all
of the three big methods that we need to think about. And now we're actually going
to do is we're going to, of course, changes of
in the dowsing rod. But for this, we're
going to need a util helper class in
our YouTube package. Right-click new Java class
called inventory util. I'm actually going
to copy over both of those methods because it's just going to make this a
little bit easier. So you can see it's just,
it just basically as a Boolean method and
a integer method. And the Boolean
method just says, Hey, does the player, this player have this item
somewhere in its inventory? And then the other one just
basically says, Hey, has the, where's the index of the
item that we're passing in? But that's basically
the general idea here. And what we're gonna do is
in our Dao single item, we're going to now change this. One of the core is of
course available to you in the GitHub repository or an
individual just as well. But I'm going to copy over
the main method here, which is going to be the
ad in BT to data tablet. Now, as you can see, we're
going to actually need to define the more item
data tab as well. So no worries there.
We're just going to do is just immediately
is register this. So data tablet. And then here data
underscore tablet. And this is of course,
a data tablet item they ago with only the
normal properties. And then. Everything here
should work fine. This shouldn't be too crazy. At this point, we've
registered so many items. Registering an item should
be almost second nature. Now what are we doing here? Well, we're basically getting the item from the
player's inventory. But by getting the
first integer index, we're getting the
first instance of this item in the inventory. That's very important. So this is basically
how it's going to work. I will show, of course, in the demonstration
just a moment. And then we're going
to create a new tag here, so NVT data. And then we're just
going to put a string in with this key. Very important that
this key is correct, because this has to be
exactly the same one by, when we're reading
this out basically. And then we just put in, well, basically the same stuff
that we put in right here. So we're just going
to print the name and basically the position
at where we found it. And then here we're
just setting the tag of the data tablet to MVT data. And then inside of
here, basically just after we found it, what we're gonna do is we're
gonna say at the following, we're going to say if inventory util dot has player stack and inventory with the player and the more items that
data tablet dot get. If that's the case, then what we wanna do
is we want to add NVT data here with the player, the position click down below I, and then lock below as well. There you go. That is pretty much it.
Now, this of course, is not Important to the
NVT data in general. This is just basically the
way that we're adding it. So this really is like the main part of
the NVT data here, in this case, making a
new compound tag and then setting the tack on that
particular item stack. That's pretty much
the basic idea. Now for completion
sake, of course, let's also add the
translation here. This is going to be the
data underscore tablet. Data tablet here. Very nice. And then also add the item model right there so you can
see it points to the data underscore
tablet underscore off, extra curious and off texture. Will is there also an own
texture? Yes, there is. But that is something
we're going to see in the next lecture. Actually. We're just going
to copy this over. And that should be pretty much all that we need to do in order to add well the data tablet
and some custom entity data. So let's see if it works. Or farces back and microvesicles see the data table has been added to the game. Now we're actually
going to have to change the max stacking here
in just a moment, but that's of course going
to be a very easy fix. And let's just see if
I can find valuables. Then we should see the
first it a tablet. There you go. So now we can see Found Minecraft copper or at exactly the position that
we had there as well. So everything works. If I
now right-click with it. It has now been deleted. And what's very important is
that if I find another one, you can see that it overrides
it for the first one. This is basically what I said, but it's going to
override it and not put this next one on. You could of course
make another well, inventory usual method that's like a find one
without NVT data. And then you're going to
add it to the next one. That would also work, of
course, totally fine. But for the time being,
this is pretty good. Now let's actually fix
the stacking of this. So now you can see they
don't stack anymore. There's one of them
had NVT data on it. But you can see, I can just get new ones here and
I can stack them, which is of course it's
not quite what we want. So let's just fix that quickly. But this is of course a
very easy fix, right? In the item properties, we're just going to add the
tax to method right here, and we're just going
to put in a 1. So that should be fairly
self-explanatory here. And with that, basically the
entire data tablet is done. And this would already be it
for this lecture right here. I hope you found this useful
and he learns of the new. And I'll see you in the
next lecture though. Yeah.
68. (Intermediate) Item Properties: Or I will come back to the
forage course for 118. In this lecture, we're
going to be adding a custom item property
to our data tablet. Now, some of you might say, Wait What the hell is a custom item model property
or an item property? I've never heard of that. Well, it basically is very similar to a
block state property. However, it enables us to 0 to a different item model JSON file if the property
will changes its value. So what we can do
is we can change the texture of the
data tablet item if, you know, if we
have, for example, in BT data on it. What we're gonna do is
we're going to make a new class in the util package called the mod item properties. And then we're going to make
a public static void called add custom item
properties method. And then we're going
to do the following. First of all, we're
going to press shift twice and we're going to put in the item properties and then make sure that the
tick here is ticked basically the box include
non-product items. And then we're
gonna go into this class and you can see that this is basically the
item properties class. And if we go down, you can see this, for example, the bowl that has the pole and the pulling item
properties which are used in order to change the texture inside of the
inventory of the bowl. So this is really freaking cool. And this is, well, one of those things that if
you don't know about it, it's very hard to
think about this. But once we know, once you've seen how it works, is actually going to be
fairly straightforward. So we're gonna say
item properties that register the mode
items, data tablet, dot get, and then a
new resource location called MC course mod, mod ID, and then on. So this is just the name of the, of the property basically. And then what we need is we
need a crazy Well method. And then what we're gonna do
is we're just going to put in parentheses and then API. And you can see that
it basically only once all generated for us
the item property function. So we're just going
to hit the Tab key and then this is fine. Now this item property
function returns a float and this basically is then the value that the
item property takes. What we're going to
see is we're gonna say P stack dot hashtag, western mark one, f colon 0, F. And we're basically using
the ternary operator. Once again, it
will return one if attack is actually present and 0 if attack is not present. Well then that's pretty much
all that we need to do. I'll need to call this
in our client setup. This is very important,
that is called the direct method here
item properties, more item properties that add custom item properties.
And that's pretty much it. For every additional item. We just add a new
register call here. And then that's
pretty much going to be all that we need to do. Now, where do we
use this on here? Well, we use this inside
of the item model. So what we're gonna
do is first of all, we're going to basically
have a new model. So the data tablet right here, I'm actually going
to copy this over. So I'm going to drag it
into the same folder while holding Control. I'm going to call this
the data tablet on. I'm just going to change this to data tablet on right here, not too soon, but on the ego. And then I'm going to copy over the other data tablet
or the contents here. We're just going to open this. We now have a data
tablet underscore on just normal based on file. And this, I'm going to copy
over the contents and I'm going to explain in well
how this works basically. So by default, this is the
texture that it chooses, the data tablet off. Now there is an overrides here. This is basically a list of different overrides
which has a predicate. And the predicate is basically you can think of this as a, if this is true, then
we're just going to overwrite it with
this model here. And the predicate is, hey, MC cores on the item
property has to be one. And then we're going
to override it with this one right here, which is the MOOC
course item data tablet on which we've just made here, which then basically points to the context of the data talent. That's pretty much
all there is to it is this shouldn't
be too confusing, this shouldn't be too crazy. We're basically doing it in a very similar way as the block say properties is just
a little bit different. And yeah, that's pretty
much all there is to it. So I'm just going to add
the other data tablet on texture as well. And then what we're basically ready to take a look at this. Once again, I highly recommend just being open to
experimentation, playing around with this
a little bit because the item properties are actually really freaking
cool and I really love that. It actually is fairly
easy to do this. So I highly recommend
taking a look at this. But for completion sake,
let's see if it works. All right, we find ourselves
back in Minecraft. So let's see, let's try
to find some valuables. And then as soon as we
find it, there it is. And then the actual texture
has changed as well. So this is actually
really freaking cool, and I can right-click to, we'll delete the data again and then the texture changes back. So this is actually how
easy it is to, well, basically change the
texture of this and just something like
small like this, right? Changing the texture
on the tablet is just such a cool
effect that sure, It's like, is it going to
make an entire mod know? But if you add
something like this to your MOD is just going to be that much frequent
cooler, Right? And that's already it for
this lecture right here. All of the code
in the JSON files are of course
available to you in the GitHub repository and
an individual just as well. And I'll see you in the
next lecture though. Yeah.
69. ASSIGNMENT 7: BlockStates & NBT: All right, Welcome
to this exercise here for the forge course. And what you are
basically supposed to do here is we'll make one as some block state property and
then one NVT data example. Basically, your, your
creativity is just, you can do whatever you want. Basically just be creative. Don't go too crazy, right? Don't think like
I'm going to make a fricking crazy stuff with
six different NVT data. Oh, very slow, very easy, right? Maybe do another
Boolean property, maybe do an integer property, whatever there is, this to
something that's really cool, but also not too crazy. Don't go too
overboard with this. Just think about this and then you will manage this assignment. There is no real solution
for this because, well, basically you can do
whatever you want in here, which might be a
little bit too big, but I'm sure that
you will manage, but I'm very interested
to see what you can come up with and yeah.
70. (Intermediate) Custom Crops: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding a custom crop to Minecraft. So custom crop is actually a fairly straightforward
process. All things considered,
there are of course, some very special things
that we haven't seen yet, but overall, it's going
to be totally fine. So first of all, we need a custom pass in
our custom package, right-click new Java class
called the turnip Rob block. And well, we have two
different possibilities here. We can either extend it
from the crop block or, and this is going
to be easier first, we're actually going
to extend this from the beet root block. Now, the reason for
this is going to be apparent in just a moment. First of all, if the
parameter your noise, you shift F6 and
then rename it to properties and middle mouse button click on the
bead roadblock here. Any will see that it has a
integer property called age. Now this integer property
goes from 0 to three, which is exactly
the same number of ages or age values that
our block has as well. This is why we can
basically take almost the entirety of this. We only need to override the good seed ID method
right here in our own class. And the rest can basically
stay exactly as is. Now if you have a different
age in your accustom crop, take a look at the crop block. You can see that the
crop luck actually has a person age of
seven in this case. If you want to
change this, also, you can just change it by using a different each year or you
can define your own age if, you know 12357 and 15 or 25 are none of the
agents that you want. You can just make your
own integer property. We've seen this previously. So this shouldn't be too crazy. The only thing that might
be a little crazy is this shape by age right here. So I can actually zoom
out a little bit and then just scroll and keep
scrolling and scrolling. This is just very badly
formatted in my mind. I just don't like this, that it's all in one line. The general idea is that
we basically just have a box in the wild level
of that box changes. The box is the black outline that a block has when
you hover over it. And the outline changes by the age of the actual crop here. And then same goes for
basically the beet root block. You can see in the 0th age, it's 246 and an eight. And you can basically change
those on will as well. So that is something
that you can also do. All of this shouldn't
be too crazy. All things considered. You know, if you have a
completely custom crop that you want to implement with a different age and all of that, I am sure that you
will manage because most of this is not too crazy. Just make sure you know, you, you override the
GetMax age method. Basically just take a
look at the beet root. Here, take a look at
the crop block here. Take a look at the
changes they made from one to the other
and then the rest. I'm sure that you will
manage and figure out. And we actually need to override the seed ID for the time being, what we're gonna do is
we're just going to make this a, make this an error. So I don't forget this. This is just a quick little
tip here because I maybe I want to forget
changing this and then you're gonna have
to go through it again. So let's not do this. And let's then add a, well the crop here
in our box class. So this is going to be a just
copying the trapdoor here. And we're going to call this
the turnip underscore crop. Now what's very
interesting is that, of course this is
also going to be the turnip underscore crop. Now this is not register block, this is blocks dot register. And the reason why we're calling blocks or register instead of doing the register
block method is because we'd actually do
not want a block item associated with this
particular prop here. What we want is we want
to make a seed later. So we're gonna say
turnip crop block. And then this is actually
going to be material of, but we're going to
say copy and mono, say blocks dot wheat, your
cell that we actually, let's do beet root, beet roots, they go
and the rest is fine. I believe that the only
other thing that we want is let's do no
collision as well. So no collision, no occlusion. Length 2 we shouldn't
actually really need here. And then the rest
should be copied from the beet roots anyway, so no worries there. So this is the
block actually done and we do still need the item. Now this item, like I said, is going to be just the seeds. So we're just going to pick the data tablet and
we're just going to say turn IP underscore seeds. And then the name
here of course as well turned up underscore seeds. And this is going to be a
item, name, block item. That's interesting, yes. Making sure this actually
stacks to more than just one. And then we're just
going to change the name here as well. So this order, and then the first parameter
is going to be block mode blocks
dot urllib crop. Yet, Let's just change the
formatting a little bit. I mean, this is
going to be fine. This is going to
be good at read. But we're going to need
to make this an item named block item
because we actually want to take the
turn of seeds name instead of the blockName
of turnip crap. Now what we can do
in the class as we can return more items, dot turnip, seeds.rb,
right here. And then the class has
actually done, like I said, if you have any particular different ages and
stuff like that, take a look at the crop class, take a look at the
beetroot block class. I highly recommend this should be basically all that
you really need to do. And in the MC
course mod a class, we also need to add the turnip crop to the
specific render layer. So let's just duplicate
this with Control D. And then put in turn
up a crop right here. And that is also done. And then JSON files
are all that remained. Now let's actually do
the translation first because there's a little bit of a tendency to forget this. So let's do turn up
underscore crop. And then this is going to be
the turnip crop right here. And then what we're gonna do is we're just going to also add, this is actually going to be
the seeds, they go seeds. And then the crop will
actually be added right here. So there's going to be
turned up, underscore crop. Turn up, Rob. So you might want this
translation as well, just so that you have
it when you have the, what am I looking at
model that basically displays what the actual name of the boxes that
you are looking at. This sometimes can
help there as well. With the translation basic. Let's copy over the block States Jason and I will explain. Of course, you can see
this is nothing too crazy, nothing that we've
not seen already. We basically have
four different ages, 0 to three, and we're just pointing to different
block model JSON files. So this is basically all
that there is to it. This shouldn't be
anything completely new. We're just going to copy
those over as well. Those are of course,
all available to you in the GitHub repository or an
individual just as well. And you will see this
is now just crop here. And then the textures
also point to crop. And then we just point to
different block models. We just point to
different block textures. So that's pretty much
all there is to it. And let's also then copy
over the seeds here. Also just points to a texture. Nothing crazy about it. Well, this actually
isn't that insane. All things considered. Let's get the Aedes
texture and then let's get a lead textures
for the blocks as well. They just 0 to 3 year. And then one more very
interesting thing is going to be, well, the loot table. Now how does the Lu table work? Well, for that, we're
just going to go down to the external libraries. Once again, the data
folder right here, right microwave client and extra 1181 to the lute tables blocks. And then we're just going
to say, for example, the beet roots. We're just going to open
this and you can see this is a little more
complicated in this moment. But what we can do is we can
just select all control C, or we can also select
the JSON file Control C. And then just go up here to our MC course Lou tables blocks
Control V to paste it in. And then we're just
going to say if Eve turn up underscore crop, and then we just need to change
a bunch of stuff in here. Now it's very important
as you can see, that we're actually
looking for a block, say, property, old age, and
it has to be three. And then this is
the condition under which the actual beat up drops. That's very important. So this is going to
be MC course turnip that we're going
to change this to. And then this is of course
going to be MC course. Turn up underscore seeds. Now very important, we have to change this block
as well, right? Because this now is going to be the MC course Olin turnip crop. Because we are checking for the age property and the turnip
crop no longer the beat, beat roots block basically. And then the same
thing goes down here, making sure that we change this to once again the term crop. And then here are
some additional seeds where it might drop. We're just going to
copy this over as well. Make sure that both
the mode ID as well as the names of the items
and blocks has changed. It's very easy to look
over the MOD ID here. So yeah, this, of course file
is also available to you, so no worries there, but that is actually all that we need to do to add
the custom crop. So let's see if it works. Or if Francis back
and microvesicles see the turnip seats have been successfully added to
the games. Let's see. I can also plant them. That is a very good start. And let's just use
some bone meal on them and they go So they're growing dairy is and let's
just switches violent. See, I can even get some
turnips and some seats back. So this is exactly
what we want C, and let's just see if
they also grow when basically the time is made
a little bit faster here. So random tics be just to like 2 thousand and there they
are growing as well. So everything working amazingly. Course when I break
them in creative, that's why I switched
to survival. So if we go to survival, there you go, It's got
some nice turnips here. And there we go. And now we can become the
gardener of our dreams, right? And that is already it for
this lecture right here. I hope you found this useful
and he learns of the new, and I'll see you in
the next lecture. So, yeah.
71. (Intermediate) Add Items to the Composter: All right, welcome back to
the forage course for 118. In this very short lecture, I will show you how you can add your items to the composter. So you can basically make
them compostable, very, very easy in the setup
method that you have. Hopefully, this should be with the FML common set
of event parameter. What you're gonna do is
you're going to say event dot and q workable. And then you're going to
put in a parentheses, a an arrow, and the
curly brackets. And inside of this, we want to call
composter loc dot dot, put more items that
turnip seeds that get, for example, 0.5, I believe, is the correct number. Then duplicate this
with Control D, and then we're going to put
it in a turnip here as well. I'm going to put in 65. So we can actually
take a look at the compossible map right here. And these are basically
the changes that we have. So you can see that three, so the ligand basically see
here typical 3.5 potato VDD. I guess the seeds
are actually less, so there are actually three. Let's change this to three. That's totally fine as well. 0.3. There you go. That's pretty much it. That's all it did you need to
do in order to add them to the composter though for completion sake, let's
see if it works. Oh, well if friends, There's a Minecraft
and there you go. The composter, both of them working exactly how
you would expect it. And now we got a bone meal, or that will already be it
for this lecture right here. I hope you found this useful and learned something
new and I'll see you in the next
lecture. So yeah.
72. (Intermediate) Custom Flower: Or I welcome back to the
fourth course for 118. And in this lecture
we're going to be adding a custom flower to Minecraft. Wiling a custom flower
is actually fairly easy. So in our model blocks class, we're gonna do is we're
just going to copy the cherry blossom, a trap door. And this is going to be
the pink underscore rows. And of course for the name as
well, pink underscore rows. Now this is going to
be a flower block, which actually takes in
three different parameters. The first one is
a mob effects or effects that let's say
blindness for example. And then the effect duration, which popular to come
and leave is actually in seconds this time
instead of ticks. I don't know why it
seems very inconsistent, but it is what it is
and the actual mapping, what we're gonna
do is we're going to not need any of this. And then we're going to
copy from blocks that dandy lion here so that we basically have all
of the properties that we are going to need. So the properties that
we are going to need are basically no collision
in seborrheic end. Also, I believe
the material from plan basically gets
you the no occlusion. So this one right here, we need both, OK, no occlusion and no collision. But by copying the properties of the any line where basically
already have that in here. What we're also going
to need to do for the flower is in
our setup method, we need to call this for
the pink rose right here. So we need to set the renderer
layer properly and then, well, it's basically just
off to the JSON files. Those are of course,
all available to you in the GitHub repository or an
individual just as well. He Bloc states Jason is
just a normal Bloc states. Jason also add the
translation here, not to forget this, the
pink underscore rows. And then pink rose right
here. There you go. And then let's add the
log model as well. Nothing really
interesting going on. We have a cross pattern this time and a cross
texture as well. You can see this time
the parent is the cross here and then the
textures is also cross. That's really the most
interesting thing in this case. And the item model
is actually also fairly interesting because
this one points to a, well, the same block texture
that the block points to, because while it is basically the same thing that
you have in your hand, that it also looks like
in the world basically, we're just going to
copy this over as well. So they go and that
is actually all that we need for
a custom flower. So now let's see if it works or we find
those back in micro. As you can see,
the pink rose has been successfully
added to the game. And doesn't it look
just beautiful? So that's how easy
it can be to add a custom flower to
Minecraft, right? And then it's already for
this lecture right here. I hope you found this useful
and he learns of the new. And I'll see you in the
next lecture though. Yeah.
73. (Intermediate) Custom Flower Pots: All right, welcome back to the
forage course through 118. And in this lecture
we're going to be adding a custom policy
plan to Minecraft. So after having added
at the custom flower, we're now also going
to make a part it will variation
of this flower. And the way that
we're gonna do this, we're just going to copy
this and we're gonna say part it, pink rose. And the most important
thing here is that this one actually does not call the
register block method, but this once again calls blocks that register right here. So what we're gonna do
is we're just going to take away the relief
tap at the end. And then we're also going
to make this the part that underscore pink rose. And this is now a flowerpot
block for this only. This actually going to need three different
parameters as well. The first one is a null, the second one is mod blocks, dark pink, rose, the
same without a get. And then this is just going
to take the audit dandy lion as it's copying
of the properties. Now, you might say, well, this is already it, not quite, because what we still
need to do is we still need to sort
of add it with a list of possible well
flowers, just essentially. So once the setup method, what we're gonna do is
we're going to say blocks, that flower part, that cast. And then we're going
to cast this to a flowerpot block right here. And then we can do is then
we can call the add method. I'm gonna say block mode, blocks dot, rows, dot getID. Then the second
one is just mapped blocks dot-product, pink, rose. So this is the way to basically add it that you can right-click with your rows here
and then you're gonna get this block out of it. Now this is still
a normal block, so we still need a
block States Jason, block model Jason and a translation file
for the piping rose. I'm just going to
copy this over. The block state is actually
just a normal block, says Jason year, the model
is a little bit different, but not too crazy. Let's first of all
actually do this. So let's do part it in
Gross are epic rows. Now this translation
is only needed if you have something like,
what am I looking at? The mode that basically
you can, you know, that what you basically looking
at which this the name of the actual block
you're looking at. Now this year, this block
model you can see is actually flower underscore
partners across. And then we specify
the anterior. Now it's also important
after we've added this, we don't need any other texture. What will we do need
is we also need to have the public pink rose here in the render
layer cut out. Otherwise, we're also
going to have a little bit of a display will issue there. Otherwise, that is all
that we need to do, though you can see
it's actually fairly straightforward, but still, there's some interesting
stuff, especially with this, with the casting of
the actual flower pot. After we've added this,
let's see if it works. Or furnaces back in micro. So let's just set the part
down and there you go. We have the potted ink rows, which is working totally fine. But this is exactly
what you would want. Rather than just as a quick
aside here at the end, if anyone is wondering,
you know, oh, how can we do the
LU table for this? Once again, it come, we have vanilla examples of this go down to the
external libraries, down to net microwave
client extra 181. And then in the loop
tables you can simply search for all of
the potted plants. You can, for example,
take a look at this and then basically just replace this allium right
here with your own one. So just copied over Control C, Control V, and then change this. That's actually how
easy that can be. So you always have all of the vanilla examples
basically at your fingertips. Highly recommend looking
at those as well. If you are ever
confused or you want something that's already in vanilla, basically
just replicated. It's often very easy to follow, but otherwise this would be it for this lecture right here. I hope you found this useful
and he learns of the new. I'll see you in
the next lecture. So, yeah.
74. (Intermediate) Custom Sounds: All right, welcome back
to the course for 118. And in this lecture,
we're going to be adding custom sounds
to Minecraft. Or custom sounds
are actually, well, I would say fairly straightforward, all
things considered. Now, what we're
gonna do is we need, of course register them. So in our MC course package, right-click new
package called sound. And then inside of their
new Java class for towns, they ago now this mode sounds
class is going to have a public static final
deferred register of type sound event called
sound underscore events, which is going to be
equal to defer register that create or registries
that sound events, MC course MOD, but modified. Now whether it's a
different register, there is a public static
void register method with an event bus, cool event bus or its parameter, and then sound events that register passing in the
event bus perimeter. Then this method
here is of course called right below the
modern treatments. So mod sounds, not sound event, but register event
bus. There you go. Now how did the
sound events look? Well, they're actually
fairly straightforward. Public static Registry
object of type, sound event,
dowsing, underscore, rod underscore found under score or is going to be
the name of hours. And for this, we're
actually going to create a custom method. Well, let me just do
this for a second here. And I'm going to
make a new methods of private static Registry. Object of type found event
would register sound events. And here we just need to
pass in a string name. And then what we're gonna
do is we're going to make a resource location. What ID? The new resource location, MC course MOT, mot ID and the name as the
parameter name here. And then we're going to return sound events that
register with the name, and then a supplier
of a new sound event. And here we just have to pass
him the resource location. This is the helper
method and this is actually going to make
our lives way easier. Here we're going to call
this dosing underscore. Underscore found under score or the name here is
going to be very relevant in just a moment. So this name here is
actually going to be the name of something we, well, we basically declare
in a separate JSON file. So now the sound has
been registered. Now, first of all, we need, of course, is some
sort of sound file. Now this goes in the assets in your MC course folder
or your ID basically. But we need two things. Number one, we need a new
file called Sounds data JSON, very important sounds dot JSON. And it is laid out like this. We have curly
brackets and then we basically declare
different sounds. So I'm going to copy over the
declaration of the sound. And what you'll find is
that this name right here is exactly the same
as this name right here. So those two have to match. The subtitles are basically what you will see inside of all what you declare inside of
your ear and underscore us JSON file when you
have subtitles on. So this is something
that you can just add to the EMRs
curios JSON file. You can also call this
something like sounds dot M, C corps, wherever
something like this. I'm going to not add
the translation here because at the moment it's not that relevant and is also just one thing
you copy over. It shouldn't be too crazy with mess with the
translation for a while. Now, this should be
fairly straightforward. And what's very
interesting is that this sounds here, this
is a list, right? Because we have these
brackets though, this year points to the
dowsing underscore, one underscore found under
school or we'll now, where is this file located? Well, definitely under
EMT course namespace, but where exactly well, in the assets MC
course folder runs. Again, right-click New
Directory chord sounds. And then inside of there we need an OGG file with that name. So I'm going to copy
this over they ago. And it's very important
that this name here matches this name exactly. It is, it has to be an OGG file. This is very important
and it has to be under the mono sound, sound type or sound space. It has to be a mono OGG file. Otherwise you might run into
some issues, very important. And you can't just
take an MP3 file and rename the ending of it. Mp3 has to be properly
converted to an OGG file. So that is very important. Now all you will find is because this is a list you could in theory have multiple
entries in here. So you can see now I
could have another one in here and then it would
choose basically one of those. So that is very important. We're going to stick with
one for the time being, but there is the opportunity basically here to
add multiple ones. Now the question is, how do we actually call this or window? We're going to call this, well,
we're going to call this, of course, in the
dowsing rod item, basically when we have found a valuable or here,
we want to play this. And how do we play this? Well, we're going to say the
contexts dot gate-level. So we need the level
when I say play sound. And then we're going
to get the player, we're going to get
the position clicked. We're gonna get Modern sounds. That dowsing rod out or that gets sound source
is going to be, let's say blocks, that's
going to be fine. And then Volume 1, f, and pitch one as well. And this is actually how
easy it can be to add a or to call a sound
rich play a sound. You just need the level
and then play sound great. But there's different ways
that you can play sounds. I believe that you might
have seen this rate as if I have a level, might get level. You can see that
I can play sound. I can even play local sound, which would then
be a local sound. So I highly recommend just playing around
with this a little bit and seeing which one of those basically
works the best. You can also do it on
the player itself. So you can do player
sound as well. You can see there
you go, though. I just highly recommend
playing around with this a little
bit and see and what might be the best idea
for you for this end. Yeah, but this is
actually all that we need to do in order to
add custom sounds. So let's see if it works. Or I farms as a microwave
and make sure that your volume is turned up just so that you're sure
that you can hear it. And let's see, there it is. N We have heard it. Ring, ring, ring. So everything
working totally fine. And now what you can
also see is when I put the blocks down because we've made it sound
source blocks. And C Now we can't hear it
anymore as soon as I turn the blocks back on its back. But that's actually really cool. Let me turn the volume
down a little bit again. And it's going to be very quiet. Maybe it, so that it's so quiet that you
can't even hear it. But yeah, that's actually
how easy it can be to add custom sounds to
Minecraft, right? That's really how easy
it is and I think that it really is
fairly straightforward. Now one thing that is
probably on your mind, yeah, but I want my custom block to
have custom sounds as well. Well, luckily, that's
exactly what we're going to look at in the next lecture. But this is it for this
lecture right here. I hope you found this useful
and you learn some new, and I'll see you in
the next lecture. So, yeah.
75. (Intermediate) Custom Sounds for Blocks: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding a custom sound type. Minecraft. Now is sound type
basically includes five different sounds and represents sound for
a particular block. But there's a breaking
sound is stepping sound, placing sound, a hit
sound, and a full sound. And we're going to add
all five of those. Now, I will copy over
the basic registration. Does this is definitely
not that interesting. First of all,
that's really funny that this is not
the correct name, but that is, of
course totally fine. They go register sound
events in this case. And you can see
that basically we have cobalt lamp break
cobalt lamp step, Let's hit and fall. So those are the sound
events, the individual ones, we need those and that
will be also need is we need a custom forge sound type. So I'm going to also copy
this one over and you can see it pretty much is
just the cobol sounds. And this is then equal
to a new sound type metric gonna do coworker
lamb sounds to study it, It's a little clearer what
this refers to basically. And in here, we
basically need to pass in the mode
sounds and we do not need to do get because the forage sound here
actually once a supplier. So this is going to
be totally fine. So we basically want
to use this instead of the sound type just to
be sure because this is, has something to do
with the loading and basically registering stuff. Right now those
five Sound events, we actually still have to
register these sounds. Json file right here. Now, I will copy this over
again, but no worries. All of this is of course
available to you in the GitHub repository or an
individual just as well. And you can see
we basically have the cobalt lamp break step, please hit and fall, which basically once you get
the subtitles here and then refer to a particular
sound file. Once again, they have to be OGG, this is very important, and also they have to be mono. This is incredibly
important once again, otherwise, there might be
some issues with the files. And also you can't just rename a MP3 file to
basically an OGG file, it has to be converted properly. So make sure that all of
those things are the case. And of course, in
our example here, you can of course
just use the ones that I supply, though. We're going to just copy
those over right here. They go, five of them. And that should be pretty much So the sounds
are registered. That's all fine, but how do
we now add this to a block? Well, as actually
fairly straightforward, but in our case we want to
add this to the lamp here. So we're just going to add a new block behavior
property and that's going to be sound the ego and already
suggests this. So this is going to be mod
sounds dot for what sounds, and that is it. All we need to do. And now the cobalt lamp
should have all of the sounds associated with
this sound type right here, which are all five of these. Though, I mean, it sounds like very anticlimactic, but
that's pretty much it. So let's see if it works. Or we find ourselves back in Minecraft and an already here. It working totally fine. So let's step on it. A. That's exactly right.
And let's break it. That's exactly correct. Now, the one thing I have found and that's
very interesting is that the falling sound for whatever reason
doesn't quite work. Or it did work there. Let's see. Now, it
didn't quite work. I'm not a 100 percent sure. The falling sound,
It's sometimes doesn't seem to want to work. I'm honestly not a 100 percent sure why
that might be the case. But the big ones,
the breaking sound, the placing sound, those are the big ones,
the hitting sound, I believe that I can also go here and then here
you can hear it as well as the hitting sound and placing
sound, stuff like that. That's really the big ones. Though. That is pretty cool, right there would already be it for this lecture right here. I hope you found this useful
and he learns of the new, and I'll see you in
the next lecture. So, yeah.
76. (Intermediate) Custom Music Discs: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding a custom music
disk to Minecraft. So to basically conclude our venture into
the sound events, we're now also going to
add a custom music disk. Now, this is once again, pretty much just in normal
sound event right here. We're just gonna copy this over and I'm actually
going to put this above the actual sound
types just in case. Sometimes may be
a bit separated. Here is going to
be the bar brawl, and then the sound event
itself is also going to be called VAR underscore role. There you go. And then of course, the
sound event is done. We of course still need to add this to the nouns
dot-dot-dot Jason. So once again, I
will copy this over. This is all available to
you as well, of course. And you will see that
it's just Barbara. Oh, this is just the same name
as we've given right here. And then this points to
a bar brawl well, name, named file in the Sounds
folder right here, which has to be ODD once again. And this time it's increasingly
important that it is mono because otherwise it will be heard on
the entire server. This is very important
and you can see we also have this stream true
here because the, well, first of
all, the length of the file is a certain length. And number two is
of course a stream that should make sense. Let's just copy this overbar
underscore brawl in. There. You pretty much go. Now for the actual disk, right? We need to go into
our more items class and create a new item here, let's just take the data tablet
and let's copy this over. And that's going to be the VAR underscore brawl
underscore record. Let's say now for the actual name I'm going to call this deep are underscore brawl and music underscore disk only stacking 21 is
actually fine here, and this is a record item. Now this takes in an
integer parameter as its first parameter. And then the second
parameter is going to be a mode sounds dot bar, brawl. You can see the first
integer parameter is the comparator value. Basically, well, what it outputs when the strength of the signal it outputs when you
put a comparator next to the jukebox when you
put this record in. Now this is a normal
item, however, it has one specialty,
so to speak. And that is going to be, well, when it comes to the
translation that we need for the translation
is a following thing. And that is going
to be exactly this. So Barbaro music disk accesses
the name of it, right? And then we also need that
DESC so for description. And this usually contains with whichever artists basically made this and then the
name of the song. I've also included CC Zero to basically signify this
is under public domain, so you are free to use this. I just highly recommend
always crediting the artist for this because that's just the
right thing to do. But this is also a normal item, so we still need an item model and I'm just going
to copy this over. This is nothing too crazy. It just points to a normal
item texture right here, which is of course
also just going to be a fairly
straightforward thing. So just, let's just
copy this over as well. They go and that is pretty
much all that we need to do. So that is pretty much it to
add the custom record here. So I guess let's just
hear if it works. All right, We farms
as a microwave can see the bar Brahms music, This has been added, so
let's just put it into the jukebox and there it is. And now that what's
very important is that when I fly far away, you can hear it getting wire and quieter until it is no
longer be able to be heard. And if I get closer, is going to get louder again. So this is perfect. And it does is pretty much
exactly what we want. This is one of the reasons, or basically you have to be able to have this
OGG file and mono. Otherwise it will actually be heard on the entire
server when you play this to make sure
that it is in mortal, I have made the same
mistake before. So basically, that is
basically how easy it is to add a custom music
disk, Minecraft, right? That is already for this
lecture right here. I hope you found this
useful in the urine. So the new, if he did our very much appreciate
a review from you. Otherwise, I will see
you in the next lecture. So, yeah.
77. (Intermediate) Custom Block Models in Minecraft with BlockBench: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding a custom 3D block
models to Minecraft. But that's a pretty
exciting thing, right? Adding a custom 3D
block, the Minecraft, basically that's
not entire block, but just a different
shape basically. And there are a lot of
moving parts to this. So first of all, what you're going to need
is you're going to need a program called block bench. Now, I already have this
open and I also already have our custom block
prepared right here. And you can see it is, you know, it's definitely custom like you can definitely
say that about it. And the general
idea is that, well, we're going to export
this as just a block. So what you can do is basically when you make a new file here, you can just make a Java
blocks dash item model. You can even specify
the texture size, just a new name, and they can do stuff with it. Now this is not going
to be a lecture on block bench itself. If there is a lot of
interests for it, I might add one here as well, but for the time being,
it's not going to be one. Basically, you could
just add cubes here. You can move them around, right? Basically building Minecraft. Well, just not in
Minecraft, so to speak. You can just build
something out of blocks and then
we'll add that as a custom block and will
be you're gonna do however is we're going to
basically discard this. We don't need that anymore. This right here, what we're gonna do is
we're going to go to File Export and then Export
block sludge item model. And this will prompt us
to basically export this. We're going to save this. So I already have that saved, but
that's going to be fine. And this is going to be
saved in a JSON file. Now I will open this JSON file
right here in intelligent. And you can see it looks
kind of like this. So this is a lot of softness that moves
us kind of confusing. I'm not sure what this means. Well, the elements here
that list basically just defines the 3D objects that
are inside of our block. And then here the
texture that is like the most important thing is
basically defined right here. Now, we do need to change this. Usually this is the case, so MC course colon and then I'm going
to actually put this under Machines slash
bought a blaster. And then the same thing goes
for this one right here. And I'm going to then API over the actual texture as well. So let me quickly do the
texture first and then we can talk about what
this JSON file does. Make a new directory
here called machines. Then inside of there
we're going to have the cobalt underscore
blaster dot PNG that you go. And then where does
this JSON file go? Well, this is just a normal. Bmi is not a normal, but it's just a
block model file. That's a block model, Jason. They ago. And there you have it. And that's literally
all that you really need for the custom
block model to work. Now, there are some interesting things that
you can define in here. So for example, you have this
display and here you can, for example, define how
does this look in 3D? How would it look if
a zombie holds it in third person and you can do
first-person respiration, Lester's person
right on the head, which is kinda funny. And then there's on
the ground, you know, maybe that's too big or
that maybe that's too small so you can change
all of that as well. And this is all part of the actual JSON file that
you were exporting here. So you can see this is exactly
right here, that display, this is all defined, so everything working
absolutely great. Now we are going to need
a item model as well. Now this of course just refers back to the block model here. We're just going to
say cobalt blaster, right there and
then here as well. Or plaster they ago. Now this is actually all
already going to work. Now, we also need a custom
blocks States, Grayson. Now, once again,
just going to choose the block one and we're
going to copy this over. And this is just
going to point to the JSON file that we've just made that we've
exported here. We are definitely going to
take a look at this one in just a moment again, because what we
have to definitely change maybe one or
two things there. But for the time being,
what we're gonna do is we're gonna make a new block. We're going to
register a new block. We're gonna take the
pink rose here because the others have the
blocks register. We want to of course
make a item as well. So this is going to be the
cobalt underscore blaster. Then here as well, Walt
underscore blaster. This is for the
time being gonna be a normal block because you could do this
with a normal block no, or is whatsoever. And this is not going
to copy anything. This is going to be above. And then let's say something
like material, metal. And that is actually for the time being, all that we need. Now we'll see two very apparent
limitations with this. We are basically going in game, but for the time being, this
is pretty much what we need. Now what we also
do need, however, is the actual render layer here. So let's set this
immediately for the cobol blaster that you go, and that should be fine. Now, we're still going to see a couple of
limitations with this. But then luckily, we're also going to see
how to fix them. So for the first time in this lecture, Let's
see if it works. Or I find ourselves
in microRNAs can see the cobol blaster
has been added. We didn't add the translation, but that's of course
something to easily fix. Now if I set it down,
you can see that, well, first of all, we're
going to have an issue with the see-through. So that is something
that we can easily fix your and then you will also
find that we're first of all, I set it down, but it always
looks in the same direction. So that's kind of annoying. And then also the
borders here are, well, not quite what
they should be. Now, they're definitely
not what they should be. So that is definitely
something to take a look at. Well, luckily, we can fix actually all three
of those issues. So let's tackle them one by one. The first and easiest
is of course, because the see-through, well, we just need the
no occlusion right here on the block properties,
block behavior properties. And if that is
cool, then that is going to be fixed immediately. Now onto the other two. Well, to get the
rotation correct, we're actually going to need a customer block us for this. So we're going to make a
custom block class called the cobalt last block. And this is going to extend the a normal block
class at the moment. We're going to just create
constructor matching Super If the properties here no, you click on it, Shift F6, and then
change it to properties. And we're going to need
a custom property. Now this is not necessarily
a custom property, is going to be a properties
of this is going to be a public static final
direction property or facing, which is equal to block
state properties. That horizontal facing
as very important here. And then we're gonna
do is we're going to basically register
the default one here. So this stumped GetState
definition dot, dot. A value of facing is going
to be direction that North. So they go, this is going to be the default direction
that it's going to face. And then we want
three methods which I will actually four methods
which I will copy over. Nothing too crazy here. So you will see, of
course, first of all, decreed block state
definition method, where we've seen
this previously, we just add the phasing
property to the builder. This should be
nothing new to you. Now, those three are definitely
knew and that's actually also added the override to both of those just
so we have them. Though, the good state for placement will basically just once again makes sure that well, the particular
placement is correct. And in this case,
we're actually want the opposite placement
of the way I'm looking. I'm looking north. I want the block
to be facing me. So it has to be looking south. So that's the general idea
of what this all does. And then these basically
just rotated and mirrored to be well in
the correct facing. Now that as actually
all that we need in this class right here for
the time being at least. And in our more blocks class, make sure that you
now of course created the new cobalt blast or block right here and no longer just a normal block.
That's very important. That's sometimes what people miss when they make
a new block class. You know that it doesn't work as well if you
haven't created it. So that is a very
important indeed. Of course, we also need to
change our, our block States. Jason here and I have
prepared this already. Now this is nothing too crazy. What this basically just does
is it basically just says, hey, if we're facing in
a different direction, we're just going to rotate
it in on the y axis by 9080 or 270 degrees. But this is pretty much
all that this does really, the model is still
gonna be the same. We're just going to rotate
the entire block basically. This of course, also
all available to you in the GitHub repository or an
individual just as well. And this should now have
fixed the rotating issue. And of course also
the, you know, basically the see-through
issue though, for a second time, this
lecture, let's see if it works. All right, So first of all, you can see once again, the actual well
see-through is gone. And then if I place it down
like this, there you go. It now faces me, just like we would expect. So it's just the bounding
box that is now the issue. And well, as luck would have it or I guess as luck
would not have it. This is also the, wouldn't necessarily say
the most complex thing, but it can get very annoying. But let's see, Just so
that I don't forget it, I'm actually going to add the
translation here right now, cobol 100 score blaster. Because otherwise, I'm
actually going to forget this. So there you go, cobol blaster, and that should be fine. Now we're going to need to adjust the cobol blast
roadblock one more time. The class you're, but what
we actually going to need is we're going to need stuff
from block bench once again. So let's reopen block punchier. And what you see is that I have all my cubes under the
group called voxel shapes. Now this is very important. I actually need this under
the voxel shapes group. Otherwise it will not
work very important here. Next thing, what I need is
I need a specific plugin to a 100 plugins you can go under available and you want to
search for more utils. Now, I already have
this installed. It looks like this from
JDK 22 and the weather. Now, this is very
important because you can see exploiting voxel shapes. This is exactly what I
want to export here. We want to go to
the voxel shape. I want to select this so that everything
here is selected. Go to File Export, and then you can see
export voxel shape. Now I want to export
this as a MOOC mapping. So official Mappings
here in this case. And then I wanna say confirm. Now I want to call this the
voxel shape underscore n. Now you might be like,
Wait, why is it n? Well, we're going to
have to export this for every different
orientations. So we're going to have to
rotate this by 90 degrees. Exported again,
rotate by 90 degrees, export again, rotate
by 90 degrees, export again. And
then we're done. We need four different
voxels, shapes. I have yet to find a
better way to do this. If you find a better way to
do this, please do tell me. I really want to know because at this point it is
become very well, it is very annoying because
we're going to have to do this multiple times. But I will show you how the Firefox is going
to be a Java file. And you can basically, you're going to have this year. Now the first thing
that you will do is you will basically
clean this up. So if you have these
zeros are users or to just round them up or round down to basically
the nearest integer. This year is basically a zero-point and then
followed by 14 zeros. And then a three is like okay, that's going to
be a 0 of course. So we basically want to
clean this up so that it looks nice and tidy that it only has introduced in here. And then we can
basically use it. And what we're gonna do
is inside of the class are basically going to
make a new private static. Private static
final voxel shape, hold shape underscore n, which is equal to exactly
all of this jazz right here. We're going to copy this and
Control V to paste it in. I'm going to import
the voxel shape. We're going to
import the stream. Import the voxel shapes. Actually this is just shapes. There you go. There's shapes. And then the eye Boolean
functions also different. This is actually the
Boolean up they ago. Now this is going to work.
So the actual mappings probably not updated yet, quite for block bench, but that's fine because
this is basically what we need here and
well, this is great, but now we only
have the shape for the north-facing direction
because of course the shape would be different if they block was facing
a different direction. But we have to do is we have to basically once again
select the voxel shapes. Very important is
that the pivot point where you can center it, but you can see that now
it's not quite centered, like it is centered, but then it has this
weird decimal values. Make sure that this
is like set on a point that is Also integers. Because if it's not, then you're going to
run into some issues. And what we're gonna do is
we're going to rotate this by 90 degrees, right this way. And now you'll see that that actually doesn't quite align. Now that's fine. What you have to do
is you have to use these arrows to move it. And then you can
basically recentered. Now this is not going
to be at C. Now, what happened here is that
basically I accidentally went into the number and then it's just going to
move every cube. This is something that's very strange and has to
do with block bench. I am just absolutely not sure you can see if
I use the arrows, then it's going to be fine that it basically moves them
as a group together. If I change the numbers
in there and it's actually going to somehow
move them individually. I'm just not a 100 percent
sure why this is the case. This is just the craziness
with block bench. Sadly, there really isn't any other program at the moment that I'm familiar with that, you know, does this
do quite as well? So we're just going to
have to stick with this. And then you can see, well, we've now rotated this and now the block is facing to the west. So now we have to once
again exported voxel shape. And then this is
the Vox underscore W. And this is very
important, right? Make sure that you export it under the rug,
correct name, right. I've seen a lot of people. It's like it doesn't work well, if you've confused
East with West, can happen under the diamond is northeast, southwest, right? So make sure that
follow that unless actually just rotate
it again here. And you can see we have
to move it once more, making sure that we
use those arrows here. And it's actually in the
different direction. There you go. And then this would be South. So this is export a voxel
shape underscore S. And then one more time luckily. And then we're basically
already done here. So this way one and then this
way, nope, I once again, I accidentally clicked
into the actual number, make sure that you do not. If you do, you can just
press Control Z to basically go back step.
No worries there. And then we're going
to export this again, export voxel shape box or shape underscore E This time or east. And then just to have it back, the original
position right here, 0, and then this
is going to be 13. Actually. There you go. I'm going to save this one
more time just so that I have this back at this position so that it's also available to you. And I now have the four
Java files as well. So let's just get
them over here. There you go. So once again, let's get those sort of imperfections
out of there. You know, those just
sometimes happen because floating point errors, it just is what it is. But this is not too bad. It's just basically
just removing all of these loading point
rounding errors. And then we're going
to be totally fine. So this is going
to be a 0 again. Let me 14 right here
and 13 right here. Save this, save this, and then we're going
to continue with E. But what I'm gonna do
is I'm just going to copy this or times and I'm going to have
sheep E, S, shape w. And then of course,
making sure that we elect the correct ones basically
to work up over there. So this was E, is E and then we're just going
to change this to shapes. And then this two
Boolean up a year ago. And this is going to be S, and this is going to be S as well. That's great. Once again, this is just
shapes and then boolean up. I'm just going to copy this
over a control C control V. And then last but not least, the west facing of voxel shape. Once again, Boolean
up, Boolean day ago. If you're planning on having a lot of blocks with a lot of complex walk-through shapes or may maybe this is going to
be a determined from it. I highly recommended to
not go crazy with it. And if you have like
insane like crazy detailed voxel shapes to not build them on like completely. Usually like this is
only just blocks, right? This is just normal blocks. If you had something
like all of a sudden and then you
rotate it like this, but all of a sudden this
is no longer a real block. I'm like it's not
a straight block. If you have a lot of those
different block states that followed the
block perfectly, what can happen is that, well, it can basically just down the game quite significantly
because of course, the voxel shapes
basically determined the collision with the
player and entities. And that actually takes a lot of processing
power and stuff. So I highly recommend
not going with UW crazy voxel shapes
just in case, right? So this is just should be fine. But I just wanted to basically
caution against this. And what I'm actually
going to basically then what we're gonna
do here is we're going to override it the good
shape method right here. And I'm actually going to
copy all the contents. This is nothing too crazy. It's just a switch
statement you can see that gets the value of
the facing property. And if it's south and we're going to return the shape South, north and we're going to return
the shape north of them, Southwestern, West,
Eastern, East. Nothing too crazy here should
be fairly self-explanatory. And that is pretty much
all that we need to do. Now you've seen that this
is quite complicated. Like I said, if
you have a lot of different blogs with adult
different voxels shapes, well, it just is what it is. If you actually do have
a better way to do this, please do tell me
in the Q&A stuff, I'm very I'm very much open to having a different
possibility of adding those. Now if we were to
change something, yes, we would need to export all
of the voxel shapes again. So it is, it can be
kind of tedious, but whatever the case may be, we have now finally done it. So the last time this lecture, let's see if it works
or if, for instance, back in Minecraft and
let's sit it down and they ago the voxel
shapes works perfectly. Let's just see, it
should work perfectly in every different direction
they go is also one of the important things
why you should definitely basically remove the imperfections because
otherwise it could just be off by just the
tiniest, tiniest bit. And that is really annoying. And also it actually
is probably going to be like better if
it's an integer, even though I believe
that it does get converted back to a float
anyway, but, you know, it's just, it makes the general calculations
a little bit faster. But yeah, that's pretty
much how you can add a custom 3D model Minecraft. One more thing I'm just
going to remove here is the parent right here because we actually don't have a blue, don't need that
parents really though. We're just going to remove that. They are. So that
should be fine as well. But otherwise, this is pretty
much how you can add it. Overall. It is, well, it can
be very complex, especially if you have
those crazy voxel shapes, but otherwise, it is a pretty
straightforward thing. All things considered,
depending on how many different custom
3D block models you want. But now you are equipped with the knowledge to basically,
we'll add those. So I hope you found this useful and you learn
something new. And I'll see you in the
next lecture, though. Yeah.
78. (Intermediate) Custom Item Models with BlockBench: All right, welcome back to
the forge course for 118. And in this lecture
we're going to be adding a custom item model, Minecraft. Last time we've seen
a custom block model. Now it's on to the item model. So first of all, we're
going to create a new item here and a copy over the
data tablet once more. And this is going to be the
cobalt underscore staff. And then for the name
of course as well, cobalt underscore staff. And this is going to be
normal item in this case. And then stacks to one
is actually going to be totally fine in this case. And let's immediately
add the translation. Otherwise, I will
forget it again. So this of course,
now we want to death. And then all staff right here. And once again we open
look bench right here to see the really cool
cobalt staff right here. And you can see I've just
prepared this already with some old vanilla extras as well as one custom texture as well. And I highly recommend going to display right here
to basically see how it is going to look inside
of the hand of the player. Third-person right,
third-person left. We have the first-person, First-person left, no head. That really doesn't
make any sense at all how it looks on the ground, actually really like this. And then the frame also
is really cool in the UI. Also really nice. So you can definitely
change this up and do, would it like whatever
display you wanted to? I highly recommend
playing around with this. And once you're happy
with your custom item, you basically go to
File Export block. Either model will export
it as a JSON file. And after replacing because
I already have one. And then we're going to
copy that file over. And then we're going to
copy that file over into the models item folder
right here for both staff. And there's a few things
that we need to do. So you can see that
the textures here come without namespaces,
so we need to add this. So Minecraft all and block lash. And then do the same for
here, here and here. Then we can just put the same in there for the cobol block, but this needs to be, of course, MC horse, that's
very important here. Otherwise, that's it. If you have all of the
relevant textures here, it pretty much is
exactly what you need. You just need this as an item
model and you don't need any other item model
for it at all. So that's I mean, that's
pretty much already. It's we I mean, I guess let's just see if it works over finances
back in Minecraft, as you can see, the cold
staff has been added to the game and it looks
frequent, amazing. So you can basically
switch it around here. And it looks great in
first-person and third-person. I especially like
the gold queue, basically like the entire block that's there in tiny form. I don't know. I really like
the look of it, so yeah, that's pretty much
how easy it is to add a custom item model
to Minecraft, right? Once again, the making of
the model of course is, well what is difficult? You just have to play around with block venture little bit. You will get used to
this fairly well fast. I feel like this is a very easy program to
get a hold off and yeah, rubber that would
already be it for this lecture right here. I hope you found this useful and you learned
something new. I'll see you in the
next lecture. So, yeah.
79. (Intermediate) Custom Bows: Or I will come back to the
forage course for 118. In this lecture,
we're going to be adding a custom Botha Minecraft. So a customer was actually
fairly straightforward. Let's go into our
more items class and let's just copy over
the cobalt staff. And this is going to be
the old underscore bow. And then the same thing here
and the name cobalt bow. And then this is
going to be a 0 item. Now unserved stacks 2, 1, 0 gonna do is we're
going to actually sit the durability to,
let's say 500. There's going to be
a little bit better than the normal bow. And for the customer, we actually need to set the
custom item properties again. So in our item properties class, We're gonna make a
private static void call, make all method that
takes in an item, item parameter right here. So let's work the item class
as well and ensure that we choose net Minecraft
world item, item. And then we're going to
middle mouse button click on the item properties
class right here. You basically go in
and we're going to choose basically these two, well calls the register, the bow and the register with the bot basically when
a Cabibbo for them. So select and press control C to copy control V to paste in. And we just need item properties dot add in front of
the register here. And then we're going to
change the items that bow to the item that
is the parameter here. Then here, there you go. And now we can basically
make as many as we want. We just call make bow with more items for what
bowl that gets. And then if you have
multiple balls, you just call this
multiple times. And then they will, we'll add the specific
item properties all and pulling to this item. And for that we basically
need a specific, well, specific item models. Let's first of all
at the translation right here, just so
that we have it. Well, underscore bow and
cobalt bow here as well. And then when it comes
to the item models, our copy those over everything here is of
course available to you in the GitHub repository or
an individual just as well. You can see we actually
need four of them. So the cobalt bowl, we've seen this before
with item properties are this is the default model
that it takes, right? So it's just this
actual texture here. And then if overrides
basically if pulling as one. So if we're pulling currently, then we're starting
to get this model. So pulling 0, then if the pole
is around 65 percent done, then we'll switch
to pulling one. And if it's 90 percent
done and we're going to switch to willing to. And yeah, that's, I mean, that's pretty much
the general idea. One interesting thing here is
that in the polling one's, the parent is actually going
to be the cobalt bot itself. So you can see MCQs item
cobalt bot is the parent. And then it just points to
a different textures again. But that's really
all there is to it. Nothing too crazy. So we can now also add
the textures here. That's going to be
four of them as well. They ago, and that is actually all that we really need to do. The big thing is once again, the actual adding of
the item properties. Now because we've already seen
this with the data tablet, this shouldn't be too crazy or too confusing
to you hopefully. And that's pretty much
all that we really need to do to add a custom role. Oh, let's see if it works. Or phronesis back
and microlensing. See the bot has been
successfully added to the game. And as you can see,
if I shoot it, then the texture changes as well for everything
working perfectly, right, That's actually
how easy it can be to add a custom
board to Minecraft. And this already it for
this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
80. (Intermediate) Custom Commands: All right, welcome back
the fourth course for 118. And in this lecture,
we're going to be adding custom commands
to Minecraft. Write custom commands, or a very interesting thing indeed. Now we will start
to, as we go along. So this is one of the
lectures where we start to copy over the code. Though once again, everything
in the code is available in the GitHub repository and
an individual just as well. So no worries there, you should be able to
find that. No worries. So in our MC course package, right-click new package
called the command. And then we're going
to immediately create another one called event. And we're going to take
a look at the event one in just a moment. First of all, we're gonna
take a look at the Command 1, and we're going to
copy over two classes. I'm actually going to copy over the classes in their entirety. So this is the set home command and the return home command, and I will explain. So it command basically is
created with this dispatcher. So we're doing
dispatcher dot register and then we have some
Commander literals. What does this mean home set, what are we doing here
and then executes? Well, this means that
basically what we need to put into the console
is slash home set. Then the command gets executed. So this is the actual
command, 0 then set. That's the general idea. If we took a look
at Homer churn, we can see its home then return. So for home, set, its home said, her home
return is Homer turn. This shouldn't be too crazy. This should be fairly
straightforward. Indeed, build your
own custom commands is a very complex thing. So I would say that
this is something where if you have a very particular thing that you wanna do with your command, you're going to have to trial and error a
lot through this. What I highly recommend this
commands class right here, middle mouse button click on
this and you will see all of the vanilla commands that
are available to you. So this is the best
resource really, to see what the types
of commands there are. And I highly recommend
taking a look at those. And I will tell you beforehand, they are going to be
really complicated, right? Even something like
the kill command, that's like probably one of the easiest ones
to take a look at. But then if you go into something
like the glute command, I mean, look at this, right? Like this is, this is so many
things that are in here. And it's so complicated you
can see even here, right? This is by the way, the
actual registration of the command dispatcher. So you can see
then, so it's like slash loot and then
okay, what do you do? Having fish tool may
have someone's like, there are so many
different things even though requires here. So you can ask, Hey, this is the person who's trying
to discriminate, have the right level of
permission, don't and so forth. Highly recommend. Take a look
at this in greater detail. If you have something that
you particularly want. In our case, we're just gonna
do is we're going to save some data onto the persistent
data of the player here. Basically, when we're setting the home position,
we're just saying, Hey, this put the three x, y, and z coordinates into a area
into the persistent data. The data is just a compound
tag here on the player. And I'm just gonna put
this under MC course MOD composite. That's
pretty much it. And then we're going to send
a success with set home at a particular position
that we've just set it at. When it comes to the
return home command is a little more complicated, but not really too. We have a has home
pause Boolean, which basically just says, hey is the length of this
getInt array here, not 0. Because if it is
0, then we know, okay, we don't have
a position yet. It is not 0, then we know, okay, we have a home position that
is basically being set. And then we just
teleport the player to that position right here. And basically saying,
Hey player, return home. And here we're sending a failure with no home position
has been set. And that's pretty much all
that we really need to do here for the two commands. You can see that
basically I'm calling this command right here
with the Git source. It takes in a command
source stack. And what's very important
is that it throws a command syntax exception, because you can see get
player or exception. So that's kind of
important here, right? So this is basically all that we need in terms of the commands. Now what we're going to
need is an event class. So we're going to right-click
on the event package that we've created mod events. And we'll actually
talk about events in a tiny bit more detail
in a later lecture. But events is basically
something that you could really create an
entire course around. That's like ten
hours long as well. But we're not gonna go
into too much detail. We're just going to say
above the class add mod, making sure that this
one is selected. And then we're going to
delete the parentheses, that event bus subscriber. And then we want to put in
parentheses with a MOD ID, which is of course
MC course MOD. And then we wanted to methods. I will copy both of them over, but I will also
explain, of course, was very important is that
over them have to be public, static, void, write the name is actually not what matters. What matters is the
parameter here. So this is the register
commands event and this is the player event that clone have to be
public static void, and they have to have the
annotation at subscribe event. This is very important. Do not forget this,
otherwise it will not work. It's very important. The own
commands register method, it'll be fairly
self-explanatory. Your screening a
new at home come out and a new return
home command, and then just registering
it in this event. This event is, by the way, also used in the forge
internal handler. So this should be
right here where the forage commands are
basically being set. You can see this is
the forage command with all of the bunch of stuff. So we can see that it
basically does the TPS, the track entity generate. Dimensions and the
mode list command. Those are some commands that are particular to forge
in that case. And you can also see
the register commands event right here is
very interesting. So first of all, it
says the event is fired on the Minecraft
forge event bus. So I'm going to just very briefly explain what
the hell is going on. Well, we have different events. If I actually click on this event and then press Control H, you can see these are
all of the events that are available
to us in Forge. And we can even expand this and then we're
going to have even more because there's events
that derive from events, that derived from events
and so on and so forth. So you can see this
is a lot of events. This one, what I'm saying
like you could probably make a ten hour course with all
of the events themselves. We're not gonna do that. Like I said, this was just, you know, to keep in mind. And the idea is that some events are fired by Minecraft forge, some events are
fired by event bus. Let's just keep it at
that for the time being. There's nothing too
crazy going on there. We are going to see
one example of this in a later lecture as well. For the time being, we're
just going to say, okay, events pretty crazy, but also pretty cool can
be very interesting. Now what is the
second event here? Well, basically when
a character dies, what we want is we want to
put the persistent data of the player that
has just died and copy it over to the
new player basically. So this is just to make sure
that, well, after death, the data stays there
and stays persistent. That's the general idea here. But otherwise that's
pretty much all that we're doing in this
mode events class. Now we don't need to
call it anywhere with this add more event
bus subscriber here. This is basically already been called an every method that has at subscribe event above
it basically gets in, then gets cold as well. So funnily enough, that
is actually all that we really need to add the
command, like I said, all of the code is
available to you in a GitHub repository and an
individual just as well. Highly recommend
taking a look at it. I highly recommend just
playing around with it, being open to experimentation. And for completion sake, let's receive it works. All right, he finds
us back in Minecraft, so let's just start
typing slash home. And there you go. We're already getting
it suggested. Let's try to return home first of all, which
shouldn't work, right? No home position has been
set. That's totally fine. Now let's sit home. Set on position set
at this location. Let's see, just to make sure, yeah, that sounds about
right, that's pretty good. Now let's go
somewhere else here. And unless say, Ohm, return in, we have
returned home. That's really good. Now let's actually just
dropped from a height high. Let's see. This is going to kill
me and then I'm going to respond and then
I'm going to say, return also works totally fine. And then let's also just get out of this
world, save and quit. And then let's
re-enter the world. And then let's see
if this still works. And it should, of
course, because what we've saved it on
the persistent data and the compound and BTEs for the entities are
basically saved on this. So let's just fly away once more and then say home return. And of course it still works. So all of the cases are basically done and
everything works here. This is pretty cool. That's pretty much how easy
it can be to add a command. Once again, if you have a very
particular thing in mind, you will just have to
play around with this. I will only help in
limited circumstances. So if you, for example, say Hey, I want to command that does
XYZ and just crazy stuff. Probably not just make the
entire command for you. You will just have to try out a bunch of stuff,
play around with it. And I'm sure that you can
manage to get the command working if you really
work at it, right? But that is it for this
lecture right here. I hope you found this useful and you learned something new. I'll see you in
the next lecture. So, yeah.
81. (Intermediate) Spawning Particles: All right, welcome back to
the forage course for 118. And in this lecture we're going to take a
look at how you can spawn custom particles
in the world. So in particular, we're
going to take a look at this for the speedy block, or basically going to
add a particular method. And that is called the animate
tick method right here. And then I'm actually
going to copy over the contents of this. This is going to be fairly self-explanatory in
just a moment though, we basically have a chance. And then we're going to
say, Hey, we just want the random float every time. And there are general
ideas that we have. We have a chance times to spawn particles and every
time it should actually be 65 percent here. So because we're basically
checking whether or not the lower than the next float and a float is going
to be between 01. So that's the general idea. And this is basically how you can spawn
a particle, right? So you need a level
and this needs to be on the client this time
that's very important. And this enemy to tick method is only called on the client. So that's perfect for us. And we just say add particle, the particle type that we
want to add, the position, right, x, y, and z, and then the speed
in x-direction, the speed in y direction, and the speed in
the z direction. And when the particle types, you can see there's
a bunch of stuff in here that you can
basically spawn. In this case, we're just
gonna take the smoke. Actually looks kinda cool and it's going to work
totally fine for us. And you can see I also have the wind speed basically
have, you know, a little bit of
randomness in there as well so that it looks kind of uneven and it's really cool actually is going to look
really freaking awesome. And yeah, that's actually
pretty much how easy it is. So you just need a level and you need to
be on the client. Now, once again, this is not for custom particles in
and of themselves. This is right now
just how you can actually spawn particular
particles somewhere, everywhere where you
have access to a level variable and basically check
that you are on the client, you should be able to spawn
the particles as well. So this is pretty
much how easy it is. So for completion sake,
let's see if it works. All right, we fantasize
in Minecraft, so let's set the SPD block
down and there you go. The smoke is already
rising from it. So it's all working
totally fine. You can see. And of course this is
something you can adjust. You can adjust the speed
that arises at even adjust where it spawns in
relation to the block. In all of that is basically
just able to be changed. And you can of
course also change the type of the particles. But that is pretty
cool nonetheless. All right, and this
is already for this short lecture right here. I hope you found this useful
and learned something new, and I'll see you in the
next lecture. So, yeah.
82. (Intermediate) Custom Advancements: Or I will come back to the
forage course for 118. And in this lecture
we're going to be adding custom advancements
to Minecraft. So adding advancements
happens solely in JSON files. So this in the data folder, in the MC course folder. And I'm just going to copy over my 20 advancements that
have already prepared here. And I will show you a great
resource that you can use to basically well read your own
advancements fairly easily. And you can see so
we have two of them, MC course Jason and
a dowsing rod JSON. Now, the first thing that you'll notice is there is a display. This is just the item or while block in this block
in some case, that is basically being, being displayed as the
icon of this advancement. Now then you have a title, description should
all make sense. You can choose the frame whether or not it
shows at a toast. So this is whether
or not it shows at the top-right corner of the screen whether an
analysis is to chat. And then this one in particular
has a background that is very peculiar
because it actually points to MC cores textures, loc, 0, ball
underscore Block PNG, but to the entire like
folder structure here. And the reason being because this one doesn't have a parent. And if you were advancement
it doesn't have a parent, then it basically creates a new tab in the
advancement window. This is very important if you switch to the dowsing
mode first, second, you can see that parent
here is MC cores, MC cores, and it doesn't
have a background. So that's very peculiar, were very interesting
in this case. So the idea is that this, if you choose a background,
if you don't have a parent, then you need a background
because that's going to be the background of
your tab basically, then the criteria is
really interesting thing. Now we're not going to create any custom criteria because
that's way more complicated. We're just going to use
the inventory change. So basically, as soon as I have at least one cobalt
England in my inventory, this advancement
will be given to me. And then for the
dowsing rod, basically, I just need one dowsing rod and then I will also have
this advancement. That's pretty much all that
there really is to it. So for completion sake, let's just see if it works. Or he finds us back
and Minecraft. So let's just see if I
get myself a cobol ingot. They go MC course mod. And I can also see the
power lies in the cobalts. That's pretty cool. And now I should also be able
to find this right here. We can see MC course
mod as the advancement. So the name of your advancement here is always going to be the first advancement that you have basically without
apparent in C, we also have the background as cobalt blocks your and then you can see the
second one, dowsing rod. If it doesn't work, the
rod doesn't like you. Well, that's at least
what I've been told. And if I just get this
and you can see I'm also getting the dowsing rod
advancement right there. So that's pretty cool. All things considered. And that's actually how easy
it is to basically add them. Well to Minecraft right now, like I mentioned, once again, a great resource here is
Miss old GitHub IO once more for the advancement of generator,
highly recommended. You can basically
take a look at all of the requirements
that there are. We can see you once again,
here are conditions. Then we can basically change
this to different things. Let's just say, for example, we have once again at
the inventory changed. And then you can basically add different conditions to it. You can see player slots, items. There's a bunch of
stuff that you can add. Highly recommend playing
around with this or taking a look at either the
advancement from vanilla. Also possibility going on GitHub and searching for advancement from
different modes. That also works totally fine. But there's a lot of options
for you basically buy, but that is already it for
this lecture right here. I hope you found this
useful and insurance of the new of the JSON files are of course available on
the GitHub repository or an individual just, well, and I'll see you in
the next lecture. So, yeah.
83. (Intermediate) Custom Paintings: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding custom paintings
to Minecraft. For adding custom
painting motifs is actually a fairly
straightforward process. First of all, in the
MC course package, right-click new package
called painting. And inside of there
we're going to create a new class called the
modern paintings class. Now the more paintings class
will have, first of all, a public static, final
deferred register of type, motif or painting
underscore motifs, which is going to be equal
to deferred register that create or add registries, that painting types are my MC course model,
that model ID. And once again, whether
it's 80 third register, there also is a public
static void register method with an eye Event Bus, Event Bus acids perimeter, and then painting motifs that register passing
in the event bus. The register method
is when cold, you're below the model
sounds so more paintings register and then passing in the event bus right
there. That's great. And now we just need to
register the paintings. And that's going to
be done by doing public static final Registry
object of type motif. This is going to
be called plant, and this is equal to painting
motifs, dark register. The name is going to be planned. And the second parameter is
a supplier of new motif. And the parameters
are going to be 16. 16, and I'm going to
explain what those are. So the motif parameters, I can middle mouse
button click and you can see this is the width
and this is the height. So the first parameter
is the width, the second is the height. This is given in
pixels basically, but this is how big
is your painting. And it just for completion sake, we're actually going to
make three paintings here. We're also going to
have the wanderer, going to be the wonder. And this one is
going to be sunset. That's probably my
favorite by the way, but we're going to see
that in just a moment. Every sunset they ago. And this is sunset as well. And this is the one row is 32 high and the
sensitive is 32 wide. Now the question is, well,
where are the paintings were supposed to be enrolled
in our MC course package, insert of the textures folder. We're just going to have a
new folder called a painting. And I'm actually going
to copy this over because the contents
are already in there. That's the plant,
the sunset and the wonder Are those
are all available. However, I will want
you to director attention to the credits because the paintings are also
done by platinum G7. Just make sure that if you are going to use those in
a public repository or whatever is at the
Curtis here as well and follow the license that's basically
all there is to it. Otherwise, you are
basically free to use them. And this is actually
all we need to do, as long as the names right here match with the names of
the actual painting. Pictures right here, the images. That's that's all
there is to it. So I guess let's
see if it works. Or a pharmacist in Minecraft. So let's just sit
at the painting down and let's see,
oh, there we are. This is sunset. I really
like this and that is, I believe the wonder. And let's just see if we
can get planned as well. All right, there we go. We have all three paintings
that we've added. And yeah, that's basically it. You basically add the paintings to the painting
rotation right here. So that's the
general idea, right? That's actually how
easy it is to add custom paintings to Minecraft. And this is already it for
this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. So, yeah.
84. (Intermediate) Global Loot Modifiers: All right, Welcome to the
forge course for 118. And in this lecture, we're going to be taking a look at global Luder modifiers. The first question
that might come up is what our global loot modifiers? Well, they are a way
for us to change, lose tables of, for example, vanilla Lu tables,
add stuff to it, or even in theory, subtract stuff from it. So you could take some
away and add stuff. I highly recommend not going in too deep with
subtracting stuff. Does this might break
mode into compatibility. Your model might not play
well with other mods, and that is usually not
something that you would want. Now what we're going to do
is in our event package, we're going to right-click
new package called glute. And instead of there, all of
our well modifiers will go. Those are basically classes. Now I will copy those
over and I will explain as we go
through the classes. So this is number one
is the dowsing rod in igloo addition modifier and the turnip seeds from
grass addition modifier. Now luckily, the
classes should be almost self-explanatory
to what they're doing. But basically we're going
to add a dowsing rod in igloo structure chest and a turnip seed inside
of the grass. When we break brass, we
have a chance in this case, we actually have a 100
percent chance of adding the turnip seats to the
lute that is being dropped. But what is this whole
ordeal will first of all, both of them look very similar. So the only difference here is currently in the
do apply method. So for our purposes, we're just going to take
a look at the turn of seats from grass
edition modifier. And well, I'll just quickly
explain the general idea. We see that the class extends from the luteal modifier class. Let's just go into it by
middle mouse button clicking. Or you can also press Control, left-click on it to
basically go in there. And you basically
can see we have one particular thing here
that is the do apply method, which is basically
the important one. Luckily, we also have
some nice comments here. We can see applies the modifier
to the generated loot. And then basically you
can add stuff to it. So this is really cool. So the generated lute is
just a list of items tax, this is what would drop
if you would do nothing, and then you return the
modified loot drops. So this is the
really cool thing, but this is why if
we go back here, you can see in the
do apply method, but I add a new item
stack of my edition. So this is the item
that I want to add to this list and then return
the list with my item added, and then my item
is just added to that list of loot that is
literally about to drop. So this is really freaking
cool thing, right? If we just did this, then we would change nothing and no additional
load would be added. If we did this. However, right, then my
addition would be added. Now what we could also do, and I highly recommend
not doing this, a genuinely mean this. Then read it, lute player. And then we can just clear the entire list of things
that we're about to be added and just
drop our own loot. Highly recommend not doing this, especially not overdoing this. Because once again,
you might break your compatibility with
your MOD and other modes. If they rely on specific blocks, dropping specific things, then you might just ruined your chance of your
mom ever getting into a particular more Peck will just be aware of this.
Keep that in mind. Let me have a
serializer class here, which is just basically
a crazy thing. Global loot modifier serializer. Well, we just have a
read and a write method, which basically the
general idea is just that it reads stuff from a JSON file. And you can see what
it basically does is it gets the value from
the item registry. So we're basically going through our will register items
and we're gonna say like, okay, we have a, something in the JSON file is
defined under the addition. We're going to see
that in just a moment. We're going to
say, okay, give me this and then give me
the value of this. So basically just get the
item that is associated with the addition that we've
defined in the JSON file. And then we're just
going to make a new additional modify right here. And we're returning it
for the read method. And the write method is
just the exact opposite, basically just making
the actual JSON file. Now this is not really done, but we still need to do this. So just keep that in mind. And that's basically all that
the additional modifiers, this should almost always be fairly boilerplate
in and of itself. I mean, if you have
20 additions, well, and you're going to have
20 different items here. And you're probably
going to pass in 20 different items into the
constructor, stuff like that. But that is just
normal Java knowledge that shouldn't be too crazy. All things considered. Now when you have this,
then you will also need another class in
the event package. So right-click new
Java class called the mod event bus events. And inside of there,
first of all, I'm going to rename this
to more event bus events. There you go. And then in there, first of all, we're going
to need is at the top, we're going to need
this exact thing. We once again need
the ad model.py event bus subscriber with
Armada DMC course melody. And then now we need to specify the bus to be the multi-bus, very important last
time with the commands, we've seen that, well, or default, this is
basically the forage bus. Now this is the mode
bus will go into the events in a little
bit more detail in a later lecture. But for the time being,
I'm just going to copy over the basic
method that we need. And that is the register
modifier serializers method. The name of the method
really doesn't matter. It's just important
that it is static, public and it has a subscribe
event annotation up here. And then basically
the event here is the register event that ADD register global loot
modifiers, serializers. And here we just say, Hey, just register all
of our serializers. And you can see we register the serializer by setting
the registry name. And this name right
here will then be the name of the adjacent file that it basically reads from. Now where do our JSON files go? We need one for each of the different modifiers
that we have. And then we also
need one for forage, basically that forge knows, okay, which modifiers do we actually have in
our data folder? Forge, click new directory called glute
underscore modifiers. And then I'm actually going
to copy over the JSON file. This is called
Global underscore, underscore modifiers and
adjacent very important. This has to be
written correctly. And then in here we have to
define all of our entries. But you can see MC
cores term seeds from grass and then MC course
dowsing rod and igloo, which is also the same names as it is here with our mod ID. So that's basically
the entries there. And then in our data folder, MC course folder, new directory called loot
underscore modifiers. And I'm going to copy over
the two JSON files again. These are all available
to you, of course, in the GitHub repository at
an individual just as well. You can see they have the name exactly like we've defined here. This would be an adjacent, the adjacent basically end. And you can see there
are some conditions. Now, overall, the lute
modifier files are both, they're interesting
in themselves, right? So you have to define a
particular condition here. But in this case we have a
loot table ID and we'll say the Lu table ID is Minecraft
chests, eagle chest. So basically the igloo chest is currently being
loaded, so to speak. Then we are calling the
igloo chest modifier. And we're then doing
the do apply method, same width for example, of the burner proceeds
from grass right here. So if grasses broken, you can see that this is
a different condition, block say property, and
then we're just checking, hey, whether or not
it, this is a grasp. Ok. And now if a grass
block is basically broken, then we call the
do apply method. Just before we drop
the generated lewd, we add our custom allude to it, our addition that is
read in from right here. And then we return
that with basically, while this one thing that is
really cool is you can see I can also use the context dot getrandom to
basically make sure that, you know, something
doesn't always drop. This. In this case, this is
basically only added 95% of the time, 5% of the time. It actually is not added. So this is also
something pretty cool, but also very basic Java
stuff, basic, right? And that is actually all
that you really need. Sometimes the, I feel
like the, in general, the global modifiers
are a little clunky, I would say like they're not that there's a lot of weirdness. You know, you have
to define them here and you'll have
to define them here. And you have a defined in here and you have to
divide them here. Like there's a lot of
things you have to do. I don't know. It's sometimes
is a little weird, but overall, I am sure
that he will manage. I will also link in the
resources is going to be the global loop modifiers or
the forge Docs right here. So basically, here's a little
bit of a summary as well, which in which you can basically take another look at
how those might work. It can be useful
sometimes, you know, i'll, I'll just link it
basically as well, or fantasies in Minecraft. So let's see if I
break the grass here, it should always
drop a turnip seed. And there we are. Basically, we have a 100
percent chance of adding a turnip seed to the
actual loot table. And just for completion sake, let's also take a
look at the Eagle. All right, in here
we can see there's a dowsing rod in
legal chess as well. That's pretty cool, right? One more thing that
is very important. We also have to add a type in
the JSON files right here, where it gives us a
in addition in 118. Otherwise it will not work. This is just simply
the your namespace, so your MOD ID, and then the name of the
actual file as well. So there shouldn't be
anything crazy right here, right, that will already be it for this lecture right here. I hope you found this useful
and he learns of the new. I'll see you in the
next lecture. So, yeah.
85. (Intermediate) Custom Fluids: All right, Welcome to the
fourth course for 118. And in this lecture
we're going to be taking a look at custom fluids. For custom fluids we have one major restriction or let's say limitation
that there is. And that's going to be
basically that the physics of the fluid that you're going
to make are going to be the same physics as water. And then also not only that, but also you're only going
to have the same articles as water in basically when you
dive in and stuff like that. But that is one limitation
that is currently well, not easy to go around. So beware of this. And also I will copy
over most of the code. Once again, everything
is available to you in the GitHub repository or an
individual just as well. We'll go through however and explain then the
MC course package, right-click new package
called fluid than they are. I will copy over the mode
fluids class in its entirety. We should get a one arrow
right here in the more items, we still need to make a, a honey bucket item. But in make that very easily. So in the more items class now, just going to copy
over the bowl, the honey underscore bucket. And this is of course
a on the under, on the underscore bucket. And then this is a bucket item. And the first parameter
being modeled fluids that an IV fluid. There you go. And that is basically
then what we need. Let's actually immediately added the translation and
stuff like that, just so that we have it, that we don't forget it. So a honey underscore bucket and the bucket they ago and
then an item model, because of course this is
still in normal item though. That does not change anything. So honey bucket, they go just
points to a normal texture. And then we're just going to add the texture
as well, the ego. So that's pretty nice. So now let's take a look
at the fluids again. In the first thing that we have is three resource location. So that is the water
still resource location, the flowing and the overlay. Why are we using those? Right? Why are we using the Manila
water or resource locations? Well, because they are gray and we can basically color them. So we have this dot color
right here in the properties, and this basically enables
us to color our fluid. So that's why we're using
those because they're already gray and they
look totally fine. Have a different register as
well as a register method. As you can see, that this register method of
course has to be called. Let's call this as well. So there's going to
be the mode fluids dot register with the
event bus right here. This is something
that we've seen multiple times now already. And then we have two
different fluids. One of them is a flowing
fluid that source, and the other one is a
forged flowing fluid. That fluid flowing. This is incredibly important. I've seen this multiple
times that people have just copied it over
and forgot to change this. Be aware that one
of them has to be source and one of them
has to be flowing. Very important. Then we need a fourth flowing
fluid properties. This is basically the
properties though, how is this being displayed
and stuff like that. You will see a lot of
the yellow overlays here and it says, hey, we can replace this
with this right here. And then it even says that a, we can even make this easier by just calling it like this. Do not do this. We have to use the
suppliers properly here. Otherwise, it's not going to
load in the proper order. So we do have to
use the suppliers. This is very important. Most of the stuff,
density, luminosity, viscosity, Those are Well, just forge values that are
don't really do anything. Slope, define distance
and level decrease. Those do however do something. But I highly recommend
just playing around with the
numbers once again, when it comes to the color. It's very strange because
instead of going like you would expect for a hex
value to go in RGBA. It actually is a RGB, so that's the color basically. But this should be
fairly straightforward. Just find a color picker online and then you can basically
define the color right here. We also need a liquid
block right here. So I honey block, that is, well, a particular block. In this case, we can see this is a new liquid block and we pass
in the fluid right there. But that's the
general idea here. Nothing too crazy. I sometimes think that the
fluids and forge are Will. There could be a
little easier because there's one more thing
that we need to add. Actually this a couple of
things that we need to add. So in our MC course mod class, in the client setup method, we actually wanted to set
the renderer layer here, and that is going to be
for the model fluids dad, and then basically the block. And that's going to be
translucent. Actually. We want to do the
same thing for the lucid and for the honey flowing, then we're going to
basically make this transparent so that we
can see through it. And this basically enables us to use the Alpha
value right here. So think of it like this. And then we also
need to add a tag. And this tag is encrypt
credibly important to know that it actually
acts like a fluid. So in the Minecraft
data folder, tags, Right-click new
directory called fluids. And inside of there a new
file called Water dot JSON. And now the contents are
going to look like this. We're going to have
the honey underscore fluid and flowing in there. Those are the names
of the world, either the source or the
flowing. That's very important. And then we should
basically be done. And then you have your
custom fluid added to Minecraft and it's going
to be registered properly. So yeah, that's pretty
much all that we need. So let's see for works or if I was asked back
and micro Tennessee, the honey bucket has been added to the game and
let's set it down. There we are, the honey
is also in there. And now you can see that the particles are
normal water particles. And when I go into it, you can see that the sort
of overlay is also blue for this is just two of those limitations
that I mentioned. It is just how it's going to be. Sometimes that is just the
way the cookie crumbles. But still nonetheless, custom fluid has been
added to microbes. So that's pretty
cool and that would already be it for this
lecture right here. I hope you found this useful
and you learn something new. And I'll see you in the
next lecture though. Yeah.
86. (Intermediate) Events Basics: All right, welcome back to
the forage course for 118. In this lecture,
we're going to be taking tentative look at events that we've already seen events in previous lectures. We have the mode
event bus events, and we also have the
motor events class. So if two classes, we've seen the register
commands event, the player clone event, as well as the
registry event for the global alluded
modifier serializers. And I just wanted to give a brief show of what this
actually is like events. So first of all, if we
haven't event or you can also shift twice and
just put in event here. And then include
non-product items. And then we can take
this one right here from net microforms event was EPI. And I can do the following. I can click on this
and press Control H. And I've already
shown you this ones, but we'll show it again. But we can expand all, and these are all of the events that forge
ads that we can basically well hook into and then do stuff when
this event fires. There are really freaking
cool things in here. The first thing I
want to mention is that you shouldn't say, I want to use this
event to do this. That's not how it works. What you should do
is you should say, I want x to happen. I want to be able to take
another break and headed n hidden entity with it
and it should catch fire. Okay, Then you think about it. Well, it can I change stuff in the item class
for the nether brick. Now really that's kind
of hard coded, right? You have to change
the source code of Minecraft,
doesn't really work. Is there an event for
it? I don't know. Like there are like
a damage event, all living damage
event. Look at that. That could be useful. You can, you can double-click
on this and then it usually has a very good
description for the events. We can see living
damage event is fired just before Damages
applied to entity. So this event is
fired every time. Just before a entity, a living hand entity is hurt. This is the thing, right? This event is fired
whenever an entity is damaged in living entity actually hurt or end in
layer actually hurt. Though I highly
suggest taking a look at the events that are
in the class hierarchy right here is it's
actually just incredibly useful to just be familiar
with a few of those events, especially when it
comes to the entities. There are so many
of them you can see Entity events and they can just open them living events
and then look at this. There's player events. There's so many different
player events that you can hook into and
do stuff with it. It's pretty crazy. Well, there's one
interesting thing and that is the well bus classification. So if I middle mouse button
click on this bus right here, you can see there's a forge
bus and there is a MOD bus. Now, the general gist is this. There are some events
that are fired for Forge, in some events that
are fired for a mod. This is the general idea that
you have to think about. Don't over-complicate this. Yes, there's of course,
a lot more to it. You can see that we've
seen this before, where we have, we've
seen this before. Well, this is exactly
right here, right? You can see this is
the MOD event bus, but this is exactly
the idea, right? You have the Mode Event Bus
and the forge event bus. And the more event bus in
this case, for example, is always used for the
different registers here. And you can see here when we
do microforms dot event bus, this is then the
other event bus. So this one is the one
for the forge events. I wouldn't worry
about this too much. Overall, you can usually see
what the events are from. When you, for example,
say the register, event register, if I
middle mouse button, click on this and then go into the registry
when for example, you can see this now implements
the IE mode Bus Event. So I can press
Control H on this and I can actually see all of the
events that are from there. So this should be
basically all of them. In theory, there might be a couple more, but
I don't think so. I think they always
have to implement this. So that is pretty much
all there is to it. So usually you should be able to tell and what we'll just
for the sake of argument, what I will actually copy over is a method this is of course all available to you and that is the set entity on fire when hit. And that is going to be
within another break. But just wanted to show
you here in one example, you can see we're choosing
the living damage event. And this event has a
couple of soft, right? We've already seen this. Well, we have the damaged
source and we also have, for example, we have the amount and also the living entity. So basically all of those
we're getting here, and this is pretty cool because we can basically get
the damage source. We can say, Hey, just give me the direct
source, meaning the player. And then we can also say get the living entity that was hit. And then we're just
setting this on fire. But this is really cool. So this means that we can add additional functionality to, for example, vanilla items. Now once again, don't overdo it. Don't be, don't go
Cu2 crazy, right? Being like an okay. So when I hit something
with another star, the entire world is
going to explode. I mean, would be
pretty cool honestly, but just don't try to shoehorn in events where they don't fit. For example, if
you're saying, oh, so I could replace this
with my custom item. And I said, Yeah, of course,
like you could still say it. You can see mod items. For example, dowsing, rod dot get. And that will also work. Now if I hit something
with a dowsing rod, right, I would set
something on fire. But then I would also be like, Why would you why would
you want to do this? You don't have to do this
in your custom items. You've access to
the source code. I could just go into
the dowsing rod, right? An override a method here. There's the hurt enemy
method for example. And I could just
do it right here, just like we've seen with
the levitation sort, right? So with the levitation
sword, if done, we've overridden the third enemy method and
added an effect. Or you could in theory also
do this right here, right? I could just say, Hey,
let's take the, you know, if this is a
levitation sort item, then bam, Let's go, let's set it on fire
or let's make it levitate the living
entity that was hit. Of course I can do this, but if you have access to
the source code, there's no reason why you
would do it in an event. I hope that I was sort of a general introduction to events. Events can be almost impossible to master because
there are so many of them. And you'll just have to see if for your particular
thing that you wanna do, there's an event
and if there is, great, try it out. Open to experimentation. I can just pretty much what I'm going to say for the
rest of the course, because it is very important to just try
out a bunch of stuff. You always have control Z. This is the great thing
about programming. You can always just go back
and say, You know what? No, this was not a good idea or, oh my god, this
functionality is amazing. I didn't expect this to happen. So that is really cool. But just for completion sake, we're actually seeing, well, does this really work?
Let's see if it does. Or if I'm says a Minecraft, so I have another
break and let's just see if I hit
an entity with it. There you go. They
get turned on fire and one another brick is
being subtracted here. So that is insanely
cool. As you can see. It just works. And
it's, you know, that's, that's how cool and interesting the wall custom events or hooking into events can
basically be right, and that would already be it
for this lecture right here. I hope you found this useful
and he learns of the new, and I'll see you in
the next lecture. So, yeah.
87. (Intermediate) Updating Forge and Parchment Mappings: All right, welcome back to
the forage course for 118. And in this short lecture
we're going to update forge as well as updating
the mappings. So over the course of
some time, you know, new forged versions
will come out. So you can see right here
on the download page, we have 39 and 0.8
at this point, and we're using,
I believe, 39.05. But we're going to check
this in just a moment, but we can update it to the
latest version right here. And then same goes
for parchment. We actually have a completed
version at this point, which is 20, 21, 12, and 19. So that's really cool. What we can do is we
can basically navigate to the build.gradle
file right here. And you can see we're using 0.5. So now we can just put in a 0.8. We don't have to
download anything. Again, it's basically
going to be done for us automatically. And then we can change
this to being the 2021, 12, and 19, and then
the C version here, and then 180, one of course. And then for our
version, I mean, at this point we're
pretty far enol, so that's all this like
0.1.5, That's fine. And then let's save this. And then we can just hit the load Gradle
changes right here, and then we'll just let
this run through for me. It just took three seconds, but but that is
of course because I've already done it and all of the stuffs already
downloaded before. So for you, it will probably
take around a minute or two fumbling that and then everything should
be well upgrade, updated and should be fine. There should be no errors here. What might happen is
if you start the game, you will once again
get a lot of arrows or rather a lot of
warnings saying like, Hey, this doesn't work,
this doesn't work, but no worries at all. Let's just keep this go
through so you can see that everything is working as long
as you aren't getting well, I mean, build failed or
as long as you're not getting microwave doesn't work
at all, it should be fine. And you can see right
here, for example, that microbe is
already starting. And then we should be fine. Here we are. There we go with
microphone 3908, everything working
in Great Britain. That's actually all that
I wanted to show you for this lecture right here. I highly recommend when you
have a new version available. I mean, if you're
watching this in the future, of course you are, then basically
this version right here is probably not going to
be the most up-to-date one. And then this version for Forge is definitely not going to
be the most up-to-date one. This is why I have linked the pages for parchment and the pages for the
download one more time, just so that you can
basically take the ones where the actual versions that
you are going to need, wherever that would be for
this lecture right here, I hope you've found this useful and learned something new. I'll see you in
the next lecture. So, yeah.
88. (Advanced) Custom Block Entity: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be taking a look at a
block. Entities. For block entities in
general are blocks that have a particular
functionality associated with it. So extra data so to speak. And this could, for example, include a GUI and
stuff like that. Now before we jump into
programming something, I actually wanted to, well, basically go through a
little bit of the theory. For that we're
going to break out the well tool that is used most often and
that is of course, our point right here. So let's just start. So the general idea is that
we have couple of things. Number 1 is we have
a block class. Now we've already done this. We have a, well the
cobol blaster for us. Now for us is it's going
to be blue button. Under the blue background. It doesn't look that good, so we have it, read it right here. But the general ideas, we have a block
class and that has a reference to a
blocked entity class. There's block entity
class we're of course going to create
in just a moment. And this contains data and functionality for
a particular block. That's the general idea. In this block entity
class is created. We can have an inventory in it, and that one can
then create a menu. Now the menu class is very interesting because
the menu class, right? You can see it's sort
of separated, right? We have a screen
and a menu class. Now what's very important is the menu class
can, for example, synchronized values
for the entity to a server and client. That is going to
be very important, especially in the next lecture. So I highly recommend
taking a look at this lecture and
the next lecture, sort of at the same time, because we're going to have a functioning block entity at the end of this
lecture over good, We're going to make it about
a billion times better in the next lecture
and just more robust. So that's just something
to keep in mind. In the menu class also has
slots for the inventory. So you can see that this basically visualize
this in a way that we have these purple
rectangles here that are sort of correlating to
the slots right here. And what's very
important is that the menu where those slots are is completely independent
of this image right here. Because what you have
to keep in mind is that when we look at the
screen class, right? This client only, this is
literally only this image. I cannot emphasize this more. Basically this, the screen class is pretty much only this image. So regardless of
what this image is, the slots could be anywhere
where we want them to. So we actually define their position inside
of the menu class. Though instead of this,
you know, the GUI year, I could have a
picture of my face, I could have a
picture of my dog. You could put anything
that you want in there. The functionality
would still work. So that's very, very important. Now it also displays
stuff like the progress. So this progress
arrow right here, or how much fuel is
left in the fuel slot. Basically, that is something
that can be done with the synchronizer values that the menu class basically
synchronizers for us. That's the general
overview of this. And sometimes this can
be a little confusing. I will also say this, Well, block entities are definitely
an advanced topic. So we have reached the
advanced topics at this point. And at this point
is also something like if you don't
know that much Java, right at this point,
it's very good. It's going to be very hard
to help you with anything does I'm basically going
to assume that you know, at least intermediate
knowledge of Java basically. So I'm not going to say, Hey, this is a static method. You know what a static
method is, stuff like that. I'm just going to assume
that you know all of that. So be aware of that. Number one. Number two, I will also
be covering over a lot of the code that is all
available to you, including this cheat sheet
is also available to you in the GitHub repository individualist
and for download. So no worries there. But let's switch over
to intelligent you again and let's see
what we can see. So number 1, what we need
is we need a new class. We need a new package
in R, block package, right-click new
package called entity. This is now the block
entity package. And there we need two classes. One of them is going to be the cobalt blaster Volokh entity. And then the second
one is going to be right-click New JAR class called the mud rock entities. There you go. So those two classes are needed. And for the block
entities, well, we can immediately fill this up with at
least a little bit, and that's going to be
a public static final, the third register. We've seen this
already, of course, block entity type, and then once again angle brackets with
a question mark in it. And then block
underscore entities, which is equal to a
different register that create registries,
dot block entities. Mc course model, that model ID. And then of course, whereas
a register there is a public static void
register method with an event bus or event bus, which cools the block entities that register and passes
in the event bus. And we can immediately
already go into our MC course mod class and just put it in here so
we can say block mode, block entities register with
the event bus they ago. And we'll have to do
this one more time before the lecture is over,
but no worries at all. We're not yet going
to define the actual. Entity because we first of
all need to make this class. I'll believe we can make
this class almost in its entirety except for one thing, but that's
going to be fine. So this is going to do
with the following. This is going to extend the block entity and
implements the menu provider. Let's hover over this,
implement the methods. So this will implement the
get display name method and the Create menu method. So one thing I will do
is I will purposefully, well make this have
an arrow right here, because I don't want to forget to add the Create menu here. That's kind of
important sometimes. I mean, I'm not
that I forget this, but it's just very important
that we actually do this because there are a lot of
moving parts to this in, you know, not doing one of those parts will
basically make it so that the block
entity doesn't work. And here we can just return a new texts component
of four volt last term. So this is just going to be
the display name basically. Then hover over this creed
constructor matching super. And this is also
going to be fine. However, what we're
gonna do here is we're going to delete the first parameter and then
you will of course get a, well, an error right here,
but no worries at all. Because what we can
do is now we can define this in our
mode block entities. And the way that we define this, I will actually
type this out, might not public static
final Registry object. It'll be fairly self-explanatory
of block entity type, this type of type cobalt
blaster book entity. Well, the cobalt blaster, and that's going to be equal
to block entities that register with the name cobalt
underscore blaster, That's going to be fine. And then a supplier of the
following block entity type dot-dot-dot builder
of cobalt blaster block entity colon, colon new. You can see that then a comma, then we have to do blocks, dot, blaster, dot get. Then after the third, after the first parenthesis
duck-billed, and then pass a null. So this is how it roughly
looks like right here. So the blocks that we pass
in here are basically the blocks that are associated
with this book entity. That's the general idea. Then instead of having
the parameter in here, what we can do is we
can say block entities, that block dot cobalt
blaster dot get. Now you might think, well, isn't that a circular reference? It actually isn't. I do. I'm not quite sure like it. It is very crazy. Like there are a lot
of circular things, so to speak, in the
block entities. So no worries. In now we will start
copying stuff over. The first thing that
we'll copy over are basically the two
fields that we have. And those fields are in item stack handler called
item handler of size four. And this is also
an anonymous class you can see because we have to put the contents changed here
where we basically changed. Because otherwise we'll, we're going to have some issues with the loading and saving of
basically the inventory. And then we have a
lazy optional of this, and we need this one
because of the capability. We're going to copy
this one over as well. So this is going to be the
Git capability method. And I'm just going to
put this below here. So they get capability method. You can see it
basically says, Hey, if you know someone or something asks about
this block entity, it doesn't have the item
handler capability, then we're just going to
return the lazy item handler. So right, this one right here. And we're just going to
say, Sure, take this. Now of course, as
you can clearly see, the lazy item handler
at the moment it has not been set.
How do we set it? What we set it in
the onload method. So what we're gonna do is I'm actually going to
copy over the booth the onload and the
invalidate caps method. They could see onload should be fairly
self-explanatory, right? When this block entity loads, we're just going to set
the lazy item handler to a lazy optional of our actual
item handler right here. So that's the general idea. And when we invalidate the caps, so this happens when the server shuts down stuff like that. Then we are just invalidating
the lazy item handlers so that we don't have any resource leaks, stuff like that. Well then the question comes in, how do we save the data? Well, we save the data by doing, by overriding two methods. That is the save additional
and the load method. So you can see that
it basically I'm taking the item handler NMC, realizing that to the NVT. So this basically does all
of the heavy lifting for us. It saves all of the slots. What is in those slots are
many items are in those slots. So that's all done
for us beautifully and we only need those
two methods right here. What is very important
is that we do need, once again, to override this
in the anonymous class. Otherwise, we will have
some issues with saving of the data because the save additional method for whatever
reason is not called. Every time when we just leave the world for whatever reason it's only called on an update. I'm not sure about this, but just make sure
that this is done. And then last but not least, for the non-static methods, I will also have
the drops method. And this one basically just makes a simple
container here, get all of the
items from the item handler and then just says, Hey, just drop all of
your contents at this position on this level. And then we're going to be fine. This is going to be called when we destroy the actual block. So all of the contents
spill out of the, of this actual block, right? So if you, for example,
destroyer chest, and of course all of the
contents of the chest will drop onto the floor. And that's of course
what we also want in our rocket right in before we
continue to do stuff here, we're actually going
to switch over to the cobalt glass or block, because now the block
will be changed as well. And this is going to
be very interesting because instead
of extending from the block class is this is
going to be extending from the base entity
block are important. And then you can see that
immediately you have to implement the new
block entity method. That's of course
no worries at all, because we can just
implement this. And this is going to be
very easy for us because what we can do is instead
of returning null, we're going to return a new
cobalt blaster block entity and passing in the EPA has
and the p state right here. And that is pretty much all
that we need to do for this. Now, there are a couple of more things that we
need to do, right? You can of course see
most of the stuff is for the actual
shape of the block. But what you then
have is we need to, and this is incredibly
important, right? We have to override the getter render shape method right here. And we have to return
render shape a model. Because if we don't do this, then our model is going to
be invisible because that's just the default of
the base entity block. You're I'm not sure why
that is the case of this. Probably going to be
some reason for it. So please make sure
that you override this. Otherwise your block
will be invisible. And that is of course
not quite what we want in that I'm going to override to other methods and I'm actually going
to copy those over. This is going to be
the onRemove method. This is exactly what I said, right when we call the
drops method right here. Well, this just makes sure, hey, when we remove this block, all of the contents of the block entity will
drop onto the floor. But this is great and this is just a really nice method
and not too crazy as well. And the US method well is kinda similar in the sense that when
we right-click this lock, we simply want the
actual entity to open its inventory or to open
its GUI basically, right? You can see here network
hooks that open Gui. So we basically
just want to open the GUI and making sure that, you know, it's sort
of synchronized via the server and the client. That's why the network
hooks basically does all the heavy
lifting there for us. There's one more
thing that we want, and that is we want
the ticker method or we want a tick method to be able to be accessed in the cobalt blaster block entity. And a tick method will basically
is just a method that is called every tick for a particular block
entity in this case. And that will allow us to add
cool functionality to it. And we'll basically custom
crafting, so to speak. And for that we need to override the getter
ticker method. I will copy this over again and we will get one
simple error here, but we can fix that very easily. We can see that this is
basically the, well, I get ticker method
and we then call the create ticker helper and return to that with
the rock entity type, we are going to pass in the
global blaster block mode, block entity year. And then here we can see we want to pass in the cobol blaster block
entity tick method, which is not yet created. But we are going to
create this right now. So those are going to be all
of these static methods. Those are four methods. I'm just going to copy
them over so we can see what is going
on here, right? This is craziness, No worries. We're gonna go through this. So the tick method is the one
method that is not custom. So these three methods
are completely custom. I made them myself. The tick method it's
in itself is going to be the same for
every block entity. You always going to have access to the level of the position, the state, and the
block entity itself. And you can see I've just
made some helper methods, basically crafting the
item will just crash. The items are going to
extract an item from 0. We're going to extract
it from Slot 1. And then we're just
going to set a, an item in the slot three. So you can see that
we're going to put in cobalt ingots here too. We're just going to
continuously do this. Of course, the craft item
method is only called when we both have a recipe and we have not reached
the stack limit. Let's take a look
at the stack limit because that's a
little bit easier. We'll basically
just saying, hey, if the count of the
actual stacks here is smaller than the
GetMax stack size, we're going to be fine. So as long as we
have not reached 64 items in the output slot, we can continuously craft items that should be
fairly self-explanatory. The has recipe method. Well, that just checks that
we have in the 0 slot called slivers and that we have in the first slot or the
slope with index one, we have raw cobalt. If we have both of
those in there, then this is true. This hopefully will be true and then we'll be
crafting the item. I will say this, this is a
very crude way of doing this. This is really only to show you one time how will the actual crafting and
stuff like this works? I highly recommend you can implement this and you can take a look at this
and you can say, well, this is really
freaking cool and it is but highly recommend. Next lecture, we're going to
make a custom recipe, Jason. And then we can basically, well define the crafting
recipes inside of JSON files, which is way better than
hard-coding them like this. Definitely not a good
idea to do this, right? This is just a very bad idea. It's very clunky, it's not good, it's, it's hard coded. Many things can go wrong. So I highly recommend,
while this is just for show one time here, it is a very crude way of doing things and just wanted
to make that clear. Now the thing is that this is pretty much done except for, of course, the Create
menu method right here. And same with the block. The block is also done so
we can close the block, we can even closer this one. We're going to keep the
block entity class open for a little bit because of course now we need to add
at the screen. So in our MC course package. Right-click new
package called screen. And inside of there we're
going to make two new, actually three new classes,
cobalt, pilaster menu. And then we're going to make
the wall pilaster screen. And we're going to
make the mode menu types class as well. And then any screen package, we also need another
package called slot. And instead of there, I'm
actually going to copy over to last star made is going to be the mode you will slot
and the mode result slot. I'll explain those in a moment when we are actually
going to use them. But I highly recommend
also copying them over. All of this is of course
available to you once again, GitHub repository and an
individual just as well. No worries there, right, we're going to
start with the menu or cobalt blaster menu. And I'm going to, this
is going to extend the abstract container menu. Very important. There you go. I'm going to
implement the methods still valid right here. And then we'll also create a
constructor matching super. Now what I will do is
I will actually just copy over the entirety of
the contents of this class. Highly recommend
you doing the same. And we will explain
as we go along. So we will have one
arrow right here. We will be able to fix that in just a moment, no
worries at all. So you can see that we have two different constructors here, which is actually very
important because one of the constructors
will be called in the mod menus and the other constructor will be
called in the block entity. Now we can actually
immediately do this. So let's switch over
to the blog entity. And then here in the
Create menu method, we're going to create a
new or bolt plaster menu when a passing the
container ID inventory. And then the last one is this. There you go. And that is pretty much all
that we need to pass in. But now the block
entity class is completely done and
we're done with this. Now let's take another
look at the menu here. So the menu, like
I've previously mentioned in the cheat
sheet in the theory, basically, This is responsible for the slots where they are, where they're laid
out, stuff like that. And you can see this right here. So we can have, we basically
add the inventory, we add the player hot bar. So those are just
two methods that I've quickly created
because this right here. So the for loops are usually like inside of
the actual constructor. That's just, I mean,
it's just seems to me to be a very bad is not that
well coded basically. Then there's another thing that's very
interesting and that's the quick move stack right here. This method is done by DZ 07, 08 credit goes to
them for making this. I basically want to say this, this is for shift clicking stuff inside of this inventory. Do not worry about this method
at all. Don't look at it. Just say thank you
so much for the for the 07 that they may
this is actually insane. I just the method we could go through spent a half an
hour to explain this. It's just not necessary. I really don't like this method, but of course it needs
to be done somehow. And this is just how
it's going to be. The static fields also
have to be there. That's very important.
And here in the TE, inventory slot count,
we basically have to put the actual
slot count over. Well, t0 inventory an archives
now it's a B inventory. So before it was
named tile entity, now it's named block entity. But everything here still
should work totally fine. And you can see we are adding
four slots as you can see. So we're basically asking, Hey, do we have item
handler capability? And if that is the
case, then let's add some cool slots here. You can see I have a fuel
slot in a result slot. I've made those
classes because well, I mean that just
makes lot of sense. Basically, have a slot where
you can only insert fuel and then ABR results
slot where you can actually not not
insert anything. Basically, only the machine itself can insert stuff into it. And I've basically taken
those from the actual slots. So you can type in, they can put in shift twice
and then put in slot. And then if I do this, then you will be able to see the slop net Minecraft
world inventory. And if I press Control H, you can see all of
the different well, slots that are available
here, for example. And then basically we have the furnace results
slot, as you can see. Let's just take a
look at this one. And well, I mean, I basically taken most of the stuff here are the
results lot, right? What is very important? It's just this May 1
place has to be false. And then same for the fuel slot. We basically just, well to
ask the abstract furnace, Hey, is this stack a fuel? And if it is, then we're
just going to say, sure, you you're about
to place it in there. Pretty much all that
there was to it. I mean, that's some
there is to it. This these two slots highly
recommend using them because they're just a little
bit nicer to basically use. But apart from that, I believe that most
of the rest is, well, not too crazy. We just have a reference
to the block entity, a reference to the level. The still valid method
basically just checks whether or not the player
can access this menu. So this would be if you
are in a mine cart, you right-click a furnace or something like that
and you were too far away and all of a sudden
the actual GUI closes. I believe that this is what
basically facilitates that. And so let's go into the
more menus class now, and let's add our
stuff there as well. I will actually now copy this over because we've seen
this plenty of times. This is a deferred
register of menu type, once again of question mark. And then when we
define the menu type, we need a register
menu type method here that just has a container
factory of type T here. And we're just basically
registering this. Normally, this
wouldn't be too crazy. All things considered
highly recommend. Once again, everything
of course available, you don't have to type
this out yourself. Github repository and
individual just as well. Now in the MC course
mod constructor, we're going to call
the modern menu types dot register with the event bus. And then everything here
is registered as well. That is great. And then we basically
don't have to look at this one ever again, at least for the time being. Now this one is also
done no more errors. So everything is great. Now one thing that people
might ask is, well, what does this exposition, what is this y position here? Well, for that, I am
actually going to copy over the texture that we're going
to use in just a moment. This is going to go in assets, MC coarse textures,
and then under Gui. So I'm going to copy this over. We end. This is the cobol blasted
GUI and I will open this. We've seen this of
course already. A general idea is that,
well, 850, right? So we 18 and 50. Why this pixel
right here is 0000. If we go 18 to the right, right, x 18, so 18 to the
right and 50 down, we end up exactly here. So this is the general idea. You will have to
count this in pixels. Though if you use Photoshop
or paint.net or GIMP, then you will usually have a Select tool that you can use. And then you can
basically select this and see how big this is. You will have to count it in
pixels is just no other way. It is sometimes a
little bit clunky, but that is just how
it's going to be. And the rest of it should
be fairly self-explanatory. But the rest is your 66
and then down 16 than other one is 50 down and 66
x and so on and so forth. So that is basically how
this is laid out, right? And then let's make the
screen last but not least. And once again, yes, we'll actually copy this over. Now. This is actually the, I think the one that is, well the least complicated. This is the abstract
container stream of type, old Glassdoor menu. So that's very
important that you put the correct class in here, the cobalt master menu, because then we'll
have access to this in this class as well. So that's very important. You can see I have the
resource location of the texture under
textures GUI cobalt, underscore blaster,
underscore GUI PNG, the thing that we've
just seen before. And this year, as you can see, is basically
rendered right here. And then we use
this doublet method under this method can
be very complicated. And we'll actually go into detail more about this method in the next lecture
when we're adding the progress bars and stuff, is then we actually
have to think about, okay, how would we setting
this up, right? What is the x? What is the why? What
is the offset here? What is the width of that? We're going to figure
this out next lecture. Like I said, for the time being, this here just makes sure
that the entire image, so all of this, right, without the stuff
to the right here, is basically displayed
in the player. Now what we still need to do
in the MC course mod class, also very important and
declined setup method, menu screens, dot register mode, menu types that cobol
blaster, menu dot get. Then a cobalt blaster
screen colon, colon new. Now this should throw
no errors because the cold plasma screen is of type cobalt
blaster menu, right? So the containers screen of
type cobol blaster menu. So all we should be fine
here and believe it or not, that should be it. Now, like I've said, this is quite a bit right? And this is not even the
final form, so to speak. This is not even the
complete thing just yet, but for the time being, this is all that we need to add. So let's see if it works or if bounces
back and Minecraft. So let's just see,
Let's set the cobol blaster down and let's
right-click it and see. Okay, so this is really good. You can see that of course, the GUI has opened now. All of these slots here work. Now let's just see if I can take rock humbled and place it here. I can't I can place a year
and I can place it here. That's exactly what I want. I can place here over, I can take my course liver and place it right here
because it is a fuel. And as soon as I put the
rock hold at the top here, we should be able to see that cobalt ingots
are being made. And there you go,
basically every tick. So we're going to basically make 20 cobalt ingots every second. And then if I put more in
here is not going to work. The stack limit
has been reached. Therefore, we don't
craft anymore, but I'll take out half of them. You can see that the other half basically is being created. Now one thing we can
check, basically, if I save the world
and go back into it, then we should have
saved the data. But this is very
important, of course, is one of the things
where we needed the save additional data and
the read method. So let's just see whether
or not that works, but I'm fairly
confident that it does. Now, we're going
to see that all of our items are still in here. And then the same thing
goes when I destroy this, you can see all of the
contents drop right here. So everything is working
exactly like we want it to. But this is definitely a, well, definitely an advanced lecture, as you can clearly tell. It, is. First of all, it takes a lot of time and
there's a lot of things that you need to be
able to get right here. But overall, this is
a really cool thing, and tile entities are just amazing things I can recommend. This is one of the
only times where looking at the vanilla
code is not quite as useful because in forage
we have to do it in a little bit of a
roundabout way to basically register our stuff. But I can highly
recommend taking a look at GitHub repositories of popular mods or they do their block entities,
stuff like that. It's highly recommend that
because there's always, you can, number 1, get some
inspiration from that. And number two, if you
really are stuck in, usually you have this also. You of course have this
GitHub repository as well. All of the code here, if
you copy everything over, this should work even though there are a lot of
parts, of course, right? We have the entire
screen, the menu, the block has to change a
little bit soft like that. So there is definitely
a lot to this, but overall, it is really cool. So I highly recommend after you finish this to immediately go onto the next
lecture and sort of look at them as a
double lecture, so to speak, by highly
recommended doing that. Otherwise, we are done for
this lecture right here. I genuinely hope you
found this useful. If anything is unclear, feel free to ask questions
in the provided Q and a. I'll try to answer them
best of my ability. Otherwise, I would very much
appreciate a review for mu and I'll see you in the
next lecture. So, yeah.
89. (Advanced) Creating custom Recipe Types: All right, welcome back to
the forage course for 118. And in this lecture,
we are going to be taking a look
at how you can add custom recipe serialization
to your block entity. So the general idea is
that we're going to add the possibility of
making JSON files, custom JSON files that you can read in and that basically have, well, the recipes for
your block entities. So once again, I will
copy over a lot of the stuff in this
lecture, but no worries, Everything is
available to you in the GitHub repository and
an individual just as well, highly recommend taking
a look at those. And the first thing
that we're gonna do is we're going to
make the recipe. So in our MC course package, right-click new
package called recipe. And then inside of there or copy over the cobalt blasts or recipe class as well as
the model recipes class. And we'll take a look at those. So neither of them should
have an error in them? I believe. So. Both
should work immediately. And we'll just go
through, we'll start with the cold blast recipe. You can see we have
three fields right here, a resource location id
and items take output and a non analyst
of recipe items. And you can also see
that it implements the recipe interface with
the symbol container here. Now it should be fairly self-explanatory
that the output is just the result that
you're going to get from the actual recipe. The ID is going to be, well, the resource location at which this actual jason file is under. The recipe items is going to be a list of ingredients or of items that are used for
crafting the particular item. Now we'll skip the
matches method for a second because this is going to be the most
important method in this entire class. So we're gonna go
through the other ones to assemble similar to the get result item
just gives you the output. Can crafting dimensions. We're just going to return true because we don't
have any dimensions. We are not in a three-by-three grid
or something like that. The idea, once again, it's
just the resource location id. And we have a
serializer and a type. Now, those are actually static classes within the
cobalt plus or recipe glass. And you can see the type
just has an instance and it's just an idea
Jacobo blasting, and then similar
in the serializer, we also have an instance
and the ID right here. It's very important that
this one and this one, but this basically a
type here determines what the name of your type
in your JSON file has to be. But we'll see this
in just a moment. Now, the zeros, it has
some more methods. We're going to, first of all
go to the very bottom here. And you can see that too, especially these
two methods which basically return the class
of the recipe serializer. And that is crazy
asked class thing. Um, I'm not a 100
percent sure what the crazy thing
is going on here. We're just going to need this. So otherwise we can't
return the class properly if we don't have
this crazy wrapper stuff. Like I said, I'm
not a 100 percent sure what they're all about. We're just going
to leave it as is, and we're just going to be
fine with us being here. Now the idea, of course
is just once again, the actual ID right here,
the resource occasion, the registry name is just
the instance itself, where we just basically
return the instance itself. And then we have the
three methods from Jason, from network and to network. Now those are
incredibly important. The from JSON method basically determines how the Jason
is ordered basically. So we can see that we are at the very beginning making
an itemset called output. And we're basically
reading that in from a member called
output in the JSON file. Once again, we'll see the
JSON file in just a moment, but that is just something
we're going to read in. And then we're going to
read in the ingredients, which is going to be a list. Here we make a non-null list. And then basically putting all of the ingredients
into this list. And then creating a new cobol
blast recipe from network. And the two network methods
are also interesting. Instead of using
the JSON object, we're going to actually
have a friendly byte buffer or by buffer. And this is basically
just so that the network can communicate the
client and the server. What is important here is
that when we're writing stuff to the network and
reading stuff from the network, it has to match exactly. What does that mean? Well, you can see
that when we're writing stuff, first of all, we're writing the size
of the ingredients list. Then we're writing
each ingredient. And then at the very end, we're reading the item stack
of the recipes result, okay? And this is exactly
how we reading it out. First we're reading out the size right here with read int. Then we're reading
out the ingredients. And then at the very
end we're reading out the output here. This is very important
that this has to match. Otherwise you will get an error, not in the development
environment, but when you are on the server, like when you're trying
to basically connect to a normal world outside of
the development environment, you're gonna get an
error and it's not going to work to
make sure that this matches if you want to
go for some other stuff. Because of course, once again,
we started playing around. Now it's sort of serious
Java knowledge time. If you want to
change this, right, if you were to, for example,
say, Hey, I actually have, not only two inputs
will have like four inputs will change
the size here, right? To do a bunch of stuff, I actually have
different types of output that I wanted
depending on certain things. Well, either you make
a new recipe for it. Or if you want to have
this all in one recipe, you can also make a list
of outputs in theory, choose from them randomly,
stuff like that. It's all about now really having a very
solid understanding because it's just
going to be very hard otherwise to make
really custom stuff. Right now we'll get to
the matches method, which is like I said, the most important
one because this basically determines
the functionality or this the implementation of
how your recipe is evaluated. Thus, what is inside of the container match
a particular recipe? How does this work? Well, first of all, we're
asking if the 0th recipe items, so the first item in our
recipe list that we're reading in from
the adjacent file, is that does that match
the item inside of the container with
index 1, y index 1? Well remember because index 0 is actually hour, you will slot. Therefore we have to
take index one here. And then if that matches,
then we're just returning whether or not the other
one it matches as well. And then this of course
would return true. Otherwise it would return
false. This is very important. This is basically the
hard piece of your, of your custom recipe year. And once again, if you have
more complicated stuff, if you have more, if you
have more ingredients, if you have more slots, you just need to
add stuff to it, change stuff in it, basically
continuously change it up. Once again, Java knowledge,
knowledge, terminology. I will keep saying this. Research, especially
right now in the advanced section,
we're basically done. So this is, this has
to be done and yeah, this is the general idea. So the entire crafting logic, the matching logic goes in here, and that is actually the
cold blast or recipe class. And then let's take a
look at the mode recipes. We can see that we have
a different register of recipe serializers here. And then just a
recipe serializer for the cobol
plaster right there. And then we're also making
sure that we register a type when we call
this register method. So this register
method, of course, has to be called once
again in our MC course mod class right here for the mode recipes dot
register with the event bus. And once that is done over
these classes are actually fine and we could already
read in the JSON files. But of course now will
we don't have any, we're not doing anything, right? So we actually need to
change the cobalt plus three block entity now so we can close this and go into
the entity right here. And we're actually going to make some major changes right here. So what I will do is
I will actually copy over all of the different things that
we're going to need. And we're going to
start at the very top. Because what we
need is we're going to need some container data. So I will copy this over. I'm gonna do something like this and then we're going
to copy this in here. So you can see that we have some protected final container
data called data. And then we have also for
fields which are progress, the max progress, the fuel time, and the max fuel time. And first of all, let's assign this inside
of the constructor, will also copy this over everything here is of
course, once again, available to you in the GitHub repository or an
individual just as well. And you can see that
the container data is also in this case a anonymous method with overriding the GET the set
and the getCount method. And we're always
returning the progress, the max progress fuel time
and max fuel time right here. Because those four
different fields we want to actually
synchronize via the menu. This is why it's called
the container data. The container menu
basically will synchronize those four fields for us via the client and the
server so that they both have the same value. Because of course, for
example, Southern, something like the progress
and Ymax progress. Well, if you have both of those, we can all of a sudden
show a progress arrow. If we have the fuel time
and the max field time, all of a sudden we can show
how much fuel is left inside of your inventory,
stuff like that. And this is why it's so incredibly important
to have this. And this is actually fairly straightforward to use once
you know how to use it. So what we're gonna
do is we're gonna go into the cobalt glass revenue. We're just going to
add the data here. So this data, now this is of course going
to throw an error, right? So we have to go
into the blaster menu and we can just say, Okay, we're going to
change some stuff here. And what we're changing is not the first constructor,
but the second one. We're going to add the
container data or data in here. And then this one
will throw an error. And we're going to say
no worries at all. Because what we can
do is we can make a new simple container
data with length 4. Because once again, of
course this is length four. And then just gonna
do is we're also going to make a private
field for this. We're going to be using this
in a two methods later or actually I think three
methods data, right? And then we're just going
to say below this level, when you're just
gonna say this dot data is equal to data. Well, basically
assigning this and now the way that we're
going to make it, so that this also synchronizes is we're going
to say add data slot. So slots actually data slots. And then we're going to pass
in the data right here. But that's literally it. All that we need to do. Now
this is being synchronized. And then we're gonna get four
new methods in which our He is crafting method that has fuel method that gets
scaled progress, and it gets scaled,
you'll progress. Now, this is just a
bunch of mathematics basically in the background
is making sure that well, okay, how much progress
we have, our max, max progress we have what is the width of the
arrow in this case, right, that we want to display. And then we're just
making sure that this all is calculated correctly. That's basically all
that this does. Though. You shouldn't worry
about this too much. I'm sure that you
will be able to figure this out if
you take a look at it for a little while
to no words there. That's actually all the
things that we need to do in the menu here. Now we actually do need to do a lot more things in
the block entity 4. We're moving on to the screen. So I will once again copy
over a bunch of stuff. Number one, we need
to add stuff to the save and load methods. Because what we wanna do is
we want to save the progress the Minimax filter
with reading it out. So loading it. Now this is actually,
let's do nb t then and VT. VT and
NVT, no worries there. So they go. So this is, well, things we want to definitely do. Because of course when
we load from world, like when we save
a world, right? And then when you
join back in, well, we want the fuel
time to be the same, the progress to be the
same, stuff like that. This is why we save it and
then read it out again. So this is basically
the general idea here. Then what we're gonna do is I'm basically everything
including the tick method. I'm going to, well,
I mean copy over. So this is going to
be a lot of code, but we're gonna go
through method by method. Now, I do not believe that we should get arrows
now we don't. So number one, we have one non-static method and that is the consume
fewer method. You can see that I'm
basically checking, hey, do I have something
inside of our fuel slot? Because once again,
remember slot 0, right? How is the fuel slot for us? So if that is not empty, then we're going to get
the burn time from it. We're extracting it. So we're going to extract
exactly one of those items. We're going to use the
recipe type smelting. Because, well, for smelting basically all of the burn times are supplied in,
saving it in here. And then we're also saving
the max fuel time as well. And if that is done, then
we can find a tick method. Now is all of our logic. Now what is all of
this craziness? Well, first of
all, we're asking, is this book entity
consuming few? This is a custom method
that I've made right here. And that's just basically
checks whether or not the fuel time is
above 0 is of course, if the fuel time is above 0, then we know that we're
still having some time left where the fuel is
ticking. Okay, Fair enough. So as long as that is the case, then what we're gonna do
is we're going to decrease the fuel time that is
left in there, right? So basically we are
going to decrease the flame that is being displayed and also how much
time it has basically left. And once again, we have the has recipe method which
has now changed. You can see this one right here is now the has recipe method. And this works a little
bit differently. So we're basically now
getting the recipe or the type of hobo blaster
recipe with an inventory. So here we're just making
symbol inventory that we can easily or more easily basically passes in because
this is of course of type, simple inventory or simple
container rather top, we're just passing this all in and we're making sure, hey, does this, this is actually, is present is a match for the inventory
that we've passed in. So our GUI stuff
that's in there, does that match any
recipe that is of type cobalt blast recipe that is basically what
this here tracks. If it is present, then we're
gonna get a true here. And then we look for
two other things. Can insert amount
into output slot and can insert item
into output slot. Those are just two very
easy to understand. Methods are basically
just saying, Hey, get the third item. If it's the same as the output item, we're
gonna say, okay, or if it's empty, we're also
going to be fine because then we can just
put in the output. And then also this one we've basically already seen, right, can insert amount
into output slot, basically just checks, is
the Max Stack size still? Is this bigger than
the actual count? Is? If all of a sudden
the count gets exactly to the Max Stack size, we can't insert anymore. So then this whole, entire boolean expression
gets turned false. But if he has recipe is true, we're going to enter into this hole ordeal and
this whole audio. Well, as a lot of
stuff you can see has fuel and fuel slot
is asked first of all, right, so if there is any
fuel in the fuel slot, it'll be fairly
self-explanatory. And then if we're not consuming fuel than we have to
consume fuel first. And we'll also setting
the change right here. Because once again, we
have to set changed, otherwise the data
will not save you. That's very important.
This is why we have the set changed three
times in this method, otherwise it will
not properly work. And then here, if
we're consuming fuel, so this once again,
it's just checking, hey, are we actually
consuming fuel? If we are, let's go, then we can increase the progress of the
item being crafted. Once again, every
tick that we're increasing the progress
we're selling change. Because once again, the
lending of the change has to be the case
because every time we increase the progress, we wanted to save the progress again. So that's very important. Then. As soon as the progress is above the max
progress right here, then we're going
to craft the item. So this is very similar. Once again, we're just now checking is the
progress finally there. And if it is, then we're
going to craft the item. And you can see the crafting
of the item is very similar. We still get the match here. We're seeing is this present? If it is, the more gonna
do with the following. We're going to extract
the item from spot one. We're going to extract
the Adam from slot two, and we're going to set
the stack in slot 3 to the actual results that we've
read in from the recipe. And then increasing it
basically by one in this case. So in this case also
the one is hard-coded. You could of course, also add in your custom recipe
count variable. And then you could either take that one there or
something like that. So this also would work. And then also note here that were recently the
progress right here, who were recently progress to 0. Because otherwise of
course we will just continuously after
again and again, which of course
we don't want to. And we're also recently the
progress if we don't have any recipe present simply
because of the fact that, well, once again, if we take
out the recipe and then all of the progress
would stick there. That's not quite what we want. And also setting the change
there as well, right? So it is quite a lot. I highly recommend going through this in your
own time as well. Taking a look at this, the tick method
here is definitely, I feel like personally it's a very well made method
in this case, right? It's very, very much clean code. I mean, at least as high as
clean as I've gotten it to be almost reads like you can read
a text rate is like Okay. As recipe in this
entity has fuel and fuel salt and is
not consuming fuel. This one, you could
even be changing the note here too and then have an is not consuming
fields of like that. So it's a little easier to read, but this is a good idea and a good example
actually of how you can basically
set up something and that is able to
read was of course, all of those things, right? I could put all of this in here instead of the
has recipe method, I could put this one, I could put this right here,
this Boolean expression. I can put that in right here. Instead of having the
can insert amount into output slot, I
could put that in there. But the issue is that if
you take a look at this, it's gonna take
you at least like a good five seconds to be like, what is this doing like? Okay, we're gonna get
the item from slot 3 and making sure
that it's exactly the same as the outer and or
making sure that the item is empty sewer basically checking whether or not we can now insert into the output slot, okay? But you can see that it just makes way more sense
to describe it in a very well named method instead of just
putting it in there. So that's just a quick aside for kind of a little bit of
a clean programming stuff, clean code stuff,
but that is pretty much the entire
block entity done. So this would now work. Now the last thing
that we need to do is we need to add stuff
to the screen. Now, this I will also copy
over and I will explain, this is going to be,
well, bear with me here. So you can see, I'm
basically asking the menu, Hey, our recrafting, this is the method that we
had here, right? And then has few method should be fairly
self-explanatory. These are the methods
basically getting from the data and then just
making sure that hey, is the crafting progress
increasing or is it more than 0? And then here the fuel
isn't more than 0 as well. But that's the
general idea here. And then once the quality
blitz right here, and then we're getting into
some crazy stuff because now all of a sudden we have some crazy Well
values here we have x plus 8422, the offset. What is, what is all
of this craziness? Okay, we're gonna get
through this piece by piece. So we have an x and a y value. Now the x and the y value determined where you
start drawing something. So what does that
mean? What do you mean where we start
drawing something? Well, x and y in this case, basically always be
the top left corner of the GUI. Go right here. And then if we think about this, but 84 to the right and 22 down, we're going to go
84 to the right and 22 down and then
we end up right here. Now I just know
this at the moment. Once again, you have
to take photoshop, Paint.net and make
sure that you align. This will basically
count the pixels. There's no other way around it, but we start drawing right here. Okay, what are we
supposed to draw? Well, we're supposed
to draw this arrow. Okay, That's interesting.
How do we draw this? Well, first of all,
the offset now is what are we wanting to draw? So we want to draw starting
here barely, okay? We've done that.
What is the offset? The offset you can see is a 17614 for a 176 is
actually right here, and 14 is right here, though. Now it sort of comes
together, right? We want to draw this
arrow starting here. Okay, that makes sense. Now, what is the last two values for the
last two values is the height and the width of the image that
we want to draw. Another really cool
thing comes in, because we're taking the
scale progress right here. What happens is that
as this increases the, we increase the width of this
arrow that is being drawn. So that is the
really cool thing. So if I just I could
also put in 2006 and then the entire area
would always be present. But because we're synchronizing it with the scale progress here, the width that is
being shown increases. That's the general idea. I highly recommend once again, playing around with the numbers
here, because otherwise, the blood olds are very complicated to really
understand at some point, I still have to play around
with them a little bit. It just is what it is. And then for the fuel, I will admit I have
basically just taken the fuel stuff from
the actual furnace because you have to add the max field progress here and then subtract your scale
progress three times, once for the height, which
should make sense, right? Because now we're basically
subtracting the height here, are basically saying we're, we're starting here
and then subtracting down there, stuff like that. It's just craziness. I just highly recommend. Once again, taking a look here, you can definitely take a look at vanilla examples of this. Otherwise, it's just
about experimentation. So we still need a recipe. So in our data folder,
MC course recipes, I'm going to copy over
the cobol pickaxe from cobalt blaster. And you can see
what this does is basically we have
two ingredients, are type is MC course
cobol plastic, and we have the gold pickaxe
and the cobalt in good. And we have to put
in, in this order, and then the output is
going to be a cobalt pigs. So that actually does
sound pretty cool. And like I said,
you can now make as many different recipes
as you would want. One of the limitations, let's say with
this is that Well, it's always going to
take the same time. Well, you could, of
course also do is add the max progress
to the JSON file. You just have to change the
serializer up a bit and then basically add this
as well. This all works. This is just a
matter of basically, well tweaking
things a little bit and changing a few
things around. But now let's see if it works
or finds us in Minecraft. So let's first of all set
the actual cobalt glass or down and everything
seems to be still working. We can still put some in. Let's now see gold pick X in the top and then a cobalt
England in the bottom. And there we go. The progress has started. We have now created a pick
ax that's really cool. And what you will
be able to see is that if I put another one in, nothing will happen
because of course, we'll pick axes don't stack. Therefore, I have to
take this out and then only then are we
going to craft again. You can see that the fuel is, we'll constantly going down. So it's constantly
assuming the fuel. And what you will
also be able to see is that if I, for example, now go out of the world
again and I go back in, you will see that the
fuel actually has stayed the same level
just as it would with, for example, a block or a
furnace or something like that. So that is pretty cool. So I can take a look
and there you go. A fuel will progress
is the same. And once again, I
can now just put this in because we
still have fuel left and we're still
going to be able to craft those as long as we want. And the course livers also
would still work by the way, everything here working exactly
how we would want it to. And now this, you have to admit is pretty freaking
cool, isn't it? So once again, this starts
to get very advanced. So I highly recommend, once again, taking
our time with this, the two methods, right, with the block entity and the customer recipe serialization
here is quite a bit. But also apart from
a few other things, this is probably one of the most complex things
that we can really do. I mean, the world generation,
I would actually say, is probably a little bit
more complicated just because sometimes it
can be like this. But overall, I think that
this is really cool. You have a really good
example right here. Read all of the code once
again available to you in the GitHub repository and
an individual just as well. So just take a look at it, copies himself over, play around with the
numbers a little bit. And hopefully then
you will be able to just get a feel for how
this all works, right? But that would already be it
for this lecture right here. I hope you found this
useful and you learn some new and I'll see you
in the next lecture. So, yeah.
90. (Advanced) Custom Wood: All right, welcome back to
the forage course for 118. In this lecture, we're
going to be adding custom wood to Minecraft. So even though this
is an advanced topic, it's definitely going to be
a little bit easier than the block entities and the
customer recipe serialization. So I thought that we're
going to basically add one or two little
bit easier lectures in here before we jump into the world generation
because that's going to be a whole,
another beast. So for our custom would, we need a custom
block class actually, so in our custom
package right-click new Java class called
the mod lambda will rotated Hitler block, a long name, but this is what it's going to be
and this is going to extend the rotated
pillar block class. And we're just going to hover over this concrete constructor matching super annoys us. We can just click on
it, press Shift F6, and then whose properties
here for the name. And I'm going to copy over the three methods that
we need to override. That is, the is flammable
method is returned true. They get flammability needs to return five and they
get fire spread. It needs to also return five. Now why are we doing this? Well, because all of the rotated pillar
blocks that we have, we're basically going
to be the wood, the strip would the
log and the strip log. All of those are well, they should be flammable. However, by default
they are not. I am not a 100 percent
sure why that is the case. And we could also make anonymous classes
for each of them, but that's just
going to clutter up the entirety of our
more blocks class. So for these ones, I choose to basically, well, what this into a block
class or both the planks. And then later in a later
lecture, the leaves, we're going to actually do
this in anonymous classes. But we're going to see
this in just a moment when our motor blocks class, Let's go, let's sort to copy
over the cobol blaster. And we're going to
make this the cherry underscore blossom
underscore log. And then the same thing, read your cherry blossom
underscore log. And then this is a MOD rotated or more flammable
rotated pillar block. They ago, this one actually will copy not a
material but a block. So this is going to
be blocks dot OK, underscore logs, so
log that you go. And then we will
actually have occlusion here and the rest is
going to be fine. So this is pretty
much what we need. And then we need to copy this four times so that we have five different
instances here. The second one is going
to be the cherry blossom would go and then would
here in the name as well, It's very important that
you change the names. And then here we just
basically copy over from the oak wood instead
of the glog. This shouldn't really make
that much of a difference, but I'm just, you know,
I still like to do this. So then we have the strip
underscored cherry blossom log. So this is going to be the strip under switcher button lock. And then here, this is of course also going to copy
from the script. Ok, should applaud the ego. And then this is going to be the strict underscore
cherry blossom, underscore wood. And this is also the of course, stripped Cherry Blossom,
would they ago. And then last but not
least here it copies from the stripped oak wood. Now this one here is just
cherry blossom planks. Now it's important that
is planks in liberal. And this is which
block can this be? Well, if there isn't any
normal block actually. And then what we're
gonna do is we're going to just format this a
little bit differently. And this is going
to of course, take the planes blocks of planks. And then after the second
parameter, actually, what women do is
we want to put in a curly bracket and
then just hit enter. I'm just going to
copy it over again. So those are just
the three methods that we're going to
need a scannable, get flammability
and fire spread. And see that the numbers here, we're a little
bit different. So this is also one of the reasons why we
can't use this block. This was another one which we're going to see in just a moment. That is the general idea. And then all of our blocks
are actually registered. So that's pretty cool. All things considered, right, we're going to add one
more method to the MOD flammable rotated
pillar block. And that is going to be
this one right here. So I'm just going
to carry this over. This is of course, all
available to you in the GitHub repository and
an individual just as well. And this is the good tool,
modified state method. So basically the idea
is that we're checking whether or not this was
right-clicked with an ax. If it was, then what we're gonna do is we're just basically
going to say, hey, if this is a cherry blossom log, we're going to turn
this into a strip blog. Otherwise, if it's a loss would, then we're going to turn it
into cherry blossom wood. That's the general idea here. And then we're just
making sure that the axis stays the same in this
moment, we can't, we're not just gonna do
the default block state will then also sending the
actual access as well. That's the general gist here. If you have a lot
of different logs, then you would in theory also always have to add
these if statements. You can also do it
like in the ACS item. So if you actually millimoles
per click on this accident, you can see there's a block
to block map right here. I highly recommend that you do something
like this as well. If you have an insane
amount of different blocks, logs and would basically
you want to have stripped That makes a lot of sense. Otherwise, this is going to
be totally workable right now to everyone's favorite
part of the JSON files. Those are once again, of course, all available to you in the lab repository or an
individual just as well. I'm just going to
copy them over. Now, overall, they are
not that interesting. Of course, for all of the
rotated filter blocks, we have an axis here
as you can see. And then it basically
just points to different models and
rotates the block around. That's all there is to it. It's actually all the
interesting stuff right there. And let's also add the
translation because otherwise I will
possibly forget it, which of course we do
not want right here. Just going to add this logs, planks would the script
variants as well. The models for the
blocks are, well, a little, while,
there's a few more, they are not that many. We have the wood, the normal word, the
stripped ones as well. So let's let's copy those over as well into
the block folder. Seven of them in total. They basically just
have different parents, but they always have
the same textures. So the end, this is just the top of the
actual block for the log. And then the sides is just
basically the bark around it. For the item models, we do only have five
item models, of course. They are and are just like
the most basic stuff ever. So they just all look
like this state all just point the normal
block model file. And then of course,
last but not least, the textures as
well. There you go. Those are also five textures. And then after we've
added all of this, there is one more interesting
thing that we want to add. And that is going to be if you tags in the Minecraft folder, tags, blocks, and then I
will just copy this over. This is the logs and
the logs that burn. We'll actually see
that we'd have to add another one here. As you can see that
this actually points to the course cherry
blossom logs tag. And we want to add a custom
tag right here as well. So this is going
to be the cherry blossom blogs also
copy this over. At this point, we've seen
this plenty of times. And I just want to add basically all of our logs in there. This is the word and
descriptive variants as well. If you add it to the
logs of that burn, that will basically enable
you to place this inside of the furnace fuel slot as well so that they
can basically burn. And that is the
general idea here. And in the logs when
we need it for if we later add the leaves, then the lease will not decay when they are near
any of these blocks, and that is pretty much
all that we need to do. So let's see if it works. Or in France as a microwave can see all of the wood has been successfully added
to the game and it looks absolutely amazing. So you can see, I can
set it down and let's just see these variants
as well. There you go. And, and also the logs, rather the planks, I guess. Then if I right-click
these ones, then you can see I can get
the strip variance as well. So everything is
working exactly how you would think it would end
as it is intended, right? That is already it for
this lecture right here. I hope you found this useful
and learned something new. I'll see you in
the next lecture. So, yeah.
91. (Advanced) Custom Sign: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding custom signs to Minecraft. For the custom sign is, well, it has some peculiarities
in it that, but we're just going
to basically took, take a look at right now. So for custom signs, but we're going to need
is we're going to need, first of all, a
sign block entity. So in our entity package, right-click new Java
class called the mode sign block entity. And this will extend. The sign block entity will hover over this create
constructor matching super, and then we'll override
the getter method. So here we can put
something in yet. So I'm just going
to make an error here so that we have this. Then we are going to need
the blocks for this. We're going to need
two blocks over here. Also, you have to create
custom block classes. This is sometimes can be
really annoying for the sign. I am not sure why
it is this well, complex to make, but it is
just how it's going to be. This is going to be a
standing sign block. So Mott standing side
lobe extends this one. We're just going to
leave this as is. And here we actually
just wants to override one thing
and that's going to be the new block entity method. So here what we're gonna
do is we're gonna make a new mode sign block entity with the position and the
state and the state they ago. That's going to be fine.
And then we're going to make another class which is the MOD ALL IN block, which extends the
wall sign block. They ago also create
constructor matching super. We'll also copy
over this method. Once again, of course, all of the code will be
available to you in the GitHub repository and
an individual just as well. Because now I will actually
do a cardinal sin and I will copy over the thing that we
need in the mud blocks class. And you will see we will need a mod Wood Types class as
well because as I've said, I don't know why, but it
is just absolutely crazy, but no worries we will
get through this. So mod would types, and this is going to
have one static fields. So public static type
or cherry blossom. And this is equal to would type. That rate. Sherry underscore blossom. The ego. That is all that we need to
put in here and then here. And then in the mud blocks, this should work as well. So now the blocks work. So now what we can do in
the mode block entities, I can actually copy this over. This is pretty much
exactly the same as this. As you can see, we just have the mod sign block entity year following the sunblock entity. If you have multiple
different signs, what you have to do
is you don't have to change these blocks. You just have to add
to consider two blocks in here and you can add as
many as you would want. So basically just
add more blocks in here and then it should, in theory work same
with this one. So now here we're
just going to say mod block entities,
entity dot get. And then that should be fine as well for another
customer signing basically what a new wood
type to new blocks here. And what you will see is
that these blocks that register instead of the
register block method, because we have to have a separate item for this
going to be the sign items. I will actually also copy
this over once again, all of this is
available to you in the GitHub repository and an
interatrial just as well. This is going to be
this right here. So let's just take away the durability and
let's just actually stack to 16 like any
other line would be. Also, you can see that the
sign item here actually requires you to put in the sine and the
wall sign as well. So that is another
important thing right here. And apart from
that, we also have one more thing were a couple of more things inside
of the MC course, mass. So at the very bottom here, we need to call would type
important class dot register, mode would types
dot Cherry Blossom. We need to register this
inclined setup method. And then in the
normal setup method, we need to do two things. So number one is the
block entity renderer. Renders very
important renderers. Register mode, lock entities. Now sign block entity dot get, and then the sign renderer
here, colon, colon new. Then below this we want to call sheets dot add would type, mod, mod would type star, cherry blossom, they go. And that should finally be all that we need in
terms of the code. We of course still
need the JSON files. And when it comes to
the days, and for us, we actually needed
the JSON files for the block states as well to
make sure that you have that. And then the same thing
goes for the translation. So let's just add this. We have the translation
for the sign. And then let's just add
the block models as well. Abutments are actually
a kind of interesting. So there actually is only
one block model because both the ones point to
the same one because this block model only
has particles defined, these are the particles that
are going to be seen at when you destroy the actual sign. While the cherry blossom sign
item model looks like this. So it's simply points to a
item texture is of course, once again at the item
texture is going to be, well the same and we have the same item for two
different blocks. In this case, we're
going to have a normal cherry blossom
sign right here. That's the item texture. There you go. And that is all of the things
that we're going to need. So once again, all of this is of course available to you
because once again, it is very circular exercise
and can be kind of annoying. So I found that signs were kind of puzzling in
their complexity. Or what you can basically
at the end do with it. You actually are going to
need one more texture. And that is going to be the actual like cherry texture
in the background. And this has to be under the
Minecraft namespace again, so assets, Minecraft textures. Then instead of
the entity folder, we're going to
need signs folder. And then inside of there
the cherry blossom PNG. And now after having
added all of this, Let's see if it works. Or in France as a micro lens, we see the block has been added. Now we do not have the
correct translation, but that's of course
very easily fixed. Let's set it down and
we can write something. So for example,
really good word, horse and done and
it stays there. And we can also put
it on a wall here. As you can see, all works well, exactly how you would expect it. And I've also just fix
the translation here. So now everything
should work for the file that has already it
for this lecture right here. I hope you found this useful
and learned something new. I'll see you in
the next lecture. So, yeah.
92. (World Gen) Creating a Custom Tree: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding a custom tree to micro accustomed tree.
Well, wait a second. We've already added custom would write in our
model blocks class, we can see there's some
planks would have the logs, but almost everything
we already have. Well, what do we not have? We don't have a sapling
and we don't have leaves. All right, so what we're
gonna do is we're going to copy over the cherry
blossom a plank once. And then I'm also
going to copy over the script would right here. We're going to need one
for the cherry blossom underscore leaves and then leaves here in the name as well. Of course, they ago this is
going to be a leafs block. They go and then this is
going to copy the oak leaves. And the flammability of
this is actually going to be 60 and the fire spread
is going to be 30. Because the leaves are
incredibly flammable. And now let's take a look at the Cherry Blossom sapling
at the bottom here. So this is sampling. And then same with the
name of course as well, changing that to cherry
blossom underscore sapling. This is going to be a
sapling block which will throw an error because we need to give it,
as you can see, an abstract tree grower and that class we will
create right now. And that's going to go into
our MC course package, right-click new
package called world. And we've started
to venture into the world generation inside of their new package called eater. And then inside of there
we're going to make another package called tree. And there I will put
the tree grow in this new Java class called the cherry blossom tree grower, which will extend
the abstract tree. Grow will hover over
this Implement Methods because we need to implement get configured feature method. And I mean that's pretty
much all that we need to do. Now I will once
again purposefully make an error right
here so that I don't forget to pass it in this method because we have not yet created the configured
feature that we need. But what we can do
is we can already make a new cherry blossom tree row so that here everything is fine and the more blocks
class is pretty much done. Now for both the sapling
and the leaves we need inside of the MC course
class in the client method, I'm going to copy over
the blast or cut out here and we're going
to say leaves and we're also going to say the
sapling they ago that we both have the leaves
and the sapling on render layer
cutout, of course. And then we'll first
of all continue with finishing the
blocks right here. So we're going to just copy over the leaf and the sapling
block stage Jason. Now those are of course
all available to you in the GitHub repository and
an individual just as well. But you can see actually
the block states, very boring, just normal
Bloc states basically. And then when it comes
to the alkylation, pretty much the same thing. Leaves and little
leaves here as well. Then of course, appealing
and a baffling. There you go. There's also
to block model JSON files. Of course, the leaves once
again being fairly boring, while the sapling is a
little more interesting, has a cross parent and a cross
texture that it points to. Pretty much all there is to it. The item model is also a
little more interesting, at least for the sapling. Once again, the sapling, as you can see now
looks for a extra in the block folder instead
of the item folder, but the leaves are just normal
item modal JSON files as you have seen them
plenty of times now for different
blocks basically. And then let's copy over the textures here as
well, just have them. And then this would pretty much be all of the JSON files that we need to do and we can now
continue in our world package. Though the reason why we have a world packages because
trees when you spawn them, they are like sort of a
very strange intersection of being a little bit
already in world generation. So when the tree spawns
from the sapling, it's a little bit of
world generation. That's just how
it's going to be. So in the feature
package this time, Right-click new
Java class called the mod configured each other. And this is going
to be our well, are best friends so to speak. As inhibitor, we're
going to have the actual tree defined. Now I will copy over the
actual definition of the tree and I will
explain as we go along. So you can see this is
a lot of stuff, right? Number one thing I want to say is when it comes to
the world generation, it can be very complicated. Okay, So there's a lot
of moving parts in the entire thing of
the world generation. I'll try to explain everything
best of my ability. However, if you want
something that's very, very, very particular, like you want your
like, I don't know, like yours to spawn exactly at 35 and you want
exactly this many. There's gonna be a lot of stuff that you have to
adjust, but no worries. I'm sure we will
get through this. Or now, the cherry
blossom tree right here. You can see we're calling
feature utils dot register, read registers, basically
this configured feature. And then we're passing in
a Feature Tree configured. So a configured feature of
type Tree configuration. We're passing in the
tree configuration with a builder here. And then the question
comes in, what are all of those different things? Well, think about this. Well, a block say
provider simple. The first one is
the log provider, meaning that we basically
have to provide a specific log that is the
actual trunk of that tree. How is that trump placed? Well, we're printing a new
straight trunk placer. If I middle mouse
button, click on this, you can see this extends
the trunk place her class. And if I press
Control H on this, consider different
trunk placer classes, meaning that in theory, you could also create your own. This of course, once
again, is something that's definitely more complicated,
more complex here. So of course, all working. You could of course do it. However, there. Now we're just, at this point, it's
not even about, oh, you have to have Java
knowledge at this point. We're going from intermediate to advanced Java a little bit. The making cousin trunk
placers and custom foliage placers basically involves a
lot of mathematics as well. So keep that in mind. Then the second block
state provided right here, the third parameter
is the leaves, and those are placed, but depending on the foliage
placers, once again, middle mouse button click on
the foliage placer and you can see there are different
types of foliage placers. This is just how
the actual well, leaves are placed down. And that's pretty much
all there is to it. And well, then the last one here is
the two layers feature size. What is this? Well, I'm not a
100 percent sure. So this basically limits
where this can be placed. That's the general idea. Year though, some things
in the entirety of the, let's say generations
still elude me as well. So no worries there. Whatever the case
may be, this is now the feature that has to
be returned right here in the Cherry Blossom Tree
growers were going to say mod configure feature
every blossom three, and that should
pretty much be it. Now as crazy as it sounds, that should be it, that's done. And now the tree would already
spawned from a sapling. They're important, It's
not going to spawn in the world just yet. We're just gonna make it in this lecture that it spawns from the Sapling so we
can bone meal ID or a grows from a
sapling natural. So I would say, let's see For works, or we find ourselves
in microvesicles. See the cherry
blossom saplings have been well added to the game. So let's just see if I can
spawn them with a sapling. And there it is, if I bone meal at it works. Now the real questions, I
think that this is a little bit placed a little closely. And also if you hear exactly, You actually have to change
the material for a second. This is still using the I
think the plank material. So that's of course not quite right. Let's do the following. Let's do a game rule, random tick speed, and
let's just increase it. And let's see if this
grows by its own. But it seems like the sapling
is not growing on its own. This probably has to do with the actual material that
is that as copying from. So let's just fix that quickly. Any oversight right here, as you can see, block
behavioral properties, copy blocks stripped, OK. Nope, This has to be oak sapling. Then it takes all of the
properties from the oak sapling. And the one thing that it needs is this one right
here, random tics. Otherwise it's not
going to take randomly. So they go and, well, if we have added this than
just for completion sake, let's see if it grows or if
it ends up back in Minecraft. And let's see if we can
release the tick speed. Let's see, the one
grows, let's go. So everything working exactly
how you would expect it to the saplings growing
naturally as well run. And what's very important
is that last lecture or two lectures ago
when we added the logs, right, these ones right here, the cherry blossom logs, it was very important
that we added to the block tags as well. So the tags for the
logs right here, and we're basically referencing
the cherry blossom logs, which is a tag that we have
in our MC course, Oda. And right here the
cherry blossom blocks, very important that
this is in here, because if you don't have that, then the leaves will
automatically decay. Even if they are
next to the log. The log needs to be in that tag. Otherwise it will not
work in the logs tag. Very important. But otherwise that would already be it for
this lecture right here. I hope you found this useful
and you learn something new. And I'll see you in
the next lecture. Oh, yeah.
93. (World Gen) Custom Tree Generation: All right, welcome back to
the forage course for 118. And in this lecture
we're going to be adding custom tree generation
to Minecraft. So we have added the
tree from sapling. Now the question
is how the FREC, are we going to get
it into the world? Well, actually, not that crazy. First of all, let's
go into our mod configured features
class is right here. We're going to need a
new configured feature. Now what's very important
is the following. We can actually take a look at some examples of
regeneration in vanilla. Highly, highly recommend
taking a look at this. But what we can do, for
example, in the feature class, we can go into the feature class and we can take a look
at all of the features. And the features you are
not that interesting. What is interesting
is, for example, where is the tree feature used that our middle mouse
button click on this, then you can see it's used
in the tree features class. Very interesting. And you can see there,
there are a bunch of places basically where
this has been used. For example, let's just
go here to the OK, and you can see that this one is a features utils register. It looks very similar to
what we've done right here. And this is pretty much
exactly what we've done. So this one has a specialized
method here in this case, or all of the features
that it uses. But what, this is exactly
what we have here. Now, can we use this? Where's this use now? Well, I'm, if I middle
mouse click once again, you can see this is used in, for example, the
tree placements. And this is the AUC checked. This is exactly what we need
to basically implement now. Well, if I go into
this right here, what you can see is that
this is all of a sudden it placed feature that's
fascinating, isn't it? Thing that has been done
is that it has been, world's generation has separated a little bit that now you have placed features and
configured features. And you can see that
this place feature in this case actually uses
the tree features OK, filter by luck, survival, and then the oak sapling. But what does that exactly mean? The general idea here is that basically checking this
place feature can only be placed on particular blocks where the oak sapling
could also survive. This is really
actually frequent, cool thing to do. And then where is this used? Well, this is once again used in the vegetal features right here. So this is a very long
one in this case. But this is just in theory. You can see that this is all of a sudden another
configured feature. For example, let's actually
take one that's not too long here. They're
all pretty long. Let's take the meadows trees
and then I can middle mouse button click on
this and then you have another police feature. So basically where
we're going from is we're going from
the trees in specific, we're going to go from
configured feature to a place feature to configure
feature to a placed feature. Because I placed
feature has to be, has to be in the world, right? It can't be, you can't have
it not be in the world. Basically, I've done this
a little bit differently. I've cut out this place feature and basically just made it so that we go from this
configured feature for another configured feature, then going to the place feature, that's not a 100 percent right, but it is almost right. So in the MOD
configured features, I will once again copy this over and I will explain what
I've done basically. So you can see that
this is the cherry blossom tree checked. And you can see that
what it does is it also filters by a
block survival. You can see the general idea is just that this
configured feature now, well, it's gonna take, you know, it has a 10 percent
chance of taking this place feature
and attempt and a 90 percent chance of
taking this place feature obviously is always going
to be the same feature. So this just a little
bit of a hack. It's probably not the
cleanest way to do this, but this is the way that I
found it without having to add another place feature than a Configure feature and another place feature
and so on and so forth, because it does tend to
get very complicated. However, you can always follow the vanilla template,
also highly recommend. You have to be taking a look
in the world generation. You have to take a look
at the classes, right? They can also go into the
package middle mouse, click on this and
you can see all of the features in here. We can go to the placement, we can go into the
placement package. You can see all of the
placements right here. We can go into the generation
to the vegetal features. Once again, in the features, we can go to the placements. There's this should also be
in the placement is right. We have all of this
available to you. You have to be taking
a look at this is now the world's generation
really gets Rican complicated
at certain points. And you just have to, well, take a look at the
vanilla examples. This is probably one of the best resources that you have and it's all right there, whatever the case may be, we now have the
configured feature. We still need a place
feature though, overlapping the feature package right-click new
Java class called the modal least eaters
and add that in there. We're going to make a new, placed each other for a
while exactly what we have and that's going to
be following a once again, we'll copy over all of the
code is available to you in the GitHub repository and
an individual just as well. Or this is not that complicated. You can see we call a
placement utils dot register and then the
cherry blossom placed, and then we're taking
the tree checked. So this is the configured
feature which will return either this place feature or
this place feature, right? So the filter by block survival. That's exactly right. That's exactly what we
want. So we will only, will have trees that spawn where the cherry blossom
sapling could be placed. That's the general idea here. And then we're making
this a place feature by adding the vegetal
decoration tree placement. And then we're just
adding count extra. So this is just how
many trees will spawn. But if I'm not mistaken,
what this means is that this means that on average one tree per
chunk should spawn with a 10 percent chance
of having two more spore. I believe that's how it works. I'm not a 100 percent sure, but you can also take a look at the tree placement method
right here and see that this takes in placement modifier one place
modifying or this case. We can then go in the placement
modifier and we can see, well, okay, this doesn't
reveal anything. Well, let's press Control H.
And all of a sudden we can see a bunch of different
placement modifiers. There's even placement filters, which I find really cool. So you can have things
like rarity filters, which basically on average
every this many chunks, I believe this is how it works. And then you can have
the repeating placement. Some noise based counts. Incredibly cool, just
absolutely frequent, amazing. There are a bunch of stuff here. Once again, the open to experimentation
tries to, without, take a look at the vanilla code, how classes are used, just highly recommend
doing that. Now The placed feature
has been created, but somehow we need to
generate it Exactly. So in our world package, right-click new
package called Jen. So this then forms
the world package. I know really spoken smart. And then in there
we're going to make a new Java class called the modern tree generation. And then this will
look as follows. 1 second, I will copy
all the method here, but I will explain everything. So this is the biome
loading event. Well, we're going to call
this in just a moment. But what you can
see is that it's actually not that
complicated, right? So this spawns the actual tree. Okay? What we're gonna do
is we're just going to get the resource key from this particular biome that we're currently loading, right? And then we're just
gonna make sure, hey, is this biome does, do the types of this
biome contain plates, but basically in all different
types of planes biome, I'm like, Yes, let's add the cherry blossom placed
feature right there. So these two calls, right? So getting the base of lists, supplier place features for the vegetal decoration
here is the first step, and then the second step is just adding our placed
feature in there. This right, this,
these two holes here, these actually add
the place feature to the particular biome. This year, of course
just filters. At this point, this shouldn't
be too crazy for you. If you have, you're like, well, I actually want my tree to
spawn in a different biome. You just have to filter
differently, right? So you can just take
this if statement away. You could just change
it around a little bit. Should not be too crazy. All things considered. And what we're gonna do
is, so in our example, it will only spawned
in the plains biome or in different planes
biomes basically. But where do we call this now? Well, in the world
package right-click new Java class called
the modern world events. And then inside of there
what we're gonna do is we're going to first of all
add the add mode. And then we'll say dot event bus subscriber ID equals MC
core Smart Touch ID. Then we're going to have
a public static void. Would biome loading event with a final biome loading
event, cool event. And this will have very
important a subscribe event at the top here for
this annotation. And then we're gonna say
model tree generation at our January trees and we're
going to pass in the event. And now you might say,
this cannot be it. It is though, everything
that we need to do. Now, of course, the very particular things quite
complicated, right? So you have different
placement utils, different tree placement stuff with another configured feature. Though, there is a lot to this. However, when you
really think about it, it's actually not that crazy.
All things considered. Like I said, if you want
different filtering basically or you want your trees to spawn
a different biomes, you just have to filter
differently here. I mean, basically you have
the biome loading event. So you should have, you know, you have the
resource location of the iamb basically
available to you. So in theory, you should be able to easily change
the filtering here. So when we go into
Minecraft in just a second, remember to create a new
world because we've messed with the world generation
just in case, you know, it should still work in the old world if we
teleport away far enough, but still just in case, let's create a new
world and let's see if the tree is generated. Or a pharmacist, a
Minecraft, and there he go, we already are spawning in
a sunflower planes biome. So there you go. The trees are spawning and well, that it's pretty much show them. Yeah, it's pretty much working exactly how you
would expect it to. So they are only spawning
in types of planes, biomes as actually
fly over there because the placement
looked a little bit weird, but actually it should not be. So you can see, or they're
just happily growing in, well, the places they
can, they can grow. So those might be a little bit too close to each
other, but who knows? I mean, at this point,
it's pretty cool. And once again, one
very important thing. You will always have
to play around with the numbers when it comes
to the world generation. Because maybe you're
like no, no, this is way too many trees. You know, you just have to play around with the count them, but overall, the trees spawn. So one particular thing
I can say with when it comes to basically
the generation here, what you could do if
you, for example, want your tree to
be incredibly rare, you could make it 0 and
then have something like a 0.1% chance of another tree
spawning something like that. But of course, you know, you can just play around with
is also highly recommend. Once again, just taking
a look at, well, the different three generations
from vanilla, right? This is always something that you can just
take a look at. I cannot stress this enough. You have available, you
all of the vanilla stuff. Just take a look at that and
you will hopefully be able to create the tree
generation of your dreams. But that will be it for
this lecture right here. I hope you found this
useful neurons of the new. If you did, I would very much appreciate a review from you. Otherwise, I will see
you in the next lecture. So, yeah.
94. (World Gen) Custom Flower Generation: All right, welcome back to
the forage course for 118. In this lecture, we're going
to be taking a look at the flower generation of
flour generation is actually, well, another part of world generation is going
to be very interesting. So let's go into our
configured feature class. And here, once again,
I will copy over, but everything like always
is available to you in the repository and an
individual adjusts as well. So no worries there. But what we're gonna do is
we're just going to copy over the ink rows. Each row right here. You can see it actually
is quite long. Let's see if I could do
something like this. Now. Well, there you go. So something like that. See we're using
the feature flower once again to make a
Configure feature, this time of random patch
configuration with a few tries, some spread right here. So what you can
see is basically, well if I just go
into the flower, so millimoles per
click on this and then middle mouse button
click once again. We can, for example, see that we have some flour default here. We can see what is
this? So this would be a random weighted
list for grass patch. Well, let's, we can't really
see what's going on here, but we can see what's
going on here. A random patch configuration, 96 spread 6, 2. And then we have this
insanely crazy simple block configured here and
see that we make a simple block configuration. And then inside of here,
a noise provider and look at this craziness,
right? Look at this crazy. So we basically just have different blocks
that we spawn there. The idea of the random patch
configuration is actually usually that you add multiple
different flowers to it. Well, in our case, I'm actually just adding one flower to it. So you know what, I'm
going to actually reduce the tries here to let's
say 32 just in case. And not as many of them
will basically own. Let's do something like this. That's going to be
fine. Now this is still a configured feature, and of course we need to make a police feature out of this. So once again, we're just
going to go back into the feature class taking
a look at the flower, Let's just go to
the default here. Where is this now called, of course, in the
vegetal placement. So let's just take the, our warm here and then we can see basically this
is a line as 71. Actually, it's actually 70. There you go. And then we can basically see we put in gravity once every x right here
in square placement, spread, height map,
and then biome filter. So what I usually do to
basically prepare this, I just copy everything over and then just see what I
need to put in there. Well, what I have is I have the following in our mode
placed features, we can basically add
this right here. So there's going to be
the pink rose placed. So you can see I also have
this and the only thing I don't have from the placement
is the rarity filter. Well, let's just for the sake
of argument, this as well. So let's just add the
derivative filter. I'm going to copy this over. I'm going to put this in here. Because the cool thing
about the placed is that in the place one, you see this dot-dot-dot. This means that we can put in as many placement modifiers as we would like inside of here, this is the really cool
thing about the place stuff. But when you have a
configured feature and you do dot placed, you can put in as many different placement modifiers
as you would like, which is really freaking cool. And now we have this placed
feature for the flower, but how are we going
to spawn it will in our Jenna package right-click new class called the mode
flower, flower generation. Then once again, I will
actually copy the, I will copy over the
method right here. But this is pretty much exactly the same as the tree generation. Because of course,
flowers are also vegetal decoration and we're just adding once again at the pink rose place right there. That should be fairly
self-explanatory. All things considered
were once again, only doing it in planes. And let's go to the
MOD world events. And let's just call this, it doesn't matter in this
case in what order we call them because they're both the same generation
step right here. As soon as we are
basically at the oars, you will see that because this is a different
generation step, will have to actually, you know, uphold the
order right here. But this is actually it. This is all that we
need for the pink rose. Once again, highly
recommend taking a look at all of the vanilla examples. There are so many of them. Just take a look at them. Happy stuff over, try
out a bunch of stuff. Try out a bunch of
values especially. And then just see what
basically happens there. But for completion sake, let's see if it works, right? And also don't forget to create a new world for this
because of course, once again, we've mess
with the world generation. So let's see if we can find
our flowers or offenses in a plane's my home and
they're, they already are. We have found or pink roses
spawning in the plains biome. There's a couple of more here. And let's see, there's
even more there. Let's find some more. They are a little bit rarer
than I expected with 32, but that's of course
totally fine. Once again, you can just
adjust the numbers. I think that there's three
ones in here as well. Yeah, there they are as well. That's pretty cool. So that is actually
really awesome and it's pretty much how
flower generation works. Once again, highly recommend, taking a look at all
of the vanilla stuff. And you will just have to play around with
the numbers until you get it well to a generation
that you would like. But otherwise this would be it for this
lecture right here. I hope you found this useful
and he learns of the new. And I'll see you in the
next lecture though. Yeah.
95. (World Gen) Custom Ore Generation: All right, welcome back to
the forge course for 118. And in this lecture we're
going to be adding custom or generation to Minecraft for the thing that you've
all been waiting for. I well, I think so At
least ordination is one of them basically always the most requests a topic out
of a lot of them, basically the ones that I am definitely going to
basically be doing. And while, how do we do this or generation,
where do we go? Well, first of all,
configured feature again, and in here I will copy over two things and then I will
explain of course as well. But number 1, we
need a list of or configuration a
target block state. Now what the FREC is this, well, we need this because if we have a particular order
or configuration, actually needs this ores
because we need to know, okay, Which rock state
should be placed in, stone, in which blocks it should be placed
in a deep sleep. So this is basically why we
need this list right here, as basically as simple as that. And then we have the configured
feature, your robot. Or now of course we need to still make this a
placed feature. But this already as a, an interesting thing
and this is the size. So this should be the average vein sides if I'm not mistaken. So keep that in mind right here. And we can also take a look at the well or feature right here. So middle mouse button click on this and then middle mouse, middle mouse button
click on this and then you will be able to see this is all used
in the order features. But let's just take
a look, for example, at something that is
more interesting, the or Redstone for example. So all Redstone is
configured with a new list right here of redstone ore and Redstone leaps late
or okay, fair enough. And now the question
is, where is this use? Well, this used in
the order placement. So you can see the redstone ore. And what you will also
find is that there are two different placements for the same or you even have, or diamond or diamond
large or diamond bird. So it's very important that you can just add
multiple ones for the same or like different place features that have different functionality
associated with them. So we're looking at 41 and 42. So let's just go in here. We can see that this is a common or placement, common
or placement. And then there's even a
rare or placement method that they basically call. We're going to see something
like that in just a moment. But you can see that this as a range placement with this uniform and a
triangle as you can see. So there's different kinds of placement basically
for the height range. And then you basically
just say, okay, from what range to what
range should the scope. And that's pretty
much the idea there. So it's pretty cool and you can once again just copy over stuff, try out a bunch of stuff, and then see the common or placement of just middle
mouse button. Click on this. You can see it's just
a private method. What we actually have to do
is we actually have to copy over all three of those methods where at least that's
what I'm gonna do. I'm going to copy over all of those methods, right-click copy. And then we're going
to go into the feature class and
I'm going to make a custom mode or
placement class. And then we're just
going to copy over the methods in here and
we're gonna make all of them are public so that we can basically use them for
our own ores because, well, they're just make our
lives a tiny bit easier, not a 100 percent, but
it just a little bit. And then after we've
copied that over, well, we can now use the
Configure feature to make a place feature. So in our model placed features, what we're gonna
do is we're just going to copy this over and I'm going to explain of course
again. So there you go. We have a cobalt or placed, which we're once again
going to register with the cobalt or place here. And then we're just gonna
take the cobalt or that we have find right here,
the Configure feature. And we're gonna make it placed with the common or placement. This year should be the average veins per trunk
as I understand it right now. And what you might
be saying, Wait, how are you taking it
to the negative 80? Well, with a triangle,
but how does that work? Well, what you
might have seen as you might've seen this picture, which sort of demonstrates at what heights the
orange now spawn. And the idea is that when
you make a triangle here, the bottom point is going
to be at negative 80 and the point at the top
is going to be at 80. And then the
triangle is going to come to a point at basically 0. So in theory, what
should happen is that most cobalt or
should spawn at, at 0 and then it should get less and
less and less and less. So the, you know, it basically is going
to be offset here. So this is just basically a point of doing the hydrangea placement
and middle mouse button. Click on this and you can
actually see that there's also add here.gov and then a
different height providers. Now take a look at
the hypervisor. So I'm going to press Control H. And there is the bias to bottom, very biased to bottom
trapezoid height, uniform weighted list
height and constant height. Absolutely amazing
functionality that you have. You can make your spawn in very particular ways
if you want them to highly recommend
taking a look at this, highly recommend playing around
with this amine basically as until you have your oars exactly like
you want them to. Now I'm gonna do is
I'm actually going to copy the tree
generation over here. So I'm going to drag it into the same package while
holding control. And we're going to rename
this tomorrow or generation. We're just going
to rename this as well, generate ors here. And then instead of the
vegetal decoration, this is now underground ors. And we're actually also
going to take this out of the if statement because r ors, let's just say for
the sake of argument, we actually want everywhere, but we're going to say cobalt
or placed, and that's it. Now the origin ration
here is pretty much done. Now this is going to
place it in every bio. Now this should not place
it in the nether or the end because the cobalt or
configure feature has a list right here of stone
replaceable and deep state replaceable and not of either nether rack or
in stone replaceable. And I don't even think that
they necessarily exist. Another wreck exists
as a rule test, another or replaceable also, what the rest I do not
believe exists there. So that's something
to keep in mind. So the end stone stuff
doesn't exist, right? And now this method just has
to be called right here. Now what's very important
is that it has to be called above the other two. Because if we actually
take a look at the generation step right here, you can see that underground ors happens before
vegetal decoration. So basically starts from
the top towards the bottom. This order has to be
well, basically kept. And here we don't even
need the types and we actually don't even need the key because we're
just going to be like, Yeah, Just wanted in every
biome that's going to be fine. So I mean, that's
pretty much all that we need to do
for our customer. Or once again, play
around with the numbers. Take a look at the
vanilla code and take a look at the vanilla
values. I highly recommend. I cannot stress this enough. You just have to
play around with that and play around with
the numbers a little bit. And now let's see, after we've created a new world, by the way, if our cobol
or its place in the world. Or if answers in Minecraft
and as you can see, some or here, already
generated perfectly fine. That was only one Eco. There's a little bit
of a bigger vein. I was actually eight
of them, though. Everything here
working perfectly. And this will already conclude
this lecture right here. I hope you found this useful and you learned
something new. I'll see you in
the next lecture. So, yeah.
96. Exporting your Mod: All right, welcome back
to the forage course for winning team and
this very short lecture, I will just quickly
show you how you can export your model as a JAR file. So let's open the
terminal and let's put in dot slash, Gradle w build. And that's pretty much all
that you need to do. It enter. And then it basically
creates the, well, the JAR file. What do you then
have to do is you have to go to your Build folder, Right-click Open in Explorer. Then in an explorer
window will open and I'll just quickly
show this. So build. And then in the libs
folder right here, MC course, this is the version defined inside of your
build.gradle file. This is basically the
name that it will take, and you can then take this, put it in your model's folder, you can put it in a uploaded to curse forage,
stuff like that. And then everything
here should work. Great. Yeah, that pretty much
is already it for this lecture right
here and afterwards. So if you're watching
this in the future, you should have
another section here with additional topics
that I will add will over the coming
weeks and months basically with different
stuff like boats, I will definitely want to
still add stuff like that. So keep an eye out
for that if you're watching this pretty early to when the course actually came out and probably nothing
will be there just yet. Well, no worries. New lectures
will definitely be added. So I hope you found this useful and learned
something new. And hopefully I'll see you in the next lectures
as well. So, yeah.
97. (Additional Topics) Updating Forge (1.18.1): All right, welcome to this
lecture where we're going to update forge to the
newest version. We've updated forged before
in a previous lecture. But it does make sense if
you're going to add a lot of stuff we will do in the coming lectures to
basically update forge again. And usually it's
also good to just keep your MOD
basically up-to-date. There aren't often
that many changes, but it's still good
to keep in mind. For this. Of course, we need to change
the actual dependency right here in our bills DOD
Gradle file now to what? To have to change this welfare
that we're just going to open the micro ford.net. And a very important note
from the future right here, I highly recommend using a 1181 version for the
additional topics. While most of this will still work if you update to one 1800s to the world generation and some of the tax
stuff will not work. I highly recommend
here actually updating still to a 181
version, one 1800s. And the update and all of the changes will be covered
in a later lecture. This is gonna take
a little while because there are actually
some significant changes. So it is what it is, but most of the stuff will work. It's just world generation
and tax, like I said, please update to still to one 1800s and then
1182 will come in, let's hope a few weeks when everything has been
settled then hopefully I will be able to make an additional section
where I go through the updating process as well as each of the individual
changes as well. So keep that in mind, please. Thank you very much. And
then making sure that we're on the latest version and
you can see download latest, This is gonna be 39079. And we can even take a look at, for example, the
change log here. We can see some of the changes that have happened
in-between versions. Quite a few actually, because we are still quite far behind on the actual
course version. Maybe you've updated
along the way as well. That might also be a
thing that could be done. But for the time being, we're basically going to
update now to a 3979. And if you're watching
this in the future, which is a very
likely than maybe your version is gonna be
a little higher up there. Totally fine. Then you
just update to that one. Usually there shouldn't be too many discrepancies
between them. So once again, this is the version that we're
going to update two, and then it just load
the girl change, Gradle changes here in
the top right corner, basically clicking the
little elephant is that doesn't appear
and always open to the Gradle tab and then click this button right here,
does the same thing. And as usual, it should take about a minute or two maximum. Usually, if there's shouldn't
be too many things, it probably actually is gonna be very fast for me because
I've already done this. Of course. If you've
done this previously to the same version than it has downloaded all
of this stuff already. But then it might go
a little bit faster, but it shouldn't take
too long a time. So let's just wait for a second. Once again, if you're
getting red here, as long as it's
only info and warn, no worries at all. It's just error that
is sort of an issue. And then of course, at
the end of the day, if there's a build failed, That's also not gonna be good. But if there's a
built successful, anything can almost
be disregarded. That is written here,
that is in red. Here we are built successful
in two minutes, 31 seconds. Like I said, sometimes it
takes a little bit longer, sometimes doesn't take too long. Now we've skipped
a lot of versions, so there was probably a lot
to basically update there. But apart from that,
that is pretty much all that we need
to do to update it. Now, usually when
you've updated it, if there's not too many changes, everything should just work. I believe that here
everything should just work. So we're just going
to let it run and see if we're
getting any errors. There might be one over,
I'm not 100% sure. I don't think that
there's anything to worry about at the moment. But of course here the case
would be just just run it, see if there's maybe
an arrow, maybe, I don't know something in the
foods, for example, change. You would, of course
then see it and then you could just change
it there as well. But in this case, I don't think that anything
drastically changed. So that once everything
has downloaded here, you can see that it
downloads the assets again, basically downloading
some of the resources once, one more time, basically, so that
everything is up-to-date. Because of course we've
updated the first run after you've updated might also take a little bit of time,
but no worries. You can see now the
run client is actually going through the task is
now basically running. You can see we're going
through some stuff. Right here. It says normal. And then on the other screen, the microbe window is
already starting here. We're just going to flip this over and everything
should be working fine. So it should be seeing the
menu screen in just a moment. And there we are. Yes, there we are. There you go. So everything's
still working great. Mods, MC course
is still in here. So everything's working
great and no worries at all that we've updated
the new forage version. And now we can
basically go through the additional lectures that are gonna be very,
very interesting. So there's a quite a few
interesting topics that we're going to basically
discuss in the coming lectures. Some of which are definitely like personally my favorites. There are some really, really freaking cool stuff here, but that would be pretty much it for this lecture right here. Very short one just
to update basically. And then we can go through
the rest of the lectures. I hope you've found this useful and you'll learn something new. And I'll see you in
the next lecture.
98. (Additional Topics) Adding XP Drops to Blocks: All right, welcome back to
the forge course for 118. And then this lecture, we're gonna be taking a
look at how you can add experienced drops
to your or blocks. Now, you might recall
that there are some specific or
blocks like Emerald, for example, that
when you mine it experienced actually
drops after mining it. Supposed to, for example, having the raw
cobalt in our case, drop and then after
you smelled it, you would get the experience. Now this is actually a fairly
straightforward process. So what we can do is
we can just press the Shift key twice and
look for the or block, making sure that we check
this box right here. And then we're going
to check this one. And you can see that
we can simply for the block has in a
uniform int right here. And this is gonna be the experience range that
it's going to drop. Though. It's actually as easy as
going to your, for example, we're going to choose the cobalt or even though it
shouldn't have, this is just an example. We're gonna change this
block to or block, making sure that I
write this correctly. There you go. I'm gonna press the Tab key to auto-complete. And now nothing should change. This should still work, but we need to add a
second parameter here. And that is gonna be a
uniform job you could see. And then we're gonna
say, for example, something like two or, or, and then it's going to be a uniform distribution
between 24. We can also hover
over the offer. I believe that this should, it actually does not offer us any insights to how this works, bummer, but that is okay. I believe that both of
them are inclusive. And we can also of course check if a middle mouse button
click on this again, and then middle mouse
button click on this. I can see, for example,
in the Emerald or we should be able to see that what they're
giving there is, for example, here
between 37 and same goes for the deep sleep emerald. And then I believe that
there is something else. So for example, in
the diamond or yeah, of course that would
also be the case. This one also gets between 37. So there you can basically
choose what you want to do. So let's just do 37 as well. Why not? And that's pretty much
all that you need to do. And now the experience
will drop after this, basically this block is mined. Be wary of course, that if you do this
on non or blocks. So if I were to do this on
the stairs for example, and of course getting
the actual block back. I mean, the stairs would
be actually kind of hard, but let's maybe
choose another one. That's a bad example. Actually, you know, any other block that's just
a block that let's say the planks, for example, if I made this on our
block and I would return certain number
of experience there, I can just set it down again, get more experienced, set it down again, get
more experienced. So this definitely
should only be used for, or blocks, or four blocks
that don't drop themselves. That's the general idea. But because this is
all that we need to do for completion sake,
Let's see if it works. Or we find ourselves back in Minecraft and let's just
harvest some of the orders. And as you can
see, there you go. I'm actually getting
experience when mining them. Like I said, this
example is of course, a little bit not too good, of course in this case
because when we actually smelled down the cobalt or we would get experienced again. But maybe that's actually
something that you want to add. Who knows. But as you can see, this
is how easy it can be to add the custom experienced drops to your customer or that is already it for
this lecture are right here. I hope you found this useful and you've learned
something new. I'll see you in
the next lecture.
99. (Additional Topics) Adding a Custom Menu Screen: Or I welcome back to the
forage course for 118. And in this lecture
we're gonna be adding a custom menu screen
to Minecraft. Now, it's very important
that this lecture and the next lecture are sort
of part one and part two. Because the next lecture
we're actually going to add conflicts to Minecraft. And when you add a
custom menu screen, you definitely 1, 1000% have
to have it configurable. Otherwise, basically
your MOD is immediately blacklisted by any
map pack at all. Because obviously a
mark pack usually has their own menu screen and
you want this configurable. Let's just go through
this however. And let's first of all
start with the menu screen. In this lecture, we're
just going to replace the turning mountain sides, so to speak, in the menu screen with our own menu
screen, just an image. And for that we're going to
go into our util package, right-click new Java class. And this is gonna be the
company title screen. There you go. And I will be copying over
all of the code here, but everything here
is, of course, once again available to you in the GitHub repository and
individual just as well. And we'll just take a look
at what all of this is. Number one, we have this splash screen resource location is exactly our custom cotton menu
screen that we're going to basically well impose there
or draw on the menu screen. And then we also have a
resource location for the Microsoft logo as this
has to be drawn well, sort of above the screen. It's a little weird, but I will basically explain in
the render method here. So the render method, we're gonna go through a few things. First of all, we're
going to call the super in the normal Tidal screen. What then happens
is that they're completely normal
Tidal screen is drawn. Then we need this integer
width and height. We just need this for
our custom title screen. Let me draw our
custom title screen, basically above the
normal Tidal screen. And then we're going to also
draw the Microsoft logo. That's very important. Then here we just
render the main menu. This is just from Forge so that everything works out here. Let me draw the string. This
is the copyrights string at the very bottom right corner. This is very important. Do not delete this. This is pretty much very important that this
actually has to be there. Otherwise, I'm not a 100% sure, but you might be committing sort of like copyright fraud
if you don't have this. So we should have
this definitely this. The widgets here are
just the backgrounds for each of the buttons
in the main menu. We can also take a look at the draw custom title screen method. So you can see it really
isn't that crazy. We're basically just
enabling a texture setting, the sort of just like a
little bit of enabling stuff. And we're setting the
actual texture to the splash screen here and
then we're drawing it. So the blood basically draws this texture that we've set
into the Render system. And then after that is done, we then draw the Minecraft logo. So by setting the texture
to the Microsoft logo, we're then in the next bleach basically drawing
the microflora. That's the general idea. And this is just code taken from the normal Tidal
screen class itself. So this is nothing
too crazy about. That is pretty much
all there is to it. Honestly, there really shouldn't
be that crazy of things. If you want a completely
insanely custom title screen with like completely
crazy stuff, then you just have to go and work through some
of those things. Usually, what most
people just want is replace the background image and that's exactly what
we're gonna show here. Now this goes in
the textures GUI, Background menu or in
the background folder. And then it's going to be
called Copan menu dot re pack. And that's exactly
what we're going to actually get this in the GUI and then right-click new directory called background. Then I'm just going to
copy over the image, which is of course
also available to you if you want to try this out. And we're not going to
spoil how it looks, just not now, but it's going to look
really freaking cool. I could tell you that. Then what do we do after that? Well, we now need to somehow set this title screen
and we're gonna do this in the event class. So in the mode events class, we're gonna copy over a method which is very,
very straightforward. This is also not too crazy, but it's of course
also available to you. We're going to use the screen
open event as you can see. And we're going to check if the screen that we're
currently trying to open is the title screen and it's not actually yet our
account title screen. Then we're just going to replace it or we're going to make a new cotton title screen
and sending it to it. This is pretty much
all there is to it. This is all of the
code that we need. So this is maybe a
little more complicated, but overall hopefully sort
of understandable what is happening here in sort
of a general overview. And then this method and this actually event should
be very straightforward. This is nothing crazy. And yeah, that's
pretty much what we need for this
lecture right here. So I guess let's
see if it works. But the sun is of
course important to see Minecraft starting up. So let's see if our custom
tiles screen is working over. I am very confident
that it will. And there we are, the custom title
screen is working exactly how you
would expect it to. We still have the
copyright notice. We even have the forge stuff
on the bottom left corner. We have the Minecraft, basically everything here, which is exactly what you want. All of the buttons still
work totally fine. So everything working amazing. And I'm not gonna say
anything about anything, but this might be
just a little bit of a sneak peek spoiler, what might come sooner. But anyway, this is really
cool and I really like the background image that
was done by your row. The, it's of course going to be linked in the
credits file as well. So this is really
freaking awesome. But that's actually
how easy it is to add the custom title
scream, like I said, highly recommend watching
the next lecture immediately afterwards to see how we can
add some custom unfixed. Because adding the conflict
to make this well, basically configurable
is incredibly important. I just, I cannot
overstate this really. Please add the conflict here. Otherwise, it's
basically your marr is gonna be never used
by any mark ever. But whatever the
case may be, this is it for this lecture right here. I hope you found this useful and you'll learn something new. If you did, are very much
appreciate a review from you. Otherwise, I will see
you in the next lecture.
100. (Additional Topics) Adding Basic Custom Configs: All right, welcome back to
the forage course for 118. And in this lecture
we're gonna be adding custom conflicts to Minecraft. Now this is not only a
very important topic for the screen or the
custom title screen that we've implemented
in the last lecture. But it is also a
very important and also highly requested topic. So first of all, we need to think
about a two things, and that is the common
and the client conflicts. There are also Server conflicts, but for the time being, we're gonna worry
about the common and the client conflict though, when we think about our
custom title screen, where does this exist as this exist both on the
server and the client, or only on the client. So the obvious
answer is of course, that this exists
only on the client. For those who have said, of course it's only
on the client. That's very good for those who have said,
well, it's on both. Well, let's think about this. Does the server, if we
are running a server, the server care about the single-player multiplayer
options menu screen. Now of course it doesn't. We can even see
this if we middle mouse button click on
the title screen here, we can see this is
only in this client. This means that basically
this class is only ever executed in the client
thread, nowhere else. So therefore to basically turn on or off our custom
title screen, we're going to need to
implement client conflicts. And then I'm also going to show one or two examples of
some common conflicts. Those would be
conflicts that are both for the client and the server. Now in that case, common is an interesting
thing because sometimes the common conflicts
basically are for both the client
and the server. And then there are also
just server conflicts. But we're gonna
leave those out for the time being after we've seen how you can add up the client and the
common conflicts. It can basically add the
server conflicts as well. Please also note that you cannot configure it or you cannot make configurable every single
certain piece of code. For example, some of
the things that are not really that easily
configurable is, for example, the durability
here of the dowsing rod. As an example, you can imagine why we can
just replace this with a configurable number
that doesn't quite work. So there might be
some workarounds, but usually when you
are registering stuff, so right now we're recording
the register method. Everywhere where you are
registering something. Usually you don't want
to change those numbers. It's very hard to sometimes say where you can
and can't do it. I just highly recommend if you really want to try
out some stuff there, try it out, see whether
or not it works. Because sometimes they
might be a mismatch from the server and the client if
the client has a different, different conflict
than the server. And therefore this might
get a little bit weird. So just keep that in mind. You can't necessarily configured everything in our
MC course package. We're gonna right-click
new package called the conflict package. And then I will actually copy over two of the classes
that we're gonna need. And I'm actually going
to go through all of the code is of
course available to you in the GitHub repository in an individual just as well. So no worries at all. And this is also not that crazy. Let's start with the client
conflicts right here. We can see that what
you're going to need is a conflict spec builder, which is just equal
to new builder. And then this conflict
spec right here. And then you can see
that you're listed are basically all of our
static config values. You can see that
it is a generic, so we're just going to
put in a different, different datatypes
basically, which are in these cases what we want to
configure it or configure. And then you can see in this
static block right here, just having a builder to push, It's just what's written on
the top of the conflict file. And then this is being set to see, first of all, a common. So this is whether
or not the default title screen will be replaced. And then we're going
to define this. This is just the name
of the variable, so to speak, and this is the
default value in this case. And then looking at the
common conflicts here, you can see that here we're
actually going to make configurable the
veins per chunk and the veins size of the cobalt. Or this is very interesting
because this is also something that sometimes
could be configurable. Or you want this to be configurable, which
is very interesting. So what we're gonna
do is first of all, we're going to use
the client conflicts, but we need to, of course,
also register those. So how do we register those
in our MC course mod class, we actually only need
to add it to things. And this is gonna be after this. What we're gonna do
is we're gonna say, we're gonna get the mod
loading on text dot, get that register config. We're gonna say
motor config data. You can see types already there. We're going to choose the
client type for the first one. We're gonna say MC. Client conflicts that spec. And then the filename
here is just gonna be, it should be your
MOD id, dash client. And then very
important that Tamil, this has to be a dot HTML file. Otherwise it's not
going to work. Then we can duplicate this
by pressing Control D. And I'm gonna change this
to the common right here. And then we're gonna
change this to the MC course, common conflicts. And then very important that
we change this name as well. You can see now we
have both, well, on fixed registered and
that's actually all we need to do to register
these conflicts. So that's all there is to it. Now how do we use them? Well, it's fairly
straightforward. We have this field right here. So let's go into our code. Actually it's not the
column title screen. We actually wanted to do
this in the MOD events class right here in this if statement, we basically wanted to say
MC course client conflicts, that custom title
screen dot get. And then It's going to end this. So this needs to be true, and all of this also
needs to be true. And then our title
screen is going to be replaced just for
completion sake, let's also just immediately
use the vein for trunk stuff. So this is going to
be in the world. The first one is going to be in the place features they ago. This is gonna be the
veins per trunk. So this is gonna be MC course, common conflicts dot
Paine's per chunk dot get. Let's just read. Yeah, that's fine. And then the other
one should be in the configured features. So this is gonna be the,
this one right here. This is the vein size
for this would be the MC course common conflicts
vein size that gets, what we're going to do actually is we're going to let this run once so that the
files here generate, so then the actual fixed files regenerate and then
we're going to change the values
inside of them. But let's just run
this once and let's then see the conflict
files generate. First of all, you can
see Minecraft has loaded and the title screen is still there because of course the default value here was true. And most importantly,
we now have generated the config files. They are under the R1 folder
config and there you go. Mc course client and
MC course common. If we open them, you can see that we're basically
getting exactly this. You see conflicts
for MC core smart, and then whether the default title screen will be replaced. We change this to false
now and saving it. And then here, let's just, let's just go absolutely crazy on this just
so we have this. So let's go. So for now we're just gonna make a lot of veins per chunk, a lot of veins size, just so that we actually can
see that this is going to work and this is going to
affect the world generation. And yeah, that's pretty
much all that we need to do to change
the conflicts. These are then of course
also available to the users, to the players,
and then they can change them however they want. So definitely make sure to
have proper comments here. There's gonna be
this one right here. As you can see, this is what has been written as a comment there. So that's pretty much
all that you need to do. So now after we've changed
the conflicts, let's see if, for example, first of all,
the title screen has changed and then also the world
generation as well. Alright, so as you
can see number one, the actual title screen has changed back to the
normal Tidal screen. But this is very interesting. Now let's actually generate
a new world here and see whether or not Then in
the world generation hour, cobalt or is going to be all displayed in a way more
forms than before. Or if answers in Minecraft. And as you can see, I didn't
have to go down very far to find an abundance
of the or, right. You can see that not only are
the actual veins massive, there are a lot of them. As you can see, these
are two different veins, three different veins like
right next to each other. And then you can see it
just goes on and on. I can actually go to
spectator mode again. And you're gonna see that there
are a lot of those veins. So you can clearly see
that even though this is definitely not something that you necessarily want to have, but it is definitely
configurable. And this is pretty much
exactly what we would expect from those or
conflicts to then do. So that's really cool. But there is another method that we might be able to
call and that is the defined in a defined
list but defining range, which is also quite
an interesting one. So this one basically here
then does the following. You can also define a
minimum and a maximum value. So this might also be
very interesting and important for you to
basically say, you know, maybe the number of
veins per trunk and the veins size should be
kept in certain values. Or maybe, you know,
some values that you wanted to make
configurable might actually be broken if they are not in-between certain numbers. So keep that in mind as well, that you can also do that. But for the time being, we're
gonna keep this undefined. I just wanted to show you this. I can also always
like every time, just advise you to play around
with this a little bit. See what you can
basically change, what types of things might
work and which ones don't. So there are a lot
of things that might work and might not. So keep that in mind. But otherwise, this is
pretty much how you can add custom
conflicts to Minecraft. And most importantly,
how you can configure it or conflict, make a conflict for your
custom title screen, because this is
extremely important. If you have a
custom title screen that you make it so that
you can turn it off because otherwise you
will never be used for NMR peg ever
incredibly important. So please keep this in mind. Otherwise, this is going to be it for this lecture right here. I hope you found this useful and you'll learn something new. If you did over very much
appreciate review from you. Otherwise, I'll see you
in the next lecture.
101. (Additional Topics) Adding Transparent Blocks: Or I welcome back to the
forge course for 180. And in this lecture
we're gonna be adding a transparent block
to Minecraft, this commerce by popular
demand as some people had some struggles with adding a transparent block
to Minecraft. However, it actually is
not that crazy if you know the two or three very important tweaks
that you need to do. So in our mode blocks class, we're just going to go
at the very bottom here. I'm just going to copy
over the sampling. Now there's a few things
we need to change here. This is gonna be called
the winter window. And this is of course, also the winter window. So first of all, into a
completely normal bulk here, and then this is going
to be a glass block. This is very important that
this is a glass block. This will only require the actual block behavior
properties right here. And then what we're gonna
do is we're gonna copy from the glass block as
well from the properties. You go into the glass block, middle mouse button click and then the middle mouse button click again on the
abstract glass block. We can see that number one, the thing that we need is
the propagates skylight down and also the shape brightness.
We get visual shape. I'm not actually a 100% sure
what this necessarily dusk. I just know that all of them
are basically important to get to have a
transparent block work. This is why we are just going
to use the glass block. This is basically
also a glass block, so no worries there. Now, what we also need in our MC for smart class in
the client's setup, we're just going to copy
over the render layer here. And this is going to get the
winter window render layer, and this time translucent. So it's going to have
the same render layer as the honey block fluid, which is also of
course translucent. This is very important, otherwise it will
actually not work. And then of course,
all of the stock stuff like just the block
States Jason here. Just a normal walk stage Jason, same with the translation. All of that is pretty
much just standard. The only difference
here is then, of course, once
we've added this, the winter window here, the model files,
all the same stuff, so it's just normal model files. We could also just copy the other normal model files over and see this
points to a texture. And then same pretty much
with the item model file. And those are of course also available if you want
to copy them over. But as you can see,
there are normal files, nothing crazy about them. Pretty much the easiest
variance of those files. And then what is of
course important for the texture that I
will also copy over. And you're going to see
this, this right here. So all of the sort
of inner blocks, those are the ones that have an alpha value that is
a little transparent. So this is of course very
important that if you have a PNG that you wanted to use and some of your actual pixels have to have Alpha values
that you can look through. Otherwise, of course
it doesn't quite work. Otherwise, the see-through is
not going to work properly. So keep that in mind. But otherwise that is
actually all that we need to do going through everything. Pretty much what's most
important is the translucent. Like that we have Alpha values
in our actual PNG file. And then also that we are using the glass block, which
is very important. I guess see for completion
sake, let's see if it works. All right, We are financial in Minecraft and as you can see, the winter window has been successfully added to the game. And as you can also see, I can look through it. No worries at all though
everything working only fine. I mean, that's how
easy it is to add a custom transparent
block Minecraft brand that is already it for
this lecture right here. I hope you found this useful and you'll learn something new. And I'll see you in
the next lecture.
102. (Additional Topics) Adding Animated Items: All right, welcome back to
the forage course for 118. And in this lecture,
we're gonna be adding an animated item to Minecraft. So this might be like, Wow, that's a really cool thing. And it might be, you might say, well, this is probably going
to be very complicated. It actually is fairly
straightforward. But we're going to see a custom animated item in this lecture. And then I will show you one vanilla example
of an animated block. And then if you want an
animated block basically, then I can highly
recommend taking a look at that vanilla example. In the mod items class, we're going to add a new item. So let's just copy over the
cobalt ball right here. And this is going to be
the magic underscore dust. And then same here
into the name. This is going to be the
magic underscore dust. And this is going to be a normal item,
interestingly enough. And we're just going to
make it so that it has basically no other item
properties here whatsoever. We're just going to have the normal item,
completely vanilla. Nothing crazy about this. And let's actually add the translation before
we go into the, into the actual other things. So the other item
model adjacent files. So there's going
to be the magic of dust and this is going to be the magic dust as well. Now, you might be saying, Well, this is probably going to be a crazy complicated query is a complicated item
model Jason file here. Let's just copy it over. Of course, everything
available to you in the GitHub repository in
individual just as well. And you can see that it is a completely normal JSON
file for the item model. Or you're gonna be like,
wait, where is it? Where's the animation? Animation is all in the texture, as well as in the
MC metafile. Aha. We're going to copy those over, which are of course
also available. And then you can see
that we have number one, The actual texture as
well as an MSE metafile. And if we take a
look at the texture, it actually is multiple
different textures. So you can see that
these are in fact six different textures
for the same, well, it's the same item. At the end, come out to basically 16 times
however many textures you have times 16. So that's the idea. So it's 16 by, in this case, 96 is a size here, and the MC metafile determines how you
actually go through this. You can see this
is an animation. Can change the frame time to basically change how
fast the animation is. And then here you
can basically say which frames are going to
be laid in which order. Interpolation simply
means that when one frame changes to another is to change gonna be discrete. So is it going to change from one picture and
then in the next, let's say second,
see other picture. Where's it going to
transition through them? That's the general idea of
interpolation in this case. But that is actually how easy it is to add a, an animated item. And then this is immediately
going to animate as long as you have the
MC Mehta file here. What is very important
is that this MC metaphor has to be written
exactly like this, including the dot PNG here. Please make sure that this
is written correctly. And like double and
triple checklist, it's incredibly
important that this is the same name as
the texture file, including the ending then dot MC Mehta. Please check this. Then when it comes to the book, we can go to the external
libraries, of course, once again to the client extra 1801 or whatever your
version might be, assets, Minecraft,
textures, Bullock. And then one thing to take a
look at is the magma block. So this one also has an MC Mehta file and you
can see there are actually three
different textures that ID, it goes through. That, as you can see here, with the frame time of eight, goes through all three
of those frames and then changes the
texture here as well, same with the another portal. So you can see the
nether portal actually has a lot of different
textures as you can see, it goes through, Well, I mean, it apparently
goes through everything. I am not a 100% sure how the
animation here is empty. I'm not quite certain
how that works, but that is also
another example. I personally recommend
the magma example. And I believe that it's
pretty much all of the sort of like
really crazy examples here, repeating command block. But there's a few things
here still there. But the macroblock
is probably the easiest to follow and should be. I mean, it's like
it's fairly sensible, fairly straightforward,
all things considered. It's pretty much
exactly the same as the one for the magic dust. But yeah, that is pretty much all that we want
to take a look at. And now I guess for completion sake, let's
see if it works. Or we find ourselves
in Minecraft. So we'll see there
the magic dust has been successfully
added to the game. And as you can see, while
I'm holding it in my hand, Let's just pick it
Southern only have one. You can see that
it is a slowly but surely animated and I can
even throw it on the ground. And you can see
that even they are, the actual texture
is animated as well. So that's actually
how easy it is. And as I've said, you can basically change the
speed of the animation by changing the frame time
inside of the MC Mehta file. That's how easy it can be. That is already at for
this lecture right here. I hope you've found this useful and you'll learn something new. And I'll see you in
the next lecture.
103. (Additional Topics) Adding Custom Effects: All right, welcome back to
the forage course for 118. And in this lecture, we're gonna be taking a
look at how you can add a custom
effect to Minecraft. Now, the adding of the customer effect
actually comes well, more or less, thanks to a student that has
added their own effect. And I've sort of co-opted their effect and made
a lecture out of it. So you of course know who
you are thinking very much. And it is a freeze effect. It's actually
really interesting. So it's going to freeze
a entity in place. And we're just going
to see how this works. It actually is more
straightforward than you might think in our
MC course package. Right-click new
package called effect. Then instead of
there, we're going to need two new classes. One of them is the
model effects class. And then the other one is
gonna be the freeze effect. The freeze effect class is where all of the functionality is in. I will simply copy
over the class like, like always, of course, everything available to you in the GitHub repository and
individual just as well, ready? So here you can see the
freeze effect in action. It is fairly straightforward. All things considered, we have overridden the apply
effects tick method, which basically will
is called every tick when a certain entity
has this effect on it. And then we also have the
duration effect tick. True, because if we
don't have this while, then basically this
would never be cold. So this is what we need. Here. You can basically see that refers of all checking
whether or not we are on the server. If we are, then we're taking
the XYZ coordinates of this particular entity that
has this effect on mortality, reporting the entity to it, and also setting the
Delta movement to 0. So this is needed for
the player basically, and this is needed for, well, animals or any NPC basically. So any non-player entity, simply because of the fact that the Delta
movement is, well, what basically moves
the actual animal and they teleport to, it doesn't just the top
row two does not work. So this is the two
things that we need. And if we add those two, then the actual mob, or in this case entity or the player is going
to freeze in place. Really freaking cool,
like really a cool idea. And I really like it. Then how do we basically, the question is, how
do we register it? Well, you have seen this before. Public static final,
what do we need? Of course, a deferred register, this time of a mob effect. This is gonna be called the
MLB underscore effects. And this is of course equal to what is it a
different register that create registries
dot mlb effects. And then of course our MC core, smart but not ID. And like every time, like we've seen a the third
register, what do we need? We need a public static
void or register method with an eye event
bus, whole event bus. And then we're calling
the MLB effects or register and passing
in the event bus. Nothing too new here. This is pretty much like every time we've seen
the effects here. And then this will be called once again, of
course right here. So just blow our mod recipes. We're gonna say mob effects that register and then passing
in the event bus. And there you go,
Everything is registered. Just need a registry
object here. So we're gonna say public
static, final Registry object. Of course of type of mob effect. In this case, it's gonna be
cooled freeze and is equal to mob effect starts register
the name freeze here. And then we're going to need a supplier of a
new freeze effect. As you can see, mob
Effects category harmful. And then just
basically any number. This is a, I believe,
a unique identifier. Take a look at this. This is actually
this is the color. There you go. This is the color. That's what it is. But this is the
color of I believe, the portion that would
be associated with it. Now we're not gonna add the
portion in this lecture. We're actually going
to add the portion on the next lecture. But after having added this, the freeze effect is
actually in-game. Now, this is all that we
need to do to add this. I know it's pretty crazy, but that is all we need to do. So I guess see if it works or we find ourselves
back in Minecraft. So let's see, Let's
give myself the effect. Let's go dev. And then you can see these freeze effect is
there unless add it. And now I can't actually move. You can see that it's
sort of jittering. And I've added this for
thirty-seconds in this case. So I can't I can actually
fly up a tiny bit, but if I try to move, you can see that it's
very, very slow. In this case. I know if I am on the
ground and try to move, I'm pressing the W key. It works like very, very slowly. And even, you know,
going around here is, you can see it's definitely freezing meet sort of in place. Now I can still
break blocks that an eye bank, but that does work. And you also have seen that the actual texture
was not there. We're going to add
this texture as well. It actually is fairly
straightforward, but that is pretty cool. All things considered. The texture goes to into
the textures folder. And here we need a new directory called mob underscore effects. And then the actual
texture needs to be the same name as the
name right here. So in the MLB effects, this name has to be this name. And now instead of a non,
nondescript texture, this texture will be
displayed and well, I mean, it's basically
going to work. Now, like I said in
the next lecture, we're immediately going
to add a portion for this because it does make sense in my mind
to have a portion. That's what basically you
can then use as well. For the time being,
this is pretty much it for this
lecture right here. I hope you found this useful
and yellows and the due. And I'll see you in
the next lecture.
104. (Additional Topics) Adding Custom Potions: Or I welcome back to the
forage course for 118. And in this lecture
we're gonna be adding a customer potion, including a custom broom
recipe to Minecraft. Now, the actual portion
is very easy to add. The brewing Recipe,
however, is, well, let's say it's a little puzzling why it works the way it works, but no worries, we're
gonna get through this. Well, first of all, in
the MC course package, right-click new package
called portion. And then inside of there, we're going to make a new Java
class faculty mod oceans. And this is going to
look eerily similar to what basically a lot of other classes that
we've seen before. A public static final
deferred register of type ocean this time. And it is gonna be
portions of course, is going to be equal to
the deferred register that create registries,
dark oceans go. And of course MC, course
moderate or mild ID. And then you need the public static void
register method as always, with the eye Event
Bus, Event Bus. And then we're gonna
do potions dot register with the,
the event bus. And then let's call this in the MC course
constructor right here, mod potions, they ago register and then passing
in the event bus. And then we just need
to create the potion. So there's gonna be a public
static Registry object of course, of type ocean. Go. And this is gonna be the
freeze underscore potion is equal to potions
that register. This is the frieze
underscore potion, again, the name here. And then this is requiring a
supplier of a new portion. This is going to need a
new mob effect instance. There you go, of our effects. So mod effects dark freeze, the one we've added
last lecture. I'm just going to do ten
seconds with lobbying. Basically amplifier is 0 here. So this is gonna be the
number of later time in tics, and this is gonna
be the amplifier. So if we're putting in a 0 here, and this is gonna
be a level one. This is gonna be flying
freeze at level one. And that is actually
all that we need to do to add the actual portion. Now for the brewing recipe, we're actually going
to make a new class. Now this is very interesting
because there actually is a class which is called
the brewing recipe, I believe yes, from micro forge. So you can see that this
is a brewing recipe that implements this I
ruined recipe interface. And this works and
we can use it over. What's really interesting
is that for the input, it doesn't actually
look at what the, let's say what's the actual portion is that you
need to put it, but you know how you can put
in a certain ingredient at the top of the actual
brewing stand, and then at the bottom you have three slots for
different portions. And usually how it
works as you need an awkward potion to do this and a specific other
posts to do this. And in using this
brewing recipe, it just doesn't matter
what the input is like. It doesn't, it doesn't check for whether or not it
is the actual portion. Therefore, this brewing class
is pretty much completely useless and it doesn't
need to be used. Now I have found a wall, an alternative that I have called the better
brewing recipe. Now we're going to
copy this over. This is actually in
the util package. And the not exactly the same, but the name is different. The class is exactly
the same as from this GitHub repository
right here from extra portions then by casualty. So this is under the
GPL three license. So be aware of that when
you're using this class. Just saying, But
overall, I mean, it's pretty much, there's no other way to do this really when I'm
thinking about it. So I've gone through this
and we're like, Okay, it's always going to look
exactly the same pretty much. And this is just the best
way to do this class really. And then we can use this better
at brewing recipe costs. To actually add the recipe, we only need to add one recipe. So this is immediately going to work for the slash potion, the normal portion and
the lingering portion. So that is really cool. Now when we add those
portion recipes in the setup method in our FML
common setup right here. When we want to
do is you want to say brewing recipe registry, this one right here, add recipe. And then we're just
going to make a new, better brewing recipe. There you go. And then
we have the passion, what portion we want. So this is gonna be pushing
start awkward in this case. Then the actual ingredient. So this is going to be an item. So we're gonna say more
items that cobalt ingot, let's say this is going to be the cobalt anger right? There. They go, dot get and
then mod portions. Because of course
the actual result or the output should
be the freeze potion. And they go now putting in awkward positions
at the bottom and a cobalt ingot as the gradient is going to yield
us a freeze potion. That's all that we need to do. That's actually how easy it is. Now for the potions, we also need to add
some translation. This is very important actually. There are few things
that we need to add. First of all, we need to
add those three ones here. So this is going to be the, you can see that this is
portion effect freeze potion, potion for the splash and
the lingering portion. Incredibly important. This is actually under
the Minecraft namespace. I am not a 100% sure
why that is the case. I mean, I'm like 80% sure
why that's the case. The idea is that when you are actually registering a portion, when you're making a new
potion, so to speak. Then what happens is that
this just gets added to the. The actual portion
list in Minecraft and then this is under the registered under the
Minecraft namespace. I'm not a 100% sure if that is a bad thing or a good thing. I mean, it might be a bad thing for the
time being though. We're gonna keep it like this. If there are any
conflicts in the future, we're gonna solve those as
well. No worries there. But that is basically
the idea of the oceans. And now we also need the effect. The effect looks like this. We're going to add this
at the very bottom. This effect dot M
C corps freeze, and this is just code freeze. These are the translation that
are incredibly important. Now also what's
interesting for the item, for the potion items that you get generated automatically. And we don't need to do
anything for them at all. So this is pretty much
all that we need to do. The color of the actual portion is taken from the mod
effects right here. So this color right here is basically what's
going to be used. I'm not a 100%
sure what this is. It might just be a hex color. I'm not sure. It might
also be something else, but this is gonna be fine. This is just play around
with this as well. If you want. Some other colors are
for the time being, this is pretty much all that
we need for the custom, both the custom portion as well as the recipe here to be added. So I guess let's
see if it works. Or we find ourselves
in Minecraft. So let's see, let's just
add the aqua portions and then one cobalt ingot and
it should start brewing. And indeed it does,
it starts brewing. And then as soon
as this has done, the awkward potions should
turn into freeze portions. So let's get some sheep just to see whether
or not they're actually going to be
basically frozen in the end. Let's see. Here, we're almost done, and then we'll
have some potions. Let's go. So we have
a freeze potion and another freeze motion and a lingering freeze
portion as well. So everything working
exactly how you'd expect it to one sheep or kill itself. That's amazing. Wow, that's really funny. Let's see. And there you go. And then you can see
they can't move anymore. I can even hit them and
they can't move because the freeze portion is literally
freezing them in place. We can also try the same
thing for some zombies, which is really fun because basically they tried
to chase you and then, oh, well, I mean, I believe I am on peaceful, so there you go. Let's copy this and then
we're going to switch to survival and then I'm
going to try and get them. And there you go. So
the little baby zombie, as you can see, that
stopped moving. Let's actually get some more freezing portions
splash poses here. Just so that you can
show this again. Once again, we're just
going to switch over and I'm going to
freeze them. Freeze. And freeze as well. Oh
no, I froze myself. That's not good. We can see that, of course
sometimes can also happen, but it is really freaking cool. And yeah, that's actually
how easy it is to add not only custom portions, but also custom portion
recipes to my craft. Has always the entire
quarters, of course, available to you in
the GitHub repository or an individual
adjusts as well. But this is gonna be it for
this lecture right here. I hope you found this
useful and you'll learn something new if you did, I would very much appreciate
a review from you. Otherwise, I will see
you in the next lecture.
105. (Additional Topics) Adding Custom Entities with Geckolib: All right, welcome back to
the forage course for 118. And in this lecture, we're gonna be adding a custom entity or
custom mob to the game. This is gonna be the
start of a, let's say, few lecture part
series where we're basically going to add more
functionality to our entity. We're gonna go
through, first of all, adding a normal entity to the game than adding
some animations. Then in the next
lecture after that, we're going to make it a table. We're going to add
different variance of that particular entity. And then at the end,
we're going to also add an entity that is
going to be writable. So all of those things are gonna basically await us in
the coming lectures. Now, what I will say is that every entity
that we're gonna add, we're gonna add two entities and both of them are going to use the gecko lip API libraries. Even though it's not strictly
necessary for, this, suggests a normal mob without
any additional animations. I still recommend
basically always just using the glycolipid library
to add the entities. Because it, it definitely
makes it a lot easier in a lot of ways. Basically, it just
makes it easier. And so we're first
of all going to set up gecko lip. For this. We're going to basically copy
this one overwrite here. So this is the, as you can see it on GitHub, the gecko lib wiki
installation guide. Basically i'm, I'm
gonna copy this. And then we're gonna
switch back to here, go into our built
DOD Gradle file. And this, the first one
we've copied it was going to go into the repositories
right here. So just going to
add it right there. And then the other one,
this one right here. In this case, I will
leave this should already be the
newest version here, 3011 on this site. I'm not sure if this is updated while every time that a
new version comes out, but hopefully this is just going to go below a
Minecraft right here. So this should be
everything that we need. And now we can load
the Gradle changes. And it's basically
going to download the glycolipids version and
it's going to implement it so that we can basically
use the gecko lip EPI in our mod as well. And after this is, once again, it might take a minute, it might take thirty-seconds. Depends on a lot of factors. Basically, you can
see actually was fairly quick year 21 seconds. That is pretty nice. Then the question is, well, where are we getting
our entities from? Well, for our entities, we are going to use block bench. Block bench is a program with which you can
make generic models. You couldn't make block
models either models. We've seen this already, but
also we can make entities. Now what's important
is that you have the under file plugins and you have the
gecko lip Animations, Animation utils right here. So we're gonna need
this particular plugin. Otherwise it's not
going to work. So make sure that
you install this. Basically go to available,
then search for it. Now I'm not getting it because
it is already installed. You can see install this
and then you should have the possibility of adding the gecko lip animated
model right here. Now I have already
some prepared stuff, so we have a raccoon
and a tiger. We're gonna first of
all use the raccoons. I'm just going to open it and
you can see, there you go. The raccoon already
done right here. And well, I mean, basically, this raccoon is also
already animated, so we actually have three
animations right here. We're gonna take a
look at the animations in the next lecture in a little more detail
for the time being, what we're gonna do is we're
just going to export this. What we're gonna
do is once we've made a, a custom entity. So to use the actual
raccoon model in our project and our MOD, you have to export this. So we're gonna go to File Export and then Export gecko lip model. If this does not appear, you can click on Convert
project and make sure to basically choose the
Kekule lip animated model. If this is not already the, already the current format, then the actual export
here should appear. We can then use this and
then save this under the raccoon GO dot JSON file. I'm just going to replace. This is gonna be fine. And now I have exported
the model actually, and we can already use this
inside of our game-based. I also have the texture, I have this actually separated. You can also in
theory save this from the actual block
bench file as well. But we're gonna be fine. Like I said, the animations
we're just going to completely ignore
for the time being. We're going to use those
in the next lecture. Let's switch back to IntelliJ. And what we're gonna do is we're going to immediately make a new folder in the
assets folder MC course. And then here we're going
to make the geo folder. And this is going to get
the raccoon GeoJSON file. They go. This is basically
how it looks like. There might be a typo
in here somewhere, that's gonna be fine. I believe that whatever
it's called in this file, actually, it doesn't matter. And then we also
going to need is, we're also actually going to need to get the texture file. Of course. The texture file actually goes
to the textures of course. And then instead of the
entity pulled up right here, entity, then the
name of the entity. In our case, this is going to be and then I'm going to copy over the actual
texture right here. There you go. This just going to be
the raccoon texture. I'm going to basically
points to those in just a moment when
we're actually implementing the entity for now, those are the main things
that we definitely need. The geo file right here, the GeoJSON and the texture. Then there could also be
an animations folder, which basically then contains
the animations which we're gonna use in the next lecture. Now, we're going to
make a new package right here, entity. Inside of there. We're going to create
a new Java class. The mode into t. The mode entity types
is going to have a public static final, the third register of
type, entity type, and then once again, the angle brackets with a
question mark inside of them. There's going to be the
entity underscore types going to be equal to the third
register dot create registries, that entity, entities
actually they ago and then MSC course
smart that market. And whether it's a
different register, of course there's a public
static void register method. Then I Event Pass old
event bus right here. And then we're gonna
call the entity types that register passing
in the event bus. Then we're immediately
going to go right here below the more portions. And we're gonna say
more entity types, not register passing
in the event bus. And then we have this
class registered as well. Now here we're
always going to have some registry objects of
our different entities. But before we are going to
basically continue with this, we're going to make the
entity class itself. Once again in the
entity package, right-click new
package customer. Once again, I'm gonna call
this the custom package. And then instead of they're going to make a new Java class, and this is gonna be
the raccoon entity. Now when it comes to
the raccoon entity, this is gonna be
very interesting because there's a lot
of things going on. I will also copy over
a lot of this stuff. This is all available to you in the GitHub repository and
an individual just as well. So no worries at all. What we're gonna do
is we're gonna make this extend by animals. So extends animal
and also implements the eye animatable
interface in this case. Now, we're just going
to hover over this, the add of those different
methods right here. And I'm going to hover
over this grid constructor matching super as well. And if those names bother you,
you can just click on it, Shift F6, and then it should suggest something a
little nicer here. This is going to be kept null, in this case, the red offspring. So this is just going to be the eligible mob
to get children. We don't need this
at the moment. The controllers are for the animation stuff as well
as the animation factory. And we're going to add
the animation factory immediately because this is
literally just one line. As you can see. There's just a private
animation factory. Animation factory. And then
we're just passing this in. Then it can basically
return this right here. The controllers, we're not gonna return anything
at the moment. First of all, what
we're gonna do is we're going to take a look at the other things that
we need for the entity. Because there are
at least one set of methods that we're
gonna need and that is the set attributes. This is something that
is incredibly important. Actually. If we don't have this, then it's actually not going to work. We're just gonna do
the following they go. We're basically just setting
some basic attributes here. The max health, the damage, the attack speed of
the movement speed. You know, of course you
can play around with this however you would like no change them about basically in whatever way, if
you would want to. But this is very
important that we have this because otherwise the actual entity is not
gonna have any attributes. And of course that's not
quite what we want here. We of course wanted to
have some attributes. There are also some other
methods that we can override. Well, let's separate
this out a little bit. So this is going to be all
of the animation stuff. This right here is
all for animations. And there are some other things that I'm gonna copy over here, but those are just some
sounds as you can see. There is, let's just
open it all up. There you go. So
there's a step sound. I've just picked a
few sounds here. There's a cat straight
sounds just as ambient. Dolphin hurt is when it gets
hurt, often deaf sound. Why not? At the moment, I don't
have any raccoon sounds, but of course they
also shouldn't matter. But these are basically the
sounds that you can define. And yes, of course,
you could also say mod sounds and then use one
of your mode sounds as well. You can of course add custom sounds or your
entities as well. That's pretty cool. All things considered. I mean, that pretty much
concludes the chunk of this. The last thing that
we also want is we want the register goals method, and that is a method that
we can also override. Now I think that we're
going to have two things, exactly two things
that are going to be a commented
out at the moment. Because those are for when we're gonna
make this T-Mobile. At the moment, we're
not going to make the raccoon table
because I want to basically go through this
step-by-step, the goals. This is basically the
AI of this entity. This is very, this can
be a very complex topic. So there are a lot of different
goals that we can add. So what we can do, for example, is we can middle mouse
button click on one goal and you can see this
extends the goal class. If I now click on this
and press Control H, These are all of the goals
and now I can expand them. And you can see there are
a lot of different goals. You can see. And of course in theory, you can even write your
own goals as well. So there really is a
lot of stuff in here. And once again, this
is one of those things where you just going to have to play around
with this a little bit. Look at the vanilla entities and see how they're using goals. The general idea is that
the lower the priority, like the lower the
priority number, the higher it actually
is in the list. One would be the
highest priority and six is the lowest priority. But if it has to choose
between one or two goals, it basically takes a
look at the priorities. So that's the general idea here. So making sure that this is basically always
set up correctly. And then like I said, you can just go to the
animal, for example, middle most punk click
on this press Control H. You can see all
of the animals. But for example, we could
take a look at the fox here. And you can see there's a
lot of different stuff in here that actually does not really interests
us at the moment. We just want to see
the actual goals. You can see we're
just her goals, but you can already see there's quite a few
different goals here. This lamp target goal, there's a turtle
egg target goal, There's a fish target goal. We got some goal selectors where we add a certain
goals in here, the panicle, the breed goal, avoid go entity goals. So this is a goal which avoids a certain entity in
a specific distance. So there's so many
things that you can do. Now. You can also see that
most of them are specific to the fox is
instead of the fox class, let's say for example, the sleep goal for
middle mouse button. Click on this. You'll see that the sleep goal is actually in the fox behavior goal
and it's actually inside of the box class. Sometimes some of
these goals are actually inside of their
actual respective entities. And this is also why,
for example, the fox, it has like 1600 lines of code. There is a lot of stuff in here. I mean, I would say probably the most complicated thing in terms of custom entities
for life in general, it just is what it is. Highly recommend. You have to go through some
of the vanilla entities and just play around with it and
then see what you can see, like I said, middle
mouse button click on this control each
year on the goal, and then you should
be able to see all of the goals available. And then it worst-case scenario, you can also copy some of them over if you
necessarily need them. Then the actual recall
entity class here is done. Let's then register it in
the more entities class. I will actually also
copy this over. Like always, everything
available to you in the GitHub repository
individual just as well. Now this error
comes about because this should be protected. So we're gonna make
this public right here. And then the arrow
should go away. So no worries there at all. And you can see there's a
registry object of entity type. Then we're gonna put the class
that we just made in here, the raccoon registering
under the raccoon name. And then we're gonna
say entity type builder of the record entity knew. This is a creature in this case, this size is actually the size of the heap
box of this entity. And the magnetic build it under the resource location
or more Id under the, once again, the
raccoon namespace. And that is pretty much the registration is
done right here. And now we do still
need to well, I mean, basically add this in a
few different places. The first place we want to
add this is actually in our events and this is gonna be in the mod event bus events. Interestingly enough, because
right here we want to add a new event as the
public static void. And this is the entity. Attribute event, I'm just going to call that
and then we're gonna say entity attribute. This is the creation
event, quote event. When we're gonna do is
we're just going to call Event tab put, mod entity types that
raccoon, that GET. Then the raccoon entity,
set entity attribute. And then we're just
going to add the add subscribe event right here. Very important that we add this. And now this will basically add the attributes that
we've defined right here to every raccoon that
is existent in our world. That's the idea. There. There are however, a few
more things for the raccoon, for the entity in general. For the entity, we also going to need a renderer and a model. So in the entity
package runs again, right-click new package
and we're gonna call this the client actually, because of the renderer
and the model for both be client only
if I'm not mistaken, we're gonna say Raccoon. This is gonna be the renderer. Then we're going to make
the other one as well. This is gonna be the raccoon. This is gonna be the model. There you go. No worries there at all. The, which one is easier? The model is gonna be
a little bit easier. But this is going to extend the animated Geo Model of type
record entity that you go. And then we're going to hover over this, Implement Methods. So we need to implement
these three methods. Now, this is actually
fairly straightforward. I'm going to copy over
the one thing here. So this is just gonna be following a new
resource location. And this is pointing
to exactly the GEO and then raccoon
that AOTA Jason's, this exactly this
tracer file right here, which we basically have. And then we're going to
also just copied this over. I'm actually not a 100%
sure what's going to happen if I don't
have this file, I'm not quite sure. And for the texture, we have this right here. So textures, entity raccoon
and then the raccoon, a PNG. Now this one I'm not on percent sure because I've actually not tried this without
the animation file yet. But I think that there's
going to be fine. We're going to see if
we're getting crash, then you're going to fix that in a moment of no worries there. But this is the actual
model file and then we also need the render. Of course, the renderer, in this case, should actually
be a little bit easier. So this is going to extend the GU entity renderer,
raccoon entity. Once again note none of record
model but raccoon entity, but it just hover over this. And if we construct
our matching a super, Now what we need to do here
is we need to get rid of this model provider and then actually just make a new
raccoon model right here. I'm also going to make this
start that or radius 0.3. I think that's gonna be fine. And then it will be awesome
gonna do is I will leave. We just wanted to overwrite render type method right here. So this scales it up as well. And then also what we want to
do is get texture location. Then we're going to choose
the same texture location. Here. We're just going to
go also provide, and that should be pretty
much all that we need to do. So the, both the model and the renderer actually
fairly straightforward. All things considered. There isn't that
many things in here. As you can see in
the vanilla models. There is actually far more
in there because of course, the vanilla models actually
all of the model is saved in the class rather than in
this geometry, Jason. So that's the really cool thing. Then we just need to basically we'll add
the renderer properly. So how are we going to do a vat? We're gonna do that by going
to our MC course moat class. And then inside of the client
setup, very important. We're gonna say
entity render us, render us this one right here. Register mode, entity types. We're gonna say the
raccoon not get. This is equal to
the raccoon colon, render colon, colon new. And that should be that. That is pretty much
the we need to do on that front as well. Now we also are going to
have to add a new item. And that is going
to be, of course, the spawn egg, the
sperm and egg. I will actually copy this one over this one time like always, of course, the actual
code is available to you. This is not too crazy. You can see this cold
raccoon bottleneck. This is of type item for
Hispanic item actually. And these are the colors
basically that the UK has. And that is pretty
much all that you need to do there. Then. Of course, because this is
actually a normal item, we also want to add
the translation here, the lang folder in
underscore us JSON file. So let's just add
this here as well. There's the raccoons spawn eg. And we actually also
need an item model file. I know this is pretty
freaking crazy, but it is true. Or this is also not too crazy. So we can see it is as the parent item
template spawn egg. So this is going to be colored in with these two
colors right here. So that is all that
there is to it. Then the item should
also work totally fine. And well, if I'm not mistaken, I believe that I should have gotten to everything
that I needed. I needed to add here. If not, then we're
definitely going to see that it doesn't work, but
that's gonna be fine. And we're going to also see what you can
do with an arrow. But for the time being, I think this is everything that we need. So let's see for works or what we find
ourselves in Minecraft. And as you can see,
the raccoon AG has been successfully
added to the game. And now let's see if I right-click
if the raccoon spawns. And there it is. In all its glory,
it's moving about. Now, of course, like we've said, it doesn't have any particular interesting animations
at the moment. And I actually believe that
the actual bounding box, if I press F3, be, be a little bit too small. So we might be able to add a little bit more
bounding box to it. For the time being, this
is really cool and yeah, it's necessary how
easy it is now. Oh, it's actually going
to flow because of the floating cobalt sore. That's kind of funny, but yeah, that's pretty much how easiest
to add a mob to Microsoft. Just for the sake of argument, we're just gonna make
this a little bit bigger. Let's say something like 0.8
and maybe height went six. That's gonna be fine. I think that we're gonna
be fine with us. And that's actually all of
the things that you need. So to recap one more time, we're going to need the
custom raccoon entity class. Of course, very important. The actual factory here,
you don't need just yet, but we've added this
already because why not? It just makes sense
in this case. And then the goals and the attributes were a
very important here. And then the other
stuff is Ritchie much. Not necessarily,
it's not necessary. It's just nice to have
and to sea-based. Then we needed to add
this and registered properly in the mode entity
types class right here. We needed a renderer and
a model file for this, the model file points
up to the model file. So this points to the
GeoJSON as well as to the actual extra
and the animations. And then the rent drop also
points to the texture. It also determines the
actual shadow size and makes a new model. This is the general idea of
how those work together. We also needed to assign
it the attributes. This is incredibly important because if you don't do this, then I believe that the game actually crashes when
you don't do this and you try to spawn the actual entities,
that's really important. Then we also added the
spawn EKG right here. And then in our MC course mode, right here, we
registered the renderer. And that is all of the
things that we needed to do. The geo file, of course, and the actual texture here
are also very important. But apart from that,
that is pretty much all that you need for a, well, very simple custom mob. Still done with gecko
lip, like I said. And then next lecture, we're immediately going to
jump in and take a look at the very cool
animations that are there, that are basically
available to us. Because that is something that is really powerful and it's actually fairly
straightforward to use. Definitely compared to
the vanilla animations, because those are those, you don't want to
use those basically. Well, whatever the case may be, this is already it then for
this lecture right here, I hope you found this useful and you'll learn something new. I'll see you in
the next lecture.
106. (Additional Topics) Adding Entity Animations with Geckolib and Blockbench: All right, welcome back to
the forage course for 118. And in this lecture we're gonna
be adding some animations to our custom entity that
we've added last lecture. And for that we're first of all, we're going to go
into what we're going to open block bench once again. Now this raccoon and the
actual block pinch model file should be provided to you, though it's either
downloadable from the last lecture or
in this lecture, we should definitely
be downloadable. And the, we're gonna
basically open it and then go to the
animated tap right here. Now, we should already have all three of those
animations right here. And I'm going to
basically quickly show the general idea
of an animation. Just for the sake of argument, we're just going
to make a new one. So we're going to click
the little plus button. And then you can make a new animation here you can see this. Now. This is usually you want to call this animation
dark raccoons. So this is the name of the item. And then whatever
the animations, we're just going to call this test for the
sake of argument. And then you can know what
you can make this loop. You can, as you can see, do a lot of other stuff here. We're just going to confirm,
am I gonna be fine with us? Now for this animation? Once you can then
basically do is you have a timeline at
the bottom here. And I can, it selects
certain body parts. For example, I can select
the body and all of a sudden you can see down here, I get the possibility
of adding keyframes. If you have ever edited a video, this is very similar to this. For example, I could say, okay, I want to key frame
the position, so I'm going to
click the plus here. Then you can see that at this position at
the time code 0, I now have a keyframe for
this particular part. So this body, it's not going
to be keyframe right here. So if I then move the
time, let's say to, let's say 0.52 frames
wherever this might be. Click this Plus again. You can see now at
the time of 0.52, now I have a second keyframe. And if I've done, for
example, were to change, I can either change it
here in this position. So I could, for example, say maybe on the actual
body to move up two, I can either do it or I can also do it inside of
the actual thing. And you can see
that on the left, the actual position
there changes as well. And it was really cool is
there's some easing methods. So you can see these basically
represent how this goes. Because if I now put this slide back and
put this play button, you can see this goes up. This is very fast. So maybe you are gonna
be like, You know what, let's pause this and let's
actually move this to like This is gonna
be a little slower. And then you can see this right? So you can see it moving up. And then it resets, of course, because this is a looping
animation in this case. Basically resets here with
the easy stuff you can. There's certain things. You can do steps. You can do some sort of
easing like this where it's go slow and
then it goes faster. You can even do it like this
where it's like very fast at the beginning and then slows
down or easing in and out. You can see there's a
lot of different types. This is even like some sort of look sort of like a
little bit of randomness, sort of bouncing up and
down, which is really cool. So there's a lot of stuff that you could actually do here. There are also some
really cool things you can add in here. Now I'm not a 100%
sure how you can all access the actual commands. But if I, for example, go
into the idle frame here, so I've clicked on this Idle. Now I'm in the actual
idle animation and I click on the actual tail, and I click on the rotation. You can see that I
have Math dot sin. So this is just the sine curve. Basically in here where u dot n m time is just
the timecode we're timesing would
multiplying that by 150 and then multiplying
the result by 225. And this basically results in the fact that the
tail is going to basically rotate
around in a very, let's say, foreseeable manner because the sine curve of
course goes like this, right? So this is just a general math
thing. That's really cool. I believe that on the website
they do actually have the sum of the methods that are available here,
basically to see. But that is a really cool thing. And whatever the case may be, Let's go back to our tests
animation with our body here. So we can see now our body, it's moving up and down. And this is pretty cool. Now, of course, when
you're adding animations, this is making them look
really nice and really good. All of that. A lot of time, it's gonna be, you know, obviously
time-consuming. So you're just going to need
to try out a bunch of stuff. See that? Hopefully it's going to work
and then it's gonna be fine. But also have a
walking animation. So you can see here this
is the walking animation. Then we also have a
sitting animation, but this actually
doesn't do anything. It's just basically the entire
bodies slant a little bit. And basically the raccoon is sitting here then
the island nation, we've seen this already,
but basically just the head and the body going up
and down, very slightly. You can see this. This is a very slight
up and down movement. And then the tail
basically wiggling back and forth a
little bit just so that it has a little
bit of movement. So you can see that. Just even this tiny bit of idle movement is enough to give a very nice illusion of
this actually being alive. And so, as you can see, it doesn't actually involve that much of tweaking that you need. Things that are very, very hard or something like the
walking animation, running animations,
especially for quadrupeds. So for animals with four legs, that is incredibly hard, there are some resources
that I have actually found. If you are really
interested in this, I will link them as
well in the resources. They are incredibly cool. So there's basically, is really
a anatomical look at how, how, how basically
quadrupeds Animals walk and how this is
basically done in animation. So it, four-legged animals is a, well something in animation
that is very hard. So it's gonna be
quite something. But because it is Minecraft, you're working with a little
bit of a block he animal. You probably have a little
bit more leeway here, whatever the case may be, if
this really interests you, I highly recommend checking
those out as well, if that is something
that might interest you. But whatever the case may be, we're basically done with
the general will animations. I'm actually going to
delete the test here again. And then the rest
are gonna be fine. What I'm gonna do is
once that is done, I can basically
either click a press Control S to save this
or I can also go, I believe to animation here. And then I can say
export animations. And I believe that that
should already do it. Or we can do save
all animations. We'll save this under actually
raccoon written correctly, not animation adjacent and
we're gonna just replace this. That is fine. And then let's
switch back to intelligence. In our assets MC course, we're gonna make a new
directory called animations. Is it animations? Yes, it is animations. And then what I'm gonna
do is I'm going to copy over the actual
animation as well. So the general idea there
is that this is gonna be the correctly spelled
raccoon animations. There you go. So this is basically all of the data that is needed there. We don't need to go into this. This is fine. Now what is important is that
we of course now need to specify these animations in the actual record in an entity. Opening the raccoon entity. What we're gonna
do is we're going to add first and foremost, the controller as well as
the predicate methods. So I'm gonna copy over
the product GET method. This is gonna be explained
in just a moment. So as you can see, we don't
have the sitting just yet, so we're just going to delete
this for the time being. And in the controller is
going to look as follows. So we're just going
to have data dot Add Animation Controller with a new animation controller,
code controller. And then we're passing in
this predicate method here. That's pretty much
all there is to it. And then making sure that this
is all written correctly. So these names right here, half the match to the names that are inside of the animation. This one right here
is the animation. You can see this actually
written, correct? Incorrectly. I don't represent know
why, but there you go. We're just gonna
change this quickly. There you go. And then it is a 100%
correct because then the raccoon is written like
this and then here also, so everything should
be working fine. It can see that the
walk animation is cooled when event dot is moving. I highly recommend.
Take a look at the animation event for
some particular stuff. You can, for example,
see there are some things in here that you can take a look at it,
some extra data even. So that's also
really interesting. But overall the is
moving is probably the one that's most
important here. And then some of
the other stuff you will just have to play
around with this as well. So I highly recommend
just be open to experimentation with this
and try out a lot of stuff. This is the best
thing that I can, basically just surely that
this is a very smart idea. Now, you might say, well, I mean, what else do we need? That's actually all that we
need because we have already set up the animation
actually in the middle. So right here, we've
already set it up. Animations recruit
animation data Jason, because this Jason
is already in here. And now we've basically
as the predicate, this is the sort of the
brain of the animations. This basically determines what animation is currently
being played. And well, I mean, that's, that's pretty much all
that we need for this. Like I said, if you have
some really cool ideas, really crazy animations, it all comes down to using block bench, trying out a lot of stuff there. Like I said, I have a lot of resources on animation
out there as well. So I hope that that helps you. But for the time being, I guess, let's see if it works. We find ourselves
back in Minecraft. So let's see, Let's spawn some raccoons and let's
see, There you go. It already works totally fine. And even the walking animation, Let's take a look at this one. When it starts
walking, Let's see. Well, it's kind of hard to see sometimes when that
is walking away. But I believe that it is working for their legs are
moving while the walk, yes. Sometimes the movement speed and the animation don't
match up entirely. This is of course
something that you just have to tweak around and will change as until
it basically works out. But you can see the actual idle animation
works totally fine. And then the walking
animation also works. Everything working great here. A new nitrogen portion here. For the sake of argument. There you go. I mean, that's that's
honestly really cool. And that's actually
how easy it can be to add some old, I mean, basic animations
with gecko lip to your Minecraft entities, right? But that will already be it
for this lecture right here. I hope you found this useful and you'll learn
some of the new. And I'll see you in
the next lecture. So, yeah.
107. (Additional Topics) Adding Entity Variants: All right, welcome back to
the forge course for 118. And in this lecture
we're gonna be adding a customer variance to our already existing raccoon
entity. What our variance? Well, you might
know, for example, that horses can have different colored mains or just in general,
different colored extras. And that is done via variance. Now, we're gonna add two of those variants to our raccoon. And the way that this works is basically we just have
a different texture. So I'm just going to copy
those over. There you go. We have a raccoon dark
and a red raccoon. Those are the three different
variants that we have. Raccoon, raccoon dark
and a red record. And how we now going
to implement this? Well, it's actually fairly straightforward, all
things considered. So this is something that you're going to have
to do basically, if you want all of
your animals to have different variants on all your entities to
have different variance, then you're going to need a, well, first of all,
a variant enum, and then we're gonna basically choose depending on this enum, a different resource location. In our entity package, we're gonna right-click new
package called variant. Then inside of there,
I'm going to put in, this is going to be
the raccoon variant. This is going to be
changed to an enum. And then I will
actually copy this over because the actual, the contents of this
should be always the same. The only thing that
should change here is these basically
your enum values. That's the general idea. When you have a
different variant, you simply rename this
and then rename all of the things in
here as well, right? So if this were to be called, I mean, now it would actually
change the name as well, but whatever the case may
be, so just changed the name everywhere and then you
would be totally fine. All of this static
method we're gonna need, we're gonna need this
final error stream. All of this is
going to be needed. The only thing that is basically bulk of custom here is that the name of this and
then also the name of your individual variance. Where do we use this or where
do we start using this? Well, we're going to use this
in the raccoon renderer. And the way that
we're gonna do this is once again, I
will copy this over, but all of the code is of
course available to you in the GitHub repository and
individual just as well. And this is actually, it'll might look a
little complicated, but it's actually
fairly straightforward. So right now we're going to just import this. There you go. And then we're gonna have a map. You can see this is a
location by variant map. This is just a map that maps a specific record variant
to a resource location. That is all that it does. Though we're saying, hey, if we have the default
raccoon variant, then this is the texture
you want to point to. If we have a dark variant, then we wanted to
point to this texture. And if we have the red variant, then we're going to
voyage to this texture. It looks a little
more complicated, but when you think about it, that's actually all
really that it does. And if you have
multiple entries, if you have more entries here, you know, you just add
more entries here. Now of course, we're
gonna see a warning here because we've already
added this actual, in this case key here. But yeah, that's all
you really need to do. So if you have more,
just add more. Same here. If you have
more, you just add more, making sure that you
increase the ideas here, that's very important as well. Well, then instead
of just doing this, what we're gonna do is we're
just going to say, Okay, um, well we just want to return the location bivariant dot get, and then we have the raccoon
entity available here. But well, the record
entity right now, it doesn't have a
variant yet, does it? That's no problem at all. Because right now we're going to basically add those variants. So we're just going to keep this arrow here for
the time being. No, not worried basically. And then we're gonna add all of the stuff that we need
for the variance. So once again, there's gonna be a lot of copying over
because once again, a lot of this code is
always gonna be the same. It's almost always going to be the same. It's going
to look the same. It's gonna be very similar. Only the details
need to be changed, but I will try my best to go through and explain
all that I need. So first of all,
we're going to need an entity data accessor. So this is the data
ID type of variant. This is basically a
synchronize entity data. So it's of type integer. That's the general idea. So usually I like to put this at the very top
of the class because it's just a little more readable even though this also
belongs to the variance. I want to keep
this at the top of the class and then the rest is going to go below this
variance comments here. Okay, what are the things
that we are going to need? Well, the first thing that
we're going to need is we're going to need a
set variant method. So there you go with
a record variant. And then we can set
the entity data of type date data
ID type variant, which is exactly this
synchronized data that we've created up here. And then we're gonna
set it to the ID. And then using an
operation here, we don't need to get
into the specifics. This is pretty much what
the horse also does. So most of this is taken
from the horse as well. If we actually shift press shift twice
and we'll go to the, I believe it's the
abstract horse that has this, but
I'm not a 100% sure. I believe that it's
the absolute horse. This has the ID. Well, let's take a
look at the horse than maybe it is actually the
horse yet data ID type. We can see that this
looks very similar. And then if we middle mouse
button click on this. You can see, for
example, right here, set to variant that
we just setting the variant and then here
set variant and markings. So you can see that here
it basically also does a few interesting things
with bit shifting. So let's not worry
about it too much. Let's just say we're
just gonna need this. And if we have this
in the morgue, gonna be totally fine. If we have a set of variant, we of course also
want a get variant, but we wanted two different
ones that we want. One where we get the raccoon
variant and one where we actually get the
integer out of this. And that is pretty much
also what we're going to need or the, this
one right here. So we can just say now
instance dot get variant. And then this one has
no longer any arrows. And now we need to do
the same in the model. What I can do is I can
just copy this here. And we're just gonna
say right here, this is gonna be the
raccoon renderer that, and then we're just
going to add this. Well, I should have
the dot in there. There you go. And then this
is called object instead. That's totally fine. And then we're done with the actual variance in both
the renderer and the model. Those are the two only places where you need to change this. Otherwise the rest
is all going to happen in the entity class. What else do we need
for the entity? Well, once the world
saves, Of course, we still need to
somehow save this. So therefore we're going
to need some NVT data. So all of this is gonna
be saved right here, read additional saved data, and then also add additional
saved data right here. So those two are very important. And then last but not least, basically I believe to
be the define sync data. This is incredibly important
because this is always going to be needed if you
have any type of entity, data accessor, a beard, the data ID type, or be it is, assume we're gonna see
a sitting as well. So a sitting data
accessor of type Boolean. This is also what we are
going to have to add in this define sync data
method is very important. This is definitely
what we're gonna need. And then last but not least, basically the last
thing that we need is the finalized spawn method. And this is very interesting. Now the reason we need
this is because this is basically called
when we use the, well, I mean, when this
actually this entity is spawned and this
finalizes the sport. So we're literally
just gonna say, Hey, just give me a random value
of this raccoon variant. And then we're gonna set it
to exactly that variance. That's all that
we're doing here. And with that, basically
the variant is complete. And you can see that overall, it's pretty much just this, these methods,
they're all going to be almost always the same. If you have a
different enum name, the name changes here. Apart from that, it's
probably pretty much is always gonna be the same. It should always gonna be there. It should always be the same. Overall, this is pretty much
all that. There's Twitter. It isn't that complicated. You just need to know where exactly you need to
do those changes, of course, in the
renderer and in the actual model as well. Just those two changes, just adding the map in
the renderer as well. So this map right
here, but overall, I believe that this should
be fairly self-explanatory, all things considered,
nothing here is two, I would say out of the
bounds of most of this. So this should be
fairly straightforward. And now I guess, well, I mean, let's just
see if it works. Or we find ourselves
back in Minecraft. So let's spawn some raccoons and let's see if the
variances are added. And there you go. Oh no, we have one variant that is doesn't have a
texture, but no worries, That should be
just a typo in the actual pulling the actual
resource location. You can see that the red
one works totally fine. Let's just see what this is
about and let's fix that. As I suspected right here, there is a typo. Don't no worries at all. We're just going to fix this. So the C was missing
once again, with that, basically everything, it would now be
working totally fine. And that's actually
how easy it is to add some custom variance
to your custom, well to your custom entity. But that would already be it
for this lecture right here. I hope you found this useful and you'll learn something new. If he did, would very much
appreciate a review from you. Otherwise, I'll see you
in the next lecture.
108. (Additional Topics) Tameable Entities: All right, welcome back to
the forge course for 118. And in this lecture
we're gonna be adding a team ability feature
to our custom entity, basically making
it possible that we can tame our raccoon. And this is once again, one of those things
that is actually fairly straightforward once
we've implemented it. And you get to see which
methods we have to override here in the Custom
raccoon entity class. Now the first thing
that we need to do is you need to go up here and actually change
this to amiable animal. So this is gonna be
attainable animal. There you go. Then we're just
going to take this, I'm going to select
it, press Control C, Control V to paste it in right here and
right here as well. I believe that
those should be all of the places where
this needs to be done. Then I will, of course, once again copy over
the bulk of this. All of this is of course, once
again available to you in the GitHub repository in an
individual just as well. This is going to be
the team ability. This is going to go at
the very bottom here, and we can see all of the
stuff and we're gonna go through each of the
methods one by one. You can see first of all, we have this sitting
data accessor. Once again, I'm going to
actually move that up as well so that we have are saying
to data at the top here, then what's very important is
because we have another one of those synchronize
data entries. We need to add this to
the defined sync data. This is very important
that we do this. So we're gonna have to say
this star entity data, define, this is sitting and then the default value is
going to be false. So this is incredibly
important and that this is also added here, otherwise, this will not work. So that's one of the
things that we need to do. Now the reason why
we actually need this particular thing,
the accessory here, is because of the fact that otherwise the predicate for
the animation doesn't work. Because in theory, if
I actually go into the table animal and I
believe there it is, the Boolean order to
sit is already there, so this already exists, meaning that why would we ever need another
accessory here, another type of data here, well, it doesn't actually
synchronize this boolean here, I believe is only
available on the server. I'm not a 100% sure, but I believe that this is only
available on the server. But of course, in the
case of gecko lip, that actually only
works on the client, meaning that there is
a mismatch between this boolean right here or
the server and the client. Therefore, we need the actual
synchronize the data here. That is why we have this. And then we can also now
uncomment these two things. Now, this is very important that your sit when ordered goal, it has a lower priority in
this or a higher priority, I guess it has to
be a lower number. Then basically all
of the other random look around at random walking
goals, stuff like that. That is very important
because if this has a lower priority
than for example, the random stroll goal, then the raccoon in this case, even if it is ordered to sit, will just stand up
and continue to walk and then sit down again
and then continue to walk. So not really what
you want it to do. So then we can also immediately
add the animation here. This is the sitting animation. So if this is sitting, then we're just going
to basically call the animation that
raccoon sitting, nothing too crazy, should
be fairly self-explanatory. And with that, the
animation is done. And now we can actually
take a look at all of the different things for the
attainability that we need. For the first thing is
basically the big method here, that is the mob interact method, but this is the method that gets called when a
player right-click. So this mop, I have
made an item here, so this is the item for taming. I've just chosen an apple. You could, for
example, replace this. You can also add multiple
items if you wanted to. Of course, normal Java applies. You're, so no worries. There. We're basically
going to check, hey, is the item that we've
right-click with, actually the item for taming. And if this animal
is not yet attained, then we're gonna go in
here, the client side, we're just going to consume,
so we're gonna make it right-click, but
nothing happens. However, on the server they are, we're going in and
doing some things. First of all, if the ability
here is instability. So the idea here is that
if this is not the case, meaning that if we're not
in creative motor than we're shrinking or decrementing
the item stack by one. And if we are in
creative mode of them, we're not doing it. That's all that there is to it. Here on animal team
is just a, you know, an event that basically gets fired when this
animal gets tamed. And then once again, we're
just making sure that we are not on the a client basically. I think that this is
basically redundant, but we're just going to keep
it because no worries there. And then we're gonna
say, first of all, we're gonna call the ETA method. This particular
player within a gonna recompute the path
for the navigation. We're then going to set the
targets to know this row. This would be the aggressing
target basically. Then we're going to
call the broadcasts entity event with bytes seven. So this is a
particular event here. You can see, since
a particular packet to all players of that event, it's, it's quite craziness. This is basically the event
that we need to send when a certain animal
has been attained. I believe that this is
responsible for spawning the Hearts when you
actually get the team, then we're immediately
setting sitting to true. And we can actually take a
look at the set sitting here. So you can see that not
only are we setting the entity data leading to whatever we're
passing in here? We're also calling the set
ordered to sit method, which was basically sets
this order to sit in the table animal here also to
whatever we're passing in. So the idea is that
we need both of those to be set properly. And then we had this, yeah, that's basically the
general idea here. And then here this one is, once we were already
have tamed this animal. And once again, we're on the, on the server making
sure that we use only the main hand because
if we don't have this, then we're basically
never being able to get the actual animal to sit because this is called
for both hands. This is very important.
This is called twice, once for each hand
of the player. So be wary of this. This is also of course
then called twice, one for the client and
one for the server side. So in total it is
called four times. So keep that in mind. And this one here, this is why we need the
interaction hand here. Otherwise this would
be called twice. And then of course, if you
toggle something twice, well, it just reverts to
its original position. Therefore, the actual
animal would never sit. So that's very important here. Here. We're just
basically making a pass when the item for
taming is used again, even though it's
basically already named. But that's all that
there is to it for the mob interact method. This is basically the
centerpiece of this, of course, where we're actually
setting it to being tamed. And we have the set set, the setting method,
nothing too crazy. We also have the set T method. Where is this cold? Let me actually take
a look at this. This is cold. Not actually 100% sure I believe
that this is cold. It might also be called via some of this
stuff right here, but we're basically
just changing some of the attributes here if
this animal is tamed. So this is a normal thing
that basically can happen. And then we also need to just, I don't think we need to
override this necessarily, but I've overwritten it
on the less is the team where basically this is the team that this
animal belongs to. Then we have the
last but not least, the Boolean method
can be leached. I've set this to false. Now. Something that is a bug
currently in gecko lip. I don't know if this is
still a thing at the moment, but this has been an
issue for some time, is when this is true and you
actually leash this lesion, a gecko lip entity, then the actual lead is, it's invisible.
It's still there. It works, but it's invisible. I don't know if there
is a solution just yet. I will check this out in
a later date as well. But if either it's fixed or if it's not fixed
and we're probably going to have a fixed for
that in maybe either later lectures or at some
point in the future as well. But that is pretty
much all that we need for the team ability. You can see it definitely gets a little more complicated here. It's not just like, Oh, let's get an enum in
there, sort of a variant. Slap a few things in there
and then we're done. Now, the team ability is a
little more complicated, but all things
considered were not. Well, it's not that crazy. The sitting capability is really the thing that might be the most the most difficult in some circumstances because all of the pieces have
to be correct. We have to be cooling
it in the correct ways, in the correct moments. And now it's very important
once again, is the goal. This is most of the time the thing that
has happened to me. Why why they basically stop sitting or when you
order them to sit. And all of a sudden
the animal just walks up and go somewhere else
and then sits back down. But this was one of the things. After having added all of this, we're now going
to be able to see not only the sitting animation, but ofcourse also how
to tame the animal. So let's see if it works or why we find ourselves
back in Minecraft. So let's see if I can
tame the raccoon. And there you go,
best friends forever. Now it is sitting. Now what I usually do to
make it basically makes sure that it stays
in the same place. It's just I'm going to not lock it in bulb basically
make a little bit of a cave here so
that I know okay, if has definitely moved, if it's out of the
cave basically. And so for the time being, this looks totally fine, like it actually seems
to be sitting there. And you can also see
the sitting animation, by the way, let's actually
take a look at the CEO. And then if I right-click again, then the raccoon should
start walking again or just using other goals basically to do whatever it wants to do. Basically stroll around, or
whenever it might want to do. There you go. Now it's
running around again. So they go and yeah,
that's I mean, you can see that it's
actually faster because of the speed increase that has, it has gained
through the taming. This is something that has
happened in the taming. We're going to take
a look at that in just a moment again. But yeah, that's I mean,
that's pretty much all that we really needed to do. And now you have a Teams raccoon That's really
freaking cool. Once again, the movement
speed right here is basically why it is
so freaking fast. We're basically setting
it to 0.5, I believe. Let's see actually what the
movement would be, 0.3. So we're almost doubling
the movement speed. This is of course something like any other time when it
comes to the attributes, values of certain certain
attributes in this case, or certain variables, you just got to play
around with them. You will have to change them probably a lot of times any way, simply because of if
you want to really dig down and make sure that your
mod is properly balanced, you're gonna have to
change the numbers. I mean, a lot of times this is one of those
things where once again, just play around
with the numbers. Try out a bunch of stuff, be open to experimentation. And then while I mean, nothing basically
stands in your way. But that is already it then
for this lecture right here, I hope you found this useful and you'll learn something new. And I'll see you in
the next lecture.
109. (Additional Topics) Rideable Entities: Or I welcome back to the
forge course for when 18. And in this lecture,
we're gonna be adding a custom rideable
entity to Minecraft. So after we've gone through
with the raccoon entity, we're now going to add
the tiger entities. So of course, once again have a blog bench model for
this. There you go. This is of course also
download both for you, but we have basically all of
this has already set up and everything basically is going to work very similar
to the raccoon. What we're going to have is
we're gonna have a new class, first of all, and that's
gonna be the tiger entity. There you go. Now there's tiger entity is
gonna be very interesting. First of all, I will
once again copy over the entirety pretty
much of this class. This is going to be
a very long class, but most of this is gonna be
very similar to the raccoon, number one and number two, I will explain
everything best I can, of course as well. So what we're gonna see
here is we should get two. Okay, that's fine. That's
actually okay because this is called the
mod entity types. Actually, there you go. And then that's gonna
be fine as well. Then one thing we have here is to see more entities
that's gonna be fine. And then there's a few
other things that we can actually get rid of here
as well. And there you go. Now no more errors if
you copy this over from the GitHub
pastor or the gists, no more errors should
be present for you. And everything here should be fine or yeah,
it should be fine. First of all, what
we have once again is some of the sittings stuff. So you can see it's
sitting, set sitting. And even here we have
the sitting and when we right-click the
mob interaction here, you can see this time
if we're crouching, then we actually want
to set the smoke to be sitting because of course we also wanted
to make it as readable. This is why we have this player rideable interface right here. And that is going to be
the interesting thing. So if I actually click on
this and press Control H, then we should be able
to see, there you go. I have the abstract
horse for example. Most of this is taken from the abstract horse and
the horse entity classes. I cannot stress this enough. Take a look at all of
the vanilla examples. You have so many
vanilla examples here. Once you understand
the basic structure of this class of like
an entity class, then taking a look at
the entity classes of in vanilla is fairly
straightforward. So as I said, most of this stuff is the
same as in the raccoon. We have the registered controls, the predicate for
the animations. We have the asynchronous
data, the sitting, and then we also have
this spray selectors. So that's very interesting. So the spray selector here
is for the target selector, for the non tame random target, this is a thing that is basically added where I
added this from the wolf. So if we actually take a
look at the wolf right here, you can see in the wolf is
also has a prey detect, prey selected right here. And this also has
this one right here. So you can see it
would basically hunt different ray at this stage in this highest
priority in this case, as we basically wanted him to do everything else
before it does this. But this is just an added thing. You don't have to have
this necessarily, but it is kind of cool. You can see we also
have attempt goal here. This is actually the thing that, that the tiger is
actually going to follow when you have a
turnip in your hand, there's also the
table item with it. So if you right-click
it with the turnip, then you have a, as you
can see right here, we actually have a twenty-five
percent chance it should be of actually taming
this entity n yeah, that's pretty much this. And most of this you can see actually it's
not that crazy. Here we start writing. This is actually the player
that's actually changed this. So click on this and
then call this player. And then this is going to be
the hand a little bit more readable than we can see
player dot star writing this. We're going to basically
start writing this. And how are we gonna be
able to control this? Well, the way that we're
gonna control this, this, with this method right here, can be controlled by a writer. And then here we
just returned and controlling passenger
is of living entity. And then here, I believe
we also have to return. This is also quite important. And then the travel method is
also taken from the horse. Most of the stuff has
been taken out because the one thing that we're
not going to have is the ability to
jump with a tiger. That's the one thing that
we're not gonna have. That is pretty much
all there is to it. Once again, also, it's very, I mean, it's, it's
fairly straightforward. Anibal, you can just take a
look at the player rideable jumping interface number one and number two also the
abstract horse. Like I said, all of this
is available to you in the external libraries
right here, right? All of the vanilla code. I can't stress this
enough how, well, how easy it is to
just take a look at that and basically then be, you know, get
something from there. Let's add this to the more
entities types right here. I'm just going to once
again copy this over. Like always afford
everything available in the GitHub repository and
individual just as well. Go the entity right here. And then we're
also going to make the two model and
render our classes. So I'm gonna say Tiger model. There you go. And then we're also
gonna say the tiger, tiger renderer go as well. And then once again, we're
just going to copy this over. This is fairly straightforward and it's pretty much looks, should look like
exactly like before. We just need to do
the model as well. There you go. The model as well. Is pointing once again
to the modal location in the geo tiger right here
are the texture and then the animation are
nothing new right here. And then in the renderer,
pretty much the same thing where we just have the
render contexts right here, and then we're making a
new model right here. Now this, of course, once
again has to be cooled in the client setup
method right here. So we're going to say
what entity types tiger, and then here the tiger
renderer, there you go. Then of course, let's not
forget the event that we need to call and that should be right here in the attributes. We of course wanted to
set the attributes here to the tiger attributes
they award very important. Do not forget this, and that
should be that as well. Let's also add the, the new spawn accurate here. Let's just duplicate this
and then we're going to say a tiger underscore
spawners Greg, in your tiger and
this correspond on his Greg and I
just needed to get the actual color codes because I've actually
prepared those in advance. Of course. Let us say this
is the color code for that. And then the highlight
color is this, making sure that we
change this to Tiger. And then this is also fine. The model, well,
we're just going to actually copy over the raccoons Baunach because that's
gonna be easiest because the contents of which of our not actually
going to change. So we're just gonna say this
is the tiger spawn egg. They ago and then adding it
here in the end underscore he was adjacent file as
well, I guess morning. And then here as well,
tiger underscore spawning. This is of course pretty
much all of the stuff that we've gone through
already with the raccoon. So nothing too new should be all everything fairly
self-explanatory. Let's also add the tiger
animation right here. There you go. Then we're also going
to have the geo. This is gonna be right there. So let's open that up and add the hydro tiger model as well. And then last but not
least in the entity, we're gonna make a new
directory called tiger. And then instead of there, we're going to have
the actual tiger PNG. This is the extra as well. And that is pretty much all
of the things that we need. Like I said, most of the stuff happens in the
tiger entity class. And also, like I said, most of this is just taken
from the vanilla examples, from some familiar
examples where we've seen the prey selector here, like I said, it's just
an interesting thing. You don't necessarily need this. This is just something that
I found interesting and I thought that I would add
this as well to the tiger. So I mean, that is, as I've said, pretty
much all that we need. Let's see if it works or
if answers in Minecraft. And as you can see, the
tiger AG has been added. So let's see. There we go. So
some of the tigers here are successfully
added in the game. And then let's get some turnips. Sierra now, they should be
following me once I actually put this in and they ago,
they are following me. So this is the tempt
goal, of course, right? Where this basically signifies what the actual thing is that
they are going to follow. And then if I just right-click, you can see this wasn't, wasn't successful,
wasn't successful. Once again, it should
be a twenty-five percent chance and they ago, now, I actually have it in here and if I
right-click again, then I'm actually going to
go through and it looks, it doesn't look very
strange, but it is pretty cool and I can't jump. Like I said, this is something that you are probably
going to be able to add via some examples
through the horse. It should actually be too crazy. And then if I shift
right-click, then you can see, then we can make this
tiger sit as well. And that should also
work only fine. Lets you can see this
is an example of a writable entity and a table
entity at the same time, basically both at the same
time and there you go. That's actually how easy
that can be as well. Well, but that is
going to be it for this lecture right here. I hope you found this useful
and you'll learn something new and I'll see you
in the next lecture.
110. (Additional Topics) Adding a Custom Boat: Or I welcome back to the
forage course for 118. And in this lecture
we're gonna be adding a custom boats to Minecraft. Now this is one of those
things similar to the sign. That seems, I mean, it should be way easier, but it actually incredibly
frustrating to actually add. So once again, a few, I mean, a lot of this is
gonna be copied over. But once you have
set up this, once, you should be able to very
easily add new types of boats to your MOD and it should be almost
no worries at all. So the first thing
that we're gonna do is we're gonna
make a new entity. First thing you're
going to be like, Wait, do we need an entity? Exactly. That's why we're basically
doing it after the entities. This is gonna be
the boat entity. They ago, however, only
going to need one. And then once again, I will copy the
contents here over. But like I said, everything is available to you in
the GitHub repository, an individual just as well. Let's just add this and
we shouldn't get any, okay, we're going to
get a few arrows, but that's gonna be fine. These are gonna be sold
in just a little bit. This is gonna be
mod entity types actually go on the boat entity we're gonna add just a moment. Now once again, we're gonna have a Interestingly eight
datatype ID type, right? So we're gonna,
once you can have different variance of
a particular entity, this is pretty much the
same thing that we did here with the data ID type. You can see this is the TI
variant and this is the type. So we're going to have a very
similar setup right here. In this case, we're
just going to have the actual type enum inside of this actual
multiple entity class. And you can see we
have the cherry blossom one with just
the name Cherry Blossom. And then the rest is basically done sort of in the background. The idea here is basically
done for us right here. And honestly, really, really, we don't really need to look
at all of the other stuff. If you want to add multiple ones just like any other enum, separate them by a
comma and then just name them if something different and then it's gonna be fine. That's something that you need
to do when you want to add a new custom variant or
a new custom boat type, you also have to change the kit drop item method right here. You can see this is
a switch statement. And then here we're dropping
the cherry blossom board. And then if you
have another one, you just add a new case here and then just add that item there. Pretty much as simple as that. The get mod board type set, both types should be
fairly self-explanatory. Read additional additives
from saves data method. We're just saving the
actual type of this boat. And then here we're just
having two constructors. We actually need those
two constructors because this one we're gonna be using in just a moment
in the mod entity type. So I'm going to actually
copy that over 1 second. Of course everything
available to you. And you can see, let's actually call this the mod
underscore board. How about that? That might
be a little bit better. And then you can see
this is the boat entity, and then this is also fine. This should work,
this should work. And then this one
heater if we can actually delete a day ago. Now, the actual boat
entity only is going to be the item that's an issue and then the rest is going to work. You can see this is
a miscellaneous, of course it's immune to fire. The size here is from
the other boat entities. So if you actually take a
look at the boat class, this is of course,
the available class. Once again, take a look at this. If you think there's anything
else you want to do, if there's anything
special you want to make, take a look at that and then you should be
fine there as well. Now we're going to
also need a renderer. This is gonna be the
model vote renderer. Up. There you go. This is actually gonna be fairly straightforward,
all things considered. There's one interesting
thing here. Once again, I will copy it over. But all of this is available
to you and we get no errors. And you can see here is a
very interesting thing. What you have here is
his own resources. This is gonna be a map of from mod board type to a pair of
resource location boat model. This is pretty craziness. The general idea here
is just that we want, this is pretty much almost
exactly the same thing. You'd see this texture location, pretty much what we had in
the renderers right here, where we have the texture
location and then the variant, that's pretty much all so
what we have here just in a very much a more
complicated a method. And it is what it is because this is the thing
that this one's right. So the peer resource
location boat model is what the model with
location months. And if we make this into a map, different types and
then different pairs, and that is basically
going to work out. Now this actually
interestingly enough, it's just gonna do
the following where basically this one looks
freaking craziness. This looks like, oh my god, what the **** is going on here. Literally what we're doing, we're going through
all of the values that all of the types
that we've defined for our boats or custom boats and then just making
new pairs, right? So we're gonna go
through all of them, make a new map for this
and say, Hey, okay, now we're gonna make a map
with this particular type. So we're gonna go
through, let's say we have seven different types. The first type, and then
we're just going to say whatever the name is. This is where the
model looks for. And then the model
layer location. So this is the
actual boat model is always gonna be the
AUC boat model. So this is the
actual boat models. You can see this is why we don't make a custom boat model. So this is all gonna
be the normal one. If you really want
custom boat models, you're just gonna have to
figure that out on your own. I highly recommend taking a look at the boat
model right here. This should be, I mean, definitely something
that is going to be a good place to start basically, but it's definitely gonna
be a bit more complicated. And then when we
have created this, the idea is that then this
is basically returned right here in the model
with location method, which you can see,
we're checking whether or not this
boat is of type or an instance of a mod
boat model entity rather. And then we're just
going to return the actual ball resource
with the actual type. This is all that
we're doing here. It looks a little crazy
and it's like, wow, this is absolute madness, but overall it's
actually not that crazy. So where do we need this? Well, we of course going
to need this once again in the MC client method right here is ordinary MC course MOD and then in the client
setup right here. So we're going to say this is the bolt entity
and this is gonna be the mod vote renderer.
And there you go. That already works. And that is that setup as well. And then we just need
an item for this. So interestingly enough, we're still going to need a custom
item for this as well. This is gonna be
a MOD vote Item. And then there's actually
a typo in there. We're just going to
fix this quickly. Go item. And once again here, some stuff that will
be copied over. This is actually the
cluster is the least. Well, I mean, wouldn't say
interesting necessarily, but the least craziness that
we have this use method, basically just doing the stuff that happens when
we right-click. This is pretty much I mean, it's almost one-to-one
from the boat item. We can see this as the
boat item right here. And this is the US method. It pretty much looks
almost exactly the same. Instead of making a new board, we make a new mod vote should be fairly
self-explanatory here, and the rest is almost
exactly the same, pretty much the same thing. So there you go. And well, after
we've added this, let's also make the item out of this so that we can get rid
of the last arrow there. Let's just copy over
the magic dusk. This is gonna be the, now this one is actually
the specific boat. So this is gonna be
the cherry vote item. For each of your
different types of boards you're going to
need different boats, basically cherry boat item, Let's actually sorry, this
is the Chevy Bolt item. Let's call it Sherry. Actually cherry blossom
board. That's better. There you go. Yeah, that
makes them more sense. Cherry blossom boat. And then this is
a MOD vote Item. Now this actually takes in as its first parameter,
the normal software. The second parameter,
as you can see, it takes in the mod
boat entity type, entity type, dot arid, awesome. This was one too
far off the ego. There is actually, there you go. Now it obviously works here. So you can see now we've created the MOD bulleted item here. And then this should
also work in the entity right here where we're going
to return to right there. Now, all the arrows
should be gone. Now we just need to
add the JSON files. So this would be the translation first and foremost, of course, for the item, this is
gonna be right here, so we're just going
to copy this over. This is gonna be the
cherry underscore blossom underscore boat. And then of course, same here. Cherry blossom boat. Now there's another
thing, of course, the item model, not
the item model. It's just a normal item model. Nothing too crazy about this, but still we're just
going to copy it over n. We're gonna
take a look at it. You can see just points to
a specific item texture. Nothing crazy here. Same with the item texture. That's just the
normal boat texture. Really textured
basically a little bit for our custom ones. So we can see they ago is
the cherry blossom board. Another the question
is weight but whereas the entity texture there, well, this goes once
again into entity. And I'm gonna make a new
directory called boat. And then inside of here was the cherry undertone score
blossom, this name right here. What's very important? It has to be the same
as the name supplied in the type of this
name has to match this name because that's
what the renderer looks for in terms of a texture.
So that's very important. And this is how it looks like. Basically once again,
just basically setup. So this is all of the board. And then you can, this is the
basic texture of the boat. That is the general idea. Now, in theory, I
believe that this should be all of the things that we
needed for a boat to add. Like I said, is
just with the sign. It's it's pretty crazy. Like all things considered. There are some pretty
major steps, like I said, most of this if you just copy it over and then you can
basically change it. So you're going to
need a new custom item for each of the new boat types. New boat type right here. So this is something that
you need and then the rest should pretty much be fine. I believe that you
should be able to use this entity type
for all of them. And that should be pretty
much all that you need to do. But for completion sake,
let's see if it works. Or if ourselves back in
Minecraft and you can see the cherry blossom boat has been successfully
added to the game. Now let's set it down. And there it is, the cherry blossom board. And we can use it in the water. Everything working totally fine, just like we would
expect it to go. And then if I actually switch
to survival mode quickly, Let's go to survivor mode
and let's see if this drops and indeed drops
a cherry blossom board, just like you would
expect it to. So there we go, working
everything, amazingly. And that's actually
how easy it is. Like I said, there's quite a few steps that
you have to go through. But once you go through them, then it's actually
fairly straightforward. But that's gonna be it for
this lecture right here. I hope you found this useful and you'll learn something new. And I'll see you in the
next lecture though. Yeah.
111. (Additional Topics) Entity World Generation: Or I welcome back to the
forge course for 100 teen. In this lecture,
we're gonna be adding custom entity generation
to Minecraft, but we have created our entities now we also want them
to spawn in the world. So for that we're
just going to make a new class right here. So in the world agenda package, we're gonna make a new mod
entity degeneration class. And once again, this one I will copy over
because I've actually basically prepared a little bit of a class here
that you can use. So this is, of course we
need to change this to more than two types they go
and then this one as well. This should be no
worries for you. You should be able to
just copy that over. And you can see the
entire class here, we have an entity spore
method that we're going to call in right here, basically at the
very bottom here. So mod entity iteration
on empty spawn, and then we're passing in
the IM loading event here. And that should be pretty
much what we need. And then you can see there
are some methods that we can use under. For example, add entity
to all overrule biomes. We have an entity to all
biomes. Net to nether. No, nether, sorry, right. So there's everywhere
but the nether, every robot, the end. And then here too, all biomes
including and another. And usually in theory, if you have those methods, you should be able
to very easily at other ones that pretty much do the same thing
that you want to do. I mean, honestly, at this point, some Java knowledge
is of course, very much a thing that you
should have at this point. And once you have it, then adding some more here
shouldn't be too crazy, even if you don't necessarily understand everything
if you're like, okay, this adds it to all biomes, but the end it's like, okay, you can probably figure out how to add them to only the end, for example, just literally
that, That's it right now. All of a sudden everything
only to the end biomes, That's pretty much
all there is to it. So this class, like I
said, I've used before. And yet here we just had the
example right now that we're going to add them to basically
all overwhelmed biomes, in this case, both the
raccoon and the tiger. So after having
added it in here, That's actually literally
all that we need to do. I guess for completion sake,
let's see if it works. It translates back in Minecraft. Now in theory, we don't
even have to make a new world for this
because the entities are, they sort of spawn. I mean, I wouldn't
necessarily say dynamically, but they don't immediately spot upon basically the
world being generated. So let's see if we can find
any of our custom ones. Was that already
tiger there it is. There's already a tiger
here in the forest. There's another
one, another one. But that's I mean, that's
actually how easy it can be. Uh, you saw that's
fairly straightforward. All things considered,
like I said, not changing it is should
be totally easy as well. You can see there are
some more tigers. I do want maybe we can find
some raccoons as well. Maybe just quickly over
this hill, command. Some raccoons. They are, Let's go away. We actually found them to read raccoons and two dark records.
So that's pretty cool. Yes, So that's actually
how easiest to add some custom entity
generation Minecraft that has already it for
this lecture right here. Like always, of course, all of the code is available to you in the GitHub repository and
individual just as well. But otherwise I will see
you in the next lecture.
112. (Additional Topics) Adding Custom Trades to Villagers: Or I welcome back to the
forge course for 118. And in this lecture
we're gonna be adding custom trades to a villagers. So this is going to
be custom traits to already existing villagers,
very important here. So we won't be adding any
custom villagers at the moment. This might happen in the future, but I wouldn't count on it
just necessarily right now. So we have to go into
our Events class. There's just an event here.
In the more advanced class. I'm just going to
copy over the method and it's very, very
straightforward. This is all that we need. So you can see we're
just going to use the villager trades
of n right here. And then we're just
gonna say, hey, if the type is specific, a profession that where we
want to add our traits too, then we just add
our trade to it. That's literally
all we're doing. You can see that it's very,
very straightforward. You can see this is the
way that you filter. So if you want to add something
for another profession, you just copy the if statement and it changed the
professional right here. Anything else that
you want here? You can specify the
villager level right here when you do
trades that yet. And then you pass in the
village or lever level here, and then you just add whatever
merchant offer you want. So the, this one right here, so the actual emerald right here is what you pay.
The merchant offer. You can also put in a
two item, three items, stacks, and then those would be the two things
you have to pay for. In this case, we
have one item stack, the Emerald to emeralds. This is what we pay,
and then we're going to get wealth turnips for that. Then you can see Max uses, we can use this ten times. The speed is 50. I think that this is
actually quite a bit too high for the stuff here. So I think that this is
more in the realm of like single-digit
experience usually, but whatever the
case may be, I mean, all of those numbers
highly recommend just playing around with them
one way or the other. I mean, that's probably
the smartest thing anyway, but that is literally
all that you need. You can just copy this over at as many if statements in
here as you would want, as many traits as you
might want to add. But that's literally
all that you need to do is really freaking easy,
really straightforward. I mean, you can't make it
easier, honestly, really. I mean, I guess just
for completion sake, let's see if it works or
if our answers back in Minecraft and they can see we already have the
turnips right here, so I can just put in to emeralds and I'm gonna get
my 12th turnips. That already works,
our custom one. And you can see how
much experience the actual farmer
again from that. And then let's actually
go to the tool Smith and let's just get some
tools here so that we can basically Level him up to level three because we
need them to level two, level three, Let's get
some iron ingots seer, if you trade as well, iron ingots the goal. And then let's hope that
this is going to work out. Let's get some iron ingots. And then level three should
be right around the corner. They ago on upgrade, upgrade. Go and now let's see. We don't have the
Paxil in this case, so this did not quite work. Well, fair enough. I guess Let's say
the other one then. Let's just let me just quickly upgraded or this tool Smith was a little
bit more cooperative. You can see the cobalt
Paxil. There you go. So we can get this and
then we could use it. However we would like. There you go. So
just like we would expect the actual tool to work, it works, and there you go. It was able to be
traded here through the actual tool Smith
and here once again, the turnips right here, we can just get a few
of them and they go. So the max uses also
working totally fine, but just how we expect it
to really freaking cool. And that's actually
how easy it is to add some custom traits to villagers. Like I said, this is of
course existing villagers, but this still already adds quite a few different ideas to your mod, which
is really cool. So I highly recommend
checking this out, but otherwise this
is gonna be it for this lecture right here. I hope you found this useful and you've learned
something new. I'll see you in
the next lecture.
113. (1.18.2) Updating Forge to 1.18.2: All right, welcome back to
the forge course for 118. And in this lecture we're
gonna be updating our project to 118 to now with
the release of 1880s, there come a few changes, but luckily nothing that we
can fix quite crust actually. Nothing is too crazy. The one thing funnily
enough that is actually completely
broken or not completely, but to a major degree, is the title funnily enough? I don't know why they
changed the title screen, but whatever the case may be, we're just going to update and then you're
going to basically see the changes in the
built DOD Gradle file. There are of course a
few changes to be made. So what we're gonna do
is, first of all take a look at what the
current version is. The current version, as you
can see, 40012, once again, of course for you, this in the future is probably going
to be a later version. So you're just gonna take
that at that point then, and then we're going to be fine. So we're going to do that first. So we're gonna go right here
to the dependencies 40012. And then this is
to just checking, double-checking 40121, 1000th 2. That is correct. And then
before we actually reload this, we also want to get
the newest version of, of gecko lip because I believe that actually the old
one does not work. So we wanted to in 312
as well right here, just gone to the
installation you once again, and then we're
using that as well. So we're gonna do this
one right here they ago. And that should
pretty much be it. Apart from, of course,
parchment mappings, this is incredibly important
to the parchment mappings. We actually want very
specific parchment mappings and they are going
to be the following. I'm going to copy them over and this is going
to be, of course, once again available to you
in the GitHub repository, an individual just as well. You see, we're basically taking the 1800s parchment mappings and then putting over that the 1880s normal official mappings. If you don't have
this setup like that, then you're going to
actually run into some issues and some methods
will not be available. So please keep that
in mind if you're using personal
magnets to use this, or if they are updated to 172, then of course you can also update it to that
version at that point. But then we're gonna click
the little elephant. If that doesn't appear, you
can open the Gradle tab and then press the reload
or Gradle changes. Now this once again might
take up to a minute or two. And because I've
done this already, this should be taken for me. There's like a couple
of seconds usually. Let's see, Just be patient
and let it run through. And then we'll see after
we get a build successful, they were built
successful actually did take a good two minutes here. But once again, of course, just be patient and wait
until you get a build successful and then
you're gonna be fine. But the first thing
we're gonna do is we're going to actually go into our MC course mod class
and we're gonna do one thing and that's gonna be pulling the gecko
lib dot initialized. This probably should have
been added beforehand, but now is the best time
than ever to just added. And then we're going
to be fine here. I think it's next
strictly necessary, but it is definitely
recommended, at least at the very least. And then what are the
changes while the changes happened mainly in the tags, then also the changes happening
in the world packets. We're gonna take a look
at that in a moment. And then also there's
one tiny change in the block entity with
the custom recipe. For first of all,
we're going to tackle the tags right here. You can see I optional names
tax does not exist anymore. But what does exist
is the TAC key, and we're just going to
replace this with tacky. Click on it, press Alt and
Enter import this class. And then we're going
to change all of the optional tags to tack key. There you go. And then instead of
creating an optional here, we just do dot create. You can see we're just
changing this to Create. And there you go. That's pretty much all
that we need to do now, one thing that still
does not work as the dowsing rod valuable
here we can see, you can see, we can't just
all the Contains right here. Now, this is what would you say? I mean, a little
annoying to be honest. This is the way that this is setup is looking really weird. So this is what you
need to put in there. See registry dot block, it holder or throat. Then we're going
to basically get the registry resource key for this block that
we're passing in here. Then we're saying,
okay, is this holder inside of the dowsing
rod valuables? It's crazy the way that
this is setup now, I don't know why the
changes occurred. I'm just saying that
this is basically the way that we have to do this. And I'm just gonna, we're just gonna be able to find
with it basically. But that is the
changes right here. So the tags are done. Let's actually then go into
the recipe right here. Any mod recipes, this line right here can no longer
be in this method. What we actually want to do
is in the event package, in the mode event past events, we want to add a new event. So we're just going
to copy this over for the moment here. This is going to be
register the recipe types. Then what we're gonna do
is we're gonna just take this Registry register
event right here, and we're going to change
it in the following way. So we're gonna say that this is actually not in global realizes, but this is actually the
recipes serializer ago. So this is what we need. Of course this once again
available to you in the GitHub repository in
individual just as well. And then we're gonna
copy this line if you have multiple
recipe types, of course wanted to add
all of them in here, all of the registry
dot register methods, and that was gonna be fine. Now this will work as well. And now we can go into the craziness that is going
to be the world generation. But in the abstract tree grower, you can see basically now we don't no longer want the
configured feature here. What we actually want
is a holdout, right? So we're gonna say Hold on and then this is going to
be very interesting. There's gonna be
question mark extends, extends the configured
feature right here. And then we're gonna do this
and then we can move into the moat configured
feature class and then basically change this. Accordingly. So this is also going
to be a holder. In this case of
question mark extends, then it's configured feature
and then here at the end, adding the closing
angle bracket. Once again, of course everything available to you in
the GitHub repository, an individual just as well. Then what we're
going to see is this configured we no longer
need including the dot. We're going to replace that
with a comma and then delete both the opening and closing
parentheses at the end. This should now be no longer
an error. There you go. And this should also be fine. Now, what we have to do
is actually we can now go from configure feature to configure feature
to place feature. We now do actually have to add another place
feature in here, and I will copy this
over once again, everything available to you in the GitHub repository in
individual just as well. And you can see here,
we basically have this place feature once again instead of this
holder right here. And we're basically filtering by block survival of the sampling, just like we are doing here. Just instead of
doing this inline, we're basically doing it
with a place feature here. And then we're using
the place feature in this random feature
configuration list, just like we're doing here. So it's very, very similar, just a little bit
different, I guess, when it comes to the rowers, this should also be
fairly straightforward. We just have to change
this right here. We actually no longer
wanted to call this. So the actual get empty
is no longer a thing. We want to do
something like this, but you don't want
to even return something because this
actually just takes this in. We're going to do
something like this. And then this is going to
be the placement utils, what we need when
the placement utils, that's only when empty. And then we're going to pass this in here and I'm going to end this with one right there. Let me just quickly
reformat this a little bit so that I can actually
see where we're at here. Let me a simple block with
a new block configuration. They block say provider of rows. Let's just
hover over this. What do we want? This is of course, going
to be also a holder. We just need to change
this to a holder they ago, and then this should work
as well. There you go. Once again, of course you can
always just copy it over. You can see that the changes
here or not that crazy, they're just really syntax,
same here with the order. The order is actually
probably the easiest one. We just have to change
this and then change this to a holder as well. They ago. And then this also needs to be of war configuration,
very important here. There you go. Then as you can see, pretty
much working as well. So these are the changes, of course, the changes on 0.5. So I have to take place right
here in the latest features where they are all holders as well or not or configuration
about holders. Let me copy over
the holder here. There you go. Hold on a go. And I'm gonna do this for
each one of them just so that we already have it
and hold it here as well. There you go. Then we're
gonna click on it, Alt and Enter to import. And then instead of having
these, This placed, what we actually want is just
removing the place again, adding in a comma here. Now this is not gonna
be checked with, this is actually gonna respawn. And now they ago, Same here instead of place, we're just gonna do a comma and then doing
something like this. And then same here
that I've placed, replacing it with a comma
and then we can also remove that and that
should be working as well. We still need to go into the Gen classes because
here has also changed. This is now a holder
instead of a supplier. Then instead of doing
it as a supplier, we're just going to
do it like this. So we're just going to remove the supplier here and then
that should also work. So this remove the supplier,
import the holder. And then same here, Last one. Delete this as
this and they ago. And that should be it for
the world generation. Let's see Morrow
regeneration. There you go. Features again, no more errors and now everything
should be working. So of course, once again, everything is available to
you in the GitHub repository, an individual just as
well to copy over. And those should be everything
that we need to do. I will actually show
you what is wrong with the title screen in just a moment when we actually
get into the title screen. But now we can actually just
start it, see if it works. Let's make a new world as well. And then we're gonna see if everything works in 1000th two. Or the custom title screen
is actually turned off. We're gonna look at
that in just a moment. But for the time being, let's
just make a new worlds. Let's do a test 1234, and let's see if
everything still works, if everything's still spawns, but I'm fairly
confident that it does, or Francis back in Minecraft. So I already basically
located a plane's biome here. And you can see we got our
custom mobs even spawning. We got our tree
spawning our flowers. So that all works totally fine. And you can see we're
just going to go in here. We can get the
cobalt blast route just like one recipe here, just for the sake of
argument, why not? Let's just try it out because the recipe should also
be working totally fine. Let's just set it down. There you go with the theory, you go and it's still
working totally fine. You can see we are
cobalt pickaxe, it's working, it's in there. And so as you can see, I mean, pretty much
everything is still working. We can also take a look at
the dowsing rod here with the data tablet a ago
also still working. So it's also working
totally fine. Everything should be functional. And yeah, I mean,
that's pretty much it. So let's just take a quick
look at the title screen. So I'm just gonna
change the on fake and then we're gonna
take a look at what the title screen and tails. All right, so as you can see, both the splash screen as well as the additional
information at the bottom left corner
are sort of not present. I am not a 100% sure
why that is the case. So I think that the best course
of action is to just keep your custom tiles screen default turn off basically
so that it's not replaced. And then once I actually
figured out something, then I will of course, make another short lecture on basically how to fix that
for the time being though, I think that this is going to be fired and it's not gonna be too disruptive robot that pretty much concludes
this lecture right here. I hope you've found this useful and you'll learn something new. And I'll see you in
the next lectures.
114. (1.18.2) Custom Structures (Working through Tutorial): All right, welcome back to
the forge course for 118. In this lecture, we're
gonna be looking at a custom structure
generation goes very important is that the custom structure
generation here is of course going
to be for 118 to, if you have an updated, very much advise you to go to the last lecture that we had and where we basically updated
to 118 to keep that in mind, the thing we're gonna do in this particular lecture
is we're gonna go through the structure
tutorial by telepathic grunt. And this is right here. I have this already opened
here in the background, and this is probably the best resource for
structures that exists ever. I mean, like props
to telepathic run because this is just
absolutely freaking amazing. And we can see there are
different branches here. They can use the 1800s, forge a jigsaw branch
if you're using 1, 1000th 2, and if not, you can use the 1800s 0
branch, this one right here. Forge. It is definitely a
little bit different. In 1 1000th 2. What we can now do is we can actually do custom structures, add them to the world without
any piece of code at all. We only need JSON files, which is really
freaking awesome. In this lecture, what
we're gonna do is we're gonna step through this structure tutorial mod right
here, all of the code, all of the adjacent files, copy them over a piece by piece, and then basically take a look at what you
need to change. What you can then, what
do you then have to do? And the general idea to add the two structures that are
added here as an example. And then in the next
following lectures, we're gonna make a one-piece
structure ourselves. And then we're also going
to make a jigsaw structure, which is actually far easier
than you might expect. It's actually all not too crazy. I think that yes, of course, if you have something
in singly custom, of course it's gonna be a
little bit more complicated. But for the time
being, let's just go in here and let's
see what we have to do. So let's go in
source main and we have to actually
open both folder. So I'm just going
to middle mouse, click on the Java one and then
on the resources as well. We're going to first of
all, start with the code. You can see There's the
main class we have the, this is what I would
call the mod structures. And then in these
structures folder, in the structures
package, we have the sky structures class. But this is the first
thing that we're gonna do. We're gonna basically,
I'm going to reorganize this a little bit, but we're gonna start
with the mod structures. This one right here and
among gonna do this one, and then we're gonna do this 1. First of all, we need a
mod structures class. Well, that's easily done in
the world package actually. Then we're going to go in here new package called structure. Then instead of they're all
going to make a new class called the models ruptures. There you go. Now it's written
correctly they ago in this class what we're
gonna do is I'm just going to copy over
the contents here. This is actually, lets
actually copy over everything. That's gonna be fine. I'm going to rename
it here again. So when I say modern structures, they will making sure that
the name here is correct. And then we can also delete
this and this. There you go. And just reformat
this a little bit. This is of course
now going to be the MC course mount at AdMob ID. And then because I
like to do this, we're gonna do is
we're gonna make a, because I like to do this. We're gonna make it public
static void register method with an I of n plus Event Pass. And then we're gonna call the deferred register structure. You could also call
it directly in the, the main class in
the constructor, but we're not gonna do
that in this class. We're going to add
in just a moment. So in the MC course
mod right here, we're just going to go down, let's say right here to
model structures that register and then passing in the event bus fare
you go, right? And now we have actually done this one right here and
then this one as well. You can see that
this is literally the only thing that
we need to add. And then here we have
the sky structures one, we're just going to copy
over the entire thing. Once again, this is
the structure package. Right-click new Java
class called Sky structures, no, sin here. What we just want
to do is we didn't want to say log manager, making sure that we choose or Apache logging log for
J. Very important. And then we say
instead of lager, we say yet lager or
log. There you go. This is not the run-down house. There's actually
skies structure. There you go at a
particular position. And then we can actually
take a look at this class, what it is, what does it do? Get rid of this import as well. And then there you go. Overall this class, you can see the structure feature of
jigsaw configuration. Now, this is sort of
boilerplate code. You can see there are a lot of comments I highly recommend
in your own time. Go through, read all
of the comments. Just try and understand a
little bit of what it's saying. The eternal ideas that you have two different methods here, these feature truck with
it and decreed pieces. The generator and the
creed pizza generator is really the thing that's most
interesting to us really. You can see in the future trunk, we're just basically
checking, hey, is this chunk the actual
chunk where this is placed? Roughly speaking, I
highly recommend, like I said, read through
all of the comments. It's highly recommended. But then in the creative
pieces generator, you can see here what we're
basically doing here. This is interesting,
right? So you get the trunk coordinates
into a blog post. So this is going to
be what it's doing. And then here we're
basically placing it 60 blocks above the top land. So you can see that
doing it like this. You can see in the comment here, we'll surface WG will stop at the top water so we don't accidentally put our
structure into the ocean. And then this is basically, you get the y-coordinate of the top of the
land basically, and then we're adding 60 to it. So this is a way of you can basically changing the y level. And then you can
also see right here, we have for each of the different parameters
that we're putting in here, the, what basically happens
here. It's really well done. I can just recommend
you if there's a certain complex thing
that you want to do, read through the
comments that are added here and then
you're going to be fine. Now this is actually all
of the code that we need. This is very interesting
because the rest is all done with JSON files. We're just going to basically
go back to the GitHub again and we're going
to close all of this and then we're
here in the resources. So the thing that we need
is in the data folder, we're actually going to need
to open a lot of stuff here. We need to add this
stuff and this stuff. If we add our
structure to this tag, you can see microbe has
some configured structure feature tags that at behavior. And then this is basically
going to add it to a locator. We'll structure on
the photographers, villagers, Ocean
map, monument maps. This is not strictly necessary. It's just an interesting thing. We're not actually going
to implement this one. We're just going to ignore it
and we're only going to be interested in the data folder
for our own custom one. This one of course, being a structure underscore
tutorial or the mod ID hours
will be Mc course. And then we're going to open
all three of those folders. And then you can see the
structures here are NVT data. This is very interesting. So the NVT data is
basically generated inside of the while
instead of Minecraft. So you build your structure, you use certain blocks to
generate it for the time being. In this lecture,
we're gonna take these NVT data and we're
just going to copy it over. And then we will
actually have to change a tiny bit in the NVT data,
but no worries there. We're going to see
that in just a moment. For the time being,
we're just going to basically download
all four of those. So we're just going
to go in here, open all of them
and then download, download, download and download. And you can see they are under Data Mart ID structures
and then the actual file. So what we're gonna
do is inside of our data folder, MC course, we're gonna make a new
directory called structures, and then I will add
all of them in there. Just going to actually
do it like this. There you go. Just like
dragging them into this folder. I mean, at this point should
be fairly self-explanatory. How you can just add
stuff follows here, just dragging them in there. And then we have the NVT data right here. So
that's really good. And that is the first part. And now we need to
switch back right here. We can get rid of all
of this right here. There you go an hour here in the tags world gen
biome has a structure. So this is a really cool tag
that we're going to add. And this is honestly really freaking cool because you
can see first of all, the sky fan biomes here. And then there's also
the JSON only house. The JSON only house, if you remember back in our
structures that we had, we only had the sky
structures right here. There's no mention of any house. Exactly. That's what I'm saying. You can actually add certain structures without
having any code at all. This DJs and only hear house. This is basically going
to enable us to do that. I'm gonna do is I'm just
going to own both of them. Then what I do is I'm
just going to copy the name here because that's
like a little bit easier. And this was a tag in our
MC course, holdup tags. And this under this
underworld Jen. And then instead of here, this is gonna be under biome. And then one more structure, one more directory which is called as underscore structure. And then we can add the
file here, this 1 first. And then we're going to
also get the second one, the name here as
well, a new file. There you go, Jason only
house biomes and you can see the contents of which if I'm gonna
copy this one over. So this is the code
structure Skype and biomes. You can see this biome tax
specifies what biomes, this actually starts in it. You can either start
it with biome tanks, with a hashtag, or you can specify a specific
biome like this. It's really freaking awesome. So this is the way
that you can basically specify what biomes this
particular structure spawns in, but also gonna copy over
the contents of this one. They go. Without that one. Of course, there you go.
And all of the sucrose also available in the
GitHub repository in the, just as well. Don't
no worries there. However, I really do think
that it's the best if you work through this structure
tutorial with me once and then maybe
even once on your own, just so that you basically
know each individual part. So you can basically say this world gen biome
tag has structure, is used to specify the biomes in which our
structures spawning. But we can basically
now close this as well. And then we can proceed to the next one which
is the world gen. There was this folder, so we're gonna
close this as well. And then you can
see there are four different folders in here. Once again, all really
freaking interesting. So we're just going to
open the first one and we're going to basically
deal with this. We can see that here we have the code structure
sky fundraising and the adjacent only house for the configured
structure feature. Once again, I'm gonna
copy over the name right here and we're going
to take a look at it. So data are more
ideal underworld yet and then configured
structure feature, we're gonna go into the heart. So this is under the tags, so very important that you don't accidentally put
this right here. Under the EMC course folder. We actually want a new
folder called world gen, which should then
be below your tags. So make sure that
this is correct, not inside of this folder. Make sure that this is,
you have two of them. You see X Gen. This one has he has
structure stuff. And then this world gen
folder is instead of your more ID for your
MC course full of very, very important that there
is a difference there. Please make sure that
this is correct. Instead of this
world gen follow, we can actually take a look
at all of the four different. The things we need,
Let's just do it like this for a moment. So we're just gonna say this is the configured underscore
structure underscore feature. And then we're just going
to copy this one over here. We're gonna say this is the
process or underscore list, and then we're gonna
copy this one. This is the structure
underscore set. And then last but not least, we have also the template
underscore pool, of course makes sure that all of those are written correctly. And then we can proceed with the configured structure
feature right here. And we're just gonna go in once again there and we're
gonna say this one, this name right here. I'm going to make
a new Drazen file. We're going to right-click
new file, call it like this. There you go. And then copy over
the contents of this. And then we're
going to see where the first things are that we actually need to change here. And as you can
see, there's a lot of comments again, no worries. By the way, these arrows, you can ignore them in the JSON files because they're
still going to work at. And so no worries there though. You can see basically here we have some overrides,
which means that, hey, these particular monsters
might spawn in this structure, you can see what mobs can spawn over time
in the structure. That's very
interesting also here, if true land will be
around the bottom of a structure based on
the pieces y-value. That's also something
that you could do. This one here is the tag. This we need to specify
this tag right here. This of course changes to
our model ID and then has structures is the
same thing and then this name is the
same thing as this. So we don't need to
change this the path to the template poor JSON file, of course, also needs
to be MC course. This is adjacent that we're
going to add in just a moment under the template
pool right here. And then here we're also
going to change this name to MC course sky structures. Very important that
this name you can see the base structure class to use for the behavior
of the structure. So we can see in the mod
structures right here, this is the name of
the sky structures and then this is what
it bases it off of. But this is basically
the connection between this JSON file and
this structure, mainly like this structure
class right here. So keep that in
mind as well that you have written the type year correctly when it comes to the JSON only house, right? We're just going to copy
over the name again. We're going to put this
into the same folder, a new file right here. Let's go and then the actual content of which
once again copied over. There you go. And then here
we also have to change once again as this to MC
course should make sense. And then we'll change this
to MC course as well. This is going to look
for a JSON file in the template
underscore pool older, where we basically add this in just a moment
Apart from that, the rest can stay. For example, you can see
there's some illusion or some pillagers and some parents
that might spawn in here. That's really interesting. We're going to then
continue along. So now we have managed the configured structure feature and then we can look
at the processor list. This is a very interesting
thing as well. We can actually just get this
based on file right here. Let's just copy it over
and we're going to look at it inside of this. This is the processor list, a new file called
the random mice underscores don't break Grayson. And this is very interesting. So I'm gonna paste this in. And you can see this is a, this is basically a
rule and what it does is it replaces a certain thing. So you can see the block we're looking for is the stone brick. And this has a 50%
chance of allowing the found stone brick to be replaced with different things. For example. And you can see
if we find a stone break, then there's a 5% chance of replacing it
with an emerald OR, and then here you can
see there's a 50% chance of actually replacing it with
an infested stone brick. And then down here, you can see a couple of deep slate
might be replaced at 10% value or a 10% probability with a deep state
Redstone or so. Those are some very
interesting examples of basically one of
those interesting rules, which is really
freaking interesting, which can make your structures
just that more, well, I mean that more
interesting if you can then replace certain blocks
under certain conditions, basically with a
certain probability here to do to be other blocks. That's really cool
and really awesome. So that's definitely
something to play around with a little bit
in your own time as well. But that has also been added
and we're gonna see where this is used in just a moment so we can close this as well. And then let's just
open to the structure set in the template pool. Both you can see once again,
the structure is set. We have two JSON files, one for each of our different structures
that one more time. So we're going to just read
those Jason files as well. Read this one. There you go. And then I'm going to copy
over the contents here. Once again, there you go. So this one is one of the, well, I would say this is one
of the easier JSON files. I would say just changing
the name right here. And then this of course, in this case the structure here, it should look for this JSON file here
if I'm not mistaken. And then the placement here
is actually very important. So the salt here,
you can see it. Make sure this is
unique and does not match any other structures salt. Otherwise, what's going
to happen is that they're gonna be placed in
the same location, which of course is
something we don't want. And you can see the average
distance support in chunks. And then here, this is the minimum distance
apart your trunk. So this one always have to
be smaller than this one. It makes sense. And then here we're
just basically choosing a random spread. This is also advisable
to keep it like that. And that is pretty
much what we need. Ear. And then what we need is the
case normally house as well. We're going to get
to this as well, they ago and then the name here, so new file and then just
copying over the contents. And you can see this is
once again change here. They ago. And you can see this salt here is
different than this salt. Once again, highly
recommend just if, when you add your own
custom structure. When we add the
custom structures in the next two lectures, then you're going to see
that we're going to change the salt as well.
Very, very important. Otherwise this is pretty much a fairly straightforward
JSON file. Once again, this one points to, point to the configured
structure feature right here. Now, the last thing that we
need is the template pool. So this is gonna be the
JSON files right here. So I'm gonna close
this, this and this. You can see we have the
single adjacent file here and we have two JSON
files for the house. We're just going to
use the sky fan first. This is gonna be right
here inside of it. So Skype on Jason and
then I'm going to copy this over as
well. There you go. And you could see what happens
here is that first of all, in the name here I'm
going to change. So this is not strictly
necessary actually, because I believe that
the name here is it's pretty much it's the name of
the template pool itself. I don't think that
this really needs to be changed here,
not a 100% sure, but you can also see
there's a link right here for the a template
pools JSON file. Highly recommend checking
this out as well. This is of course linked here as well, so no worries there. And then you can
see what are the elements that we're looking for? Well, we're looking for eighth. Once again, structure
tutorial has to change to MC course, the sky fan. Now this, as you can see, the final path is resources data structure
tutorial in our cases MC course, It's structures rundown,
left house, left side MVT. Now this is of course
not quite right. This looks for Sky
underscore fan, NVT, sky fan, and then
this is right here, Skype and MET under the
EMC course location. This is where it looks for. And then this one is
also very interesting. You can see we're adding in
the processor right here, which is the MC course,
randomized stone, brick. This is exactly this
JSON file right here, so this is actually not needed. This is just an added
bonus, so to speak. And you can see specifies the processor list
and then basically applies it to the NVT file right here when placing
it in the world. And then it's there. You can see processor
lists are great for randomizing blocks and making structures appear more natural. Really freaking
awesome, Really cool, and overall not
too crazy to use. Once again, this is one of
those things where of course, adding in exactly what you want might be a
little bit tricky. But overall, it is still
a really cool thing to basically take a look at and change around and
played around with, right? So this is going
to be the sky fan. And now we're gonna do is
the these run-down house. You can see there's a site
pool and a storage pool. We're gonna basically
near both of them, are just going to get
to the site pool first. And this is in a, in a
new folder right here, which is going to be called Run underscore down
underscore house. And then we're gonna
have a new file called the dot underscore pool, Jason. And we'll also
have a base so far which is called the
site underscore pool, underscore dot dot js and actually cite Poole side
underscore fooled adjacent. There you go. This is
the site pool JSON, and then this one right here
is the start pool Jason, why do we need two of them? Well, the actual run-down
house Is a jigsaw structure, meaning that it has two
different parts of it. You have a left
side, right here. We're gonna change this
once again to MC course. This is the run-down
house left side, which points to this one, this NVT data right here, run-down house left
side and the side pool. You can see we actually
have a list of elements which has
different weights here. And it points to two different
NVT by else basically. And you can see that
there's a 50% chance of spawning the gold run
instead of the regular one. That's the idea here. And we're gonna see
one example of this, the custom jigsaw structure
that I will do as well. Once again, of course, changing
the MOD ID right here, which is very important. And then here we can just
change the mode idea. I don't think it's
strictly necessary, but we're just gonna
do it as well, just so that we have it. So you can see there are a
lot of moving parts here. However, I will summarize
one more time because there's actually one more
thing that we need to change because as it
stands right now, this actually is not
going to work 100%. The run-down house
is actually only going to spawn a left
side and right side, because in this MPT data, the wrong monody is saved. We're gonna see how we can
fix that in just a moment. But first of all,
let's summarize with all of the stuff
that we've done. We have added two
different structures. We've added the sky structure
using some code as well, mainly the sky structures
class right here, which can be used to what
at certain other features that are not possible to be added via only the JSON files. Mainly, you can see this one
right here where we specify the actual y position of this particular structure and
some other things as well. But what we've also
done is we've also made a structure purely
with JSON files. And you can see for that
structure we needed. 12345 different Jason files that all of course have to be in the correct locations and they are all related
with each other. Let's think about
this for a second. So it's best to probably start with the storage
pool right here, because the store pool
references the NVT file. This is the NVT
file right here in, under your data folder
mod ID structures in VT. And this is referenced
right here in the star pool. Now whereas the store pool reference their star
plus referenced in the configured structure
feature class right here. So we can see this is the store pool that
is being referenced. You can see this is
the configuration of this particular structure and
this has been referenced, whereas also referenced
is the biome Jason, This is the under the tax world, Jin biome has structure. Jason only How's the biomes, which basically signifies quick in what biomes can
this structure spawn? This pretty much explains
this chase and followed here, this JSON file is used for
actually adding the world, basically adding
the structure to the world that this
structure is set. You can see in this comment here basically it's going to pick
one of those structures. I mean, in this case
there's only one structure. You could in theory at
multiple structures of a not mistaken as this right here
refers to as this one. I'm not 100% sure on that, but I think this
should refer back to this particular JSON file, which of course refers to the store pool and
also the biomes. That's sort of how they're
interrelated with each other, right then for the site pool. But because this is one of
those interesting things, the cycle once again
is because we're using the jigsaw block. I highly recommend if this is a little confusing with
a psych pool for you. We're gonna see that in the, when we actually talk
about the jigsaw ones in just a little bit
in the next lectures. And this is it. So there's quite a few
moving parts to it. Once again, I highly
recommend you might have to watch this lecture twice.
There's no way around it. Structures can be
quite complicated. However, once you
have set them up, once adding more structures is actually very,
very straightforward. The ones everything
here is set up. I recommend not changing
anything too much, is basically changing
your MOD ID, that Ahmad ID to your model ID, and then that should
be it, right? So because this is basically everything that we need
for the time being, what we're gonna do is we're
gonna make a new world, see if the spawns, and then we're gonna see that we need to change one more thing, which is gonna be fairly
straightforward to change. But let's just see if it works. Also keep in mind when
making these structures, you will get this
the world's using experimental settings is not supported. It just
is what it is. You can just click proceed. It's mine. Might look a little bit
different if you are joining into a world
that already exists. In this case, this was
creating a new world. There's basically
no way around it. This is going to show up, but no worries there. You can basically ignore it. Just say proceed
and there you go. All right, So we
find ourselves in Minecraft and you can see one of these structures is already successfully added right here, and there's even another one. They might be a
little bit too close. But first of all, you can see the actual
structure spawning. You can also see some already spawned
people are like mobs here. And then what's also
really interesting, you can see the
replacements right here. You can see some of the bricks have been replaced and you can see some of them are also
infested. That's really cool. So there's a 50% chance, of course, of them
being invested. And then some of them
are also replaced with the Emerald OR, and then you can
see some of this is also replaced with redstone. All, That's really cool. This was the replacement
stuff that was done. And you can see they
are, they are spawning. Then the other, the house, we should actually find it very, very fast because it's
born like every few, there's actually
a house already. And what you will
find is that it kind of looks like half
a house, doesn't it? Yes. This looks like
half house because it actually is only half house. You can see. First of all, there's some
helpful hints here as well. Highly recommend checking
those out as well. But you can see you're, the jigsaw block was actually
replace here and well, the issue is that the actual
modal he does not match. To get this to work,
what we're gonna do is we're just going to get ourselves some distance
and some space. Basically. Let's actually just
fly over Here we go. This should hopefully
be enough distance. And then what we need, we
need to give ourselves the structural block
right here, this one. And then let's just set it
down and let's right-click. Now the structure
name here is going to be structured name
year is gonna be MC course colon,
left underscore, run underscore down
underscore house underscore, left underscore
side, I guess then it's not gonna be left
here at the front right. The name here should be
this name right here. Let's just actually right-click Refactor Rename, copy this. That's going to be a
little bit easier. There you go. It actually is that
and now if I go into load right here,
it should load this. And then I could do load again, and then it actually
spawns the house. You will now be able
to see right here, this is the jigsaw block. And you can see here
it actually looks for this site pool, which
we have to change. I have to change this
to MC course, say done. Then we also want the
other part of the house. We actually want the other
part of the house as well. What I'm gonna do is
I'm actually going to copy this over here. So just like Control a to select all control C to copy
control V to paste it in. And then this is going
to be the right side. When a load, and then
we're gonna load again. And here you find the
other jigsaw block. Right-click on this one. We want to change the name here to MC course right side done. You want to change
the name here to MC course right side. Done. And then what we
also want to do, just so that we have everything. We want to spawn another house. That's going to be
the right side, golden, I believe, right side. So there's gonna be right. If you write underscore
site underscore, golden. There you go. Pull that and then load
it. And there you go. Now, this is the golden site, just going to have some
golden locks in there. And then here we also want
to change this to MC course, so to our model ID, yes, And then we're
gonna be fine. Now what we need to
do is we need to actually save the NVT here. Once again, this is a little bit what the FREC are redoing.
Don't worry about it. This basically
what we need to do in order for this
to properly work. Once we've done this, in
the next two lectures, we're gonna go through really how to do this
completely custom. So we're going to build
a custom structure. We're gonna save the
custom structure. And I'm going to explain
a little bit more detail what we're basically doing here. If you don't want to
follow this, then that's of course also fine. But basically there are some very straightforward
things that you have to do. Now here, after we've
changed the jigsaw block, what we're gonna do
is we're going to go here to the safe mode. We want to say safe, then you can see it has now
been saved and the same thing goes for the
other two are safe mode safe. Here as well, go
to Save mode safe, and then we are done. We can now do is we can
get out of Minecraft. We're going to just
get out of here. And then the NVT
data is going to be stored in the R1
folder under saves. Then wherever you have, this was the don't forget to review world and then this
should be under generated. And you can see all three
of the NVT data right here. We're going to actually get
this over to right here. And we're gonna say
override for all. So now the NVT
data here has been overwritten with
our MOD IDs in it. And if I now start
again, make a new world, then what we're going to see
is we're actually going to find the house
complete as before, instead of the
left house or the, the other part of the house. So the house, we have this jigsaw block that
was actually looking for the site pool under the
structure tutorial mod ID, which is of course not correct. Let's see, let's actually
create a new world. Here. Is gonna be the structure
test. Structure tests. That's gonna be fine. A rate of world. Once again, we're gonna get the, you've changed world generation and experimental settings. That's gonna be fine. We're just going
to hit Proceed and then we're just going to
wait until it finishes. And then we're going
to see whether or not our structure is complete. Alright, we find
ourselves in Minecraft, so let's just see there it is, and you can already tell that the structure is complete now. Well, let's just go in
here and let's see. They can see if we go in, you will find there you go. This is even the
golden variant of it. This is the right side
for the goal and then we shouldn't have to fly far to find another example of this. So this is amazing world
generation looked amazing. Though we should be able to find another house quite fast. Usually they shouldn't spawn too far away from each other. Let's see, There is another one, so you can clearly see
they're not that rare, but of course this is
something that you can very easily change as well. So let's just go in here. Let's see, this should
hopefully is this normal one? This is a normal
one. There you go. No, no goal here. We also have stuff in the
chest right here, and you can see
everything working fine. This is the basic structure following the
tutorial right there. And if you're at this point, then adding new structures
is very straightforward. So we're basically
going to see in the next two lectures
on how you can add some custom
structures as well. First, basically one
piece of structure, because a structure can
only be 48 by 48 by 48. And then if it's
bigger than that, you have to use jig source. But like I said, it's actually, it's not actually as complicated as some might make
it out to be now, it's still not very easy, but it is easier than
you might expect, right? But this concludes the
structures lecture here following the structure tutorial
from telepathic Grundy, once again, amazing repository. I will of course
link this as well, is pretty much the
best resource that exists for structures here, it is incredibly useful and I cannot recommend
this enough. Now, once again, there
were a lot of stuff here. It's a long episode. There was just no other way of making it any shorter really, because there are a lot
of things in there. Once again, for the
custom structure, next time, I highly recommend that you have
gone through this once. Otherwise it is going to be a little more complicated
because we will copy over the already
existing JSON files here and then just changing them
for our own custom structure. So keep that in mind. Otherwise it will be this
for this lecture right here. I hope you found this useful and you've learned
something new. I'll see you in
the next lecture.
115. (1.18.2) Custom Structures (Single Piece): All right, welcome back to the forage course
for 118 and we find ourselves in Minecraft with an already built
structure right here. What I highly recommend
you do is you can either copy the structure or just create your
own structure. And then basically after
you created those, we can continue along. So I'll just give
you a little bit of time to create your
own structure. But I hope you pause and just
create your own structure. Because now what we're gonna do is now I'm going to make an MVT file out of this.
How do we do this? Well, we need to first of all, give ourselves the
structure block runs again. So this one right here. And what we need to do is
we need to place it in the corners of this
particular structure. So what we need to do
is we need to place it outside of the actual
will entire structure. So we need to place it
right there and right here. And then also on the other side, on the same locations
basically right here, and then also right here. There we go. Now what we want to
do is we want to right-click this and
then we need to split. First of all,
specify a name here. This is gonna be the
MC course colon. So always taken your
model ID colon, whatever the name is. And this case it's gonna be
the kelp underscore house. And then we're going to press
Control a to select it all, Control X to cut it out and Control V to
paste it back in. That's basically
what I just did. And I'm going to go to the
owner mode. Very important. We're going to say done,
and there you are. I'm gonna do the same here, paste it in corner mode, done, a sit-in, more done. And then this one, we're actually going
to paste it in and then we're going to
go to the Save mode. We then want to press this
detect button right here. And it should in theory, detect the entire structure. So you can see we've basically highlighted the outside
of the entire structure, which is exactly correct. This is what's going
to be saved your. Then what we can do is we can just click the Save
button right here. And then this NVT
data has been saved. So that's literally
all that we need to do to save some NVT data. And now we have this house. Now what we can do is
actually really fun, because this is already saved. What we should be able to do
is just go somewhere else. Say, Hey, give me this house. I can just put this in, say load, and it should
detect this house. And then we can say load it
again, and there you go. And now I can actually copy this house from there to here, and then I actually
have this already done. But of course what we wanna
do is we want to take this house in a naturally
spotted in the world. So what we're gonna do is
now we're gonna go outside of minecraft back to Intel J and then basically adding some
of the adjacent files so that we can spawn at
this house, the world. All right, so we find ourselves
in an intelligent way. And the first thing, of course, what we need to do is we
need to get the house. So this is once again
in your run folder. This should be in your
sales right here. This is the structure tests
in my case, under generated. And then here we have
the counting house NVT. So I'm just going to drag this over right here
to the structures, and then we have
this right there. So that's very important. And now we can basically
change the JSON file. So what are we gonna do? What do we have to do? Well, the first thing we're
gonna do is we're gonna make the structured JSON file
for this, for the tag. This is going to be
including all of the different biomes that we wonder this
structure too small. And so we're just going to copy over the already
existing one here. This is going to be the
count and underscore house. Honestly, I think that
this is going to be fine. We're just going to
take these biomes tier. You can of course also change
it however you would like. But I'm actually happy with
this and we're gonna be fine. But this is the first one. This just once again signifies which biomes this
structure can spawn. And then we want to get the
configured structure feature would just once again,
I'm gonna copy this over. I change this to carpet
underscore house. We're going to use that
name a few times now. And here we want to change the start pool to our account
and house stored pool. This is gonna be the thing
that we're going to add here in just a moment
and same here. This is now gonna be
the counter house. This biome tag refers to this one that we've
just created here. But no worries. I personally actually don't want any monsters to
be spawning here. But what I do want is I
actually want some of the MC course tigers to
spawn there. Why not? Let's just say that
there's gonna be one or two tigers that
might spot on there. Let's just add it like this. That's gonna be very interesting and see if that
actually also does it. Now this should be
pretty much all that we need to change right here. Then the next one, we don't need any processor
lists in our case, but we do need a structure set. Once again, copying
this over at changing the name to cope
and house, this, changing this one to come house, which then it points to this JSON file that
we've done before. Very important here,
changing the salt, this has to be a unique
salt and quite big. And then the spacing, we're just going to
give it a little more spacing here on both counts, and that's gonna be fine. Then the last thing we
need to do is we need to create a new folder
right here directory. This is going to be once again
the CAPM underscore house. Then the name of the
file here is gonna be the start underscore pool that adjacent and the contents of which I will actually copy
over from once again, the already existing JSON file. This is why I said if
you have it setup once, then adding new ones is
very straightforward. So what we can do here
is basically this one has to change to count
underscore house and then. We're going to
copy this and then change it here one more time. And that's it. We're already done this now our actual structure
will spawn in the world. That is all that we need to do. 1234 JSON files in this case because it is a single
structure and one NVT file, this is literally it. You saw that it's fairly straightforward once
you have it setup, once copying some of the JSON files,
changing a few things, tweaking few things and then, and then you're
pretty much done. That's literally it
As all that we need to do for completion sake. Let's see if it works. It just to make sure that
everything works, I highly recommend making
a new world just in case. And then also of course, keep in mind that you will get the experimental
world settings. We just have to press Proceed. That is just gao. It's going to be when you
add the custom world Jen, via the data based on files. But that is going to be fine. Let's let it generate
and see if we can find our accounting
house in the world or your friend's
house in Minecraft. And there you should
already be able to see it. The carbon house successfully
added to Minecraft. And see it's right
here and it's set out into the ground perfectly
just like we left it off. I actually accidentally
destroy the door there. That was not intentional.
There you go. But yeah, it's pretty
much already added. Like I said, it's
very straightforward. Once you've done it, once. This is why I said, you
should definitely go through the structure
tutorial once with the lecture by basically shows the GitHub
repository of it. And then once maybe
even on your own, take a look at some of the
some of the comments there. I mean, yeah. I mean, I don't even
know what else to say as you pretty much saw that. It's very, very straightforward. There's a few things
that you can change. And now it's really
just up to you, up to your creativity on what you want to
add to Minecraft. Let's actually see if I can find one more of our camp houses. You can see a lot
of the run-down houses pointing out here. I want to find one
more account House. Let's see if we can find it. No, there is there
is another one, so you can see there you go. So overall, I think
really interesting, but also fairly straightforward.
All things considered. I don't think it's that crazy
and that hard and well, I mean, yeah, that's pretty
much how easy it is to add some custom
structure to Minecraft. But as I've said multiple times now and I'll
say it one more time. If you've set it up once
you've seen, it's very, very straightforward to add
more structures to your game, and it's very straightforward. Now once again, for the drink source that
we're gonna look at in the next lecture is gonna be a little
more complicated. But even then, after you've
seen one example of this, basically set it all up, you're going to say that even
that is gonna be fairly, very sensible and
fairly straightforward, all things considered, right? But that would be it for
this lecture right here. I hope you found this useful
and you learn something new. Or the JSON files are of
course available for download in the GitHub repository and
an individual just as well. But otherwise, I'll see
you in the next lecture.
116. (1.18.2) Custom Structures (Jigsaw Structures): All right, welcome back to
the forest course for 118. And in this lecture
we're gonna be looking at some jigsaw structures. You can see I've already
prepared something right here, which is going to be
the storage platform. And the way that this is
going to work is that this is going to be two
different structures, but it's gonna spawn as one. So the idea is that one
part of the structure, which is gonna be basically
everything left off here, going to be the start pool. And then we're gonna
have a jigsaw block in the middle that's going to then generate this right
side here of the structure, which is going to be
either, let's say iron. And then we're going to also
make a variant basically which has going to have
something like diamond maybe and then even
one with emerald. So that's the general idea. And then this is going to end. We can then have it spawn with different weights
so that when you go around the world
needing to find a lot of it with the
iron for example, with like, I don't know,
like 80% and then like 10% of the time you're
gonna find the diamond. And then 10% of the
time you're going to find the Emerald,
something like that. So what we're gonna
do is we need to set this up properly. So what we're gonna do is we're just going to take, right. So now let's actually
do the main 1 first. So this should be right here. So we need the structural
block right here. And then right here as well. That should be fine. And then on this side, we showed that we choose the correct It's sort
of speak so well, let's go down here. So there you go. And then for the
height h should be right around your, I believe so. Let's just double-check
this as well. So this should be this
one. There you go. Let's delete the
helper blocks here. And this is actually higher, so we're going to do
one below it that they ago that we have the owners ready and
then we're going to, and then we're gonna call this MC course storage platform. That's gonna be fine. Once again, Control
a, Control X, Control V, so that we have the name and this is gonna
be the quarter mode. And then we're gonna go
through the corner mode for each of them, or mode. There you go. Acing this mode and then this
is gonna be the safe mode. So we're gonna do this
safe mode and then detect. And then once again,
we will find that this is now what
is being detected. Of course, what you'll
find is, oh no, we actually needed higher up, but there's no worry at all. What we can do is we
can just build it up. You're, let's just build it up to the height that we need. Right there. There you go. And then we'll destroy this one, which was basically
the actual thing is going to stay
for the time being. But once we actually reload
it, and it should be fine. So this should be about this height, I believe
this should be. Then we can once again
are corner mode, yep, and then delete
this one as well. Also mode with that same
with the right name. And then we can detect it again. And then you will
find that the ego now it's done and
everything is inside of it. So basically, that's one
thing that you could do. You set it up and
then you're like, Oh, that's actually some
blocks outside of it. Just replace it
and there you go. Now this is the main one. And what we'd still need
to do is we still need to place down the jigsaw block. So for that we're going to do open the terminal and the
command is once again, of course they did
give command or the jigsaw block,
this one right here. And what we wanna do is we
want to be facing this way. So what we want
is this should be still inside of
it. There you go. The arrows should point
to the outside of it. So you can see that
this is still inside of the structure and it should a point outside
of the structure. And then right here, we want the other jigsaw
block to point towards it. So these are the two jigsaw
blocks that we want. This side here is going to have a name associated with it. So this is gonna be
MC course colon, Let's say for example, site, platform, something like this. And I'm gonna say done
this name right here. We're going to copy
it over and this is gonna be the target
name right here. And then the target
pool here is gonna be MC course colon. And this is the name of the JSON file that
we need to put in. So this is gonna be
the storage underscore platform slash site
underscore pool. This is the JSON file right
here, we're gonna say done, and now those are more or less
connected with each other. And the important
one is of course, this one for the time being, because this is in this
structure right here. So we can now save this. We can then say Save. And now the storage
structure has been saved. We can now do the similar thing
for the other structures. So we're gonna just gonna
do this one right here. And then we only need
to go up to here. For the other side, we're
just gonna do it on, it's simultaneously basically so that another
structure block here, and then the other
structure books should be right around here. That seems fine. So then the name here we're
gonna do MC course colon, iron storage, plant form. Going once again,
I'm going to copy this corner mode mode or remote. And then down here,
this one is going to have the safe mode
once again detect. Let's see. There you go. So then now this
is also detected and you can see now we
actually have both. And I highly recommend
doing it like this. Because now basically
when you change this one right here for
another variance so to speak, and it's very, very
straightforward. The names here can
basically stay. So this is the side
platform and side platform. That's all fine. So we're going to
save this for under the iron underscore stored
under score platform. Save it. And then what I
will do is I will change this and
then we'll save it under diamond storage platform
and then emerald as well. I've replaced the iron
with some diamond here. And then of course,
what we want to change here is the name, right? So this is now going to be
the diamond storage platform. Once again, copy this,
I'm gonna say done. And then we're going to
change this in here as well. So in all of the
corners, basically, we're gonna be able to detect it in just a moment as well. We're going to do this and
then go back to this one, detected one more time. Then now the diamond sort
platform has been detected, and now we can save it under the diameter storage platform. And then let's do the same
thing for emeralds as well. Alright, so now it's been
replaced with m roles. So let's just change the
name one more time here. So this is going to be the
Emerald storage platform. Once again, copy it over, and then it changing
the names and all of the corners right here. So nothing too crazy. There you go. And then
let's get this again. So let's just gonna
be the acting Here, Emerald storage platform
and then saving it again. But now we have
one main platform and associated with
it three different, let's say variance of the other type of platform
that we can spawn. Now let's switch over to
intelligent you again, and then let's set
everything up. All right, so we find
ourselves an intelligent. And first of all, of course,
let's get the NVT data. This should be under
the structured tests. If I'm not mistaken,
there we go. So we have the
storage platform and the three different
platforms as well. Let's just copy them
over right here to the structures once again. Then what we need is, of course, the structure
in its entirety. We once again need the five
adjacent files for that. We're just going
to copy them over. So this is gonna be the
storage underscore platform and we will need to use that
name a couple of times. So just copy it over. Once again. We're
just gonna stick with these biomes
for the time being. This is of course very easy to basically just change up here. And the configured
structure features storage platform
and want to point to the storage pool inside of the storage platform holder, which we're going to
create a little bit. And then this is the
storage platform JSON file, which signifies which
biomes are to be used here. Now I actually don't really
want any Richards here. However, what I have
found is that if you remove the small
overwrites entirely, then they actually get an error. So I'm not 100% sure yet
what you have to do here in order to not get anything where we can just
do is something like this. So we're gonna be fine then I think no, nothing spawns here. So we're gonna be okay,
the structure set. What we're gonna do is once again copy over
the counter house, change the name here, and then here once
again, of course, changing the name here
so that it points to the correct structure feature. And then very important here, changing structure,
the salt here, of course, and then the spacing
I'm gonna make a little bit more than what the
minimum separation. And they're like 12,
that's gonna be fine. And then it all comes down
to the template house, which we're going to just
copy over the run-down house. We're going to rename
this to storage platform. Then inside of the JSON files, we want to change this
to storage platform. This is the right side, so this is gonna be
the three right sides. So what we're gonna do is
I'm going to just delete it, the comments here. And then
what's going to happen? We said we actually
want one more of these. And then this is probably gonna be something like a weight, let's say five, weight three, and then wait to
something like that. And that's going to be the the four underscore storage
underscore platform. That's gonna have the
authority that's not or it's iron. Of
course, there you go. Iron storage platform. Then we're gonna call it copy this over and this is gonna be the Emerald storage platform. And then let's say this is
the diamond storage platform, but this should have a
50% chance of spawning. This is a 30% chance and
this is a 2% at 20% chance. This is the different weights should be fairly
self-explanatory. It's basically the weights of
how they are being spawned. So this should be the
site pool and then for the storage pool of
the storage platform, let's go to the store pool here. This is gonna be of course, then the storage underscore platform. Once again, platform. There you go. Copy this one. And then this is of course
the storage platform. This is our starting place basically are starting NVT data, which is going to have the
jigsaw block inside of it, which is then looking
for the site pool, which we've defined in the
jigsaw block just before. And that is literally
all that we need. And now all of those three different while variance
would also spawned. So like I said, it is once
again, once it's set up, once very straightforward,
All things considered. So now let's create a new world and let's
see if we can find our storage platforms or Francis in Microsoft
in a new world. And let's see if we can't
find our storage platform. We can also just located like this going for our MC course. And that is the storage
platform right here. Let's see. So right here, one of them is, let's see, There we go. One of them already spawned here with the iron in this case. And you can see
exactly how we left the basically and volume in the jigsaw blocks are gone as well because they've
been replaced with air. Let's actually just
HTP somewhere else and see if we might be able to
find another one of them. Let's just go to like, you know, 20 K or whatever. And then they go and then
let's locate it again. Let's just go for a, another, locate a platform
and then let's see. There it is. It's another one with irons. Halley. Well, I mean,
sometimes it works like that. Let's go for one more,
Let's try one more time. Negative ten k this time. Why not? And then they go. And
then let's located again. Let's see if this one
might have something other than iron and
it also has iron. Well, I mean, it is one
of those things that is more prevalent
than the others. It just is what it is. And also I think that just moving around
and flying about, we're not going to
encounter too many of them as we made
them a little bit rarer than the other
stuff that we made. So the counting house and the run-down house are way
more prevalent in that case. But yeah, I mean, that's
pretty much the thing. That's actually
try one more time because I actually do want to see the other stuff working. So let's go to of, I don't know, like a 100 and then we're
gonna do it minus ten K here. Then let's do another locate or MC course word
platform. Let's see. Oh, well, I mean this is also something that
can happen, right? So this is a very
rare occurrence. So this is usually not
something that happens, but you can see that both of these structures actually spawn pretty much in the same chunk. That the same moment. This is why you want
to change the salt. Now in our case here, we just got incredibly unlucky. Let's say that they
basically shared the same general vicinity. This should not
happen too often, but yeah, I mean,
it can't happen. It just is what it is sometimes. But you can see this one is the emerald variant
in that case, so it does definitely work. And so this is just,
sometimes this happens. It should not happen a lot. So this should be a
rather rare occurrence, but that is pretty much
how well it goes, right? And that's pretty much
going to be how you can add some jigsaw structures
to your MOD as well. All things considered fairly straightforward is just once
again at the JSON files, setting up the structure
correctly and then getting the NVT data for that structure. But that would be it for
this lecture right here. I hope you found this useful and you'll learn something new. And I'll see you in
the next lecture.
117. (1.18.2) Custom 3D Armor Models: All right, welcome back to
the forage course for 118. In this lecture,
we're gonna be making a customer 3D armor model
or our cobalt armor. So instead of using our
armor that we have before, so this one in the
models right here, which is then the
thing that is sort of being overlaid in 3D. We're actually going to make
a new custom ARMA model, which definitely is not going
to look as good as this. Because I basically just
want to sort of show you the steps that you need to do in order to actually make this. But we're gonna see for this, we're gonna use a block
bench in gecko lip again, I've already prepared the
actual armor right here you can see this is the
blog bench file. This happens when you do
this following, right? So when you make a new
gecko lip animated model, you can just do
this, for example here tests armor, right? And then what you can do
is you can go to File to the gecko live model settings
and change this to armor. If you then hit Confirm, you can see that some stuff
generates right here, which is basically the, what, the already prepared body. And then you can add stuff to it where you want to add
it is under these ones. So you have the bipeds head, Don't touch the
particular thing. This is of course the
head in that case. And then your custom
stuff can go in here. So you can just add a cube. And then you can
just use your stuff, make it, size it up
right here, right? So scale it a certain point and then
they go and then you can just play around with this
basically duplicate that, make a new cube once again, make it down here,
move it again. But this is of course all just
stuff that you need to do. And you can create your
own custom things in here. Once you've done this, we're going to have a, well, basically no texture
at the moment. And then what you can do
is I'm going to just for a moment and delete
this and then you can see you're going to have
something like this. And then what you can do is
you can press Control a, and then it's going to
select everything in here. And what you can do is then
create a new texture here. We're just going to
call this the Humboldt armor extra, I'm
gonna say confirm. And then you can see it
looks kind of like this. If we now save this, so we'll just save this as
the cobalt Armor Texture. Then if I actually take a look
at it, it looks like this. So I'm just going
to open it quickly so you can see it
looks like this. And I will now open
it in Photoshop. I've already prepared a
bunch of soft course here. You can see, you can
also open it in paint, dotnet or GIMP or whatever, basically think you have. And what you can then do is
usually what you want to do is you can just like
in here for example, I believe this should
be the head actually, not a 100% true,
but I think it is. Then we can, for example,
just take any color here. I'm just going to put it on the same layer and then we're just going
to save it again, that the actual thing changes
in block bench itself. We can now right-click refresh. And then you can see, for example, this
actually was the head. This was, of course, not
the most interesting stuff, but you can basically change the individual components of this are something like this. Maybe let's just change
some stuff like here. For example. This is, I mean, I wouldn't necessarily say a
tedious process, but this is a process that
is definitely gonna take some time for you to basically
do this refresh again, we can see they go
through this the back of the head in that case. You can also of course, manually take each of those cubes
and see what they are. But this is basically the idea. So you're going to have to make the armor the actual
texture or self. Now, I have of course,
prepared a texture. This is gonna be
this one right here. And there's actually
a little thing that we want to do and
that is going to be basically taking all
of the don't touch and then just moving
them at the bottom here, just so that we basically
can see the difference here because the actual don't touch us are not
gonna be used anyway, but they are just
there for reference. Basically, just take this here. I found this to be
the most easiest way to basically change
the armor around it. So you can, for
example, see here, this armor actually is
a little bit too low. There's a couple of things
that are too low and we can also just take them and then
move them about, right. So you can see that we then
change the armor here. Like I said, it is
not going to be the prettiest armor
or the time being. The actual, let's say the actual model
here is pretty cool, but the texture definitely
could use some work. I will totally admit that I'm, I absolutely agree over. I just wanted to
show you basically the general gist
of how this works. So what we then have
is this cobalt armor. So I'm gonna save
this, this block bench file will of course
be available to you. Let's just close
the other one here. And then what you can do
is you can then go to export the gecko
live model here. This is gonna be cobalt
underscore armoured, GO dot JSON. So we're just going
to save this, override that the other one. And then let's go to intelligent and
let's add it in there. What do we need for a customer? It's actually quite
a lot of stuff. First of all, let's
add the model file in the geo folder right here. So we're just going to tap
it over. There you go. And then we also need an
animations JSON file. Now this is gonna
be, I have already prepared this and it's
literally just as this. I'm not a 100% sure. You can just pretty much
take this and use it. And it should be
pretty much fine. We also need the
custom ARMA models, so like the texture. So we're going to add
this in the models here. Like I said, this is the one
that looks a little weird, but no worries at all. And this is actually going
to be called the cobalt Armor Texture just
because I think that that name is a
little bit nicer. Go about Armor Texture and
then the files are all setup. Now what do we need in terms
of what renderers and stuff? Well, in the entity renderer
we're just going to make in the client in new
package called armor. And this is going to
include two new classes. One of these, the cobalt armor
model and the other one is gonna be the hello
world armor renderer. Now before we actually
proceed with those, we actually need
a new item class, which is very interesting. So this is gonna be in
the custom package. This is gonna be the
cobalt armor item. And then the first
thing we're gonna do is we're gonna take everything from the mod armor item
and just copy it over. So I'm actually going to just
copy everything over here. So we're gonna do this. There you go. And then we're gonna
get a few errors here. No worries, we're just gonna
do this one right here. And then what we can
do is we can then change this to be the following. This is going to now extend the geo armor item and it's going to implement
the AI animatable, which then also requires us
to implement the two methods, the register controller
and they get factory, but just actually going
to move that up here. Just actually let's
write it here below. They'll suit below the, the constructor. That's
gonna be fine. So the, we also need a predicate which
I've already prepared. This is the fairly
straightforward same thing that we've done with the
entities predicate, the animatable factory we
should also be familiar with. We've seen this
previously as well. And of course all of the code
is like always available in the GitHub repository in
individual just as well. The register
controller method is exactly the same
thing as the entity. And then the factory
literally just returns The factory here. So this stuff factory,
Let's just do this. I mean, it's just a
little bit nicer. There you go. There's a factory,
which is this one. We still have all of the functionality that
we did before. Now there's one tiny thing that I actually want to
change them then it's the last method right
here, the house correct. Armor on I suggest you
do this as well because otherwise you might run into an issue if you
have a full armor, like if you wear the
full armor and also have an electron so
that sometimes has an issue with the other,
with the old stuff. So keep that in mind as well, but that is not part
of the custom model. Now any more armor item
anymore items class, and we actually do want
it to change all of those to the cobalt armor
item right here. This is a little bit of a
difference than previously, but no worries
there, There's also is totally fine and
that should be it. So now we have this
one set up through, we can do now is go into the model and actually
do the following. This is going to extend
the animated Geo Model of type or both armor
item. There you go. You're going to hover over
this implemented methods. So we're going to implement
the three methods. I will once again copy it over. This is the strain like
the same thing that we had in the models for the
raccoon and the tiger. You can see pretty
much the same thing. We're just pointing to the cobalt armor GeoJSON
file right here. We're also pointing to the
test armor in this case. Now we actually want to
change the name here. This is cobalt underscore
armour layer, actually texture. There you go. Texture, there you go. And then this is the
armor animation. This is also fine. So these are all of the things
that we need to do here. And then for the renderer, it's gonna be very similar. We want here is once again, I will just stands the
geo armor renderer, this time of type cobalt
armor item as well over, over this create
constructor matching super. And then here we
want to actually get rid of this constructor, put in a new cobalt armor model. Then we also want to make sure that we select the correct, well things so to speak. This is gonna be
very interesting. What I'm gonna do
is I'm going to copy this over one more time. And this is actually should
be fairly straightforward. So you see headphone
is the armor head. If we switch back
to block bench, you can see this is
this one right here. The armor head, armor,
body armor, right? And so on and so forth. What is very interesting is
that for whatever reason, the leg bone is actually
switched with a leg. I don't know why.
So you can see that the right leg bone
is actually ARMA left leg and then ripe boot
is actually the left boot. I don't know why
that is the case. It just is what it is. I don't know why that
might be the case, but just keep that in mind. So if you think that
that's kind of weird, there's a mismatch there. Yeah. It's basically because for whatever reason it just
it just is what it is. We still need to
get this Renderer registered and we
do this in R event, in the Mode Event Bus events. And that is going to
happen in a new method which is going to be this
one over for the time being. And this is going to be
the following event. This is going to be the
entity render us event, dot add layers, the scope, medical and be cold event. And then the only
thing that we need to do here is we just needed to the geo armor renderer, register armor render us for the cobalt armor item
dot class and then a new award armor
render a day ago. Pretty crazy stuff overall. But in aggregate, not too crazy. A lot of the same
stuff that we did in the entities already, right, with the armor model, with the model and
the renderer file. It's not that crazy. The JSON files also
fairly straightforward. This one, like I said, you can just export from block pinch. This one. I would just take the
one that I've prepared. I mean, it's also not
that complicated, but you should probably
be fine with it, like it's not that complicated. And then the texture, you
just have to make yourself, that is probably the most, the most time-consuming
part of all of this. And I just switched back to
Photoshop for just a second. Now, filling everything out
like you want to definitely take most of most of the time you're at
for the custom armor. But yeah, That's pretty much
how what do you have to do if you want a really
cool custom ARMA model, it just is what it is, but
those are the steps necessary. So once again, that's pretty
much all that we need. So for completion sake,
let's see if it works. Alright, we found solace
back in Minecraft, so let's just put on the armor
and there we freaking go. We have the armor on the LAC
also still works, of course. And you can see
the armor working. I mean, pretty much how
you would expect it to. Like I said, it's not the
prettiest armor overall, but it is functional and it is definitely whatever
you might say, it is definitely a custom. That's definitely the thing I highly recommend just
playing around with it, being open to experimentation
for the armor. As you can see, it all works for the swinging of the arms and the legs and
stuff like that. But it's really cool. Yeah. I mean, that's pretty
much how easy it is to add the custom
armor to the game. Adding it very straightforward
and fairly easy, making it look really
freaking cool, definitely a lot harder. Always, of course,
all of the code and the JSON files are available to you in the GitHub repository
and individual just as well. But that would be it for
this lecture right here. I hope you found this useful and you'll learn something new. And I'll see you in
the next lecture. Yeah.
118. (1.18.2) Custom Villagers: Welcome back to forge
course for 118. And in this lecture
we're gonna be adding a custom villagers to Minecraft. So now it is time for the
customer villager profession, because it turns out is actually
fairly straightforward. All things considered. What we're gonna do is we're
gonna make a new package in our MC course
package, old villager. And then inside of
there we're gonna make a new Java class
called MOD villagers. Now in this one I'm going
to stray a little bit from my usual thing that we'll do and we'll actually add
to defer registers. The first one is
gonna be a public static final deferred register of play type. So this is the point
of interest type. We're just going to
call this the point point type type stay ago equals to deferred register that create or to
registries types, AMC course moderate
and moderate. And then what we're gonna
do is we're gonna make a second or third
register which is going to be of type
villager profession. A villager underscore
professions. There you go. And there's gonna be
a different register, dot create, registries, dot villager, dot professions. There you go. Mc course
monitor modality. And now for when we have
different registers, of course we have a public
static void register method with an eye event
bus, cool event bus. And then we're gonna
call the point types that register asking
in the event bus. And then secondly, we pass in
the village or professions. I've registered
with the event bus, making sure that we
call this right here. Let's just call it allows
the mod structures. So mod villagers dot register and then passing in
the event bus, There you go. Very nice. And what we then
need is of course, registry objects
for the prototype and the villager professions. So we're gonna make
the point type first, this is gonna be the Registry
object of type prototype. This is gonna be
the blaster point. So we're going to use
our cobalt blaster here. There's gonna be the
prototypes that register. This is gonna be
the blast point. That's when I hold it. And then of course once again, a supplier of a new prototype, it'll call this blast point. Then we need to type
dot, get blocked state, say mod blocks, dot, dot. Then afterwards we say 11. Let's actually take a look
at what this all entails. Closing parentheses. There you go. And then let's go into the
actual prototype here. You can see Max tickets is this one and this
is the valid range. So you can, for example, take a look at this where
this has been used. Let's actually see, I believe here and then
in the register method, this is probably
where it's been used. There you go. Usually
they are all 11. There's some other, usually
the prototype is 11, so this is why we use 11. There you go. Then let's
go for public static final registry, registry object. This time of type
villager profession, which is gonna be
the blast master. And this is gonna be equal to the village or profession
stat register, the blast master right here. And then a new
supplier or a supplier of a new village or profession. This is once again, of course, could be going to be the
blast master right here. Let me write this correctly. This is going to take the
blaster point dot get, and then it's gonna take very interestingly, a mutable set. And then we're just gonna
say off with nothing in it. And then we're gonna
say another mutable set with nothing
in it, actually. And then the last
one is going to be the sound events dot. And then just any villager work. Let's just take the
tools myth for example, and then ended with a semicolon. And then we are done in the
village of professional. We can see that the
first immutable set is the requested items, defines items will address
of this can pick up and use. And then the other one
is the secondary PUI, which is like roadblocks, are this professional
interacts with? In our case, we
are going to have none of those are
highly recommend. Once again, being open to
experimentation on this, trying out some stuff and
seeing what you will find. Then the last thing
that we're gonna do is we're gonna have
another method which is gonna be the
public static void, and this is gonna be the
register please method. And this is
incredibly important. We're going to have a try and
catch statement right here. Don't write this one in. The catch one is going
to have the following. It's gonna have an invocation
target exception with this one single straight
line legal access exception called E exception.
There you go. And then this is gonna be
the exception dot print, stack, trace. There you go. And what it has in the
trie is the obvious. And then here in the try, we're gonna say obfuscation
reflection helper method. We're gonna do the
point type dot class. The method name is gonna
be register block states, and then once again, passing
in a pointer type dot class. Then afterwards we're
gonna say invoke null and the blaster point
dot get, There you go. Now this might look absolutely freaking insane to
you, and it is. Now the reason we
need to do this is basically we need to, well, we need to register
the block states. We can actually
take a look at it as this method right here. You can see this register
block states method. As you can see, all of the
register block States methods are all private. This is why we have to use the obfuscation reflection
helper in this case, and then we can
actually call it. But if you have multiple points, you can just add another one
with your other point here. So just add the other point and then you're
going to be fine. This method needs
to be cooled in the MC course setup method
in the FMLA common setup. So we're gonna say mod villagers start register poise
and there we are. Now we're not done yet because
we still need to add on translation a few traits
to this villager. And then also very important. The extra, let's start with the translation to
the translation is a fairly straightforward
all things considered. I'm just going to copy this
over and this is of course, available to you in the GitHub repository, an
individual just as well. You can see Entity
micro villager, MC course blast master. And this is gonna be the name of the actual entity
at the top when you open the inventory or the texture, this is gonna
be very interesting. This is under entity
and I'm gonna make a new directory
called a villager. And then I'm gonna copy
over what I already have here and I'll show
you where I got this from. So this is gonna be number
one, the villager here. I'm not sure what we needed
the villager itself as well, but apparently we still
needed unless professionals, of course named just like this one right
here, blast master. And you can see, I
really much just add recolored a already-existing a profession here in this case, just so that we have
something that looks different in that moment, but it actually does work. And I got this, of
course, once again from the external libraries going all the way down
to the following. Let's see, it should be
right here by an extra 1182 or whatever your version
is in the assets folder, Minecraft, textures
in the entity folder all the way down to the
villager right here. Then we have the villager right here. This is the
normal villager. Then here this is
the profession and I took the armor, I believe.
Yeah, there you go. But just record the armor are a little bit so
highly recommended, taking this, using it and then training it
about a little bit. So the textured here is
definitely going to be the one thing that
might take you quite a while until
you get it right, but it is what it is. And then the types,
I don't think he actually needed you do
anything with the types, but you do somehow
for whatever reason, need the villager
and the profession. I don't know why
that's the case. At least that's what my,
that's what my testing has. Economy. Then when it comes to
the actual traits, well, we can just
use our event again. So in the motor events class at the very bottom
right here, this one, we can just literally use
this for our event as well, for our custom professionals. Well, so more
villagers that last master dot get and now we
can add stuff to it as well. So we can just say
something like this where we can
just add the list, just add a few things
here for the level one. And then just for the
sake of argument, let's just add a couple
of two level two here. We're just gonna change
this to level two. But this is going to be,
we're just going to add the same thing for different
prices because why not? Let's just do this and
then we're going to do a level two. We're gonna do something like a 58 as a very much test here just so that you can see
you can add those as well. It's all the same cobalt
Paxil basically that we're being able to buy here. So it's not gonna be
that interesting, but let's just try this
out and you will see that this will add the
trades to them as well. So I guess let's
see if it works oh, right in front of
us in Minecraft. So let's just spawn
a villager And then let's set down the
cobalt blasts or which immediately recognize as a point of interest and it should move towards it and then get
the actual or I guess not. Let's get a little
bit closer here. Well, I there was a typo there. It's actually the
cobalt block that is the point of interest,
but fair enough, I guess. So let's just set it down and then you can see now
it's moving towards it. Because you can see we do have
an arrow and the texture. We're going to fix
that in just a moment. See the O, it's actually
the blaster Moscow. That's great. But you can see the trace here have been added. I can get those. And then afterwards, we
should be able to see, once it actually levels up, should be able to get
the other ones they go for level two
and there it is. So that is definitely working. So let's just see to fix the actual texture
for just a moment. Right here it says blast master. It should of course
say blast masters. So that should pretty much
fixed all of the rest here. Also gonna change this to the
cobalt blaster right here. And then just for the sake of argument, let's see if it works. For instance, back in
Minecraft once again, and let's just set
it down and they go Now everything is
working fine if I go here and the last
master also working so everything like you
would expect it to. So that's how easy it is to add a custom village or
profession, Minecraft, right? Once again, of course
all of the code will be available to you in the GitHub repository and
individual just as well, but that would be it for
this lecture right here. I hope you found this useful and you'll learn something new. And I'll see you in
the next lecture.
119. (1.18.2) Baby Entities: All right, welcome back to
the forge course for 118. And in this lecture
we're gonna be looking at baby entities. Yes, So we're gonna add the
baby entity to our tiger. And once again, this is one
of those things that is actually way easier
than you might expect. I also was a little
more complicated, but it actually is not
complicated at all. Inside of our breed
offspring right here, what we want to do is we want
to say mod entity types, not a tiger that gets that create and then pass
into the server level. This is this
parameter right here. I'm just going to click on it, press Shift F6 to rename
it to server level just so we know what we're
passing in here and then we're passing
it in right here. This is number one
that we need to do. Number two, we need to override a certain method and
that is the food method. Instead of here, we're basically checking whether or
not this stack is the food that this particular
entity can be bred width. In this case, we're gonna
say p dot get item, and I'm gonna say is
equal to items dot beef. I basically want you right-click the tiger entity with beef
than it is ready to breathe. That's the idea here. We
then need a new goal. So I'm just going to copy
over the settlement or goal and this is going to
be the breed goal, is also going to take in a one
speed modifier right here. So we're just going
to have the same speed and I just put it here under the in
priority three. I think that, that
should be fairly straightforward entropy fine. Now these are actually
all of the things that we need to do in the tiger entity. There's one more thing we
need to do in the renderer, and that is gonna
be the scale here. So this is of course the
scale of the actual model. And what we can do
is we can say if animatable, that is baby, and we're going to scale
a differently from just press Control X to cut it out and then
paste it back in. And then right here,
we're gonna do this one. So here we are when
it's not a baby, and then here we
are if it's a baby, so we're just going
to put that in half and then that's it. And this should be
everything that we need to do to have the while
the baby's work. There are some
interesting things. For example, once we actually have the tiger teams and then we give it a right-click it with
the food item right here. Then we still sort of like
go onto it to write it. So there's a little
bit of weirdness here, but that should
be fairly trivial to fix that right here,
basically to check, hey, as a player right-click
with a beef and then we shouldn't actually
even start writing it. That should be fairly
straightforward to fix. But for completion sake, let's see if it works or
it finds us in micro. So let's respond to tigers and let's see,
right-click, Right-click. There we go. And then as soon as they
find each other, yes, no. Okay. There you go. There was an there is the baby tiger as well or
working absolutely fine. Now it actually takes quite
a while for them to grow up. I have tried it out
and they will grow up. It just takes a lot of time. This I believe is hard-coded
in the animal class, but we can actually check
that in just a moment. But yeah, that is pretty
much how you do that. And then this one, of
course, we can't breed. Now a think that only enough we should be able to
possibly write it. I mean, okay. That's like there should probably be
a check for that. But honestly, that's
baby entities. Very self-explanatory. Really not that difficult. I really thought that they
would be more difficult, but they're actually fairly
straightforward, right? So just one more
time if you actually take a look at this one
middle mouse button, click on this middle mouse,
right-click on this. You see, this is the animal, and this one has sort of all of the different things
for the breeding in it. So you can see it has, it has a lot of stuff. You have the candle and
loved set and love that. I love time getting enough time, get loved course is in love, reset, love can meet. Those are sort of the things. I mean, here you can
see the spawn child from breeding method, which basically sponsor
the actual child. You can see that it gets
enabled mobile from the, it read offspring here. So that should be the thing
that you need to take a look at if there's
anything that you wanted to possibly override. So yeah, that's pretty much what you need maybe
in the rubble mop. Yes. So you can see
babies start h, This is the stored h here. So you can probably change this as well inside of
your tiger entity. In that case, if
you want to, maybe the tiger to grow up
a little bit faster, that could be done as well. But yeah, that is pretty
much how easy it is to add baby entities to your mobs. It's way more straightforward
than I thought, but that would already be it
for this lecture right here. I hope you found this useful and you'll learn something new. And I'll see you in
the next lectures.
120. (1.18.2) Custom Geodes: All right, welcome back to
the forest course for 118. And in this lecture we're gonna be taking a
look at how you can add custom geocodes
to a Minecraft. Now, this is actually a fairly straightforward
thing to add and we're just going
to take a look at it. So in the world package,
in the feature package, the mod configured features
is where we will add the geode and I will copy
over the entire holder. And then we're
going to basically take a look at each of
those lines and what they mean and the
craziness that is associated with it because
it is quite a long thing, but no worries at all. They can see it's actually
make a new line here as well. And you can see it is quite
the long field in this case, but no worries at all. So of course, once again,
we're using feature utils dot register to register a
geode feature in this case. And we then have to make a
new geode configuration. This is also a great class
to basically take a look at. So if we middle mouse
button click on this, you can actually see what each of these
things mean, right? We have the block settings, we have the layer,
the correct settings, we have potential
placement chance, and all of those crazy things that we can basically
add into here. What is very interesting
in this case is actually also going to be the geode
block settings here. So this is basically everything
selected right here. And those are actually
very interesting because here you can see what the particular
wealth layers are basically made out of. So you can see the filling
provider is going to be air that should be
fairly self-explanatory. So the G or inside of
it, everything is air. If you don't want it to be air, you can also change
something else, right? So you can change this box right here to
someone else, right? If you have a different
block that you want this to be filled with Hindu. So that is really cool and
it allows you to basically modify and configure almost
anything that you would want, which I find really cool. So this is pretty
much the idea, right? So this is once again, one of those things
where I just highly recommend just playing around
with the different blocks, the different numbers,
especially as well. It is the best thing
that you can do. Just try around a few things, see until you can
basically find a GO that you like in terms
of how cracked it is, right with the correct
settings, for example, this just means whether or
not there's some side to it that is exposed and they can immediately go into
things like that. Just highly recommend
taking a look at this, play around with
the numbers here. And then hopefully
you're going to create a geode of your
dreams, so to speak. Now what I wanna do is I want to replace the deep
slate right here. Let's replace this with dirt. And let's say right here, let's just do emerald. Sure. Why not? Just in case, I basically
want to take a look at how this affects
the geo blog settings. And then you can
see where all of these different blocks are
basically placed, right? So the most important one is actually this list over here. Because this list usually write, this list is actually
the inner placements and the inner placements or
the amethyst crystals. So this lists basically would include these amethyst crystals. So what we can basically
take a look at, for example, is another
feature, geode. So let's just middle
mouse button, click on this, middle
one announcement, click on this and you can see
the amethyst GO right here. If we just go all the way
to the, there you go. So there you can see
the budding amethyst. And this is also done
in the list right here. So you can see amethyst cluster, wherein you can see here we have the small amethyst bud
medium MF is buds. So this is a list of the possible amethyst
cluster amethyst buds that might be able to spawn. That is the general idea
of this list over here. So I've just used the
cobalt block in this case, but you can of course, make your own, cluster your own. But basically and then
swan that as well. Now that's all fine and well, but what do we do with
this configured feature? Well, we go into the more, we go into the marketplace
features class once again, and we're just going to, and I'm just going to copy
over the holder once again, this is all available to you in the GitHub repository and
individual just as well. And you can see this is
the cobalt geode placed. Of course, we're taking
the cobalt geode from that we've just
created basically, then we're making a
rarity filter on average every, every 50 chunks. The N-squared spread is just
something that I've taken pretty much from the
vanilla geode as well. And then you can see, we're basically this morning it above six and all the way up to 50. Once again, highly recommend
playing around with the vertical anchors
above bottom, below bottom,
absolute, all of that. Just try it out and see
what you can basically see until it is placed the way
that you want to write. So this is pretty much it. And then we need to just go
into our more or generation. Then instead of calling
the cobalt or placed, you want to call the
cobalt geode placed. Those are actually all of
the things that we need to add our custom geode
here in this case. So let's make a new world
and see if it works. Or we find ourselves
in Minecraft. And as you can see,
I've already found a nice little geode, so you can see what the
different blocks basically are. So first of all, of course,
the inside of it is well basically filled with air just like specified in
the very beginning. And then you can see, and
then you can see the blocks here would basically be the
budding amethysts, right? While the horse would be the blocks where
the MSS grow out of. That is the general idea. You can also see where
the dirt is placed. An emerald, or where's this? Well, if we actually go outside of here than we
should be able to find some emerald or possibly on the other it is so they can
see the amro blocks actually. So this is all the way out to here where the
actual geode spots. So you can see the
actual size of the geoid is quite
a ways bigger. And C, There you go. So highly recommend maybe not changing this to emerald auras, but emerald blocks in this case. So that is pretty crazy. But yeah, those are
basically the ideas of what all of these
different blocks do. And then it's just a matter of playing around with
them a little bit on your own time and trying out some different
values, right? But that would already be it
for this lecture right here. I hope you found this useful
and the alerts that the New, and I'll see you in
the next lecture. So, yeah.
121. (1.18.2) Block that interacts with Redstone: Alright, welcome back to
the forge course for 118. In this lecture, we're gonna be taking a short look at how you can make your blocks
interact with a Redstone. But this was
something that a few people actually wanted to basically take a
look at and they weren't quite sure how. So. Let's take a look at our
customer block class, mainly the cobalt lamp block. So instead of making it so
that you can right-click to basically turn
this on and off. What we're gonna do is we're just going to check whether or not a Redstone signal is
applied to this block. Now, once again, of course, our best friend here is
the external libraries, mainly the Minecraft
source code. So if we actually press shift twice and then take a look
at the redstone lamp. This is gonna be
the redstone lamp, making sure that include
non projects is ticked. You can see this one right here, its own lemma block,
then we can pretty much, and this is craziness, actually
copy over most of this, most of it that is
written in here. So we wanted the
tick method and as well the neighbor
change methods. So those two are basically the
only methods that we need. So we're going to
copy over those two from the
redstone lamp block. All of the code is of course also going to be available in the repository and
individual just as well. And we only need to
change the lid over here basically to collect because
we call it clicked they ago. And that should be fine. But we can change this here
into this year as well. This year as well. And then here as
well, there we go. Let's just add an add override
here just so that we are, we know that we've overwritten those methods just in case,
and that should be fine. Now, I actually want nothing
to change over here, so we're just going
to comment this out. That should be fine as well. And now this is actually pretty much all that we need
to do in this case. So what does this
actually do? Right? So because you might be
like, that's kinda weird. Well, first of all,
the neighbor changed method will be fairly
self-explanatory. This is called every
time a neighbor of this particular
block changes. What it then does
is it says, hey, just like any neighbor have
a signal over here, right? So it's going to basically say, it's going to get, first of
all, the value of Clicked. That is fair, fair
enough. This is true. So we're currently on, right. Then we're basically want
to check, hey, is the, we also, do we not have a
neighbor signal if we're on? Because then what we wanna
do is we want to turn this particular rock off
as the general idea. This is a little bit over complicated in the way that
this is basically phrased. But that is the general idea. The scheduled tick
pretty much just, well schedules a tick if
we actually go into this. And this is a little
bit hard to read with the non map parameters. The general idea is just that
we're basically scheduling a tick and then the tick
method is called over here. Tick method here in
this case, once again, it checks whether or not our own and if the neighbor
doesn't is not on, if there's no signal on the neighbor, if
that is the case, the more setting
this block to being, and we're actually cycling
through the linked right here. So we can actually
take a look at what the cyclist by
Nixon collection, what this pretty much just does is it reverses the clicked. So it's the same thing that
we did right here with the current state and then negating it, It's
the same thing. Just we're cycling through it. So that is all that we're doing. In this case, almost no change
to the code from vanilla. In this case, just
changing the lit basically two clicked
in this case. And that is pretty much it. We also wanna do
is I wanted to add the following system out print line just so
that we can see this. So we can say over here, let's just say that
to say powered by. And then we're going to say, when I say P level, get a best neighbor signal. See, we're just passing
in the position over. But what is the best neighbor? Siegel? What is best neighbor signal? Well, the best
neighbors signal is simply from all
of its neighbors, which has the strongest signal. And we'll just
basically outputting the actual signal from
that particular neighbors. So this is an integer. You can see where it's 15 is the highest signal strength
that redstone can have. So if some one of the
neighbors has 15, then we're going to output 15. If there's a weaker signal, we're going to output that. Let's just go into the game and see what this actually does. Or France or in Minecraft. And I've already set
it down a cobalt lamp. Let's just try a level. First of all, there you go. I can turn it on and off, so that does work. And I can also put
redstone to it. And this also works as well. If I now right-click it
and show you intelligent, you can see powered by 14. Why is it 14? Well, of course,
because this would be 15 strength and this
would be 14 strength. By now, turn this one
on as well, right? So the lever then in C, now it is powered by. So that is pretty much
all there is to it. This is basically
how you could change a particular block
state property when applying Redstone to it. And this is pretty much
all that you need if you then want some special
functionality towards it, well then you need to of
course, take those blocks, say properties, for example, that change and do
something with them. But that's pretty
much all the doable. That's how easy it is
to add a block with some redstone
functionality of the game. As always, all of the
code is available in the just and the GitHub
repository as well. And I'll see you all in the
next lecture though. Yeah.
122. (1.18.2) Custom Block Entity Renderer: All right, welcome back to
the forge course for 118. And in this lecture we're
gonna be taking a look at block entity render us. Well, this is a very
interesting topic that basically allows you to render some custom things onto your block
entities basically, now what we'll do
is we'll import a custom block model
from a block bench. So I've already prepared this. It's called a pedestal. And what will it be
able to do is we will be able to
right-click with an item and then the item will float
on top of the pedestal. That is the general idea of
this particular example here. And it's gonna be really,
really freaking awesome. The block bench file will of
course be available as well. And when you have this, what you wanna do is you wanna go to file and export the block
item model right here. We're just going to export
it pedestal that Jason. Alright, that's gonna be fine.
And then we can proceed. So there is of course
going to be our block model JSON file. But first of all,
let's create a block, the block entity and all of the craziness that
entails there. Let's start with the
actual block class. So we're going to
right-click new Java class in our custom blog package. And this is going to be
the pedestal block a ago. Now this will extend the base entity block class right here. It will hover over this
Implement Methods, the new entity method. And then we'll hover over again, create constructor
matching super. If the parameter
here annoys you, Shift F6 to rename it to properties and then
everything should be fine. Now the first thing I
wanna do is I want to make a deliberate error right
here so that we don't forget to change this
after we've created the block entity because
that sometimes does happen. And what I will
also do is I will copy over the rest of
the code right here. So this isn't too crazy. So it might look a lot, but
it actually isn't too crazy. We also get one error
here because we don't have the block entity
credit, but that's fine. The first thing
that is incredibly important as they get render shame method and all of the code here is of
course also valuable. Get a pastor in
individual just as well. So no worries there. But the retina shaped method
is the most important, otherwise, your block
will be invisible. So that is very important. They used method of course,
is the method that is, that is called when you right-click this
particular block. And what happens here is that basically we're
just checking, hey, is there anything
inside of this inventory? If it is empty, then
we're just taking the item in that is in the player's hand and we're adding it to the inventory here. So pedestal to player item, copying it over,
decrementing it. We're also getting the
playing the item pick-up sound because that's just
a little bit nicer here. And then if the
pedestal is not empty, then we're basically
spawning the item from the pedestal and deleting it
from the pedestal as well. But those are just three little private helper
methods in this case, and the rest happens
in the used methods. So overall, the
actual functionality here isn't that crazy,
all things considered. Now of course, we still
need the block entity, so let's actually get
the book entity as well. So let's make a new class
and the entity package, this is going to be the
pedestal lock entity. And let's first of all,
important right here. So there you go. We can just import this. And then we're going to
be fine just a second. This error will go away once we actually implement
everything in here. So what do we need here?
Well, first of all, of course this needs to extend
the block entity class. Shouldn't be too crazy. And let's create the
constructor matching super. And then the question is,
well, what do we need? Well, we actually need
quite a few things. Once again, I will copy
those over, but no worries. All of this is available in the GitHub repository and
individual just as well. Now, these two
shouldn't be crazy. We've seen this in the chordal blasts or
block entity as well. Just the item stack
handler here, basically our inventory of
this particular rock entity. And then we also need the laser optional so that we make it available through the
capabilities as well. Then let's copy over some
helper methods over here as what you will find is we also have a rotation over here. Now why do we have the
rotation over here? Well, because what we
wanna do is we want each of the different block entities
when the item is there, we basically want it to rotate. And the rotation
here in this case is actually saved on
the block entity. We need to save it right here, because if we save it
on the entity renderer, that does not work because every block entity basically
shares a renderer. And then each block entity
that you add just makes the, well, makes it
basically spin faster. So each block entity needs its own rotation, but
that is fine, right? We haven't add
rotation over here. We would just add a rotation
when it reaches 360, then we're just
resetting it to 0. If it's less than 0,
we're just adding it. So basically we're just
rotating it around. That is the general
idea. And then here we have a get rotation method, but nothing too crazy. Then let's add the capability as well as the save
and load methods. But once again, those
should also not be crazy. You get capability we've seen in the custom entity as well, as well as the safe
additional and low methods for the tag where we just
saved the inventory. So when we leave the
world and go back in, the actual inventory
is still saved, right? And then the last methods
that we also need here are the drops
method, right? So this is just the methods
so that things actually drop. So we want to implement that in the block in just a moment. And then we also have the
invalidate caps method, the onload method
that we did get update packet method and
they get updated tag method. Now these two are important to invalidate
the camps and then unloading so that the
actual item handler is initialized properly
and all of that. Now, these two are important because otherwise there might be a synchronization issue between the server and the client. This is why we need
both of these. And we basically want
to get the update tax. So we want to get a tag over here and then load
it in and then return it. So this Well, it's not too crazy, but just know that we need this. Otherwise the client
and the server will not sink properly, and then the actual
item will be saved, but it's not going
to be to split. This is why we need both of
these methods as well, right? Then let's go to the block
for a moment and let's add, you can see the arrow
here disappears. And I'll also add the
onRemove method here that calls the drops method that we've just
implemented over here. So in theory, we don't even need to do a for-loop, but
this is gonna be fine. There's gonna be okay. This is the same drops
method that we have in the chloroplasts
or block entity. And that is actually all that we need inside of the block entity. Overall, it is not too crazy and it's not
too complicated. Basically just some
of the things that we need to save the data there. Then let's actually go into the mod block entities class
and let's register it. But we're just going to, let's
take the co-op last row. We're just going to
copy this over to the header store block
entity over here. This is going to be
the pedestal as well. Pedestal. There you go. Then of course,
changing the name here, very important
indeed, than we need this to be the
pedestal block entity. And this needs to be the pedestal which is not yet implemented,
but that is fine. Now let's also go
into the pedestal block entity one more time. Because of course we do need to change the constructor
over here. Otherwise it's not
going to work. We will then want to see him,
but look, entities that, that is still not get the ego and now the block
entities should be fine. We now need to register
the actual book. That's gonna be fine
that it's going to be in our blog class, more blocks class right here. Let's just go to the
very bottom over here. Copy over the winter window. In this case, this
is going to be the pedestal and of course
name as well, pedestal. And this is gonna
be the pedestal. Luck. Now this is protected, so we need to change
this to a public. There you go. And then we can do this as well. There you go. Totally fine. This is going to copy over. How bout this is actually
not going to copy over How about this is going to
take a material that stone, I think that that would make the most sense material
stone The ago. And it's going to be added
to our custom Creative tab. That is fine. Then we can go back to the pedestal block once again and call mod block
entities that pedestal dot, dot create, passing in the position and the
state over here. And the block should
be done as well. And then the mode
block entities, this one now is also no longer an error and everything
should work fine. That is absolutely great, but we still don't have
the display of our world. We don't have a customer block
entity renderer basically. Well, let's In our
entity package, make a new package
called client. And then instead of
there, we're gonna make a new Java class called
the pedestal block, header store block
and entity renderer. And this is going to extend
the book entity renderer, this one right here of
type pedestal bulk entity. Let's hover over this,
Implement Methods, the render method in this case. And then we also
actually want to change this to implements
instead of extends. Actually that is a good point because this is
actually an interface. We also need a public
pedestal block entity Renderer with a block, with a book entity
render up provider. This one right here, that
context or contexts, and this is gonna be our
constructor in this case. Now, I will once again copy over the contents of
the render method. Once again, all of
this is available to you and this should get, this should be fairly straightforward, all
things considered. So first of all, we're
basically getting the item renderer right
here from Minecraft itself. And then we'll
say, okay, give me the stack that is
inside of here, and then we'll do a
bunch of craziness. The general idea is that
the stack over here pretty much just does the
rendering, roughly speaking. And what we're doing
basically is we're just making the actual stack
move up and down. So this is going to be R,
This is gonna be the item. We're gonna make it up and down. We're going to scale it
to the size over here. And then we'll also
get a rotation. So this is just rotating
the item around the y-axis. That is pretty much all
of these three things don't do them will render
the actual item here, and then we have
to pop the stack again, and then we
should be fine. Then we basically add a negative one
rotation so that every time this is basically
called every tick or so, roughly
speaking, right? So every time that
this is called, We basically rotated
around by minus one degree so that it will
be a smooth rotation. Once you actually see this
shouldn't be too crazy, You shouldn't be
too complicated. All things considered is
actually fairly straightforward. Now the block entity
renderer actually has to be added to a certain event. And for that we actually
need a new class. This is going to be
the client mod events, and I will copy this
over one more time. But once again, this is
actually very straightforward. They see you need the add mode event bus subscriber
at the top of the class are important that this
is the mortar bars as well as the value
dist dot client. This is extremely important, otherwise it will
not properly work. You then of course, need a
public static method with an subscriber vendor
attribute here on top of it. And we need the
entity renderers, event register renderers. We then just registered the
block entity Renderer with the pedestal block entity and the pedestal block
entity renderer. That is all that we need to do. And now the actual render is
registered properly as well. The last thing that we
now need is just two. Add the JSON files. You can see we've
not added any screen or any menu because
in this case, our book entity actually does not have a screen or a menu. Let's just copy
over the pedestal Jason over here,
shouldn't be too crazy. The block state is Jason
fairly self-explanatory? Same with the translation
of this point. These things should be, I mean, at this point shouldn't be
even be a question here. This is just a very
straightforward thing. We're going to add this. Let's add the block
model JSON file. So this is going to
be the one that we've actually taken from
a block bench. So let's copy this over as well and then see what we
need to change here is the smooth stone
because this is under Minecraft slash block
is under microblock. So make sure to change
this on both of those. And then the item
model JSON file is also fairly straightforward. This is just
basically once again, points back to the
block model Jason file, and that is pretty much it. No texture is needed in this case because
we're actually taking the Minecraft textures
smooth stone for that is, that should be fine as well. So those are all of the
steps that we need to do to get our custom entity over here and have it basically with a special
block entity renderer. So let's go into the world
and see if it works. Alright, fantasize in Minecraft
again and you can see the pedestal has been
successfully added to the game. So let's just set a few of them down and let's see
what we can see. So if I right-click this, we shouldn't have the cobalt. Cobalt appear right here on the pedestal and one of them should be disappearing
from my inventory. And that is exactly
what happens. Let's just do the same
thing for all of them. They ago though,
sometimes you might get those weird rendering
arrows right here. So this is something
that I'm not a 100% sure about why
that might be the case. So I think that it has something to do with
the shadows and stuff. So let's just see if this
might change itself. If I do this. But this does not change it. But as I've said, there, sometimes it a little bit wonky next to it
with a rendering. And I will be honest, I'm not as another expert with rendering. Rendering is actually one
of those things where, um, let's just say that, that's, I wouldn't say my
worst nightmare, but it definitely is not a thing that I like particularly. So, yeah, but overall, it's still does work quite
well and quite cool. And it is a thing
that is forming. It is pretty awesome. This is how easy
it can be to add a block entity
renderer microphone. As always, of course, all of the code is
available to you in the GitHub repository and
individual just as well. And I'll see you all
in the next lecture. So, yeah.
123. (1.18.2) Loot Chests in custom Structures: All right, welcome back to
the forge course for 118. And in this lecture
we're gonna be taking a look at how you can add custom load to your
customers structures. So what I've done
is I have spawned in the cabin house right here, just so that we have a
structure and we're going to save it in just
a moment as well. But we'll move gonna do is
we're going to place down a chest and we're going to
fill it with some random loot. Now the question is,
how does this work? What you cannot do? And this is the thing
that some people try. They just take the
chest and then just set it down and then alike. Why is there no random loot in there? Well, that does not work. What do you have to do is
you actually have to own the chest via a command, right? So I've prepared the command
already and what you can do is I will basically make this available and it's
not gonna be that crazy. So what you can see
is that there's just less set block at
your current position. You're standing than
Minecraft chest facing. So you just want to make
it facing some way. And let's actually
do this on easier. So let's just make
this facing east. And then you can see curly
brackets, loot, table, Minecraft, chests, simple
dungeon in this case, let's just execute this. Now. It actually does point to the
wrong way, but that's fine. This is just a matter of
changing the facing here. And if we open this, you
can see there it is. So some random elute. Now the real question is this. If I now save this, is this random loot? No, because when, once
you open it will elute. Table actually
generates some loot. So now every single one of the houses is going
to have this loot in it. So what you need to do is
you need to not open it. So what you need to do is
let's just go down here. So let's just
actually make this, believe this should be South, actually generate
this one south. Okay, That's also
not quite right. So let's do, right, let's generate this with
the North one actually, I think then it should be north. And I was pointing to
the right direction and do not open it. Otherwise, you will actually solidify what the
loop is inside of it. So this does not work. So you have to just keep it there and you have to be like, I don't know if it
works, it will work. Don't worry about it. So
then we can save this. And you can do this either
when you have loaded it in or you can also do it with
a corner and molt method. When you actually build it, you can just add a chest like that and then save it so
we can go to the Save. Moreover, here we're
just going to say Save, and then this has been saved. So now we can replace
it in intelligence. So let's just take
a look right there. But once again, we want to
go to the run folder saves, and this should be
the ludicrous folder inside of the generated one, we have the Calvin, how's NVT? And we want to change the data folder, MC
course structures. We have the count my house, and we just want to replace
the one with the other. So I'm just going
to copy this over, overwrite it, and that is
all that we need to do. Now once again, we have
not opened the loot chest. So the loop should be
basically generated every time the actual
house generates as well. So we should not have the same loop in two
different houses. So let's just make a new
world and see if it works. All right, We're microfinance
New World and let's see, there's the first
count, my house, and we have the chest over here. So you can see we've
got a music discs. A few gunpowder is. Alright, that's fine. So let's find a
new column house, and let's see if
we can also find the same music disks or if
there is something different. So there's a new camp
miles and let's just hope that the loop
there is different, but I am fairly certain that
it will be there we go, a completely different load. So exactly what you
would want there to be. So what's important
is we have of course use the
knockout mouse MET, but we've used the
simple dungeon one. So this is the one
that is actually right here at an example, right? So this is the actual, the actual command here. You can see the chests
simple dungeon and you can use any different
type of load table. So you can also make your own little tables and references. They are, but that's
of course something that you can do for
yourself as well. And that is pretty much
how easy it is to add a custom loot chest to
your structures, right? But that would already be it
for this lecture right here. I hope you found this useful and you'll learn something new and I'll see you all
in the next lecture. So, yeah.
124. (1.18.2) Fixing Some Mistakes: All right, welcome back to
the forage course for 118. In this lecture, we're
just going to be fixing some small mistakes that I might have made during the course of this
course basically. So, of course, with the amount
of lectures that we have, there are bound to be a few
mistakes here and there. So the first one is going to
be in the mod armor item. This is gonna be very
interesting and that is the has correct armor on method. Because what we wanna
do is we want to replace it with the following. So we basically
want to add at this for loop over here that loops through the armor and it checks whether or not the
armor is actually, the items are actually
armour items. And if one of them is not, then we're immediately
going to return false. Now the reason why
we want to do this, if we were to add an electron or a pumpkin to our armour items, basically in our
armor inventory, then the game would crash
because we are trying to cast it to an armor item
and that does not work. So this is why we want
to basically with this and then we should be fine. The second thing we
want to change is in the MC course mod class. And what we wanna do
is we want to take the entire client
setup method and we want to basically
what's selected here, hold Shift, click here, and then press Control
X to cut it out. You can then delete this line
over here and we want to go into the events class,
find more events. Hopefully you've created
this through the last or the
second-to-last lecture, we're going to paste the, the
mindset of methods in here. We want to change this
to be public and static, and we want to add these
subscribe event to it as well. Now why do we need this?
Well, just in case usually the client set-up event is
only called on the client. However, the MC course mod class is actually
a common class. So this is called both on
the client and the server. And it can sometimes happen that through some
Java mumbo jumbo, basically, some of these classes are also called on the server, which will then get
the server to crash. And of course that's
not what we want. So just to be sure, add this to the climate events. What's important is that this is a mob boss and also with
the value desktop client, and then she should be fine. And last but not least, we have something in the
dowsing rod item. And namely the way that we can basically take
a look at tags. So this is a valid way
of basically taking a look at whether or not
the particular block here is in this tag. However, that is insanely complicated and we can do
it a little bit easier. So instead of expecting
a block here, we actually want a
block state, right? So block state,
change this to state. And then when we wanna do is, let's just delete all of this craziness and we're going to worry about this in a moment. First of all, how do
we get the state in the is valuable block method? So we're going to get an error right here because
we have a block. Now we want to change this
to be the block state. And then instead of calling
blood get block here, what we're gonna
do is we're just going to get the block state. We're going to change this to be kept block and then same
here, not get blocked. And that is all of the requirements that
we need to change here. And then in the is
valuable block method, what we can do is
we can return state is more tags that blocks
that dowsing rod valuables. Now this is much easier than the thing
that we add before, and that will pretty
much be all of the things that I wanted
to show you as well. This will also
conclude pretty much the 118 part of the
entire course right here. So there's gonna be a 1 ninth
update after this as well. So there's going to be
basically how you update all of the different things
that are in there with maybe one or two
different things, if they are not yet discovered on how easily
to do them in 119, but that will follow
after this and then the course is pretty
much done regardless. I hope you found this useful
and you'll learn something new and I'll see you
in the next lecture. So, yeah.
125. 1.18.2 UPDATE TO 1.19: All right, welcome back to
the first course for 118. In this last lecture, we're gonna be updating our
project from one 1890s. Now luckily, the update from
1890s is not the craziest. I've seen far worse
updates between vergence, but there are still some things that are gonna
be completely changed. And I believe there's
at least one thing that doesn't work at all, but that's just how
it's going to be. So we're just going
to navigate to the built or Gradle file down here to our dependencies over here where we have the
Minecraft Forge. And what's very
important is that backup your entire project. Because if you don't
have it backed up, things can happen. You might break your
project when you update. Either have a GitHub repository, make a new branch in it so
that you have everything saved or you just copy over the entire project so
you have it backed up. I highly recommend doing
that now to what do we need to change the forage
dependency over here? Well, it's actually
not that crazy. What we wanna do is we
want to change it to 41038, of course 119. So this is the latest
version for you. It is probably going to be more advanced here, but
that's gonna be fine. Always, you can always use the latest version and
that's gonna be okay. So let's just change
it over there. So let's go back
and that's gonna be 119 dash and then 41038. There you go. And that is the version that we
wanted to change to. We also want to update
gecko lip over here. So this is now going to
be forge a dash 193119. There you go. 1313. There you go. I believe this should
be the newest one. In this case. It can just be looked
up on gecko lip. You can easily find
the version here on the gecko lip GitHub repository. So no worries there. And after
we are changing these two, we're just going to click
Load Gradle changes. And then once again it's going to build stuff, download stuff, all of the same jazz that
we've made a couple of times, especially in the
beginning of all of this. So highly recommend
staying patient, just let this run through any
errors that might come up, anything red, most of the
time, safely be ignored. And then we'll see,
are there we go, build successful in two
minutes and 28 seconds. Now we're not quite done
yet in the build-up Gradle file because we also want to change it to the
parchment mappings. So we have parchment for
this one right here, and we want to change
it to the following. 1182022 or six, or 5119. So this simply takes the
119 official mappings in overlays the 1800s to parchment
mappings on top of it. And then we're going to have roughly parchment
mappings for 119. Not everything is going
to be perfectly mapped, but this is, I believe, the newest version that we have, that there isn't any
119 version yet. Once again, of course
you can just look at the parchment repository
and you shouldn't, you should be able to
find something there. So let's just reload this again, radial changes and this
shouldn't take too long. I hope not another two
minutes, but let's just see. Let's just wait once again,
patiently waiting here. And then we're gonna be fine. Alright, there we go.
Build successful in one minute and 37 seconds. So we're now going to be fine
and everything is set up. But now let's jump into the
MC course mod class and we're immediately going to be greeted with a tiny arrow here. And that is just the imports. So you can see, I still have
stuff in the imports here, but no worries if there is anything wrong
with the inputs. You can see the three dots
over here turning red. Basically, you can just press Control Alt O and then everything in the
imports is going to be, well basically deleted
that we don't need. And for the time being,
nothing wrong here, but there are going to be, well, a few things that are
wrong in other classes. So usually what we do is we
can just go down the classes. I believe that the first-class where we're going
to have an issue is actually going to be in the flame ball
rotated pillar block. Interestingly enough, or
we have to change here is just the parameters over here. So I'm just going
to copy this over. Once again, everything
here is of course available in the
GitHub repository. And indeed just as well, this is going to be
now at the stack. This is going to
be context stack. And then we're just
going to pass in the context right here, and then also the
Simulate right here. They ago and that
should fix this. Now, this one is done and I believe the
rest should be fine. Actually, aldi speedy block, yes, because the animator tick, because now we're no
longer using the random, but we're using the
random source class over here from that
micro view tool. Just do that. And then we don't pass
in anything over here. And that's going to
be fine as well. So this should be
pretty much all that we need to do in the
SPD block as well. And I believe this should
fix all of the blocks. Actually. I believe
the rest are fine. Indeed, they seem to be fine when it comes
to the entities. I believe they're only should be like a tiny change
over here. Yes. And that is the text component because the entire
texts system changed. Luckily, the change here is incredibly easy component that
literal, and there we go. And that is it. That
is all we need to do. Just making sure that
the inputs are correct. Control Alt O and then
the rest here is a fine. Let's just make sure
that the rest here is also okay. And indeed it is. So nothing crazy going on here. And mod blocks, once again is just the translatable
components here. So it's just component that
translatable in this case. And there we go. So it is actually made
very easy indeed. So nothing crazy going on. We have no longer
have an oral block. That is also correct
because now it is actually a drop
experienced block, but it works exactly
the same way. Once again, Control Alt or
to get rid of the imports. And then we're going to be
fine and the entire block. Package is actually done. The commands also will change a little bit
more in just a moment. But first of all, of course,
the text components, the first component are literal
again, **** and literal. There you go. Then the same thing here. And then I believe we also have this in the set one yet we do Control Alt O to get rid of the year wrong
imports and they would go, we also will have to change the constructor here
if I'm not mistaken, but those are gonna be fine. We're going to talk about
that in just a moment. The conflicts are,
conflicts should be totally fine and nothing to
do there as well. Effects also have not changed. So this is all going to be okay. And treatments have not
changed the entity, that something is different with the entity and that
is the model because the actual names of the methods have
changed a little bit. So this is now GET model
resource over here. Resource they ago, and this is now get texture resource and this has got
animation resource. So what you can
do is if you have multiple ones of
these model files, the Geo Model files, what you can do is
you can just press, let's say go to
the Common Rule or whatever your name is package, press Shift Control R. Look for good model location and then change it to
get model resource. You can see we're
actually having this in the other two models as well. So we're just going
to say replace, yes. I'm going to do the
same thing with the texture location
replacing the resource. Now this one sometimes has one extra one which we actually
don't want it to change. I believe it is this one, so we're going to
replace them one-by-one, only the ones where I
actually am sure I do believe that this should not
be changed. So there you go. And then the last one,
good animation file location has now changed to get animation resource as well, replace all that's
going to be fine. And there we go. Now
this should be fine. Let's see where the
arrows over here are. It's gonna be right here. Okay, so inside of the renderer, this actually remains
to be texture location. It's a little weird
because this is also through gecko
lip, but there you go. So that should be fine. Just make sure that
when you replace it, you don't replace it
in the render as well. I guess the boat is not
going to be saved sadly. I have to look at the bolt and I sadly have not been able
to properly get it to work. So what we're just
going to have to do is we're just going to have to live without the
boat for the time being. So you can either just
delete everything, just do it like this, and then get rid of it here as well. Sadly, it is, it is what it is. The issue with the
boldness, of course, they added the chests into the boat and have not yet figured out how to
change this around. Sorry about that, but that is
just how it's going to be. Sometimes that happens when you change from one
version to another, that certain features,
they've completely changed. So then you're not gonna
be able to actually, you're not going to be able
to figure it out quickly. This is also sometimes why certain molds take so
long to update, right? Because through versions things change and that is just
how it's going to be. So I believe we can
also get rid of the old entity over here. We might be getting
an error somewhere else, but that's gonna be fine. So this, I believe, should be everything that
is actually changed here. Okay, The multiple entity then also was not going to work. But once again, I'm just
going to drag all the way down so that you can do this by dragging while holding Alt. And then you can
just, you can select multiple different
lines in that case. Then same with the
item. Absolutely. Just gonna get rid of this. So as I've said, I don t think that
it's too extensive. The changes aren't
too extensive, but it is what it is. Sometimes that does happen. So let's just get
rid of this as well. And then the what? This is fine. This is
fine. This is fine. And then we can
proceed to the events. In the events the
lute actually has changed to the loo tables
have changed a tiny bit, but luckily not too crazy. So the only thing
that has changed here is actually the
do apply method. As you can see, you can no longer be overwritten
like this because this is now instead of a
list is an object ArrayList. We just put an object every list important class, and then
you're gonna be fine. Same one right here. Changing this to the object, every list importing that class. And then the lute modifiers should work the same as before. I went fine. And then we come to the Registry
event which has changed, I would say roughly significantly because we no longer have the Registry event, we now have a register events. So this is now going to be a final register
event over here. And then now inside of
the actual event method, we have to look for the she. Basically, we're
going to say, oh, this is of course called event that is quite
important over here. There you go. Now
instead of doing this, we're gonna say event
that register and then saying forge
registries that keys. That in this case loot
modifier or serializers, Hama, helper, and this
is just a consumer. And now we put these
things into there. So we want to put
this into here. And the way that we wanna do, we wanna say helper
that register. Then first taking the
resource location of the actual name. And then the second
thing is going to be a new serializer. So we're going to take the
new serializer over here. There we go. And this should now
work. And then we can. Duplicate this, changes the name over here and then change the change the
sterilizer to this one. And then we're going to be fun. So they ago, this is how
this changed and then the same thing happens
in the recipes as well. So if I am not mistaken, what we wanna do is
we want to say event a dot register registries that keys dot recipe serializers because this is a
recipe type actually, sorry, this is a
recipe types, yes. Then once again, helper, um, or like this, naming it
whatever we basically wants to. Then we can say recipe type
of helper, that recipe. And I think we can literally
just copy this over. Okay, Not quite though. Not quite. Because what we do want to
hear is either a string or a resource location or so
couldn't we do this then? Yes, we can because the
id is going to be that. Now the question is, okay, I'm actually feeling a
little bit better if I'm making a new resource
location because I'm not sure if this makes it under
our resource location or not. We're just going to do
something like that. Ending it right
here, There you go. So making a new resource
location under our model ID with the id column blasting. And then we're gonna be fine. And then we no longer
need this one. And the rest here, I believe
should be totally fine. Control Alt O to get rid of the imports and then
we're going to be okay. More events are totally fine. Nothing has changed,
so events are done. And now we come to the
fluids because the fluids, the finally the new Fluid
API has been introduced. However, I have not been able to figure out exactly
how it works yet. They're also is not yet any
type of documentation on it. So sadly, for the time being, fluids also gonna go
the way of the boat. It is fitting when
you think about it. But yeah, the boat are the fluids in this case are
sadly not going to work. So fluids for the time
being, not working. Once again, you can just look at if you're watching
this in the future, Let's take a look at the forge, look at the documentation. They might have added something
in there as well already. So then you can try to
figure that out on yourself. The new Fluid API should be
way more versatile than this. But for the time being, sadly, fluids not going to happen, in this case, custom items. I believe that there should only be something in the data tablet. Once again, the
component over here, so component dot literal. And then the same thing happens in the dowsing rod item as well, just with the O and the registry name as
well, fair enough? Yes. This is component
translatable. Nope. How about we
do it correctly? Component dot translatable
in this case. And then here as well. Then sent message is
actually system message that no longer takes in
a UUID at the end here, but it does take in a component literal they go registry
name no longer available. So what I will do is I will
just say the lock below dot get name here and then
the same oblique up here. That should be fine. Getname here as well, and that should pretty much
be it. Are there you go. We have another SYN message,
send system message. We no longer need the UUID. And then this is going to be
the component data literal. Actually, no, it's not. It's gonna be translatable. And that is everything, just the imports Control
Alt O as always. And there we go. This should be pretty much all that we need to train it
over here, I believe. The mod fluids here. Yeah, that's fine. We're gonna go through
the normal class. They are in just
a moment as well. Materials are fine,
creative mode. Tab foods are OK mod items. This should be the honey
bucket absolutely. Will get rid of this
writ of the imports. And then we are okay
with this as well. The tears are also fine, so everything working fine. Now, interestingly enough, paintings actually have changed. I know it's actually crazy
to think about this. This is no longer motif. This is now called
painting variant. And this is also called
painting variance. There you go. We're just going to
change the motif here to painting
variants everywhere. Then we're going to be
fine control of all, once again, for the imports
to get out of there. And that should be it. Potions are fine. Recipes have actually changed. So let's go to the recipe. There's two important
things that we have to do. Delete all three
of those methods over here, and that's
going to be okay. And then in the mattress method, we have to add if P level
that is client side, you just want to return false. So that should be all that
we need to do here as well. And that should pretty much be everything that we
need in the recipe, in the customer recipe class, the screen, it has
anything changed here. I do not believe that it has. So that's actually really good. And then the sound, sounds
should also be fine. Now in the util, I think
something changed somewhere, not here, but in the tags. Nope. Item Properties, util,
actually no changes at all. The title screens
still has some issues, so we're just going
to ignore this. Now the villagers class
has actually changed and we need to do a few
things different here, right? So this is done a
little bit differently. Now, we are actually
doing the following. We're actually making
a new prototype. And what we're doing
is we're making an immutable set dot API of this remains so the
cobalt blaster dot, dot get default state definition or GetState
definition dot possible states, then the one and the one here. And then here, we're actually
doing it the following way. We're making a new
village or professional. We actually need two
predicates over here. So it's gonna be x-dot yet. Equals last or point
dot get as well. And then the second predicate is gonna be exactly the same. So x dot get equals blaster point that get and
that should fix this as well. And the rest here
should be totally fine. We will actually need to add
tags in a moment as well, because both the
villagers as well as the painting is
interesting enough, have some added
tags now as well. And then last but not least, we come to the world generation, which of course is always
the favorite part. So here, luckily, it's easy, just a random source in the
abstract tree grower here. But then we come to
the craziness Because now what has happened in these classes,
nothing changed, right? To configure features
or everything is fine. But then we go to the
gen classes and we see the biome loading event
is no longer available. And everyone, and everyone
starts freaking out because how do I now do
some custom world, Jan. Well, customer origin
has completely changed where now we're going to be
using a bio modifiers. So in theory, we can just delete all of those four
classes over here, delete them, and
then make new ones. Same goes for this
one right here. Motor world events, we
no longer need this because it doesn't
do anything anymore. We now need to use
bio modifiers. So we're just going
to take a look at the bio modifier class,
this one right here. So you can see an interface
and we basically have to make a custom codec that reads in a JSON file that is pretty much all that the
codec really is. Now, luckily at this point, or it actually has added
some example ones. So if you take a look at the
forge bio modifiers class, we have a Add feature
to bio modifier, a remove one, and we also have a spawns two by m one and a
remove spawns from biome one. So this is actually everything
that we're going to need. Luckily, it isn't too
crazy and we don't actually need to even make
any custom class over here. What we can do is do this
stuff in the data folder. Let's just start with
the bio modifiers. So how can we get our
custom stuff to still work? We want to go to the Data folder MC course,
very important. And then instead
of a woman to make a new directory
called forge, yes, the forge directory has
to go into your MC course or whatever your mod ideas directory that has
to be the case. And then instead of
the force directory, we're going to make a new
directory called bio modifier. There we go. And then we can add
the JSON files. So this is how the json files
are going to look like. So I'm just going
to copy this over and we're gonna make
a new JSON file. Let's actually see what our place features
are in this case. So this is gonna be
the place features. We actually do
have to change the place features in just a moment, but we're not going to worry
about that at the moment. Let's just add the
first bio modifier and then we'll look at the
place features as well. But this is going
to be a new file and then we're going to
just going to call this the ad cherry blossom
down adjacent. We're just going to
add this over here. And then we're going to
see the first one is this, this is required, we'd
always need to do this. Then we want to say hey to what, what is the namespace of the
biome that this attitude, we're just going to
say forge yz plane. So this is going to be
a tag from forge that is going to basically have all of the planes bombs
inside of it. Then we're going to
have MC course, Poland. And this should be ebony cherry
blossom placed over here. Yeah, there you go. And then
this is not underground. Oris, this is actually
the other one. Let's actually take a
look at the decorations. I believe it is called this is the or is it decoration step. It might be this. Alright, fine. I mean, I'm okay with this. This should be named
vegetal decoration. This one right here.
We're just going to add it right here and
then we should be fine. And this should in theory, add our cherry blossom placed feature into any
planes biome that exists. So fairly self-explanatory. However, the place features actually also have to
change a little bit. We actually have to use a
different register here. So we're just going to make
a deferred register of type least feature or placed uterus. And then this is equal to
a deferred registered. I create this registry dot
least feature registry. Very important. Then
MC course aren't dumb model ID and of course we'll also need a
register method. I'm just going to copy this
over a little bit easier. We're going to call
this right here. This is going to be called, I think it shouldn't matter
that much more place features that register and then
passing in the event bus. And instead of
registering like this, we're going to have
to, It's gonna be, it's gonna look a
little weird now, luckily, all of the code here will of course be
available to you. So this is now a registry
object instead of a hold on, nothing too crazy at the moment. They may want to change
the placement utils are registered to a place
features that register. That's not quite right,
sorry, there you go. And then this one,
this one and this one. This is all fine. I'm going to copy
the line and this has to be added right here. So then we should have no errors except for one
closing parentheses. You can see we want to
call it Place features that register and
passing in the name, normally, like we've done
with every register before. And then we have a Supplier of a new place feature. And then we have to cast
this mud configured feature first to a holder of Configure
feature question mark, question mark, and
then a holder of Configure feature western
mark, question mark. It is craziness,
but this is how it suddenly has to happen for the time being when
you're watching this, you might actually have a
better way of doing it. You might have something has already been found out
or something like that. But for the time being, this is suddenly how this is
going to have to go. And then for both the rows
as well as the geode, we actually have to have a list of all of the
stuff that we have here. So list of n, then we just have to add all of the
different things here. It's saying it's
irreverent to filter all that craziness goes into a list. And then just two
closing parentheses. And then same here
if I'm not mistaken, list of the goal and
then just closing parenthesis two times n
there, we should be fine. So this is what we need to do, as crazy as it looks like. But this should
actually indeed do all of the stuff that
we wanted to do. So then we can actually add the other bio
modifiers as well. This is gonna be the
add pink rose as well. And this is going to
place the feature of the pink rose placed a goal. Then let's add also under vegetal decoration
that makes sense. And then we're going
to do the whole bald, or let's get that
over here as well. And this is now no longer
vegetal decoration. But this is actually, let's go back to the
declarations over here. This is now underground, or it's very important
that we change this. There we go. We're just going to
add it to how about let's do Minecraft
colon is over world, so we're just going to add it to every biome that there is in the oval world,
that's going to be fine. And then last but not least, let's copy over the cobalt or, and that's gonna be
the ad or bolt geode. And then this is just
changing the name. He placed a geode over here. Let's just also add it to all the over world and
that should be fine. But this is the new
world generation, very important that
everything here is correct. And then last but not least, we also have these
structures now luckily, telepathic ground has already updated that their repository, so nothing too crazy
is going on over here. So we're just going to
have to do the following. So let's just do this. I'm going to copy over first
the mode structures class. Let's see. There we go. And then we're going to have one issue here with the sky structures,
but no worries. Let's just delete the
imports here as well. And then in the sky
structures class, this is also going to be, well, I mean not too crazy. Let me just once again copy
over the class over here. And then we're going to see it's only the imports are wrong. Once again, Control Alt O. And you can see there's a, another codec here as well. This is just, as I've said, basically a certain field
that generates read in a race and file then generates a class that's pretty much the high level overview of this. Yeah, those are the
two changes here in these structures
and then there's also a change in the structure, race and files as well. Because of course, there
couldn't be anything crazier. But first of all, the
older here changed its name to just
being a structure. So we're going to change
it to the structure name. And then inside of
the adjacent file, there are actually
quite a few changes. First of all, this conflict
is no longer needed, so we're just going to
delete the config and then they start
pulling the sites are still needed but not
inside of the conflict. Then what we wanna do is we want to add the step over here, and that's going to be asked. And then the next thing is
the max distance from center. So this also has to be added. And then we also need to
add three different fields. That is going to be the step, the start height and the project start to hike map and
deleting the Arab noise. So this is what we're
gonna do always. Now. Now this is for the
one where you actually have a type inside of the code. If you don't have that, we can
no longer use the village. We now want to use
Minecraft jigsaw. So we want to use
this once again, get rid of the unfit here, keep the star pool and the size at a max
distance from center. And then if we're
using the jigsaw one, we actually want to use
for different fields. Still the leading
the Arab noise. Once again, this is the step, the absolute height and the
project starts to height map. Those are going to remain
basically the same, maybe changing the start height. But then for the jigsaw, you also need to
use the expansion. Heck, I'm going to copy over the stuff for the cameras and the storage
platform as well, but it pretty much
is the same thing. Now you can actually
look this up as well in the GitHub repository and
an individual just as well. So there should be no, but no worries at all. As I've said, we're
gonna be fine. Luckily, the changes
aren't that crazy. I still remember it
changes from one to 1617. Those were changes where yeah, that was that was pretty crazy. Now this isn't for this. Now the only two
things we still need is for the villagers and
the paintings of the tags. So those go in the data
folder on Minecraft. And then instead
of the tax folder, we want to make a new folder called painting
underscore variant. And then you need
tax folder again, we want to make a point. Underscore, underscore
interests, underscore type. And then I'm just going
to right-click new file. This is going to be the
wire a bull underscore job, underscore site that Jason is in the point
of interest type. And this is going to
be the following. So this should be. In theory, this value Mc
cores, blast or point. Let me just quickly check
if this is the name. It's actually blast
play. There you go. Thing I double-checked over here into the painting variant, right-click new file
called police sub bowl that Jason, there we go. And this is going to include
all of these things. Let me actually just
copy this over. And then I have to check
the names over here. So we're going to have plant and then two more and then it's going to be the Wanderer
and then sunset as well. And hopefully this should
be all that we need to do. Now as you've seen, there actually is
quite a few things, quite a few steps over here. It's not that it actually is easy as much
as you might say, Well, this has been
quite the ordeal. Know, this is like actually very team to as
I've said, 1 16th, 117. That was like ten hours of just like absolute craziness
going through everything, changing everything because
class name is changed, method names change methods
that were available, were no longer available. And luckily here, most of
this stuff still works. So I'm actually quite happy
with the update here. But for the time being, let's just start and see
if anything might come up. There might still be an error
in one of these classes. That's gonna be
fine. There you go. We actually even
founded cobalt lamp. So this is the take
method over here. Once again, just
because of the random, this is now a random source. Actually they go into random source and
then it should work. No worries at all. Let's continue along once again, starting and seeing,
there we go. We also have this in
declined model when we actually get rid
of the mod fluids. Absolutely no worries here
are the climate events. Let's start this again. This also happens when you start it, you're
getting an error. You just fix the error
and then you start again. So no worries at all. And now it does
seem to be working. So let's just see if
Minecraft starts. That will be a great sign. And then we can see, go into our world and
see if everything works. A mangrove is starting. However we are getting an error here, but
that's gonna be okay. Let's just see first of all, if it actually starts at all or if it doesn't
start a dust storm, that is a great sign. Let's just create a new world. We're not getting
anything because we have some unknown
elements over here. Okay, let's think about this. We can see because Minecraft cherry blossom
checked is not available. Well, that is probably
an arrow by myself because I have not
changed the model ID. Well, this is not quite right. Iteris MC course,
cherry blossom checked. So that is very strange
over here because indeed, if I look at this, I'm
always using my MC course. So that is a very
strange, alright, so the issue actually was
using the conflicts over here. I'm honestly not sure why the conflict is don't
quite work here. The it should work in theory. Now the only thing
that I could imagine, and I'm actually like,
I'm doing this live. I have not tried this before. Putting the registration
conflicts before everything else might possibly
change this around. Let's actually try
this and see if the conflicts work properly. Then though, it's just
because of the conflicts, that the actual registration of the place feature
does not work. So as I've said, I've
not tried this before. So let's just see if there's does anything
and if it doesn't, then apparently
sadly the conflicts also don't quite work. Which is very strange indeed because I've not
run into this before, but let's just see. So maybe we're gonna
get the same error about the conflicts
not working again. And if we don't get this, I'm actually feeling pretty confident now we are
actually getting this, which is very strange. Indeed. I am. I honestly don't
know why that is the case. So let's just see. But at this point,
when this happens, I'm actually very confident
that it's not going to work, but we're just going
to have to live without the configs
for the time being. Once again, it's probably just
a forged change somewhere. So there we go, it doesn't work. But if I however, change this back to not
using conflicts, but using just a
normal number here. And it doesn't matter, the
conflicts are never actually loaded here and then
it should work. So once again, I don't, I have no idea why that doesn't work with the
conflicts over here. It did work before, but they ago, let's just do it like this
without the conflicts. And then if the
conflicts actually did change and we have
to change them, and we can always do that
later down the line. Usually it is more important
to get a working model in a new version rather than having everything
working immediately. That is usually better
because then you can fix it. And yeah, so there we go. And then we can go
single-player create world, and now it should actually work. We should get
validating data packs. And there we go, Come on, There we go, new world. Let's just do whatever, something like that breed of n. Yes, we do want this with
our experimental settings. I am well aware of this and
then we're gonna be fine. We should be fine here. There's actually one more thing that you can also
take a look at, which is kind of annoying, but it's not the
most terrible thing. It's just the door actually
that is not going to work. You will actually have to
change the block States, JSON files and the block model
Jason false for the door. But honestly that should
be fairly trivial. All things considered if
annoying but still trivial. And let's just see loading
the terrain and there we are. So let's first of all, I mean, this is like the perfect timing. We are on the snowy planes
and we already have our cherry blossom trees
over here growing. We also have our
custom structures also working totally fine. Then the question is, and
we find any of our roses, red roses, and there they are. Also works totally fine. And then just for the
sake of argument, let's go down and
let's see if we can find some of our orders as well. And then we didn't have
to even search for that long deep sleep cobalt or so everything should be fine. There's some more there as well. So this also works. Now the real question
is, do our due, all of our items work
and all of that, I think all of them should work. Like the most
important one that I'm interested in is
the cobalt blast. Or to be honest, because
that usually is the one that can break fairly
easier, easily. So let's just put some stuff
in here and it still works. It's still doing its stuff. And let's see, There we go. We still have a cool
pickaxe and let's just make sure that it
actually does work. And I believe it
does. It's just not going to be able to
mine this properly. I think no, it is.
So there you go. But everything is still working exactly how you'd expect it to. So I mean, yeah, that's pretty much how easy
it can be to update to 119. Now, as I've said, plenty of
things might not still work. That is totally expected
and totally normal. You're not going to just
change the number from 1890s and everything is
going to work perfectly. So if there are any issues, you're just gonna have to look
in the forums microforms, or just go onto the
Microsoft discord. There's also might be
something they are the micro forge discord where some additional information
might be gathered and also the forged documentation
and also help you along. But overall, I think
that this update actually is quite great amine, we have probably like 80 to 90% of features still working, which is honesty better
than most things. But that will conclude
this lecture right here, and this will also conclude
the entire course here. I'm not really planning on adding anything else after this, there might be a
slightest chance of another tiny update video,