Castagne Engine

The Open Source Fighting Game Framework

Forum - Discord - Youtube

April 2026

(2026-04-16) Start of Camera and Motion Inputs

Small update because I just wanted to improve a bit on yesterday’s screenshot.

Castagne now also sends the camera information to the editor! This means that the EdSpec viewer now has everything needed to show cool stuff. I’ll add more to it over time, but for now it’s really competent! Also look at the improved trace:

Screenshot

I’ve also started the motion input system. At the moment, the only motion is a single direction, but that’s a start! The system itself is halfway implemented: it can parse simple motion inputs and match them in the input history, but at the moment it’s not hooked to anything. The next step is going to be the Input Transition system, and hooking it back up to it.

(2026-04-15) EdSpec Trace, FG Movement

Yo, managed to get regular fighting game movement back into the engine, it’s cool

Look I made so it also leaves a trace in the EdSpec viewer, gonna have to hook up the camera to it too later

Screenshot

Looks smart and technological therefore the new editor is a million times more advanced

Still writing the base gameplay but better, got some time before all mechanics are online but we’ll see

(2026-04-13) Elseif, Static Strings, Before Event

I’m not sharing much these days since a lot of my improvements are editor-side and unfinished, but I did progress enough to start writing gameplay! And while I’m doing that, I’ve been adding some features. I’ve bundled enough of these in this post to share.

First off: we got some nice syntaxic sugar with handling of else if! It makes some code a lot nicer to read:

I Down:
	V MOVEMENT_StandToCrouch_Time:
		Transition(StandToCrouch)
	else
		Transition(Crouching)
	endif
else I Forward:
	Transition(WalkF)
else I Back:
	Transition(WalkB)
endif

I would have needed a whole more endifs and indentation to write that. You might also have noticed the space between the branch and the condition. It was already working due to how I’ve implemented the lexer, but now that I’ve noticed it I quite like it! The space is optional, but I recommend using it unless it’s something with just a number like F10+:, which also btw now works but it’s not exactly new lol.

Secondly, strings! We already had them in the old Castagne, but this one is different: they are all static, meaning they don’t get changed during execution. This ensures fast speed, as passing a static string is as fast as passing a regular value. This was already in the engine as I’ve been using it for all the Target.Variable stuff, but it’s now available as a proper type. I wanted to delay this implementation to avoid using strings as a crutch instead of more relevant semantic types, but it’s now done and I need stuff like file paths to work.

Finally, I’ve added a new event: Before, which executes at the start of the main phase. This is because I noticed a design flaw during a discussion about engine internals: since I only transition the state at the END of a tick, if you press a button, you’ll only start the attack on the next frame. This effectively adds one frame of input lag. This can be avoided with some tricks that are a bit complex in some cases, but not all. By making an event that allows transition, I can do an early check much more simply, and make many actions have less lag. I don’t think it’s going to be on the mind of most users. Here’s the main phase flow now:

  • Before Event fires, and some of the input and transitions are handled directly.
  • Early state transition, which can fire Exit and Enter. No sync point here, so it stays fast.
  • Action Phase is executed, you do your actions.
  • Sync point between the entities. No transition here.
  • After Event is fired.

This makes the main phase a bit complex now, but I hope this ends up being manageable. We will see. In any case, there’s now less input lag so that’s good!

I’m still working on a lot of stuff at the same time, I will post other updates when I feel they show enough what I’m going for.

(2026-04-07) Game Link Improved

Little update: the game link feature of the editor, which connects to a separate game process, is now much more robust. I’ve done that by fixing two things:

  • Skill issue on my part, where I forgot that streams are not cut automatically. This led to “packet drop” by virtue of the algorithm thinking it was getting weird packets.
  • Speed mismatch between the game process and the editor. Funnily enough, this was an issue on the local side, as I’ve added the local test option without thinking and it was ticking at a much faster rate.

So now, it’s working as expected, at a stable framerate. As always, you can always run it directly. Very nice.

My eyes have been blessed with high framerate, which is nice, but for now I’ll keep the engine at 60 ticks per second. I might add high FPS later, but raising the physics rate itself will destroy online quality, as making it twice as fast requires the computer to be four times faster for the same result, so it would cut a large portion of the player base.

(2026-04-06) State Call Defaults

Today, I’m making updates for me. That’s right, it’s the castagne dev experience update, but CASP-side this time.

You know how sometimes you want to make a part of a state easily extensible? Like how I like having WalkF and WalkF-Movement so that you can completely change the movement if you don’t like it? It’s great for the end user, however it’s always annoying to set up: I need to create several states. That’s partially why I added hooks, so that I can “add” these without really doing work, with a simple WalkF-Anim? for example. The issue is that they don’t do anything, therefore if I want to have behavior you can change as opposed to behavior you can add, I still need to go through that process. Introducing:

!WalkF-Movement:
	Move(1000)
endif

As you might expect, it’s just like a hook, except if the hook doesn’t exist it will call on the interior code! That allows these elements to be MUCH cleaner, as all the behavior is in the same state. These have got two particularities:

  • You can’t use arguments. If you want arguments, you need to define them and therefore should add them to an actual proper state.
  • Call Parent works, HOWEVER it is a tricky one: the parent will ONLY exist for that specific state that calls the default. This means the same function could compile to different code, and that !!? is mandatory. Good enough imo, it’s added as the base parent so overriding the hooked state works as usual, it’s just a tricky integration that most likely won’t come up unless you start calling on hooks from several states or have several defaults.

