This is the first release of OpenBOR 4.0, representing over five years and 1,139 updates to the source code. In order to avoid yet more delays and keep the promise I made to release before year end, there are still elements in progress that I will be finishing up in the coming weeks.
However, you will find a wealth of long awaited new goodies to play with, plus full documentation, along with an internal codebase and development strategy that enables fast updates as we move forward. So much I had to compress what was over
twenty pages of updates into an ultra abbreviated list that links off to wiki articles. In addition to more updates and polish, I will try to put up some video tutorials explaining these powerful new features.
Let's get started...
Legacy Compatibility / Compiling
Unless otherwise noted, the items below do not affect legacy compatibility. However, moving forward, I am striking the forced legacy compatibility policy. Despite the best efforts of SX and then myself, through the years some compatibility issues manifested. We've also found creators tend to stay with the version they started with.
The idea of using one copy of OpenBOR to open up a big bag of games was originally intended as an add on convenience, not the primary engine design. As we move forward, this functionality is phasing out. Creators will be encouraged (and given more tools) to treat OpenBOR as what it is: An engine you build games with. Meaning, each game is a singular compiled entity unto itself with the engine being part of that - just like Unity, GoDot, or any other engine out there.
In short, there is not enough justification to continue prioritizing legacy compatibility. We will of course make reasonable efforts to maintain compatibility, but no longer at the expense of possible improvements.
Documentation
OpenBOR 4.0 isn't just a coding update. It is also documentation project. As part of this, I have created extensive wiki type articles using tag indexes and categories.
See the overview page here. Many of the entries below include a "see wiki for details" link. You will find these links lead to full length explanations of the feature and its use. The wiki is in progress and will see continuous updates as we move forward.
Codebase Updates
I have reworked much of the engine logic to be smaller, leaner, easier to read and easier to debug. Despite all the feature additions below, there are are actually far fewer variables and internal properties.
Ports
- Support officially dropped for PSP, and over time I will remove more and more remnants of superfluous port code.
- Numerous Android port tools and fixes by @msmalik681.
General
- The
ajspecial
command now accepts text arguments and allows mapping to alternate buttons. See wiki for details.
- Cheats are now a dedicated menu. You can configure availability of cheats menu, individual cheat options and the default state of cheats at startup. See wiki for details.
- Consolidated
jumpmove
and walkmove
into new property air_control
. Accepts text arguments and offers many more options, including native Mario Style jump height control (hold Jump button to control height), deceleration, and more. See wiki for details.
- Closing credits removed.
- Now you can control a projectile's color, velocity, direction, launch offset, and more. See wiki for details. Caution: Shortly after adding "projectile", I started work on a much more powerful "Child" system (see here) that handles all forms of child entities (projectiles, particle effects, NPCs, and so on). Projectile system WILL be depreciated when Child system is completed, so use at your own risk.
- Legacy
subject_to_...
commands and several others consolidated into new property move_constraint
. Provides total control of all movement limitations and abilities (following terrain, screen boundaries, etc.). See wiki for details.
- The
paingrab
property now adds its value to antigrab
when entity is not in a pain state. For example, paingrab 2
increases the entity's antigrab
value by two whenever the entity is not in hit stun. Previously it was 1 (only susceptible to grabs in pain state) or 0 only. See wiki for details.
- There are now named references for Burn, Freeze, KO, and Shock maps. You can assign these a palette index, and then reference them in attacks for convenience. This makes using palettes for common special effects simpler as you don't need to worry about remembering numeric indexes. See wiki for details.
- New property
weapon_loss_condition
. Set up events that cause loss of carried weapon. Accepts string arguments and enables many new conditions or combination of conditions. See wiki for details.
- New property
weapon_loss_index <int>
. Entity reverts to <int> entry in its weapon list when losing current weapon. See wiki for details.
- Collision updates:
- Multiple collision box support now open to creators (supported internally for several years but was not accessible in text). See wiki for details.
- Some collision elements such as Z depth now accept more user readable names. See wiki for details.
- The type attribute of new style collision command will now accept named attack types Burn, Freeze, Shock, and Steal (example:
attack.damage.type burn
). Remember that attack types are nothing more than an ID. How the attack actually behaves is up to you. See wiki for details.
- Direction force and legacy
forcedirection
attack property now accept text arguments left, right, none, and opposite. Example: attack.reaction.reposition.direction left
. This works for all other uses of direction adjustment and also includes two new options:
- away: Face away from target/attacker position.
- toward: Face toward target/attacker position.
- Automatic damage dealt by engine (ex. time over) now uses special attack types. Previously most internal damage either used normal 1 or the last attack type in order. These new types are available through script and native offense/defense. See wiki for details.
- Recursive Damage updates. See wiki for details:
- Unlimited items on single entity (previously limited to 10).
- Improved memory efficiency. Does not consume memory when not in use. Slightly less consumption otherwise.
- You can mix and match the resources (MP, HP) affected.
- New property
attack.damage.recursive.type
. Attack type applied by recursive damage. If unused, defaults to legacy behavior (uses same type as the parent attack).
- No longer breaks grabs and spams the HUD unless the damage kills target.
- Font limit increased from 10 to 20.
- Smartbomb can use
forcemap
like an attack box.
- Video updates (@Kratus):
- Reversed the FPS limit code to reduce CPU usage, if the engine has no FPS limit sometimes it reaches 3000+ depending on the hardware used, causing a high CPU usage (between 30% and 40%).
- The Plombo's V-SYNC code is intact, if enabled it runs at 60 FPS.
- The previous code will only work if the V-SYNC is disabled running at 200 FPS max, no more than that.
- Disabled the V-SYNC by default.
- Control updates (@Kratus):
- Changed the default controller configuration to "NONE" for p2/p3/p4, the p1 remains the same.
- Disabled some internal engine functions to make the controller IDs more persistent when it's plugged/unplugged.
- Disabled the Android "Accelerometer" (Gyroscope).
- Added the "DISCONNECTED" message when any previous configured controller is unplugged before the engine starts.
- Changed some button tasks priorities in the select screen, it's to avoid a issue that happens if you press "attack + right or left" buttons together when a character is highlighted, sometimes he will not be confirmed (@Kratus).
- Enabled a new flag in the "gotomainmenu" function, use 11 to escape directly to the title screen, works only in the select screen for now (@Kratus).
- Audio (sfx/music) volume now ranges 0 to 120 (previously 0 - 60) (@Kratus).
- Offense/Defense is more robust. Now you can add direct adjustments in addition to multipliers, and cap values to a min or max. See wiki for details.
- Flash position and layering now adjustable at global, attack, and body box with dynamic priority system. Useful for games with a greater emphasis on Z axis movement or wide objects. See wiki for details.
- New faction group system. Set membership, hostility, and damage properties from one or more of 26 (A to Z) faction groups. Great for RPGs and royal rumble style battles. See wiki for details.
- New animations:
- Blockrelease - Transition animation when entity stops blocking.
- Blockstart - Transition animation when entity starts blocking.
- SelectIn - Transition animation when cycling to model in select screen.
- Selectout - Transition animation when cycling away from model in select screen.
- Increased maximum simultaneous sound effects from 64 to 256. See wiki for details.
- Shadow configuration is much more flexible, including seperate handling of shadows on the ground and in the air. See wiki for details.
- Falldie and nodieblink consolidated into new property
death_config
with many more options. Now death behaviors can differ in the air vs. on the ground and you can configure a different set for each attack type. See wiki for details.
- Nodrop, nopain, and backpain consolidated into new property
pain_config
with more options. See wiki for details.
- Nopassiveblock, holdblock, and blockback consolidated into new property
block_config
with more options. See wiki for details.
- Enhanced Delay (edelay) improved with more options and ease of use. See wiki for details.
Script
In addition to the following items, there are dozens of new functions, constants, and other updates, far too many for a comprehensive list in one place. You will find additions not listed here documented in the wiki for the respective elements they support.
- New event
inputall.c
. Runs before command actions are processed for all players, active or not. Great for doing things like reversing player controls or catching input outside of gameplay. Returns following localvars.
player
: Player index executing the script.
- New entity property access functions
get_entity_property(<entity>, <property>)
and set_entity_property(<entity>, <property>, <value>)
. These new functions expose ALL entity properties. They are also lighter and faster than their legacy counterparts. Along with model properties, this is a massive update, exposing dozens of properties and supporting constants. See wiki for details.
- New model property functions. these are in progress and will be completed with another release in the coming weeks. They will expose all the model properties and sub properties like animations, collisions, etc. that are currently hidden. See wiki for details.
- Binding.
- Direct access to bind properties. Binding is (and always was) actually a sub set of entity properties, they were just hidden behind the legacy bindentity() function. Those properties are now exposed and added to with the following functions. See wiki for details:
get_bind_property(<bind>, <property>)
set_bind_property(<bind>, <property>, <value>)
- You can now read and write bind properties, not just write them. Leveraged properly this eliminates the need for keeping global variables to track your binds.
- Match is more powerful. You can now kill the bound entity on a frame mismatch. It's also possible to specifically define animations and frames to match to.
- Controllable by axis. Each axis can be bound to the target entity, a static position in the level, or nothing at all.
- Sort ID adjustment to control layering. You don't need to offset Z position to control which entity is in front or behind, allowing more precise binding.
- Override option allows you to disable certain entity behaviors while bound. For instance, you can disable special moves and landing behavior, again helping to create grappling moves with less workarounds.
- New events:
on_bind_update_other_to_self_script
: Executed on entity that is the target of a bind. If the entity is the target of multiple binds, this script executes once for each.
on_bind_update_self_to_other_script
: Executed by the entity that is binding itself to another.
- Drawmethod is now directly exposed through the drawmethod pointer. See wiki for details.
- New Global Config container for config settings that control engine operation outside of levels, models, and so on. See wiki for details.
get_global_config_property(<config>, <property>)
set_global_config_property(<config>, <property>, <value>)
- It is now possible to convert strings back into numeric values. See wiki for details.
- New system variants exposed, and existing variants documented. See wiki for details.
- More math functions exposed and documented. See wiki for details.
Improved Debugging
- Basic Properties debug option now displays current HP and MP.
- Debug options have improved centering and display property labels with Font 2 for better readability.
- openfilestream() now returns -1 on failure to load a file instead of throwing a shutdown error. You can use this to test for existence of various files in your module.
- New function isarray(<mixed>) accepts any type of variable. Returns true (1) if variable is pointer to an array, or false (0).
- Collision debug draws hard outlines around boxes. It's a small change, but this is in preparation for debugging walls and platforms.
- Onkillscript now populates a local variable trigger with a constant indicating reason for kill. This can be very useful to debug frustrating issues where entities seem to vanish for no reason. You can also supply a constant manually when running the killentity() function. See wiki for details.
- You can use openborconstant("PROPERTY_ACCESS_DUMP") in any new property function (ex. get_entity_property(<entity>, openborconstant("PROPERTY_ACCESS_DUMP")) to dump all the properties to log in a table format.
Bug Fixes
Known Compatibility Breaks
- Legacy getentityproperty(<entity>, "edelay", "mode") always returns 0.
- If legacy edelay header command is used for an "add" modifier, it is not possible to get this value with legacy getentityproperty() script function.
- I noticed a few
openborcosntant()
entries that are actually system variables with values that can change at run time. This is a pretty serious bug, and required moving access to openborvariant()
. If you get an alert that a constant does not exist, check system variables for it instead. Known entries:
- openborconstant("PLAYER_MIN_Z") -> openborvariant("player_min_z")
- openborconstant("PLAYER_MAX_Z" -> openborvariant("player_max_z")
- openborconstant("SCREENPANEL_Z") -> openborvariant("screen_panel_z")
- openborconstant("PANEL_Z") -> openborvariant("screen_panel_z")
- Hard coded sound sample access through
openborvariant()
is grouped and alphabetized. The new names are as follows:
- global_sample_beat
- global_sample_beep
- global_sample_beep_2
- global_sample_bike
- global_sample_block
- global_sample_fall
- global_sample_get
- global_sample_get_2
- global_sample_go
- global_sample_indirect
- global_sample_jump
- global_sample_one_up
- global_sample_pause
- global_sample_punch
- global_sample_time_over
Future Plans
These are some of the features and updates we have planned post release:
- Incremental updates - I am returning to the old model of smaller, more frequent updates. The build up and years long wait for 4.0 was obviously a mistake and I am scraping that development model.
- Locking/Compiling - If OpenBOR has a flaw, it's that it is too open and too easy for its own good. I am working on a setup for creators to compile their game data into a closed form without resorting to third party tools. This should open the door for cretors interesed in professional work or projects with original content and cut back a bit (though never fully eliminate) the proilferation of "EXs", "XXXs", "super-ultimate-whatever" hacks from outside the community that have caused some of our best creators to depart.
- HUD control - Toggle all or parts of the HUD during creation or runtime.
- Access to system clock - IOW, real world time and date).
- Push/space boxes - These are partially coded already.
- Completed model/animation access properties - Most properties are already coded and documented, but there are a few that need some last minute stabilizing. I considered another release delay, but have decided to release now and finish these up with another release in the next few weeks.
And much more...