TheGreyGhost / MinecraftByExample

Working sample code for the basic concepts in Minecraft and Forge.
Other
1.24k stars 187 forks source link

Need advice on how to make a minigame-style plugin #43

Closed uglycoyote closed 6 years ago

uglycoyote commented 6 years ago

I am a professional game developer, but new to minecraft modding. I'm trying to help my kids make some ideas of theirs come to reality.

I was very glad to find this repository with great examples on how to get started on modding. But unfortunately none of the examples seem to fit with the kinds of ideas that we have, so I was hoping for a bit of advice on where to get started. We want to make some kind of a minigame, so what I am looking for is a way to add on my own "update loop" where our minigame can contain its own logic. Most of the samples here seem to revolve around creating new types of entities/blocks/recipes for the game which have a specific pattern to them, but it is not clear to me what the correct pattern is for adding in general-purpose code that runs all of the time in the background.

Here are some of the kinds of things I was thinking we would want the mod to be able to do:

We are hoping to make this run on a server where several clients can connect and I don't think we actually need to create new block types etc, so possibly the mod we want to make will be server-only. (We play on hypixel, and the minigames on there don't seem to require a client side mod, they all work just by connecting to their server). I have heard of Bukkit, which seems like it is an alternative way to create server-only mods, but Forge seems like it is more flexible and i get the impression it is more recent/modern, so it would be the way to go even if we were only doing something server side.

Are there any samples you can point me to of how to create a mod/server like in my examples above? Are there are samples like that in this repo that I missed? Or other resources elsewhere?

I have already looked at the forge documentation, but it seems a bit slim and I couldn't find any direct answers there for my questions. I have also done a lot of googling and reading random forums populated by 12 year olds that banter back and forth without arriving at helpful conclusions.

Apologies if this is not the right forum for this question, I just thought I would ask since you have excellent tutorials and you seem to know what is going on.

phase commented 6 years ago

What you're describing sounds like it can be entirely implemented in a server-side plugin. If you don't need to add any new types of blocks / items / entities (remember that you can already do a lot of customization in vanilla with server resource packs), then Bukkit or Sponge is what you want. These APIs are server-side, meaning that they only modify the sever code and vanilla client can still connect. You may also note that servers like Hypixel are still able to do some crazy stuff, even with supporting vanilla clients!

I have heard of Bukkit, which seems like it is an alternative way to create server-only mods, but Forge seems like it is more flexible and i get the impression it is more recent/modern, so it would be the way to go even if we were only doing something server side.

The Bukkit API hasn't evolved at all. What you're looking for is the Sponge API. I would highly recommend using it as it is constantly evolving with new updates. As a plus, if you ever do decide you want to add specialized blocks, or just use other mods, Sponge works with Forge!

Forge seems like it is more flexible and i get the impression it is more recent/modern

I would say that the Forge API is somewhere in the middle. A lot of internal tools are being completely rewritten for 1.13, so we will be getting some cleaner and upgraded APIs from both Forge and Sponge (the two work together a lot).

I have already looked at the forge documentation, but it seems a bit slim and I couldn't find any direct answers there for my questions.

Sadly it is slim, but the Sponge Documentation is quite the opposite!

You can learn more about Sponge on the website: https://spongepowered.org/ You can join the Discord server for Sponge here (I'm in here if you want to personally ask me questions, @phase): https://discord.gg/PtaGRAs

(disclaimer: I am a Sponge staff member, but I don't directly update the API or even use it much, I only work on the plugin repository.)

I wish you luck on your modding!

TheGreyGhost commented 6 years ago

Howdy Mr Coyote :)

Thanks for the positive feedback!

In addition to what phase said, I've got a few thoughts based on my own experiences with Minecraft and Forge

The first thing is that IMHO Forge isn't really an API in the sense that you're used to. Its primary benefits are to make your mod compatible with other mods running at the same time, and to make it a lot easier to hook into the Minecraft code. However it doesn't really isolate the interface from the implementation in the same way that conventional APIs do. The interface can and does frequently change with each version update, usually because the underlying minecraft code has changed and this is directly reflected in the interface behaviour and function signatures. Sometimes it changes because the Forge development community has decided to implement something a different way than they used to. As you've noticed, the quality and quantity of the documentation can vary dramatically and in many cases is rather slim, outdated, or just wrong. Coding for Minecraft and Forge always involves a lot of digging directly into the implementation code to try and figure out how it's supposed to work and (more often than not) why the blazes it's not working how you expect.

This is just something to be aware of, just part of the Minecraft coding experience. You will probably have to perform major updates to your mod every time the minecraft version updates, if you use the Forge directly.

I don't have experience with Bukkit or Sponge but I believe their interfaces are a lot more stable and reverse-compatible. You can also minimise the upgrade pain a lot if you use your own wrappers to interface with the Forge API, (although this doesn't save you 100% of the time)

There are lots of ways to add update loops to the game; in most cases it's easiest to hook into one of the events that gets fired every server tick (@SubscribeEvent TickEvent SERVER for example; see src/main/java/net/minecraftforge/fml/common/gameevent/TickEvent.java) and run your logic in there. All of the things you mention look to be possible that way, like Phase said server only.