Another update is that, since the Castagne base files are now embedded inside of the binary, well you can’t really change them. This instantly makes the lock feature of the old editor unneeded since you can’t change it, but that means that I as a dev can’t do that either, which is annoying for development. I’ve therefore added an option where you can give the path to Castagne’s source to load these dynamically!

These updates mostly affect me since I’m the one writing the base CASP files lol. I am making my work environment better so that I can do better work, and I wish to thank me for taking the time to add one of my requested features.

(2026-04-04) Gizmos!

Heyo! I’ve been working in the editor these days, but never had time to share. I’m writing a quick post to share some screenshots.

First off, I’ve advanced enough on the EdSpec compilation and handling to properly handle functions! Every function has its own EdSpec it can add internally, that is different from the one you can attach in the editor.

There’s also handling of colors through a system, and several options out of the box for Gizmos, including lines with caps and boxes with different styles. You can specify boxes in different ways, which match the way hitbox vs hurtbox are handled. In the screenshot below, you can see how Move() now adds an arrow, with a notch. The notch shows one frame, the arrow shows 10, in order to visualise the movement. Boxes show the box where it is.

Screenshot

Additionally, I’m working on the UI bit by bit. A lot of it is temporary with big buttons that don’t do anything but take place for future functionality, but here’s the file selection! As you can see there’s a good few more than usual, and it’s gonna get bigger. The rest of the window will help keep track.

Screenshot

There’s still some work to be done editor wise before I can get properly started on the mechmods and base CASP, mostly how to link to the actual Castagne project, and a fair bit of in engine stuff. Stay tuned!

March 2026

(2026-03-31) Introducing EdSpec!

Hey! So I’ve mentioned the EdSpec (which I’ve just renamed from ‘VarSpec’ if you’ve read the previous updates) system a few times, but what is it? Put simply, it’s a refined version of Castagne’s Gizmo, SpecBlocks, and Custom Editors, all put together as a single interface.

At it’s core, it’s a second language right inside of Castagne Script. Don’t worry, most users don’t need to learn it, and it doesn’t affect gameplay in any way, it only talks to the editor (hence the name, EDitor SPECifications.). It’s also way more forgiving, as it always tries to work and doesn’t crash (although you might get funky results). Its main objective is to make character creation in Castagne extremely efficient and fast. Here’s a quick example:

> GLine [0,20000,0] [20000,0,0]

This command, Gizmo Line, will draw a line on-screen at those game coordinates. This is the most basic usecase. A new feature in the editor is that these gizmos can now be drawn on a separate grid, even when the game is not running. Take a look!

Screenshot

As you can see, the grid is centered at your character, along with a preview of your ColBox. When the game is not running, information available is more limited, but this might also make it more clear. This is something I wish to expand upon in the future, but at the moment it’s already quite agreeable. The mouse is also tracked, which is a slight hint about future abilities ;)

I’ve got a LOT to say on EdSpec, but after writing a very long post yesterday (which I didn’t post), I figured it’s one of those cases where it would be way too much info at once, and actually seeing it will have more impact. So, expect little EdSpec updates bit by bit! What I can say however, is that this is the star of the new version, it put a lot of constraints on the compiler but I sincerely believe it will be worth it. The most impressive features are still on the way!

Also, I noticed just before posting I left some other hints about parts that got implemented in the screenshot. Consider that a bonus preview lol

(2026-03-29) Editor CodeView

Hey! I’ve been restarting work on the editor, and the first job is just a straight quality of life update:

Screenshot

As you can see, there’s now syntax highlighting for Castagne Script itself! The previous one was just coasting off its similarity to GDScript, but this one actually uses the Castagne Script syntax. I didn’t do much, that’s thanks to the Godot team’s efforts mostly, I just told it a couple symbols. Still, that’s a great improvement.

The second one you can see is that the Documentation panel looks a bit different. While that is still a WIP, this one actually adapts to the type of line you’ve selected, with the interface being able to change in the future. Since it doesn’t just read functions anymore, it will be very helpful for beginners as it can remind you what basic elements do, and in general its ability to display more info will be helpful.

Stealth addition that will pay dividends, but the docs here isn’t isolated: there is now a proper Documentation system in the editor, and the panel reflects its contents. This means there is now a centralized location for the docs in-engine, which can be exported on the website. It works off with internal paths, so you can refer to a concept immediately, such as language/branch/input will give you all the detail you need on input branches. This ensures the static part of the documentation is referred properly, and will allow an up-to-date version on the website.

My next editor step is the navigation panel, although the VarSpec system is another key implementation I’ll need to do sooner than later. The roadmap here is a bit less defined, as the editor is still in flux and there are a LOT of systems to make work together.

(2026-03-28) Walking is now optional, but Standing is not (MechMods!)

