-
Notifications
You must be signed in to change notification settings - Fork 8
Adding Custom Objects to Ahorn
Ahorn is a visual level maker and editor for Celeste, based on the
Maple wrapper for celeste, written in Julia.
This tutorial will explain how to integrate your custom Entities and Triggers with Ahorn, in order to access and place them from within the editor.
Every distinct entity or trigger that you want to add to Ahorn needs to be defined in a .jl
Julia language file within the Ahorn
subfolder of your mod folder.
Within the Ahorn
folder, entities must be placed in an entities
folder, and triggers in triggers
. Additionally, a lang
folder can be used to provide tooltips for various options.
Every .jl
file needs to start with the following code:
module YourModule
using ..Ahorn, Maple
This, similarly to C#, defines a "namespace" for your entity/trigger, and imports the Ahorn and Maple libraries for use.
Defining a custom entity or trigger for ahorn will always look similar to the following:
@mapdef Entity "YourMod/YourEntity" YourEntity(x::Integer, y::Integer,
attr1::String="default1, attr2::String="default2")
or
@mapdef Trigger "YourMod/YourTrigger" YourTrigger(x::Integer, y::Integer,
width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight)
The string (in quotes) should be the name of your Custom Entity.
The Entity/Trigger constructor can take any number of arguments, which are then accessible from the EntityData object that is passed to your C# object's constructor. Depending on the Type of the argument, it will automatically be displayed in the configuration panel for your entity/trigger within Ahorn.
Ahorn gets any placeable entities and triggers from the placements
constant; an Ahorn.PlacementDict
, which is a series of String
=>Ahorn.EntityPlacement
pairs.
The String
is what will show up in the Ahorn selection menu, and the EntityPlacement
is a struct containing the information on the entity/trigger.
An EntityPlacement
struct can be created using the Ahorn.EntityPlacement
function, which takes four arguments:
# Required
func::Union{Function, Type},
# Optional
placement::String,
data::Dict{String, Any},
finalizer::Union{Function, Nothing}
func
in most cases will be YourEntity/YourTrigger, and placement
will be one of "point"(default), "rectangle", or "line", depending on which best suits your needs.
data
allows for placement-specific attributes to be added to the EntityData,
and finalizer
allows for adding a function that is run only when the entity is placed, or the preview is updated.
Ex:
const placements = Ahorn.PlacementDict(
"Your Entity (AhornDemo)" => Ahorn.EntityPlacement(
YourEntity,
"point",
Dict{String, Any}(
"attr1" => "foo"
),
function(entity)
entity.data["attr2"] = "bar"
end
)
)
Providing additional information to Ahorn on the placement of your entity can be done by overriding the Ahorn.selection
function.
This function recieves the selected entity, and can be used to return an Ahorn.Rectangle that will be used to draw the selection.
Ex:
function Ahorn.selection(entity::YourEntity)
x, y = Ahorn.position(entity)
width = 10
height = 10
return Ahorn.Rectangle(x, y, width, height)
end
Other functions that can be overridden to affect the placement of your entity include Ahorn.minimumSize
and Ahorn.resizable
.
The main way to set how your entity is displayed within Ahorn is by overriding the Ahorn.render
function.
This allows you to draw sprites, rectangles, lines, and other graphics through the
Cairo graphics library for julia.
Examples:
sprite = "collectables/strawberry/normal00"
Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::YourEntity, room::Maple.Room) = Ahorn.drawSprite(ctx, sprite, 0,0)
function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::YourEntity, room::Maple.Room)
x = Int(get(entity.data, "x", 0))
y = Int(get(entity.data, "y", 0))
width = Int(get(entity.data, "width", 32))
height = Int(get(entity.data, "height", 32))
Ahorn.drawRectangle(ctx, 0, 0, width, height)
end
A .zip file containing all graphics currently in the base game can be found here.
module YourModule
using ..Ahorn, Maple
@mapdef Entity "YourMod/YourEntity" YourEntity(x::Integer, y::Integer)
const placements = Ahorn.PlacementDict(
"Your Entity (AhornDemo)" => Ahorn.EntityPlacement(
YourEntity
)
)
Many more examples of various custom Entity and Trigger files can be found in the Sprint Collab 2020 repo.
For questions and feedback, please contact @coloursofnoise on the Celeste Discord.
Home
Contributing
FAQ
Useful Links
Your First Custom Map
Your First Texture Pack
Mod Setup
Custom Maps
Texture Packs
Uploading Mods
Generated Dialog Keys
Reference Code Mod🔗
Vanilla Audio IDs
Vanilla Decal Registry Reference
Character Portraits
Mod Structure
Debug Mode
Debug Map
Command Line Arguments
Environment Variables
Install Issues
Common Crashes
Latency Guide
everest.yaml Setup
Mapping FAQ
Map Metadata
Vanilla Metadata Reference
Adding Custom Dialogue
Overworld Customisation
Entity & Trigger Documentation
Custom Entity List🔗
Camera
Ahorn Scripts
Custom Tilesets
Tileset Format Reference
Stylegrounds
Reskinning Entities
Skinmods
Decal Registry
Chapter Complete Screen
Custom Portraits
Adding Custom Audio
Advanced Custom Audio
Code Mod Setup
Making Code Mods
Settings, SaveData and Session
Everest Events
Understanding Input
Logging
Cross-Mod Functionality
Recommended Practices
Core Migration Guide
Lönn Integration🔗
Custom Events
Adding Sprites
Adding Preexisting Audio