qad3n/modport

Porte um mod Java do Minecraft (qualquer versão, .jar ou fonte) para o carregador de mods b1.7.3_rewrite como um único arquivo .b173mod que funciona no cliente e no servidor, estendendo o carregador e o SDK onde necessário.

O que é modport?

Esta skill permite que um agente de IA (como Claude Code) realize a portabilidade de mods Java do Minecraft para a plataforma moderna b1.7.3_rewrite, que usa Rust e WebAssembly. Em vez de emular a JVM, a skill converte o mod original em um guest WASM que utiliza a SDK `b173_api`, garantindo a mesma aparência, sensação e jogabilidade dentro do beta 1.7.3. O processo inclui descompilação do .jar, extração de assets, conversão de modelos, reescrita manual de lógica de jogo e testes com servidor e cliente dedicados. A skill oferece um conjunto completo de ferramentas bash e Python, um fluxo de trabalho modular, e suporte para extensão do carregador e SDK. Ela é compatível com Claude Code, Cursor, Codex, e outros agentes que seguem o formato de skill do Claude. O usuário pode simplesmente fornecer um arquivo .jar ou dizer "/modport" para iniciar o processo.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/qad3n/b1.7.3-modport/tree/HEAD/skills/modport

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Portar um mod para o carregador b1.7.3_rewrite

Mods Java não podem executar. Uma porta é uma reescrita em Rust (convidado wasm, SDK b173_api) que usa o mod descompilado como sua especificação. Objetivo: mesma aparência, sensação e jogabilidade dentro do b1.7.3, a partir de um único arquivo em mods/ tanto no cliente quanto no servidor. Corrija bugs de origem e otimize livremente quando a aparência e a jogabilidade permanecerem as mesmas. Nunca substitua uma tela vanilla: UI extra é uma sobreposição alternável.

Este arquivo é o mapa completo. Não leia documentos de design do carregador ou progresso, guias ou arquivos SDK inteiros para se orientar. Use as ferramentas, depois abra apenas o único arquivo de exemplo que a etapa precisa.

Espaço de trabalho

Os caminhos são relativos à raiz do espaço de trabalho, a pasta que contém b1.7.3_rewrite/, ports/ e o repositório do kit b1.7.3_modport/. O install.sh do kit vincula suas ferramentas a tools/modport/ (escrito T/ abaixo) e esta skill a .claude/skills/modport; de dentro de uma pasta de porta, T/ é ../../tools/modport/. Corrija ou estenda ferramentas em b1.7.3_modport/, nunca dentro de uma porta. Em uma máquina nova, ou quando uma ferramenta falha por dependência ausente, execute T/doctor.sh: ele imprime o comando que corrige cada lacuna. Todas as ferramentas são bash: no Windows, são executadas no Git Bash (a ferramenta Bash do Claude Code no Windows) e lidam com .exe, py e caminhos por conta própria. Chame ferramentas Python através de T/py.sh, nunca python3 diretamente.

Modos

Verifique uma vez por sessão: test -f .modport-maintainer na raiz do espaço de trabalho.

  • Modo mantenedor (o marcador existe): os repositórios do carregador, SDK e kit são do próprio usuário. Faça commit e push para eles apenas quando o usuário pedir, conforme os passos abaixo.
  • Modo usuário (sem marcador, o padrão): os repositórios do carregador, SDK e kit pertencem ao seu autor upstream.
    • Extensões do carregador e SDK permanecem na árvore de trabalho local. Nunca as commite nesses repositórios, nunca faça push para seus remotos, nunca execute gh pr create, gh issue create ou qualquer outro comando gh de escrita contra eles, mesmo quando for solicitado a "compartilhar" ou "enviar upstream" uma alteração. Diga ao usuário para fazer isso ele mesmo.
    • Registre cada alteração no carregador ou SDK em ports/<modid>/LOADER_CHANGES.md: o que adiciona, por que, quais arquivos.
    • Informe ao usuário que uma porta que precisa de uma alteração local no carregador executa apenas no carregador modificado deles, não em um carregador padrão.
    • A pasta da porta é o próprio repositório do usuário: faça commit quando solicitado, envie push apenas para um remoto que o usuário configurou.
    • Nunca crie o arquivo de marcador.