This one is one of the more user-facing additions: MechMods! I’ve finally added the multiple file inheritance. The compiler-side was working, but it wasn’t yet searching for files by itself. ‘Bit more robust than before too. So, what is the general order of files?

  1. Base CASP: These are fundamental files that are included with their specific module. These are mandatory, and define some key concepts for the engine.
  2. MechMods (Mechanics Modules) !NEW!: These are optional files that define game mechanics. You can enable and disable them as you wish from the editor.
  3. Common Skeleton: This is a file YOU make that holds all your common behavior, such as system mechanics.
  4. Fighter: This is the character you make! It holds all your character specific behavior.

The common skeleton and fighter are self-explanatory and were already present before. The difference is in the Base CASP and MechMods, which solve an organizational problem much more elegantly than before, and are one of the most impactful new features in my opinion.

If you remember, Castagne is surprisingly game-agnostic: it just assumes you have entities directed by state machines. In practice, you have a lot of common behavior that got put in the Base CASP, and from there you could rewrite what you didn’t want. As time went on, I’ve added more integration of that base behavior, including visualisations and interfaces (the SpecBlock system), which improves the common usecase but makes the other ones a bit clunkier.

This new organisation goes both ways: on one hand, it makes Castagne more knowledgeable about some game concepts, and on the other hand the other game concepts become much more malleable. I’ve selected some concepts to become core components, for example the dichotomy of Grounded / Airborne, the concept of a combo, hitstun and blockstun, the difference between a neutral state and a comitted state… There’s not that many, but each allows the engine to do a lot more, while also not restricting the ideas you can do much (e.g. you can ignore the Airborne concept if your game has no jump). Many of them are also linked to their module, so for example if you change the physics module you won’t have the Airborne concept.

This allows the MechMods to know much better what they can rely on, and thus focus on key elements. This allows me to separate many common behaviors, such as:

  • The Movement MechMod, which has never-before seen elements such as Walking Forward, but if your game has no use for that you can disable it. (Standing is part of the Base CASP, hence the title of this update)
  • The Dashes MechMod, which adds many fan favorites such as Airdash or Running.
  • The Combo Proration MechMod, which adds limits on your combos by reducing their damage and hitstun over the hits.
  • The Combo Escape MechMod, which adds a burst to your system mechanics.
  • And many others of course. The full list is still being built, and the granularity might change, but you get the idea.

Just based on that, you can see how much more powerful the flow just became. If you want a mechanic in your game, you just enable it and get it immediately, and the interface allows easy access to them. I’m also thinking of allowing MechMods for characters on top of the skeleton, so you could surgically add an airdash to a character.

MechMods are what makes a lot of the new additions I’ve made make sense: the state call hooks (!!? especially) allow extension of behavior without requirement, the helper functions allow definition of new tools like !StandardAnim(Standing), and especially the upcoming VarSpec system. This is the last missing piece for my full vision: a system to allow additional editor integration of CASP tools in a simple way. A big element of the SpecBlocks in the editor was how they allowed very strong integration in-engine through buttons and graphs, and this is now comming to CASP itself! This will push Castagne to new heights, and I can’t wait to be able to use it!

(2026-03-26) Battle Init Data

Yo! Another update to a structure you know (and love?): BattleInitData, which as the name implies, holds the data needed to initialize a Castagne fight! Most probably didn’t use it much, but it’s been a cornerstone internally.

There is not much to talk about to be quite honest with you, as the ideas work the exact same, the interface is just better. It used to be an unwieldy JSON dictionary with a weirdo format, now it’s a properly reified object with a functional interface. Here’s an example where I create two players and their character, both have a 100 meter but the second one only has 1 HP.

// Assume we got config, player_1_scripts, and player_2_scripts properly handled before
let mut bid = BattleInitData::new(config);
let character_1 = bid.player().entity(player_1_scripts);
let mut character_2 = bid.player().entity(player_2_scripts);
character_2.entity_override("HP", MemoryEntry::Int(1));
bid.entity_override("Meter", MemoryEntry::Int(100));

As you’ve seen, it is simpler to build, and the previously available functions are there. Overrides allow you to change a variable from the character at creation, and you can set them up to be inherited. As such, the Meter override here was set at the root, so it applied to all entities defined in this BID, while the HP one was only done to a single entity. You can override global, player, and entity variables, as well as create entities with no player parent.

This is still a work in progress, as I’m focusing first on key functionality there. The new idea is that known data can be set more easily in general when the engine knows about it, with simple functions. Here’s an example of a new functionality: instancing subentities directly:

bid.player().entity(scripts).subscript(fireball_subscript_id)

This is honestly fairly low priority compared to other tasks once that the basic functionality is there (some overrides don’t currently work because there’s no player memory yet for instance). It’s needed to set up fights in the editor and game, but at the moment only the first is needed to get started with the engine (as you remember with my priority list). Still, are some planned / potential functionalities:

  • First of all, there is going to be a host engine interface. That example was in Rust, but you’ll be able to have a very similar interface from within Godot.
  • The flow module will be able to handle “standard” variations of this. An example you already know is the fighting variation, which just gives you a 1v1 with potentially multiple characters.
  • An idea I’m evaluating, is the ability to save a state to a BattleInitData, which would allow to store state on disk. This could be REALLY strong for editor tools.
  • Another idea in a similar way, is the ability to add BattleInitData DURING a fight. With proper management (keyword: proper), this could allow complex worlds and situations, which would be quite interesting for the more platforming focused cases.
  • Another one that’s linked to both, is the ability to reference existing HostStructs or similar from within. I’m not sure yet of what this would imply, but the idea is to be able to integrate Castagne into game flows better, like starting a fight from an RPG overworld seamlessly. We’ll see when I need it I guess lol, that’s real low prio compared to actually making stuff work.

