#how to prevent spagetti code

1 messages Β· Page 1 of 1 (latest)

dry ospreyBOT
#

<@&987246399047479336> please have a look, thanks.

#

Here is an AI assisted attempt to answer your question πŸ€–. Maybe it helps! In any case, a human is on the way πŸ‘. To continue talking to the AI, you can use </chatgpt:1108714622413963314>.

#
TJ-Bot
I have a big minecraft plugin for my custom minecraft server but the structure is really bad

To prevent spaghetti code, especially in a large Minecraft plugin, focus on clean architecture and code organization:

  1. Modularize Your Code: Break down your plugin into smaller, well-defined classes and packages. Each class should have a single responsibility (Single Responsibility Principle).

  2. Use Design Patterns: Patterns like Command (for handling commands), Listener (for events), and Factory (for object creation) can give structure.

  3. Separate Concerns: Keep your game logic, data management, and command handling in separate layers.

  4. Consistent Naming & Conventions: Follow consistent naming conventions to make your code easier to navigate.

  5. Avoid Large Methods: Refactor long methods into smaller ones that perform one specific task.

  6. Use Interfaces and Abstractions: This helps make your code more flexible and testable.

  7. Documentation and Comments: Maintain clear comments, and consider adding a README or architecture overview.

Remember, refactoring incrementally works best for large existing projects. Analyze the parts that cause the most confusion or bugs first.


Useful links:

waxen gull
#

How can i structure the project better

quiet zenith
#

have you got static variable + methods

#

remove them all

waxen gull
#

not really tbh

#

but i just have a lot of classes and packages in packages

#

cuz the project is getting really big

quiet zenith
#

how big is big?

#

200 file?

waxen gull
#

hmm idk

quiet zenith
#

just don't do more deep than 3 package deep

waxen gull
#

something arround 100 i think

quiet zenith
#

can you say why you think it is spagetti?

#

are you getting lost?

waxen gull
#

yes

#

i gotta use classes from a lot of places for 1 script

quiet zenith
#

make your classes do 1 thing with a small surface interface

waxen gull
#

my main class is a mess

#

300 lines for only initialising stuff

waxen gull
#

i think i understand what it does but not the use case for it yet

quiet zenith
#

do you have it public?

#

your code?

waxen gull
#

no not really

#

i vibe coded a lot too

#

but i started learning how to code more

#

and i wanna stop

#

the code is old tbh

#

cuz the project i made was old and since then i learned al ot

#

i wanna start all over again

quiet zenith
#

ok, well keep it all for now

#

but start from 0 in another module

waxen gull
#

the code has al ot of bugs too and i can do it a lot better now

quiet zenith
#

spigot plugin?

waxen gull
#

paper plugin ig

#

wait i haven't clicked this so i dont think so

quiet zenith
#

ok

waxen gull
#

but i use some paper import things

quiet zenith
#

what dod you have right now?

waxen gull
#

and some other htings

#

but those are the biggest things ig

waxen gull
quiet zenith
#

your main plugin should look like this

@NullMarked
public class MainPlugin extends JavaPlugin {
  public void registerCommands(ReloadableRegistrarEvent<Commands> commands) {
    commands.registrar().register(FlySpeedCommand.build(this));
    commands.registrar().register(BuildCommand.build(this));
  }

  @Override
  public void onEnable() {
    var manager = Bukkit.getPluginManager();
    for (var event : eventsToRegister()) {
      manager.registerEvents(event, this);
    }
    this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, this::registerCommands);
  }

  private List<Listener> eventsToRegister() {
    List<Listener> events = new ArrayList<>(7);
    events.add(new PlayerJoined(this));
    events.add(new ServerListPing(this));
    events.add(AsyncPlayerChat.configured(this));
    events.add(new PlayerDeathAndRespawn(this));
    events.add(new PlayerFish(this));
    events.add(new PlayerAutoRegen(this));
    events.add(new RemoveCreeper(this));
    return events;
  }
}
#

just a simple place to link it all

lyric spade
#

how to prevent spagetti code
experience

#

theres no magic formula to it

#

its what differentiates the junior from the senior

#

its pure experience

waxen gull
#

for example listeners

#

etc

lyric spade
#

the more u code, the more u know how to code something in a particular situation in the best way, so to speak

quiet zenith
#
public record ServerListPing(JavaPlugin plugin) implements Listener {
  public ServerListPing {
    plugin.getLogger().info("ServerListPing");
  }

  @EventHandler
  public void onEvent(PaperServerListPingEvent event) {
    int numPlayer = Math.max(event.getNumPlayers(), 0);
    event.setNumPlayers(numPlayer);
    event.setMaxPlayers(100);
    event.motd(Component.text("Β§aWelcome to the server!"));
  }
}

example listener

waxen gull
dry ospreyBOT
waxen gull
#

but i got a lot more experience now

quiet zenith
#

many feature require multiple listeners to make work

waxen gull
#

would you recommend to make a lot of small plugins or 1 big one

#

cuz the code is seperated then but at the same time i need to manage multiple build.gradles

#

and i can't access the classes as easy

quiet zenith
#

I just make module with each feature

#

then make a module in which I include all feature I need

waxen gull
#

i dont really know what a module is yet

#

let me search it up

waxen gull
#

i had multiple listeners for that too

quiet zenith
#

different class for each part of the system

#

then just plug them all in the register

waxen gull
#

okay i had a gui system in my old plugin and a lot of classes needed it cuz i could make really ez guis with it i should make a package for that too right?

quiet zenith
#

events.addAll(Atm.listeners(this));

#

something like this

#

Then I would just add it all in it

quiet zenith
#

group it

#

and make it 1 thing