Ferramentas

FerramentaUse quandoSaída
T/new_port.sh <modid> <jar> [nome]Iniciando uma porta. Escreve manifestos, git init, descompila em reference/src (Vineflower, baixado e verificado no primeiro uso), executa o inventárioports/<modid>/
T/inventory.sh <src>Listando o que um mod registra: blocos, itens e entidades com classes, tiles, modelos, renderizadores, GUIs, geração de mundo, eventos~15 KB para um mod grande, mantido em reference/inventory.txt
T/api.shAntes de escrever código contra o SDK. sdk <file> (world, register, screen, behavior, events, terrain, config, services), spec <Struct>, enum <Name> (HostCall, EntityField, ModelOp), templates, events, console, hooksuma linha por assinatura com números de linha do SDK
T/py.sh extract_assets.py <jar> <modid>Uma vez, a partir da pasta da porta. Texturas, sons e idioma em assets/<modid>, chaves de idioma mapeadas para tile.<modid>.x.name, item.<modid>.x.name, <modid>.<key>nunca commitado
T/py.sh convert_models.py --out src/models/generated.rs <Model.java>... [--arg Model.scale=0.5]Modelos. Construtores de ModelBase (nomes SRG ou MCP) para partes e caixas. Envolva a chamada no tools/convert_models.sh da portaRust gerado, nunca edite manualmente
T/test.sh deploy ports/<modid> [--game]A cada ciclo de teste. Compila, para o servidor de teste, instala o mod sozinho, inicia o servidor. --game primeiro recompila o jogo e cargo-b173 (após alterações no carregador ou SDK). Recusa enquanto um servidor de teste estiver em execução: outra sessão pode possuí-lo, pergunte antes de --forceconsole do servidor (final)
T/test.sh errors [n]Primeira coisa após qualquer falhalinhas de panic, trap e erro de ambos os logs
T/modtest.sh cmd <linha do console> / log server 80Dirigindo e verificando o servidorapenas linhas de resposta
T/modtest.sh client / shot <png>Apenas verificações visuais. Pergunte ao usuário antes de iniciar um cliente: ele abre uma janela na área de trabalho delesPNG da janela do jogo

Console (T/modtest.sh cmd loader ..., sintaxe de T/api.sh console): gen, map (PNG de cima para baixo), slice (PNG de corte vertical), column (verifique antes de tp: um jogador teletransportado para dentro do terreno sufoca), fill, tp, use, interact, close, entities, summon, slot, tile. Leia PNGs com a ferramenta Read. Coloque cadeias de verificação repetidas em pequenos scripts em ports/<modid>/tools/ em vez de redigitá-los.

Fluxo de trabalho

  1. Configuração. Escolha a versão fonte mais próxima do beta (1.7.10 sobre 1.12 sobre 1.21): seus modelos, texturas e formas de dados mapeiam quase 1:1. Jars 1.7.10 usam nomes SRG (func_, field_): leia o significado pelo uso, não caça mapeamentos. Execute new_port.sh, depois extract_assets.py. Copie classes de modelo vanilla que um modelo de mod estende para reference/vanilla/ para o conversor. Extras de assets específicos da porta (sprites de renderizadores 3D) vão no próprio script tools/ da porta.
  2. Planejamento. Transforme reference/inventory.txt em linhas de TODO do PORT_STATUS.md em ordem de dependência: blocos e itens, receitas, geração de mundo e dimensão, entidades, máquinas e GUIs, estruturas, chefes, sistemas do jogador, slots extras, comportamentos de item, sons e partículas, config. Marcos terminam com um deploy e uma verificação no console.
  3. Porte módulo por módulo. Leia a classe do mod, verifique o SDK com api.sh, copie o padrão de um exemplo. Cite a classe fonte em PORT_STATUS.md, não em comentários de código.
  4. Estenda o carregador apenas quando api.sh não mostrar nenhuma maneira (lista de verificação abaixo).
  5. Teste após cada módulo com deploy, cmd, errors. Mantenha uma lista de bugs em PORT_STATUS.md em vez de repetir um problema; corrija a lista no final.
  6. Finalização. Atualize PORT_STATUS.md. Execute cargo +nightly fmt na porta e cargo clippy em b1.7.3_rewrite. Faça commit apenas quando solicitado: uma porta contém código Rust, ferramentas e manifestos, nunca assets, reference/ ou arquivos de IA. ports/ é ou um repositório git por porta ou um monorepo com uma pasta por mod; new_port.sh detecta qual. No modo usuário, liste as alterações locais do carregador que a porta precisa de LOADER_CHANGES.md no relatório final.