I have generally found that the best way to add a new functionality is to think of a vanilla function that is similar, then reverse engineer the code in that. Or to think of a mod which already does something similar, and learn from it. Sometimes a google will help.

By far the most helpful forum I have found is this one http://www.minecraftforge.net/forum/forum/70-modder-support/ There are a number of very talented folks on there with encyclopediac knowledge due to 6 years of Minecraft + Forge development. Much more than me, that's for sure!

Cheers TGG

uglycoyote commented 6 years ago

@phase and @TheGreyGhost, thank you both for your thoughtful and detailed answers.

I wasn't aware of Sponge, but that seems like the direction to go. It seems that Bukkit is dead in the water, though I guess a lot of people have built a lot of servers/minigames on Bukkit so I would guess it still has a largish following despite being abandoned by the developers. But as someone starting out, Sponge seems more promising as it is in active development, and yes the documentation looks quite a bit more detailed.

For my update loop question, subscribing to the TickEvent sounds promising, that is kind of what I was looking for.

I have generally found that the best way to add a new functionality is to think of a vanilla function that is similar, then reverse engineer the code in that

I'm curious for a bit more detail here, is this done by using a bytecode decompiler or is the source code actually available somewhere? I don't know what tools are out there for this in Java, but I have used Jetbrains decompilers for C# before. I got the impression somewhere that the game's bytecode had obfuscated identifiers, which seems like it would make this a bit of an uphill battle.

Thanks again. I will close the issue, but please feel free to comment further.

ryantheleach commented 6 years ago

@uglycoyote I missed your post in the SpongePowered discord, and didn't have a better way of contacting you.

Our community is usually pretty friendly, but occasionally gets tired of kids learning to program for the first time, trying to learn Java, then not understanding even basic loops, scope, etc.

https://plugins.jetbrains.com/plugin/8327-minecraft-development if you are using IntelliJ helps create a template Sponge plugin, and will setup a test plugin for you to try. It's the best way to get started IMO.

Otherwise checkout https://github.com/SpongePowered/Cookbook/ for the official example plugins, or https://github.com/RTLSponge/chatclear for my personal, example plugin.

uglycoyote commented 6 years ago

@ryantheleach hey, thanks so much for reaching out to me! It did feel a like a bit of a smackdown but I can totally understand not wanting to be inundated with beginner java questions. I'm fairly comfortable jumping around to different languages, so although my java is rusty and I can't remember all of the file/folder naming conventions and other such details, I'm sure once I get over the initial setup hurdles I'll be off to the races. The guide in the sponge docs is pretty detailed, but just lacked a few key pieces which might be obvious to people using java more often.

(My stuggles with the directory structure would have been helped by the setting "Create directories for empty content roots automatically", under IDEA's Gradle-specific settings. It is kind of funny, that actually Jetbrain's own page on Getting started with Gradle shows it automatically creating the src directory and subtree underneath, but it seems that the setting that creates these for you defaults to being off. I found the setting through someone else's post asking about why Jetbrain's tutorial did not work as advertised)

I'll check out the Jetbrains plugin that you linked to, that seems like it might be a better starting point. Thanks also for the cookbook link. That looks like great stuff. Those both seem like resources that the main Sponge docs should link to, but I had not run in to them yet.

I did run in to the link for the video series by Sibomots from the Sponge Tutorials page, which seems like it might help to fill in a few of the gaps if setting up a project from scratch. (I generally prefer written documentation, but the videos seem pretty concise and are divided up nicely for jumping around).

Thanks again, and perhaps I'll try the discord channel again when I have some questions which are more specific to Sponge.

ryantheleach commented 6 years ago

@uglycoyote For what it's worth, people are generally happy with answering questions relating to building Sponge plugins, I think you just got a bit unlucky as I thought your questions were on-topic shrug.

TheGreyGhost commented 6 years ago

Hi coyote

I have generally found that the best way to add a new functionality is to think of a vanilla function that is similar, then reverse engineer the code in that I'm curious for a bit more detail here, is this done by using a bytecode decompiler or is the source code actually available somewhere? I don't know what tools are out there for this in Java, but I have used Jetbrains decompilers for C# before. I got the impression somewhere that the game's bytecode had obfuscated identifiers, which seems like it would make this a bit of an uphill battle.

Yes it's done by a decompiler called Fernflower I believe, which I think might be the same as the one present in IDEA IntelliJ. The very helpful folks at MCP project decompiled the bytecode and designed tools to assign meaningful names to the decompiled labels, so the minecraft source is actually quite readable (the function signatures, at least). The local variables are not meaningful but it's usually fairly straightforward to figure it out.

If you install the Forge MDK, the decompiled deobfuscated minecraft source is included in one of the packages (I forget the name but it's easy to find). You can even use the debugger to trace into it.

Cheers TGG

phase commented 6 years ago

Writing a Sponge plugin with SpongeCommon should also give you some deobfuscated code when looking into the methods in IntelliJ. I don't quite remember what enables that, but the Minecraft Development plugin for IntelliJ might do it.