Porting a Fabric mod by hand
Status: Implemented as a mapping to the API that exists; rows marked planned name CLight features that aren’t in the game yet.
Celestial does not run, convert or translate Fabric or Quilt mods, and there is no conversion tool. This guide maps Fabric concepts to CLight so you can rewrite your own mod. Read Porting existing mods to CLight: overview first.
Fabric mods are often small, data-heavy and mixin-based: the data carries over as-is, and many mixins map to an event, a behaviour or a CLight mixin.
Project and metadata
| Fabric | CLight |
|---|---|
fabric.mod.json |
clight.mod.json (Writing the manifest) |
id, version |
id (keep it: it’s your namespace), version (SemVer) |
environment: *, client, server |
side: both, client, server; plus sync |
entrypoints.main / client / server |
One entry point; lifecycle.common_setup, client_setup, server_setup |
depends, recommends, breaks |
depends, optional, breaks |
mixins config files |
"mixins" in clight.mod.json or cl.mixin.inject / CL_MIXIN, on named game targets |
accessWidener |
CLight accessors where the game has them |
| Gradle + Loom | clight build (C/C++), nothing (Lua) |
src/main/resources/assets, data |
assets/<ns>/, datapack/<ns>/ |
runClient |
clight run |
Entry points and lifecycle
| Fabric | CLight |
|---|---|
ModInitializer.onInitialize |
The entry point (subscriptions, mixins) plus lifecycle.register for content |
ClientModInitializer.onInitializeClient |
lifecycle.client_setup |
DedicatedServerModInitializer |
lifecycle.server_setup |
| Server lifecycle events | lifecycle.server_starting, server_started, server_stopping, server_stopped |
| World load and unload | lifecycle.level_load, level_unload |
| Data pack reload | lifecycle.data_reloaded |
Registration happens only during lifecycle.register.
Registration
| Fabric | CLight |
|---|---|
Registry.register(Registries.BLOCK, ...) |
cl_block_register / cl.blocks.register{...} (vanilla-backed) |
Block settings (strength, sounds, luminance, slipperiness, velocityMultiplier, jumpVelocityMultiplier) |
destroy_time, sound_type, light_emission, friction, speed_factor, jump_factor; shape and tool from the base block |
A Block subclass with overridden methods |
A behaviour table: use_without_item, attack, random_tick (more entries planned) |
| Block states and properties | planned (one state per block today) |
BlockItem |
item in the block descriptor |
Item settings (maxCount) |
max_stack_size; other components come from the base item (components from code planned) |
| Item use | cl_item_behavior.use |
| Item groups | creative_tab on the item (a vanilla tab; the item goes after the vanilla items). Custom tabs planned |
BlockEntityType, EntityType, ScreenHandlerType, SoundEvent, ParticleType, data components |
planned (sounds work through sounds.json; menus through vanilla chest menus) |
Events (callbacks)
| Fabric callback (concept) | CLight |
|---|---|
| Server / world / client tick | tick.server_pre/post, tick.level_pre/post, tick.client_pre/post |
| Use block | player.interact_block, or your block’s use_without_item |
| Use item | player.interact_item, or your item’s use |
| Attack entity | player.attack_entity |
| Player block break | block.break (cancellable; xp, drop_items mutable) |
| Block place | block.place |
| Join / disconnect | player.join, player.leave |
| After respawn | player.respawn |
| Living damage, death | entity.damage (amount mutable), entity.death |
| Command registration | server.command_register |
| Chat | player.chat, client.chat_received, client.chat_send |
| HUD render callback | cl_hud_layer_register |
| Screen open | client.screen_open |
| Loot table modification, tooltip callback, world render events | planned |
The full list: Complete event list.
Mixins
Ask what each mixin changes, then use the table in Porting existing mods to CLight: overview. Many become an event with cancel or a mutable field; the rest become CLight mixins on the game’s named targets (head, return, value, call, wrap, overwrite), which compose by priority.
Networking
| Fabric | CLight |
|---|---|
| Custom payload types + registry | cl_payload_register (an id, a direction, byte buffers) |
| Send to a player / to the server | cl_net_send_to_player, cl_net_send_to_server |
| Receivers | The handler runs on the receiving side’s tick |
| Send to players tracking an entity, “can send” checks, configuration tasks | planned |
Client side
| Fabric | CLight |
|---|---|
| Block render layer map | From the base block today (render_layer is stored) |
| Key binding helper | cl_keybind_register (in Controls, rebindable) |
| Screens | cl_screen_open with vanilla widgets, or RmlUi documents |
| HUD | cl_hud_layer_register |
| Colour providers, entity and block entity renderers, particle factories, baked models | planned |
Data and config
| Fabric | CLight |
|---|---|
| Data attachments, persistent state | typed attachments (cl.attachment, cl_attachment_register) and saved data; files in data/ through cl.fs / cl_fs_* |
| Config libraries + Mod Menu | cl_config_define_* and the Mods screen’s Config page |
| Biome modifications, custom features | planned; data-pack worldgen JSON for vanilla features |
Common conventions
- The shared
c:tag namespace works the same way; keep using it. - Keep your lang keys (
item.<ns>.<path>,block.<ns>.<path>).
A porting example, in words
A Fabric mod “Gem Shop” has: a gem item, a shop block that opens a chest GUI, a /gems command, a HUD counter and a config.
- Copy
assets/intoassets/gem_shop/and the data intodatapack/gem_shop/. - Register the gem item (base
minecraft:emerald) and the shop block (baseminecraft:barrel) inlifecycle.register. - The shop block’s
use_without_itemopens a locked chest menu withcl_menu_open; clicks take and give items (A shop block (block + menu)). /gemsbecomes a command tree (A command with arguments and permissions); the HUD counter a HUD layer that counts on the client tick.- The config becomes
cl.config.open("common")with the Config page in the Mods screen. side: both,sync: optional: vanilla clients see a barrel and an emerald, and the shop still works for them.