Next up is multiple file loading for CASP files, as well as Editor control there. It’s time for the Base CASP to get a tune up, and that would already cover most of the prerequisites for the engine!

(2026-03-24) Physics engine okay!

Big milestone! I’ve advanced the whole engine flow enough so that we now have both physics and attacks working! They kind of go together.

First off: Physics. The new engine is more advanced than the previous one, as it’s made to handle more colliders and both 2D and 3D at the same time. 2D colliders are compatible with 3D and vice-versa, although it’s not what I would recommend to use lmao

At the current moment, it’s at mostly parity with the previous engine. While I could finish it right this week, I know people will want to use the new Castagne for the upcoming Indie FG jam this april, so I’ll be postponning it for a bit to focus on the editor.

Something that is of note here is the interface: the collider functions have changed. While I know this adds additional work for the porting of projects, after tests I’ve seen that this way is a bit better.

  • Colbox and Hurtbox now work with an horizontal center, and a base and height. This is a better way to adjust colliders that are close to the character imo. Colbox(0,100,0,500) (equivalent to Colbox(100, 500)) will produce a box going from -100 to 100 horizontally, and 0 to 500 vertically, so it’s a simple way to add one to characters.
  • Hitbox now works with width and height from the lower back corner. Hitbox(0, 100, 0, 500) (equivalent to Hitbox(100, 500)) will produce a box going from 0 to 100 horizontally, and 0 to 500 vertically. It reflects the more forward-facing nature of hitboxes, and thus allow faster set up.

I’ve set it up this way because it also becomes easier to move colliders around from code, as instead of being coordinates it’s now origin and dimension. This makes operations easier, except shrinking a collider forward which is the same difficulty as before. Do note that the order of parameters stays coherent: it’s dimension by dimension, and the shortcuts are (width, height) and (width, base, height) for each function, covering most cases.

This is not fixed in stone yet, so you can discuss it on the forum. Something to note is that I’m planning on adding drag-and-drop in the editor for these, so it should be easier to set up once the editor is more featured.

Some changes on the Attack module front too, although this one is quite tamer. It’s just a slight rework of the attack events, which work as such:

  • At the start, OnAttacked is called on the defender. This is the first event, where most attack overrides will happen. This is before the blocking computation, so you can potentially decide to get hit or not, which is a new ability.
  • After that, either OnAttackHit or OnAttackBlocked is called on the attacker depending on the result. The rest of the overrides happen here, and that’s where the attacker gets his meter and whatnot.
  • Finally, OnGetHit or OnBlocking is called on the defender. This is where you apply the changes to HP and the like.
  • In the case of a clash, only OnAttackClashed is called on both clashers.

All attack events share two properties: the target is the opponent for the attack, and Attack. allows you access to the current attack instead of preparation. This is intended to allow more flexibility in case of multiattacks and to enable more behaviors. Do note however, that the engine doesn’t store recieved/inflicted attacks anymore so you can’t refer to them outside of these events.

There’s more upcoming changes, although this post is long enough and I’m deciding on the details. Something to note, in this whole rework, is that the engine now makes more assumptions about your game, one of the key ones being the ground. The previous Castagne didn’t really care, but this one assumes that being grounded or airborne is a fundamental caracteristic of the game. I like that because you can ignore it if you don’t care, but it allows better integration, which really helps many cases. This is a throughline of the updates.

My next step is to advance the flow module, and to advance the editor workflow. I want the engine to be ready for the jam, although if you want to use it you’ll need strong basics with the previous one. Please get in touch, as this will probably be a closed beta, as it has enough caveats that I don’t want it available without supervision, and instead focus on a polished release. See you next update!

(2026-03-21) Forum Launched!

Hey hey! So up until now, the Castagne community was a bit spread around, but especially on Discord. This isn’t always the best for storing information long-term and having transparent discussion, but it was good enough for a while. However, now that Castagne has grown, it’s time to migrate to a proper forum!

You can find a couple things on the forum already:

GO TO THE FORUM

The Discord will still exist, but I’m going to focus more and more on the forum as time goes on. The forum is going to be the one pushed forward on the website from now on, and there are integrations from the forum to discord.

Little extra info: at the moment the forum is using DiscourseID, since my mail is blocked by gmail (probably previous owner of the IP doing weirdo stuff with it), but I’m hosting it on my own server. When I have the time to properly investigate and fix this, I’ll add the option for local accounts.

(2026-03-20) Host Engine Structures

Remember that Castagne can be run independantly? It handles all the gameplay on its own, but needs to be hosted by another engine to actually poll input or display anything, which in most cases is Godot. This also means that some data has to be shared, which is the subject of today’s update!

Introducing two new types of data structure to Castagne: ModStructs and HostStructs. ModStructs are an extension of the structures that already exist, they store another Memory Stack and thus can be rolled back if needed. They are separate from the main memory, and live inside of the engine itself, which allows additional abilities where needed.