#

then make small method that take max 3-4 parameters and give you a gui all built

#

some factory methods

#

the goal is to only use these factory methods elsewhere in other package

waxen gull
#

huh i see a really weird system now too my plugin extended the gui class 😭

quiet zenith
#

it become your public api in the rest of the code

waxen gull
quiet zenith
#

I dunno, you are talking about minecraft internal gui?

#

the one with buttons

waxen gull
#

it is basically a chest

#

wait i can send a screen

quiet zenith
#

wow, this look complicated a lot xD

#

you know dialogs exist?

waxen gull
#

no im not using dialog

quiet zenith
#

ok

waxen gull
#

i showed this without the resourecpack

#

so u know what i mean now

quiet zenith
#

yeah I get it

waxen gull
#

i extended safegui (the system)

safegui removes your inv when you open it

#

and restores it when you close it

quiet zenith
#

so it use a plugin?

waxen gull
#

it uses my own

#

and itemsadder

quiet zenith
#

ok

waxen gull
#

this is with the resourcepack

#

prob gonna change the textures etc

#

😭

quiet zenith
#

nice

waxen gull
#

looks a bit fat now

waxen gull
#

so the system is good but isn't it weird that it extends a class? to make the gui

#

i prob should use parameters right?

#

or not idk

#

😭

#

im confused

quiet zenith
#

peepo_shrug not really

waxen gull
#

it is a bit early too first thing i went to do is made this qusetion

quiet zenith
#

it is a choice

waxen gull
#

okay

#

yea okay i realise minecraft extends Screen too for screens (this is mc modding tho)

#

so that isn't smth weird to do

#

okay i prob just gotta go start with it

#

gotta go eat first

#

okay im done eating

#

one small question now 😭

#

i first wanna make the atm

#

should i just make a package called GUI then

quiet zenith
#

sure

waxen gull
#

and put there the gui class in?

#

and do you recommend a lot of small plugins and then an api

#

or 1 big one

quiet zenith
#

1 big one that you setup as you want if the plugin is just for your server

#

if it is for others, lots of small one with configuration

waxen gull
#

it is 1 big one

#

but im planning on that it's gonna be a really big server

#

with a big plugin

quiet zenith
#

but just for you?

waxen gull
#

other people will join

quiet zenith
#

I mean just for 1 server

#

yours

waxen gull
#

yea

quiet zenith
#

1 big is good

waxen gull
#

alr πŸ˜„

#

are a few static variables bad?

quiet zenith
#

yes

waxen gull
#

for the main class too?

#

cuz there is only 1 main class

quiet zenith
#

it point to spaghetti

waxen gull
#

im not really gonna turn it into a object

quiet zenith
#

yes

waxen gull
quiet zenith
#

you never need them

waxen gull
#

true

quiet zenith
#

the problem with static attributes is that it is like a cheat code when you start programming.
but it is a lie.
it is like glue
it make it impossible later to change anything.

waxen gull
#

but it isn't always bad right

#

otherwise it wouldn't be a thing 😭

quiet zenith
#

in my mind it is an error xD

#

it take memory when not needed

waxen gull
#

i made a voicechanger mod for simplevoicechat

#

i used static there

#

it was fine ig

#
package dev.griekseei.simplevoicechanger.config;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.fabricmc.loader.api.FabricLoader;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Config {
    public static final Config CONFIG = new Config();
    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
    public static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("simplevoicechanger.json");

    public boolean enabled = true;
    public float pitchAmount = 1.0f;

    public static void load() {
        if (Files.exists(Config.CONFIG_PATH)) {
            try {
                String json = Files.readString(CONFIG_PATH);
                Config loaded = GSON.fromJson(json, Config.class);

                CONFIG.enabled = loaded.enabled;
                CONFIG.pitchAmount = loaded.pitchAmount;
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    public static void save() {
        try {
            String json = GSON.toJson(CONFIG);
            Files.writeString(CONFIG_PATH, json);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}
dry ospreyBOT
# waxen gull ``` package dev.griekseei.simplevoicechanger.config; import com.google.gson.Gso...

Detected code, here are some useful tools:

Formatted code
package dev.griekseei.simplevoicechanger.config;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.fabricmc.loader.api.FabricLoader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Config {
  public static final Config CONFIG = new Config();
  private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
  public static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("simplevoicechanger.json");
  public boolean enabled = true;
  public float pitchAmount = 1.0f;
  public static void load() {
    if (Files.exists(Config.CONFIG_PATH)) {
      try {
        String json = Files.readString(CONFIG_PATH);
        Config loaded = GSON.fromJson(json, Config.class );
        CONFIG.enabled = loaded.enabled;
        CONFIG.pitchAmount = loaded.pitchAmount;
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  public static void save() {
    try {
      String json = GSON.toJson(CONFIG);
      Files.writeString(CONFIG_PATH, json);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
quiet zenith
#

it never get cleaned

#

do you put GSON like this in all class?

waxen gull
#

was a really small mod

#

but getting the values was really ez Config.CONFIG.pitchAmount

quiet zenith
#

just create it when needed.

quiet zenith
waxen gull
#

so why would i need multiple objects

quiet zenith
#

it make the rest of the code structure not flow

#

as you used a magic portal

waxen gull
#

so yall never use static?

quiet zenith
waxen gull
#

then

#

if it isn't static

quiet zenith
#

well give them?

#

or make the structure public

#

save(Gson gson)

#

or make the save not in the config class

waxen gull
waxen gull
quiet zenith
waxen gull
#

πŸ™

quiet zenith
#

you could just have another class that save/load config class/other class

waxen gull
#

yea ig it could be seperate but it wasn't relaly an issue tbh