Hey! First update in a looong time (almost 9 months!) and it shows! The long delay was due to various things, but it's mainly because it's a turning point where the engine starts going from experimental and prototypey to an actual mature project bit by bit.
So you may have noticed the long scrollbar on the side, that's because this update is massive! There were a lot of internal improvements, new feature, QoL, you name it! Since it's over so long a period, which itself was pretty busy for me in general, I had to reread the whole codebase to analyze what changed. I spent quite a few hours just preparing this release, but I still might have missed some details! Please also read the breaking changes, you didn't lose a lost of functionality but will probably have to pass over a fair amount of moves.
Additionally, a lot went into project management and presentation. That work is not done, but considering Castagne is becoming more serious I've had to make a lot of non-programming work so that it's sustainable over time. That's why I also split this changelog intro into several parts.
We're also seeing growing pains, as some editor systems are being stretched a lot beyond what they were supposed to be and handle! Mainly the parser that got roped into being a compiler that becomes more and more complex, and the editor having to dance around new UI systems. While not a big issue, considering it's still very usable and part of the lifecycle (they have reworks planned since the beginning specifically because this would happen), this means that there will be a bit of jank during editing that won't go away in the very near future!
Project management
So this is the main part and I've talked about it before, but the thing is that the project is becoming more serious, and the environment changes around it. Therefore, in order for it to stay healthy and scale correctly, I've made the decision to change the license from MIT to MPL. This is a weak copyleft, which won't change anything for most projects. What it aims to do mainly, is to ensure Castagne is not completely forgotten by the projects that use it by making them say they used Castagne (meaning more users come to it, and keep the ecosystem nice), and share back some improvements made they make to the engine (bugfixes mostly).
The idea here is not so much to limit what you do with it, but rather ensure projects give back a bit when they can. The license is light enough to still permit an ecosystem around it, as you can still make proprietary extensions (although at this point in the engine lifecycle I wouldn't recommend it).
Another change to go with it, is the future addition of a CLA (contributor license agreement), in order to allow me to act as a single owner when needed. I've talked with several experts and done some research, and this has been a recurring recommendation, as it will allow me to enforce said license agreement and to react to the needs of the project as needed (for instance, for console ports which are not always full open-source compatible). Since this is a bit more complex and needs additional time to be finalized, there is a temporary stop to contributions (unless MIT licensed). If you're contributing, we'll discuss it case by case for a bit until I can sort this out, but I decided to not delay the release even more.
Another issue in the project management was the more freeform release scheme and process, which wasn't clear and resulted in a few bugs at times. Now I've made more tools to help me do that quickly (a release can take hours to release properly before) and with more quality checks. The branches are now as follows:
- Main is the classic release, and compared to the other branches it always go through the full tests (meaning tutorials work for instance). The idea here is to make a version for the standard user that doesn't mind waiting for features and is not super technical / willing to put up with too many loose ends. Of course, the project is still in development and the priority is to speed, so bugs are still expected.
- Unstable takes the place of the old "dev" branch, and is meant for more gradual releases. Only basic tests are made here, the idea is that I can push new features here almost as soon as they are done, meaning engine dev can pick up speed. I probably won't do changelogs for these, the idea is to keep the process as lean as possible.
- Dev is not a real release, but is now referring to the "dev" branch of the git repo. It's for collaboration, which was a bit tricky / centralized beforehand. As such, it's only accessible with git pull directly.
On top of these, the updater now allows patching directly, meaning the project can now support a lot more iteration. That's going to be nice! I've also updated the packaging to make it simpler to use, including launchers for the editor and a project option as the "Castagne only" option instead of just the repo.
Dependencies have also been managed, I've removed the strict rollback pluggin from dsnopek requirement as the codebase is not performant enough atm, and won't be until v0.7 and Godot 4. I've also added gdunzip as a dependency for patching.
The four main features, and the rest
This release is centered around four main additions:
- The Specblocks, which are a cool system in module development, but also embody the new more practical direction of the engine by providing an interface for a lot of features that were already present. It's complex, but it keeps all the good parts of Castagne I like in terms of flexibility while also acknowledging the need for a good user experience.
- The new Subentities flow, which are a refinement of the more general entity system to match the reality of FG dev. It does not limit what you can do, and instead adds more communication pathways and ease of use for what you were actually using it for.
- The new Sound module, which is barebones for now but is a base for further improvements.
- A new Attack Flow. This is in spirit the second part of the previous attack improvement: while how you create and register attacks got improved, now it's the turn of what you can actually do with them. I've pushed a lot of behavior CASP side, allowing for maximum flexibility, and added a new way to manage counter hits, starters, air hits, etc. I believe this is very typical of what I wanted to achieve with Castagne from the start, which is efficiency of iteration coupled with strong flexibility.
There are also other improvements, including engine optimizations (around 23% faster), more advanced sprite management (backported from v0.55), and CASP script improvements (S branches, modulo, and freeze / halt phases).
Next up
The next main version is v0.55, which focuses on two things: menus and graphics. As mentioned, some of the improvements of this version are backported from my own branch of v0.55, considering v0.54 has been code-ready for a while. I'm intending v0.55 as a release where you can actually make a real playable build of your game.
If you remember correctly, there are two pilot projects for Castagne: Kronian Titans, which is the progenitor of Castagne and pushes its more advanced features, and Molten Winds, which is built on more standard features and pushes Castagne to be release ready faster. I'll do a more in-depth announcement later, but due to how things evolve, the Molten Winds project as is has been rebranded to Molten Winds: Open Edition, and is currently on Steam. You can wishlist it here, it's currently in a sort of closed beta that will open up with time. MWOE is still meant as an open source release using only vanilla Castagne and its 2D module, but considering the change in my own environment and what I potentially want to do with the project, these limitations are starting to be a bit too stifling, and as such MWOE will release with "only" 9 characters.
The reason I bring it up is that, considering my dev profile, 2D doesn't really make much sense for me. The 2D module has always been a community addition and want, and as such I don't plan on really adding new features to the 2D module / sprite flow after v0.55. Considering Castagne is FOSS, I believe the development of this part should also reflect its users, and as such it's up to you if you want to improve it beyond what I did! I'm always available to give a hand (as usual), but I prefer focusing on the more general features that will be useful to everyone, since the module will be functionally complete. 2D flow is less standardized than 3D, and it tends to be a target by a lot of beginner users, therefore it's a lot of UI/UX work and I'll be eating my share with the menus already.
In parallel, I do want to improve the presentation of the project over time, including the website (fun fact, it looks good on my screen but after viewing how other screens change the colors I understand the criticism over my palette choice a bit more lol). The characters also are gonna get a rework, and I'll try to include the community as much as possible with a moveset jam! More details to come, as I want the pieces to be ready before throwing people at a wall. We're also overdue for a second Castagne survey / birthday celebration, but with how things are going we might be going straight to the third one instead, considering people need to be more comfortable with the new version for the answers to be meaningful.
And with that, I hope you enjoy this new release, and I'll leave you with the complete changelog. See you for the next one (hopefully not in 9 months lol)!
Main Additions!
- Repo Cleanup and License Change: Having to apply the MPL everywhere was a good opportunity for that, so a lot less dead code now. Also moves some dependancies around.
- Specblocks System (Better UI): Additional CASP / module system which reflects the increased coupling that became more part of the design of the engine, and which allows for some defines to be managed from specific interfaces in the editor, while also being able to be processed on compilation and accessible as metadata. For most users however, what will show is that almost all previous variable settings that were hard to access are now presented in a graphical interface and easily accessible, check the full changelog for the list.
- Subentities: The previous entity system was very powerful but also very complex and hard to handle. The new one instead splits entities into two categories: full entities (the characters you control), and subentities (projectiles, puppets, etc.). Now a file only has one full entity defined and as many SE as they want. They have more restrictions, which enable easier interaction (including stuff like same-frame instancing).
- Sound Module: While simple, there is now the skeleton for adding sound effects to the game and special parameters. Music support is now in too, with the ability to setup intros and loops.
- Attack Module Improvements: Flow, Overrides, Transition to state: Instead of the blocking code and attack application code being locked in GDScript, it's now more generic and in CASP, so you can create new cursed ways of blocking and new funky burning poison drain effects or whatnot. You can now specify blocks and unblockables easily too. The flow of attacks is now more involved, with some back and forth for each hit so you have the ability to react to each one. You can also now conditionally override attack variables on generic and premade triggers, which allows you to for example change damage on aerial counter-hit only quite easily, see the changelist for more details. You can also now force a specific state on hit / block, which is crucial for throws.
- Attack Inflict and Avoids/Requires: On top of that, additional options have been added for hit detection, mainly requiring the defender or the attack to have a specific flag (for instance, only be hit by OTG attacks when knocked down), or to avoid said flags (be low-invulnerable). You can also ditch hitboxes all-together and just use
InflictAttack
directly. Throws have been reworked to make use of that system, so you must use it for your followups to work.
- S Branches and F Modulo: CASP has good some really good QoL changes here, because now instead of having to specify each frame ID manually you can instead say "do this for X frames, then do this for Y frames", and it gets translated to F branches seamlessly. F branches now also got a new ability: modulo, so you can run a behavior periodically.
- Sprite Management Improvements: Backported from v0.55 technically, sprites now have much better support, with the ability to setup spritesheets "graphically" and setup sprite animations. Palette system is also starting out and working, but it is scheduled to have improvements in the near future.
- Engine Optimization and New Freeze/Halt Phase: Runs 23% faster now by applying some notes/ideas I wrote earlier in the engine lifecycle (sometimes like 2 years ago). Freeze phase has been split in two for more control, with Freeze now being individual, and Halt being a way for an entity to lock others out in an order-independent way.
- Packaging and Updates: New release procedure that's a lot more automated, and also more backed up on my end. Has a checklist and all, and a new "project" setting for people only downloading castagne so that they don't have to resetup their code. The updater is also now able to patch in the updates, which is quite nice, but as usual I still recommend you keep your projects backed up. Oh and it has some gitignores by default now so you can setup source control more easily.
- Tutorials: In-engine ones have been updated / new ones have been added, I've remade the video ones. I hope they stay for a while.
- Misc: Input ANY has been added for combination inputs. Stage selection is in. Additional safeties and QoL changes for the editor (less compilation time in mirror matches). Bug fixes. Physics transformation functions.
Breaking Changes
- Entities have been reworked, and subentities must be recreated if you had some. Your code is not lost but unusable as is.
- Some CASP states have name changes, and as such might not override things properly or even be called. Mainly init states.
- VFX system has been changed, you'll need to redo the associated code.
Anim
has a behavior change that you might notice in edge cases.
AF*
and PF*
flags now start with AF_*
and PF_*
, you'll need to check your conditions manually (using the new search function.)
- Specblocks are overriden by variables, you'll need to transfer the variables values manually.
- Lows and Overhead need to use
AttackMustBlock
now.
AttackRearm
still exists but is now very specific. Use AttackMultihit
instead.
- Groundbounce is out for the moment
- SpriteFrames support has been removed. Afaik, no one uses it.
- Some internal path changes might break your own scripts if you extended Castagne.
- Some functions have been renamed:
CreateModel
-> ModelCreate
CreateSprite
-> SpriteCreate
RegisterSpritesheet
-> SpritesheetRegister
Known Bugs
- Editor
- Subentity edition is janky
- Navigation is a bit constrained at times
- Might need an Action state every time
- Specblocks don't show inheritance properly
- Specblocks interface is a bit janky, and might create specblocks if you switch to an entity which doesn't have one specifically.
- Wrong targets of
Call
functions report several times instead of one.
- On small screens, not all buttons are visible (more like a lacking feature)
- Can't mute specific sound effects when putting volume to zero (lacking feature again)
- Game
- If cancels are done frame perfectly, attack animation plays too early
- Variables set between entities a bit janky (not a problem in most cases, but will need to fix in the 0.7 cycle)
- SOCD issues due to new input system
- Can't cancel into attacks during dashes (was on purpose for an easy feature add and the PR has been made, just not integrated)
- Palette is forcefully applied on models in some cases and doesn't work properly.
Full Changelist
- Project Organization:
- Updater:
- Version is now stored as a file instead of a castagne config variable
- Updater now actually patches the project
- Dev branch is now unstable, new dev branch is just the code on github which you can access with git.
- Packaging:
- New packaging option: Project, which is the default and setup castagne project without godot. Will reduce support questions.
- Windows and Linux builds now have scripts to launch Castagne Editor or Godot Editor directly for ease of use with beginners.
- Added gitignores for easier setup of source control.
- Repo:
- Reorganized and cleaned up files internally
- Changed license to MPL and appended it to files
- Removed dsnopek's plugging for now, until rollback is ready to be added again
- Added gdunzip as a dependancy
- Specblocks:
- Added Specblocks, a system in-between Character and Variables block that can add constants to a module for use in CASP.
- Added ability to transform the data of said constants in another format for more advanced use.
- Added ability to access data and transformed data of specblocks outside of games
- Added structures to specblocks, to handle data with multiple constants for use in modules.
- Added Editor support for specblocks, along with automatic graphical interfaces.
- Added Gizmo support for specblocks.
- Added support for unspecified variables in the specblock, to avoid loss of data preemptively in future updates.
- Added inheritance of specblock constants between files
- Added Specblocks for subentities
- Specblocks can specify if they apply to full entities, subentities, or both.
- CASP variables moved to specblocks when possible
- New Specblocks Added:
- Note: Most of these were functionalities already present in the engine, the new part is having an interface for them. Below is the description of what each specblock does.
- Attack - Types: Default parameters for attacks
- Automatic cancels from one type to another.
- Damage and Hitstun proration for each type
- Proration graphs / simulation in the editor for hitstun and damage
- Attack - Mechanics: Global settings for combat
- Hold back to block vs button block
- Can block in air
- Continue blocking in blockstun
- Attack - Throws: Manages setting related to default throws (command grabs are bespoke on your end)
- Ground and Air throw state and position setup
- Tech window time and lockout
- Thrown default states setup
- Subentity: Helper for subentity specific settings
- Default hitbox / hurtbox
- Collision behavior
- Destroy on hit / block / when hit / wall collision / floor collision / timeout
- Attack parameters
- Basic movement
- Basic animation (model / sprite through graphics specblock)
- Sound Effects
- Animations: Setup basic animations here (can override states specifically for specific behavior)
- Movement (Basic and Dashes)
- Reactions (Hits/Block/Knockdown, Throws, Recovery)
- Graphics Settings: Model, sprite, and palette setup
- General parameters (scale)
- Model / Scene parameters
- Spritesheets can be registered through the GUI
- Sprite Animations can be specified (slightly clunky)
- Palettes can be specified
- Physics - Movement (2D): General physics variables for movement
- Gravity and friction (ground & air)
- Transitional states (stand to crouch etc)
- Grounded movement (walk and crawl)
- Jumping / Landing
- Running
- Step Dash
- High jump
- Air jump
- Air dashes
- Air actions
- Movement visualization through gizmos
- Physics - System (2D): General physics setup
- Default colliders (hurtbox and colbox for standing / crouching / airborne / knockdown)
- Hitstun / Blockstun physics
- Throw Teching physics
- Facing / air facing
- Internal input parameters
- Physics - Recovery (2D): Techs / Knockdown options
- Recovery physics
- Grounded recovery options (neutral, back, forward, up)
- Airborne recovery (neutral, back, forward, up, down)
- Knockdown recovery (neutral, back, forward, up)
- Subentities:
- Removed the ability to store several full entities in a single file
- Added new type of entity: subentities, which have additional restrictions
- Subentities are processed after entities.
- Subentities initialize on the same frame as they are created.
- Subentities have special communication pathways with their own entity, allowing for easier and faster inter-entity communication.
- Subentities inherit constants from their main entity.
- Subentities are integrated in the main loop with their own phase instead of Action/Reaction
- Added Editor support for Subentities.
- New function:
CallFromMain
, to call function from the full entity associated with this subentity.
- Added inheritance for subentities
- Added Base and Projectile subentities
- Sound:
- Added background music to be played in games.
- Added a menu for music setup, with support for intros and loops.
- Added Sound Effects (setup through Specblocks)
- Added base framework for playing sound effects using
SoundPlay
- Added support for generic param setting with
SoundParam
- SFX volume can be adjusted
- Basic setup for sound mixing done, not super advanced.
- Engine:
- Speedup of 23% on the main loop through various optimizations
- Freeze phase now affects entities independently
- Hitboxes are now preserved in freeze phase
- Attack transitions are preserved in freeze
- Added Halt phase, which freezes time for every entity except the caller.
Call
is now always static and can't do dynamic calls anymore.
CallParent
is now always static and can't do dynamic calls anymore. It can also now only target the overriden parent state.
CallAfter
is now always static and can't do dynamic calls anymore. Code is now properly inlined, and function definition changed a bit.
AttackRegister
is now always static and can't do dynamic calls anymore. Code is now properly inlined.
- F branches can now use a modulo to loop with this syntax:
F1-6%12:
(play on frames 1-6, 13-18...). The modulo is slightly shifted for easier use (you will not get 0 but instead the value of the divider, which in the example case means 12).
- S branches can now be used to add behavior to execute sequentially. They have some restrictions as they are translated to F branches internally. Please check the language documentation for information on their use.
- Added more compiler error verification.
- Graphics:
CreateModel
CreateSprite
and RegisterSpritesheet
renamed to ModelCreate
SpriteCreate
and SpritesheetRegister
to stay coherent with naming conventions.
- SpriteFrames support removed, now it's only scenes and spritesheets.
Anim
has improved behavior that is more natural to use.
- Spritesheets can now be setup through specblocks.
- Sprite animations have been added and are setupable through their specblock.
- Palettes have been added for sprites through 16x16 palettes. Implementation is scheduled to be expanded upon.
- Sprites now instantiate with their own script and shader that can be overriden.
- VFX flow changed, now uses new functions.
- VFX now supports sprites and sprite animations.
- VFX update properly in Freeze phase.
- Added VFX helper functions to make their simple use faster.
- Added support for Idle Animation Override, not exposed yet.
- Physics:
- Can now bypass hitboxes and hurtboxes and attack directly with
InflictAttack
.
- New additional filter for attack collisions using state / attack flags with the
HitboxAvoids
HitboxRequires
HurtboxAvoids
and HurtboxRequires
functions.
- New transformation functions added to switch between World, Local, and Absolute space.
- Third dimension added to some functions for future addition of 3D Physics module
- Warning added for negative volume colliders.
- Internal callbacks altered slightly to be easier to use and more performant.
- Attacks:
- New attack recieved flow in three parts
- Attack data recieved / inflicted direct manipulation added
- New attack override system to alter attack values depending on attacker and defender states using
AttackOverride
. See the documentation for more detail.
- Added default overrides:
Block
, FirstHit
, CounterHit
, Punish
, Hit
, Airborne
, Grounded
, Clash
, Multihit
- Added hooks in CASP for adding overrides and similar things.
- Moved damage and momentum application to CASP
- Attacks can now use OTG flag to hit on the ground opponents (thanks to HurtboxRequires)
- Throw flow reworked to use no hit/hurt boxes, must use
InflictAttack
- Added
AttackMultihit
that should be used instead of AttackRearm
in most cases.
- Added attack proration for hitstun and damage.
- Added minimum hitstun and damage.
- Added chip damage.
- Changed blocking system to work in CASP and with generic triggers, using
AttackMustBlock
and flags families CanBlock-
and Blocking-
. See the documentation for more detail.
- Added
AttackUnblockable
to make an attack unblockable if an opponent has a specific flag.
- Added
AttackUnblockableGround
and AttackUnblockableAirborne
as helpers.
- Added a
PhaseBlock
flag as a generic way to make attacks not register instead of being blocked.
- Removed groundbounces for the moment
- Added the ability to force a transition to a different state on hit/block with
AttackTransitionTo
- Added
AttackStartup
and AttackWasActive
flags to the default state.
- Misc:
- New physical input type: ANY (any one of several buttons).
- Game input type Combination is now known as "Multiple".
- Castagne Starter now has to be explicitely unlocked as an additional safety.
- Modules can now register Player variables on top of Global and Entity variables.
- Stages can now be selected
- Files don't need to be compiled multiple times in mirror matches (faster loading)
- "Local" variables temporarily added for making more complex computations easier.
- Some behavior moved to the CallAfter part of Common.
- Init flow slightly changed.
- New search function in states in the navigation panel.
- Bugfixes:
- Main entity now gets updated properly to the oldest full entity of the player when the current main entity is destroyed
- Fixed override bugs in Flow module
- Fixed 3D pixelsize bug in 2.5D graphics
- 3D Pixelsize is now unused in 2D
- Fixed bug with attacks hitting on landing hitstun frame (very tricky)
- Fixed bug with Air Jump and models / sprites
- Some animation bugs fixed.
- Frame advantage bug fixed.
- Air attacks being able to be triggered on landing if frame perfect fixed.