Code Monkey home page Code Monkey logo

amethyst's Introduction

Image

Project Amethyst
Discord GitHub Downloads (all assets, all releases)

Project Amethyst is an open source-project for building client-side mods for Minecraft Bedrock 1.20.71.1, client-side mods are able to stretch past the limitations of addons and have full control over the game such as using Minecraft's input system, creating your own user interfaces, changing vanilla functionality, and more. Please consider starring ⭐ the repository, doing this takes a significant amount of work.


Mods built with Amethyst

image image

Better Inventory is an inventory improvement mod for Minecraft Bedrock edition, version 1.20.71.1. It adds in a shulker box preview, as well as the ability to see extra information about other items, like its identifier, namespace, durability and aux id.


Before Zoom After Zoom
image image

A small mod which adds in an "Optifine" like zoom into the game.

Using the API for other projects

To link AmethystAPI with another mod, we use an environment variable %amethyst_src% to point to the cloned repository. Here is a quick list of commands to clone Amethyst into the Documents folder and setup the environment variable automatically.

powershell
$destination = Join-Path $env:USERPROFILE "Documents/Amethyst"
git clone https://github.com/FrederoxDev/Amethyst.git $destination
[System.Environment]::SetEnvironmentVariable("amethyst_src", $destination, "User")

amethyst's People

Contributors

adrian8115 avatar atxltheaxolotl avatar cxiro avatar duckos-mods avatar frederoxdev avatar notchyves avatar outercloudstudio avatar zeromemes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

amethyst's Issues

Feature Request: onStartCloseGame

We have onStartJoinGame, which allows use to run code when a player joins a world.
If we want to stop something when the player closes a world, we don't have anything...

That's why I propose to have a onStartCloseGame func,
which will allow us to execute code when a world is closed

This will help prevent crahes when a world is closed, but the mod still thinks the player is in the world

clean(): Pass AmethystRuntime to Initialize function

About

Pass down an AmethystRuntime instance or some other "Manager" to the Initialize() function.

extern "C" __declspec(dllexport) void Initialize(AmethystRuntime* runtime) {
    runtime->inputManager;
    runtime->gameVersion;
};

Why?

Every time a change is made in Amethyst’s function parameters all mods break. While the community is small for now, hopefully it wont be in the future. If this is the case, it would be best to reduce future technical debt whenever we make a change to parameters so that mod developers don’t have to constantly make changes.

To go even further

Additionally, I personally think having so many
extern "C" __declspec(dllexport) at the beginning of functions is a bit ugly. Perhaps we could allow people to register it themselves.

For example we could make recreate something similar to the C# delegate pattern (not sure if that is something C++ will allow, I haven’t really looked into it) or just continue with the observer pattern we currently have.

extern "C" __declspec(dllexport) void Initialize(AmethystRuntime* runtime) {
    runtime->events->RegisterInputs += RegisterInputs;
};

void RegisterInputs(InputManager * inputManager) {
    inputManager->RegisterInput("f3", 0x72); 
}

Post Scriptum

Btw this was written on mobile so forgive any typos (and I didn’t proof read this)

Load resource files from mods

Mods should be able to load behavior and resource packs into the game. Preferably being able to also specify things as global resources, with the files being stored specifically in the mods folder.

RelWithDebInfo shouldnt be forced as the configuration

The configuration should be decided by the user, not by the project in the CMakeLists file. Debug and RelWithDebInfo are two different build configurations, and it may be helpful at times to have the ability to use Debug.

HookManager->CreateHook across Dlls doesn't work

MinHook seems to have an issue trying to remove a hook created within a Mod.