Currently, this covers the AttackData structure, and you can guess what it’s used for based on the name. The interesting part of ModStructs is that they are also accessible from CASP directly. As such, AttackParam is a thing of the past, you can now directly use Set(Attack.Damage, 1000) for example. It’s also much more flexible than before, as you will be able to declare any type of attack parameter using the declare variable syntax: declare Attack.MyCoolParameter vec() = [0,0,0] creates a new MyCoolParameter attack parameter of type vector. This will still be compatible with the Attack Overrides system, so it’s quite strong!

HostStructs are an extension of ModStructs, as they are one ModStruct plus an additional data structure on the host side. The most direct application is the ModelData structure, which holds the parameters for the model. This is stronger than before on the Castagne side, as you can do Model.Position for example instead of having the whole ModelMove functions. On the host engine side, HostStructs recieve callbacks at key points in the process, such as the graphics update step for models, which are used to handle data while keeping rollback in mind. Since HostStructs have access to this managed memory stack, they can read the correct values and update accordingly, which works better if you use an immediate update structure (meaning, you are not dependant on previous state). The responsability of data lifecycle during rollback will mostly be handled by Castagne, while the responsability of acting on the data is on the HostStruct. This effectively replaces the InstanceData system, which worked in a similar way but was less structured.

Anyway, that’s mostly internal stuff which is going to be useful for engine devs or those that go really far. On your end, it’s most likely buisiness as usual, as you just make your Godot scene and it gets loaded as expected. Or, you use Sprites which are handled for you.

One change that will be coming however as a result is the fusion of the 2.5D fighter and 2D fighter genre into one. This was a big mark of using Godot specifically, and it brought a lot of issues because Godot’s pure 2D engine doesn’t handle 3D models (duh), and as such a lot of default behavior couldn’t be used. Using Godot’s 2D engine won’t be off the table however, as it will become a config option, that way if you want to use pure 2D sprites and background you will be able to set it up.

This change will make the beginner experience much less brittle, and will cause less confusion around some features of the engine which are not available when using the pure 2D renderer as it will be opt-in AFTER the initial approach and ensure you actually know what you’re getting into. Many people think “2D Fighter” refered only to the characters, which is not the case but it’s not something you can “fix”, especially in the first 3 minutes someone has with Castagne. It also prevented the default characters from being used, so the choice most beginners made would cut them off from learning! Won’t happen as much now.

(2026-03-14) States as functions?!

This is a pure banger feature, one of the best usability improvements of the new Castagne. State Calls were a huge feature in the previous version, and you could use it to create behavior either by extending a state or through composition. Interally both were the same, but I added warnings and _Helper() to distinguish between the two. You could alter internal defines, but it was a bit janky.

First off, there’s a new syntax for state names, which immediately distinguishes between the two: StateName is a regular state, while StateName() is a helper state. Both can be called without issues by using !StateName (equivalent to Call(StateName) in the old version), that part doesn’t change. What is new is that you can now add parameters to that, which are treated as local variables! Here’s a long snippet showcasing the new abilities:

:HelperState(var X int(), var Y bool() = true):
# You have access to both X and Y here.

# A is a local variable that you can't set from the outside.
var A int() = 10

V Y:
	Add(A, X)
	!OtherHelper(A)
endif


:OtherHelper(var Z int = 5):
# This has only got access to Z, even when called from HelperState.
# These are copies, so even if called through !OtherHelper(X), it can't change X

# You can call parent with arguments too
!!(10)


:RegularState:
# You can specify parameters with or without defaults
!HelperState(5)
!HelperState(5, false)

# If there are no parameters, these are equivalent
!OtherHelper
!OtherHelper()

# Hooks also work! The parameter list will resolve when needed.
!SuperState?(10, true)

So now you’re either super hype or super confused. This is a core feature of the engine that allows many mechanics and tools to be made inside of CASP in an efficient manner. Let me illustrate the difference with the old Castagne with some examples:

  • Kronian Titans has a lot of dashes, but internally there are only a few types with specific values. This can be replaced with a simple !AirStep(5000) to make the behavior easily readable and contained!
  • Molten Winds has levels and some characters might have custom behavior when a levul up happens. In this case, use the hook syntax: !OnLevelUp?. Compared to before, you don’t need to create the state immediately, it will only be used in the characters that want it.
  • Kronian Titans again has IMPACT moves, which launch a cinematic under specific circumstances, and requires a couple lines to set up with a hitstun that could differ. A simple !IMPACT or !IMPACT(120) can now take care of everything!
  • Molten Winds has Aster who has overdrive version of some moves which can be done by holding the button for the first X frames. Instead of rewriting it each time, how about a !TransitionIfHeld(M, 6, OverdriveMove) to automatically handle moving to OverdriveMove if M is held for the first 6 frames? Easy QoL on something that’s a bit too niche for the modules!
  • If you made custom modules in general, this is a way to make new CASP functions in a rollback-safe way, without leaving the editor. Take FlagCarryover(F) for example, it’s just FlagNext(F) in an L branch. You could make functions like that for your own use in minutes! It’s not as optimized, but that’s easily done later, and you can get started with it faster.