Exemplos

Exemplos do SDK, sempre presentes: b1.7.3_rewrite/vendor/b1.7.3-modding-sdk/examples/ com testmod (cada módulo da API em um arquivo), ruby (apenas conteúdo de dados), energy, energy_api, machines (serviços entre mods).

Uma porta finalizada, quando o espaço de trabalho tem uma, é o mapa mais rápido. A porta do Aether (ports/aether/src):

NecessidadeArquivo
Tabela de blocos, templates, comportamentosblocks.rs (um array de linhas const por tipo)
Itens, ferramentas, armaduras, comida, receitasitems.rs, tools.rs, gear.rs, recipes.rs
Opções de configuraçãoconfig.rs (porte cada rolagem de taxa de spawn, as faltantes inundam o mundo)
Registro de entidades e auxiliaresentities/mod.rs
Mob passivo e montaria, hostil, voador, projétilentities/phyg.rs + mount.rs, cockatrice.rs, zephyr.rs, projectile.rs
Estado de entidade visível no clienteentities/swet.rs, entities/moa.rs (setSynced/synced)
Modelos e animaçãomodels/mod.rs (part, cuboid, Program; copie para uma nova porta)
Chefe, HUD de barra de chefe, tela de diálogoentities/bosses/mod.rs, valkyrie_queen.rs (tela transparent() mais canal serverbound)
Máquina com GUI e dados de tilemachines.rs (ScreenBuilder, #[tile_behavior])
Slots de equipamento extras, camadas de renderizaçãoaccessories.rs (screens().overlay("GuiInventory", ..), playerLayer)
Movimento local do jogadorplayer.rs (lado do cliente em TickPost, estado do servidor em mapas thread_local por id de entidade)
Dimensão, terreno, decoraçãoworld/mod.rs, world/terrain.rs, world/decorate.rs
Estruturasworld/dungeons/mod.rs, writer.rs (terrain::structure::candidates, recorte para StructureBox::populated, comprima alturas de 256 em 128)
Portal e viagemportal.rs

Formas que sempre se aplicam: chamadas GL do renderizador tornam-se operações Program (push, translate, rotate, scale, texture, blend, lighting) em pose da entidade; onLivingUpdate/updateEntityActionState vão para onAi (substitui AI de template) ou onTick; terrain::Random e o ruído das portas mantêm sementes idênticas; verifique isAuthority() antes de mudar o mundo (jogador único loopa pacotes de volta, mesmo código em ambos os lados); valide cada payload serverbound; chat através de translate("<modid>.gui.…"); sons como <modid>.<caminho.com.pontos>; texturas como <modid>:<caminho>.

Formas de dados (API do carregador 1.1, ABI 3). Identidade é sempre por nome, nunca por id numérico:

  • Variantes de bloco e face. Metadados fonte ou block states tornam-se estados nomeados: ctx.blocks().states(nome, BlockStatesSpec) ou data/<modid>/states/<bloco>.toml.

    • Liste os valores de cada propriedade na ordem dos metadados fonte, para que o código ctx.meta() continue funcionando.
    • Um bloco com mais de 16 estados recebe ids ocultos extras do carregador. Leia e escreva tal bloco apenas através de world.blockState/setBlockState ou ctx.state()/setState().
    • Texturas por estado vão em variants.
  • Dados por pilha. NBT de item e capacidades tornam-se componentes de dados: stackComponent/setStackComponent com um StackRef.

    • Um mod escreve apenas componentes <modid>:*.
    • Pilhas com componentes diferentes nunca se mesclam.
    • Dano permanece durabilidade. Use um item por variante em vez de subtipos de dano.
  • Dados em coisas que o mod não possui. NBT ou capacidades de entidade, jogador, tile, chunk e mundo tornam-se slots por mod:

    • entidade: entity.setData ou setSynced
    • jogador: player.setData(key, ..)
    • entidade de tile: world.setTileAttachment
    • chunk: world.setChunkAttachment
    • mundo: setWorldData

    Cada slot é chaveado pelo id do mod, assim dois mods nunca colidem.

  • Edições em conteúdo vanilla ou de outros mods. Edições de propriedade (dureza, luz, inflamabilidade, ferramenta) tornam-se ctx.blocks().modify(BlockModifySpec) ou data/<modid>/modify/blocks/*.toml. Edições de lista de spawn tornam-se modifySpawns ou modify/spawns/*.toml. Velocidade de mineração para uma classe de ferramenta vem das tags minecraft:mineable/<pickaxe|axe|shovel>. Edições conflitantes são relatadas na tela do Mod Loader. Nunca substitua um bloco vanilla inteiro para uma mudança de propriedade.

  • Geração de mundo e comandos.

    • Nomeie cada recurso de geração de mundo unicamente. O nome sementeia seu aleatório, então outros mods nunca o deslocam.
    • Comandos respondem a /<modid>:<nome>. O curto /<nome> vai para o primeiro mod que o registra.

Estendendo o carregador

Apenas recursos gerais, nunca um hack de um mod. Caminhos abaixo estão dentro de b1.7.3_rewrite/. Pontos de toque, em ordem:

  1. Protocolo: acrescente variantes no final de HostCall, GuestCall, GuestReply ou EntityField em vendor/b1.7.3-modding-sdk/mod_protocol/src/abi.rs; novos campos de especificação em spec.rs como tipos Option ou Default (structs de especificação são #[serde(default)], então mods antigos ainda carregam). Contratos lançados nunca mudam: um contrato alterado ganha uma nova versão.
  2. Host: braço de match em crates/modloader/src/host/world.rs (chamadas de tempo de execução) ou host/register.rs (fase de registro); sistemas maiores em seus próprios crates/modloader/src/<sistema>.rs ou extensions.rs. Novos templates são linhas em crates/modloader/src/entities.rs (ENTITY_TEMPLATES) ou content/templates.rs (BLOCK_TEMPLATES).
  3. Wrapper do SDK ao lado de seus irmãos em b173_api/src/{world,register,screen}.rs, no prelude se mods o usam em todos os lugares.
  4. Lado do cliente em crates/client/src/modded/. Código vanilla chama novo comportamento através de um hook de uma linha com um comentário // rewrite:, listado com uma versão em crates/modloader/hooks.toml.
  5. Ferramentas do console de desenvolvedor em crates/modloader/src/devtools.rs (adicione a USAGE).
  6. cargo build e cargo clippy, depois T/test.sh deploy ports/<modid> --game. Anote a adição onde o espaço de trabalho mantém notas do carregador. Modo mantenedor: mudanças no SDK são commitadas no submódulo do SDK, depois incrementadas na reescrita, apenas quando o usuário pedir. Modo usuário: nada é commitado lá, a mudança vai em LOADER_CHANGES.md.

Exemplo de cadeia, World::lightning: HostCall::Lightning (abi.rs) para seu braço em host/world.rs para o wrapper em b173_api/src/world.rs.

Armadilhas conhecidas

  • HostCall, HostReply e structs de especificação são codificados em postcard. Nunca adicione um campo a uma struct existente: convidados ABI 2 parariam de decodificar. Novos dados precisam de uma nova variante ou uma nova struct.

  • T/modtest.sh dirige um servidor e cliente de teste compartilhados (b1.7.3_rewrite/target/modtest, servidor em seu server/). Nunca pare, reinicie ou assuma outra sessão que outra tenha iniciado sem perguntar ao usuário.

  • cargo b173 build já executa a compilação wasm; não há uma etapa cargo build separada.

  • Mudança no carregador ou SDK sem deploy --game: o servidor ainda executa o binário antigo sem as novas chamadas de host.

  • A janela do cliente de teste perde o foco e abre o menu de pausa; é o harness, não a porta.

Habilidades Relacionadas