ModFunction void Initialize(HookManager* hookManager, Amethyst::EventManager* eventManager, InputManager * inputManager) {
    MH_Initialize();

    hookManager->RegisterFunction(&Item::appendFormattedHovertext, "40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 49 8B F1 4C 89 44 24 ? 4C 8B F2 48 8B D9");

    hookManager->CreateHook(
        &Item::appendFormattedHovertext, 
        &Item_appendFormattedHovertext, reinterpret_cast<void**>(&_Item_appendFormattedHovertext)
    );

I think I will look into alternatives to MinHook, that hopefully support this.

Bug: afterTick/beforeTick is called too often

This is my example code:

#include <chrono>

std::chrono::time_point<std::chrono::system_clock> last;

ModFunction void Initialize(HookManager* hookManager, Amethyst::EventManager* eventManager, InputManager* inputManager)
{
    eventManager->afterTick.AddListener(afterTick);
}

void afterTick(){
    std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
    auto duration = now - last;

    // millis since last tick (for 20 ticks per sec ~ 50ms difference)
    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();

    Log::Info("MILLS SINCE LAST TICK: {}", millis);

    last = std::chrono::system_clock::now();
}

This code gives me 16/17ms per tick, which roughly means it is executed 60 times per second,
but there are normally just 20 ticks in a second

Using beforeTick doesn't really change anything.

It seems like it uses the wrong function for ticking

Catch errors thrown in base game

Look into if we are able to catch any errors thrown by the game, so that:

  • we can log the crash
  • we could automatically unslide the address of the crash and get the exact line of assembly that caused the crash (Right now you can do it but its manual)
  • Have an abort mod function for mods to do whatever

Launch Minecraft suspended

The project long-term needs to be able to hook functions which are called really early. This would be a significant thing for the project, and would solve one of the problems with the api running before it's possible to attach a debugger

Proposition: Compile server side mods

It could be interesting to allow users to easily make server side mods in the same source as their client side mods, since I am moving the project in the direction of autogenerated headers, we could switch addresses to be got externally when targeting server.

I'm not too sure on the specifics on the idea though, the goal of the project still is client stuff, but having the ability to do both would be powerful

Separate source files from headers

I believe this is important for at least the API part of Amathyst. This is better for mod developers since they could simply use FetchContent on the Amethyst repo and link the AmethystAPI target to use the API, and keeps the headers seperate from the C++ source files to keep things organized. If the source and header files are together, and FetchContent is used, the AmethystAPI target will likely include the source files as part of the includes paths.

Generally its just good practice to have the headers separated from the source files for libraries.

Documentation please

Please make an documentation so I can see what I can do... Like functions and classes.

Sorry for making an issue

Partial Support for latest

It could be nice to have support for the latest version of the game, with minimal features enabled etc (e.g. no input handling etc), while also not moving amethyst entirely to a version.

That way some mods that are smaller in size can be updated to trail latest stable release. I'm not entirely sure how this will be able to be managed on git, we can make a fork and make changes to that branch etc, but im not sure if we can properly keep that branch updated from main?

As of current I want to keep working on 1.20.51 until I have gotten most of the stuff I want to explore and do in amethyst

Near-Term Roadmap

My near term goals for the amethyst project is to overhall mod management within Amethyst Launcher

  • Versions of runtime should be available to be downloaded through amethyst launcher
  • We need a better way of updating the launcher, it should be able to fetch its own updates to avoid users having to manually update it each time
  • We need a better mod management system. Drag to import, UI to manage things with mods, e.g. remove them

Feature Request: in code construction of TexturePtr

We can get TexturePtr by loading it from the ResourceLocation
but we curreently can't construct it in code...

It would be absolutly useful to make it code generatable.
We could draw procedural textures and would not need to use drawRect with many small rectangle blobs
This would also allow us to not render these every frame, instead just build them every few second or so
and then just to use them every frame.

I've looked into this but couldn't find anything useful...

Near future goals

I'm probably going to approach how we do 1.3.0 slightly different to 1.2.0 where we ended up with nearly 70 commits behind, using an entirely different setup. Obviously we aren't changing any of the setup anytime soon, so we won't have that problem, but I still also want to do things with more minor releases, and go for more things in 1.2.x

The things I want to mainly achieve (not in any particular order):

  • get block items properly working, they are quite buggy right now and I haven't been able to get them to show up in creative inventory, nor command list for /give
  • BlockGraphics class, I need to look into for using hardcoded block shapes / more complex block designs
  • entities, I want to get most of the ground work up for them, I have never tried entities in the past, like I have for blocks and items, so this could be a challenge. Most entities seem quite data driven so I'm not sure how easy it will be to integrate with that
  • tesselator, I think it could be neat to do some basic rendering stuff, I'm not entirely sure if this is the right class, but it would be nice to start creating 3d stuff in the world, and is needed for one idea I have

Better CMake build setup

It is typical for CMake projects to have a single main CMakeLists.txt file that is used to build the whole project. It would be reasonable to leave the other CMakeLists files as their own projects as well, like in the AmethingRuntime and AmethystAPI folders so they can be built independently as their own project as well.

On top of this, libraries should be submodules and not .lib files with the headers in the project files directly. The benefit of submodules like this is that they can be built independently, and linked with the project in the same way, but a .lib and header files do not need to be committed to the repository. I find it to be generally bad practice to have pre-built libraries included in the source code of projects.

I'm going to start working on this on my fork and will submit a pull request hopefully changing this about the project.

Create a clearer division between the API and the Runtime

Right now it is not exactly clear what the API and Runtime parts of Amethyst are actually for. What I mean is that the API contains classes like HookManager and InputManager, while the Runtime appears to be whats responsible for making them work...

I think this is fine, having common data, structures, and functionality in the Amethyst API, as well as initializing hooks and executing input callbacks in the Runtime - but I think it should be a cleaner setup to make it clear what exactly everything is.

Most modding platforms such as forge offer an "Event Bus", and I think amethyst should have something similar. From my understanding, Amethyst is supposed to be like Fabric but for Bedrock edition, so having mods initialize their own hooks is reasonable, but I think having a central "Event Bus" system should also be provided to help mod compatibility.

On top of all of this, Hook Manager, Config, Runtime Input Manager are all members of the AmethystRuntime class - why?

Mod functions are a strange concept as well, this is functionality that can be replaced with the event bus idea (with the exception of mod initialization and shutdown, for example).

The solution to this I believe is to have a central AmethystAPI class that contains a map of a type id hash, and a corresponding instance. This would be for quick access to the various API feature singletons, such as Hook Manager. The API is never responsible for creating hooks, but it, in my opinion, should be responsible for managing them.

On top of this, I think there should be a central system for getting the addresses of various symbols and class member offsets. The runtime would be responsible for actually finding these addresses and offsets with the use of signatures. The API can then be written to use these addresses and offsets provided by the Runtime in a central way, allowing for the API itself to be almost versionless in a way. The Runtime would be the only thing that needs to be 'updated', with the exception if Mojang removes a class member or function.

In conclusion, the Runtime itself would be solely responsible for finding functions and offsets. The API would be responsible for managing the results from the Runtime, as well as providing a central means to manage hooks, events, and provide classes, structs and functions for Mods.

Feature Request: blocksource* in CI headers

As I was told CI has a blocksource*, but we don't have it in the headers rn

Would be nice to add it...

It would give access to mods to get blockpos and other instances which could be used with getMapColor or other funcs to interact with the current level/world

Question

This is not an issue but my only way i found to contact i just want to ask if and where there are any mods and/or installation guides for amethyst launcher

Auto-Generated Documentation

Does anyone have any experience with auto generated c++ documentation? It could be nice to get some basic stuff up, things I'm looking for:

  • being able to stick examples in doc comments, I've seen this in visual studio code with some npm libraries. I'm assuming this is possible with visual studio?

  • build to a static site (nice to have, not necessary)

Re-Implement the input system

I have a few paths I potentially want to take the input system, the first is finding a way to listen to key presses directly, although this comes at the trade off of not being rebind-able through the game which is important to me.

The second option is to try and track down where the vector of key-mappings gets stored in the game, so that we can modify it while running, rather than having to rely on the game calling it. My issue with the old input system, was that it was a bit too sketchy, with large chunks of it not working with hot reloading

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.