This is already super useful, but when you’ll combine it with the upcoming MechMods (!!? is specifically superb in this context, as it allows needed modularity) and Varspec (which can understand when it’s seen from a state call), it will be incredible. These three features are the ones that will bring the editor to a new level and I can’t wait for that!

Slight design musings to finish, since this post is already super long:

  • I thought about adding persistant variables to states, potentially allowing a Transition(CoolState(500)) or something, but I think it would be a bit overkill in complexity and we can hold variables in memory for that. Maybe I could add a variable tag for that.
  • Speaking of, the variable syntax is now lighter: var X int is valid. The variable tags are optional (the () in int(), which isn’t used for anything right now nor was it before, always a planned feature), and you don’t need to specify a default. In fact, some variable types don’t accept defaults, such as state or flag (semantic types in general), but you may use them in state calls.
  • Some modules have functions that are basically just syntaxic sugar and could be made as CASP states now. The Attack module is a prime example, as it’s mostly functions that call AttackParam internally. I don’t think this would be for the best however, as it would complexify the docs and make it more confusing to follow. Allowing the ! to become optional would fix that but introduce confusion instead. Making them as CASP functions would allow overriding module functions, which is another can of worms. I’m probably going to introduce module functions as macros to implement that.

What’s next is a bit tricky to choose, but I think I’ll start working on the modules again. Logically, I won’t be actually able to implement the MechMods without having something to put in them! Varspec will probably be the very last core feature to be added, since it’s so dependant on the rest.

(2026-03-12) Local Variables!

New feature alert! Whereas before you could only declare constants in your state, now you can declare variables!

These variables are only available for the state (or most likely, scope, due to how I’ve implemented it but I haven’t tested it at the moment), and get reset when going through it again. This means they are volatile: you can’t store state from one frame to another, and you also can’t reference them from the outside.

For the technical detail, it’s a per-entity memory stack that doesn’t get saved or rolled back. It has no upper limit, but it might need to reallocate. It starts at a reasonable size so it probably won’t come up unless you push it explicitely. Its volatility allows it to not bog down the implementation, as it gets “reset” every time you try to execute CASC code.

While it might not sound like a huge thing in the context of the previous versions, it actually enables a lot of future behavior. If you looked at the Base CASP I already used a proxy for them using the RegA/B/C/D variables you might have seen at times. They are usually used in intermediary computations. One such example that I’ll need to convert is F branches, which use it to handle modulos.

The main usefulness however is coming soon: using State Calls as functions, with their own local variables. Previous versions of this were limited and hard to parse, but this time it will be much clearer and integrated. Another benefit that is already in, is shorter compilation times: helpers don’t get compiled anymore so it removes like 80%+ of states. Unsure how needed that was since the compiler is in a compiled language now, but we’ll see when it gets to a higher level. This will be tricky to implement, but I’ve got a fairly clear idea of how I want to do it.

(2026-03-11) Vectors in the compiler

Incredible, but true! I’ve added structures to the compiler, the first of which is the humble Vector! It’s always a 3D vector, even in the 2D settings. You can use them either as a structure, or as individual components:

var V vec() = [0, 0, 0]

# As a component
Set(V.X, 5)

# As a structure
Add(V, [1, 2, 3])

At the moment, this is the extent of the system, but I’m planning on having 3 types of structures:

  • Vectors: 3D int vectors with support in math functions.
  • Arrays: Arrays of a single type, which can be iterated on in an upcoming A branch.
  • Custom: User-defined structs, which you’ll be able to declare from CASP on in modules.

Vectors are meant to be used in many places in the engine, especially for anything involving Physics or Graphics. I’ve still got design concerns for the other two, namely if the Arrays should have a fixed length (most likely yes), and how Custom structures are meant to be used (just organisation is a bit weak, but I’m thinking it has great potential to replace Specblock structs). Please note that all structures are just in the compiler, and not an actual type in the runtime itself.

I’ve done a lot of design work for the next parts of the engine, as they link a lot with the upcoming systems for top-tier integration in the Castagne engine: Varspec, a second language in the engine for editors, and MechMods, a simple composable way to add mechanics and system mechanics to your game. Combined with the upcoming State Calls with parameters, this will enable tremendous flexibility. That and a basic implementation of Physics, Attacks, and Graphics is my current objective, as this is where I can start porting projects to it.

Also, the forum is almost ready. I’m still testing out the rollout and managed to put myself on a spamlist thanks to a technical error. I guess it happens lol.

(2026-03-02) New Landing Page!

I’m really not a webdev dude and it shows lol, but we got a new landing page now! The previous one looked “unique” (better on my screen in my defence) to the point I’m being cited as a part of the “anti-design” movement. You can’t take the artist out of me it seems.

This solves a few problems around communication, the first being that most progress was not really accessible unless you were already in the community. This shows how active the project is a bit better! It was also a bit tricky to keep up with the weekly video, and until its quality improves I believe it’s not currently worth the effort of translating them. So instead of having to spend big time every week, this style of short update is probably better? I was already doing it before, so it’s not like it takes much. Might be able to rig it to videos too, once I improve my pipeline a bit.

One of my next objectives is to move the Castagne community towards this website. Discord was a useful crutch there, but information easily gets lost, and it becomes more walled over time. This is going to happen slowly, as I also want to develop the engine, and being currently mostly a solo thing that means I’m already pressed for time lol. But this is a priority, as my gambit to develop a full engine in 3 months didn’t pan out as fast as I hoped so I’ll need to switch gears into more paced and clear development instead of a short intense period. I’m still very satisfied with the project’s progress, and you can see how many features are already in on the page.

This doesn’t change much my plans, except that March might be filled with more “admin” and “surrounding” work rather than pure programming, but it might make more people aware of the engine, which is nice! My next programming steps are going to be structured types (especially vectors) and either the physics or graphics module. Input already works, so this is some of the last steps to make the engine usable. Knowing the extra features coming, I can’t wait to port my own games to it!

February 2026

(2026-02-24) Input Works!

Quick preview of changes:

  • Input layouts are a bit heavier handed now and don’t customize the name as much, which prevents many beginner errors
  • The main stick is now separate from stick, because it has much more assumption built in for motion and the like.
  • Multiple type inputs are a bit more generic and can be derived, or depend on derived inputs.
  • Derived inputs have been split into the new input events system, which enables a bunch of stuff. (No derived inputs yet as the main ones rely on physics)
  • Input events now replace the Press/Release thing, any input can have input events and they linger for a bit until explicitely consumed. This makes input much cleaner and reliable. It’s more KOF style, which is think is the best implementation.
  • Some extra events like DoublePress, or motion inputs, can be added in the future
  • Interface supports multiple inputs per frame, although I’m not sure I want to keep this? food for thought.

The syntax is a bit different, check this:

# Assuming L is a button
IL: # Is L currently held down ?

IL.Press: # Is an L press buffered ?
# The buffer lasts around 8f at the moment, and is unbuffered if released
# If going into this branch, the event is consumed.

IL.Press?: # Same as previous, but doesn't consume the press.
(2026-02-17) Inter-Entity Communication

I’ve worked a bit too much today to finish the CHECK in time lol so I’m giving a real quick preview

  • Targetting works ! And it’s robust and now properly handles the delay. You can also now read variables from nascent (= yet to be born) entities.
  • As a simplified reminder: reading gives you the variables at the start of the frame, writing is done at the end of the frame. Subentities have a faster pathway.
  • Variables from targets are much easier to access using Target.VariableName, peep some examples:
    • Set(V, Target.V): Copies the value of V from the target inside of our own V.
    • Set(Target.V, V): Writes the value of our own V into the target’s V.
    • AttackDamage(Target.HP): Makes an attack that does exactly as much damage as the target has HP, killing him instantly if it hits!
  • As dev starts to take longer and my other commitments are arriving sooner than expected (PhD as you may guess), I’ll be switching some gears for better communication !
  • I’m likely going to ask for help on some stuff soon-ish! Some stuff around the engine, some stuff more on research on existing fighting games. Be ready for that!
(2026-02-15) Entity Lifecycle 2

Fixed some bugs there and adjusted behavior to be defined Subentities will now go to their parent, so the execution order is not shaken too much CreateEntity and DestroyEntity have been renamed to EntityCreate and EntityDestroy for greater consistency, but I’m also adding aliases ! (they don’t work yet), so you can still write CreateEntity if you want. Gonna be useful when I want to write AttackFA instead of AttackFrameAdvantage And NEW FUNCTION ! EntityDestroySubentities. Destroys your children. Combine it with EDestroy: to bring your children to the grave with you ! (in castagne) The only remaining big module feature for the core is inter entity communication and targetting ! After that it’s onwards to the other modules

(2026-02-14) Entity Lifecycle

you can now destroy entities This also triggers a Destroy event so you can spawn one last VFX or something and detach it An entity’s subentities will be promoted to main entities (there’s no difference nowadays anyway except execution order), so you can kill (in the game) with no worries At the moment, there’s a bit of an edge case I haven’t decided on: if you kill a subentity that has subsubentities, should they go to the parent entity or be set free in the wild as strong independant entities? It’s the later at the moment, but I’m not sure if it’s the best course of action Additionally, I’ve decided for After to do what I said, and it now activates after every Action/Freeze/Halt phase has gone for entities and after a data sync but before entity destruction, and doesn’t process new entities created in After. With this, you can do both helper behavior like adding hurtboxes automatically if forgotten, or even synchronize entities a bit more, like tracking to the opponent. IF YOU’RE A REAL NERD THAT UNDERSTANDS WHAT I WROTE REACT WITH :brain:

(2026-02-13) Phases and Events

I’ve added phases and events, compared to previous versions these work properly even with state calls That means that your custom code in states like AttackReactEvents doesn’t need an additional EOnAttackHit: anymore !

Also CallAfter is now EAfter, it’s an event now for easier use

Regarding EAfter, at the moment it’s akin to a second phase after the first, and runs after the inter-entity communication sync. I did it that way now to get it online, but I’m not sure how much of that to keep. I think I’ll remove the possibility of a state transition, but keep the barrier and sync to allow some tricky behavior that requires getting data from the other entities on the same frame

(2026-02-11) FlagCarryover

Lil surprise new function FlagCarryover(FlagName) If the flag is raised, calls FlagNext on it I use that pattern all the time and figured I might as well enshrine it instead of writing three lines everytime

(2026-02-09) Castagne CHECK 5 - Editor Edition

New CASTAGNE CHECK! Got the editor working properly, onto the core module!

Nouveau CASTAGNE CHECK ! L’éditeur marche bien, c’est l’heure du module core !

https://youtu.be/yKQK69eA_X0

(2026-02-06) Editor Link Online!

Alright we’re in buisiness ! The editor link is now fairly robust (it works in all my tests, even if the engine itself crashes) and the lifetime of the engine is handled by the editor (so you don’t have to think about it) (in your computer the window will be hidden but on mine there’s no “minimize” function in my window manager lol)

Display is calibrated for accuracy rather than exact input, so there a bit (+2f) of input lag. This is due to godot’s rendering delay and only affects the editor. This could potentially be removed at a later time, but this would require a deeper dive into godot’s rendering architecture for something that’s not a priority. You may still test without input lag by launching the game separately (which the editor can also do). This is a bit of a downside of the separate editor, but there’s many upsides like the game crashing not crashing your editor too lol

But yeah good progress, this was one of the big technical issues to solve and it’s done now, the editor is almost usable in production now!

January 2026

(2026-01-31) Editor files

Editor now loads and saves files and projects ! It’s getting close to a usable state ! Main remaining things to go through for a minimum viable editor are:

  • Error display
  • Clean up the game running code
  • Improve navigation a bit (the editor can load multiple files now, it just doesn’t do it yet lol)
(2026-01-26) Castagne CHECK 4 - Compiler Edition

Castagne CHECK! I reworked the compiler and my brain is fried help

J’ai retravaillé le compilo toute la semaine aled

https://youtu.be/1R53n-GNAS8

(2026-01-19) Castagne CHECK 3 - Modules Edition

New Castagne CHECK, this time on the modules! I also introduce the upcoming changes to the physics!

Nouveau Castagne CHECK, cette fois sur les modules! Je parle aussi des changement au module physique!

https://youtu.be/sb5xF_uoWZ8

Actually lets ping @Castagne too because I need you guys to SUBSCRIBE (you don’t need to like, you can hate if you want) so that Youtube knows I’m trustworthy enough to put links and multiple audio dubs

(2026-01-13) Castagne CHECK 2 - Godot 4 Edition

Castagne CHECK #2 is out ! Come get some news on development Today’s subject : Godot 4 and Subentities

Gonna add an @everyone / @Castagne for a quick favor :

PLEASE SUBSCRIBE SO YOUTUBE LETS ME PUT LINKS IN THE DESCRIPTION AND MULTILANGUAGE AUDIO thank u

https://www.youtube.com/watch?v=NrSpCEwxK3I

(2026-01-11) Castagne Editor works!

Castagne Editor now works!!! It uses IPC to allow for better UX and new possibilities (like network, customization, better crash handling…) and it was tricky. It’s fast enough, but can be improved if needed. I finally got the basics down for the project!!!

(2026-01-07) Castagne now runs inside of Godot 4!

you gotta know right away

CASTAGNE NOW RUNS INSIDE OF GODOT 4

that’s it, that’s the message Doesn’t look like much (yet) but it does compile a casp file and run it inside of the CastagneEngine node Each time the button is pressed, an engine tick advances, and the state is read back with no issues.

What’s next?

While you might think it’s “just port the rest of the functions”, it’s actually the editor connection. Castagne’s true potential is unlocked by allowing it to serve as a tooling platform, and for that it needs close communication with the editor.

I’m thinking of making the editor a separate program, so that use is a bit simplified and you don’t need to download the full thing every time, or open and close the editor every 5 seconds, as well as permit more advanced features. This is going to be extra tricky however, so I want to nail it early.

The editor being functional will mark the end of the first phase of the compiled castagne rewrite: the core structure. Phase 2 will be continuing development on the core to allow each module to come back, thus building it back into working order.

(I’ll of course make a video like the one from monday to explain more, just give it a bit of time)

(2026-01-05) Castagne CHECK 1 - New Year Edition

@Castagne-SmallUpdates First Castagne check / changelog preview / whatever you wanna call it I’ll try to put some small videos for progress from time to time With the software it’s really quick to make BUT i do need to spend a couple hours to improve it if I can I planned on doing dev today but I got roped into helping out with cursed computer problems lmao https://youtu.be/oklO_x6w5Ag

December 2025

(2025-12-15) Castagne Stream 4

Starting stream soon! Come for the whiteboard catch up on castagne’s design lol https://www.youtube.com/watch?v=k3s8JSZg82Y

(2025-12-10) Castagne Stream 3

Castagne dev stream: Variables Let’s go, this time I actually slept before lol https://www.youtube.com/watch?v=aprIF_6Ze1U

(2025-12-09) Castagne Stream 2

Hop in, we doing the compiler I’ll only ping @Streaming from now on if that becomes regular, so check the role if you’re interested! https://www.youtube.com/watch?v=VSkvQRiN0AU

(2025-12-07) Castagne Stream 1

As requested by you guys, dev stream for castagne https://youtube.com/live/wEmolGKz8pI?feature=share

(2025-12-05) Castagne for Godot 4 Start!

Castagne for Godot 4 STARTED TODAY! currently doing setup and writing the design in full the new editor is going to be incredible

Try the Godot 3 Version now!