Skip to content

Releases: jakubg1/OpenSMCE

Beta 4.8.0

22 Aug 00:34
Compare
Choose a tag to compare

Hello! We're back with another update. This is a big one, as it brings official Luxor: Amun Rising support to the engine! Keep in mind however, that mods for this game aren't supported - only the original game. Don't worry, support for mods will come at some point!

You might have noticed that the releases are getting rarer and rarer. This is unfortunately true, but each release comes packed with more and more features! And this release is no exception - it is the biggest release yet when it comes to added features!

As always, the full list of changes can be found here.

Thank you @bchantech for a few contributions!

Happy matching!

Changelog

Game Support

  • The Luxor: Amun Rising support is here!
    • The game converter will detect Luxor Amun Rising automatically and will convert the game properly.

Game Development

The Resource Manager has been overhauled, and as such the way resources are loaded has changed. Instead of having to be in a specific folder, the resources now need to have an appropriate extension or, if it's a JSON file, a JSON schema assigned to it.
The resources contained in the root game folder, as well as in config and maps subfolders, are not loaded.

This also means that all resources must be now referred to with a full path, starting from the game's root directory. However, assets can be now placed inside maps, which use the special syntax:

map:asset/to/load.json

If you're editing a configuration file inside of a map and want to access a resource in that same map, you can omit the map name:

:asset/to/load.json

You can find out more information about the new syntax here.

  • Changes in game data:
    • The files config/loadlist.json and config/music.json have been removed.
    • The modules folder has been removed.
    • Added Color Palettes!
      • They were in the game already, but did not have any configuration files assigned to it and needed to be explicitly mentioned in the config/loadlist.json file.
      • They are located in color_palettes/*.json by default (not config/color_palettes/*.json!).
      • Color Palettes, to be registered by the game, need their $schema field to end with schemas/color_palette.json.
      • The data contains only one field:
        • image - The image to be used as a color palette.
      • All references to Color Palettes as images must now reference color palettes' configuration files instead. This includes particles and spheres.
    • Added Music Tracks!
      • Similarly to Color Palettes, they were in the game already, but they were all specified in a single file - config/music.json.
      • They are located in music_tracks/*.json by default (not config/music_tracks/*.json!).
      • Music Tracks, to be registered by the game, need their $schema field to end with schemas/music_track.json.
      • The data is an object with just one field:
        • audio - The audio file to be used for this music track.
      • You are now supposed to put full paths to the music tracks in order to access them.
        • Example: f.musicVolume("menu", 1) -> f.musicVolume("music_tracks/menu.json", 1)
    • Added Score Events!
      • Score Events are objects which contain data about how many points should be given and how this information should be displayed for the user.
      • Score Events are stored by default in score_events/*.json, not config/score_events/*.json!
      • Score Events, to be registered by the game, need their $schema field to end with schemas/score_event.json.
      • They have five fields:
        • score - The amount of points to be given with this Score Event. Can be an Expression.
        • ignoreDifficultyMultiplier (optional) - If set, the score calculated by this Event will not be mutliplied by the current difficulty's score multiplier.
        • text (optional) - The text which should be displayed instead of the raw score value. Can be an Expression.
        • font (optional) - The font to be used for the FloatingText. If not specified, no FloatingText will appear.
        • fonts (optional) - A form used when the Score Event can produce texts with multiple different fonts.
          • It contains three required fields:
            • options - A list of Fonts to choose from.
            • default - The fallback font if the choice does not pick any of the options.
            • choice - An integer expression which evaluates to a number. That number is the item index from the options list, starting from 1. If an invalid index is returned, the font specified in the default field is used.
    • Added Path Entities!
      • Path Entities are used as a universal superclass for data-driven entities like Bonus Scarabs, Scorpions, Path Introductions, Pyramid Blockers, Black Holes and more.
      • They are located in path_entities/*.json by default (not config/path_entities/*.json!).
      • They have A LOT of fields:
        • sprite (Sprite) - The sprite to be used by the path entity.
        • shadowSprite (Sprite) - The shadow sprite to be used by the path entity.
        • spawnPlacement (string) - Where the path entity will be spawned at, or in relation to that place.
          • "start" - The path entity will be spawned at the beginning of the path, and will move forwards along the path.
          • "end" - The path entity will be spawned at the end of the path, and will move backwards along the path.
          • "furthestSpheres" - The path entity will be spawned at the furthermost sphere on the path. The entity will move forwards along the path.
        • spawnOffset (number) - If set, the initial location of the path entity will be moved by this amount in pixels, in the movement direction dictated by the spawnPlacement field.
        • speed (number) [>=0] - The starting speed of this path entity, in pixels per second.
        • acceleration (number) [>=0] - The acceleration of this path entity, in pixels per second squared.
        • maxSpeed (number) [>=0] - The maximum speed of this path entity, in pixels per second.
        • maxOffset (number) [>=0] - The maximum distance from the initial location of the path entity, in pixels.
        • destroyOffset (number) - The offset from either of the path ends this path entity is going towards, when this entity will be destroyed. Defaults to 0.
        • destroyTime (number) [>0] - If set, this path entity will be destroyed after this many seconds of existence.
        • destroyWhenPathEmpty (boolean) - If set, this path entity will be destroyed if there are no spheres on that path.
        • destroyAtClearOffset (boolean) - If set, this path entity will be destroyed once it reaches the path's clear offset (i.e. Bonus Scarabs).
        • particle (Particle) - The one-time particle that this path entity will be spawning every set amount of pixels.
        • particleSeparation (number) [>0] - The distance between each particle, in pixels.
        • renderParticlesInTunnels (boolean) - If set, the trail produced by the entity will be seen over the tunnels.
        • loopSound (SoundEvent) - A looping sound event which will be played during the path entity's existence. (path_entity)
        • collectibleGenerator (CollectibleGenerator) - A collectible generator which will periodically generate collectibles from this path entity. (path_entity)
        • collectibleGeneratorSeparation (number) [>0] - The distance between each collectible generator activation, in pixels.
        • destroyParticle (Particle) - The one-time particle that this path entity will spawn upon destruction/despawning.
        • destroySound (SoundEvent) - A sound event which will be played when this path entity is destroyed. (path_entity)
        • destroyScoreEvent (ScoreEvent) - The score event which will be executed when this path entity is destroyed. (path_entity)
        • destroyCollectibleGenerator (CollectibleGenerator) - The collectible generator which will generate collectibles when this path entity is destroyed. (path_entity)
        • canDestroySpheres (boolean) - If set, this path entity will destroy all spheres which are further than this path entity's position.
        • sphereDestroySound (SoundEvent) - A sound event which will be played when this path entity destroys a sphere. (path_entity, sphere)
        • sphereDestroyScoreEvent (ScoreEvent) - A score event which will be executed when this path entity destroys a sphere. (path_entity, sphere)
        • maxSpheresDestroyed (integer) [>0] - If set, this path entity will be destroyed after destroying this amount of spheres.
        • maxSphereChainsDestroyed (integer) [>0] - If set, this path entity will be destroyed after destroying this amount of sphere chains (scarabs).
        • All besides spawnPlacement and speed are optional.
    • Added Sphere Selectors!
      • They're used to... select spheres. They can be destroyed or their color can be changed.
      • They are located in sphere_selectors/*.json by default (not config/sphere_selectors/*.json!).
      • They have one field:
        • operations - A list of operations performed in sequence in order to form a list of spheres. Each item is an array, which contains the following fields:
          • type - A type of an operation. The only currently supported type is "add".
          • condition - A boolean expression evaluated for each sphere on the board. If the expression evaluates to true, the sphere is added to the list.
            • The expression has the sphere context, which is a different context than in Path Entities... It contains the following variables:
              • distance - Only Sphere Selectors which are not referenced from Collectible Effects have this variable. The distance from the se...
Read more

Beta 4.7.2

28 Nov 20:09
Compare
Choose a tag to compare

Hello! After six months, it's time for another update! This time around, we've focused on even more parity changes with Luxor 1. This includes tweaks to sphere and powerup physics, sphere reload animation, sphere rolling sound, and a few other minor improvements!

We didn't forget about other features, such as path introduction, custom sphere sizes, smooth color change for reticals or experimental Z-axis support for paths!

As always, the full list of changes can be found here.

Thank you @bchantech for two contributions!

Changelog

Game development

  • Changes in gameplay.json:

    • Three new fields have been added to the sphereBehavior section:
      • attractionForwardDecceleration - Used when the sphere group is magnetizing, but moving forward at the same time.
      • attractionForwardDeccelerationScarab - As above, but only when magnetizing to a scarab.
      • backwardsDecceleration - How fast the spheres slow down while moving backwards.
    • In the scorpion section, two new optional fields have been added:
      • offset - The starting offset of the Scorpion, counting from the end of the path, in pixels.
      • acceleration - How fast does the Scorpion accelerate per second.
    • A new optional section has been added: pathIntroduction.
      • Inside, four required fields are located:
        • particle - A one-time particle packet which spawns throughout the path.
        • speed - How fast does the trail go, in pixels per second.
        • separation - The distance between each particle, in pixels.
        • separatePaths - If set, each path will be introduced immediately after the previous one finishes. Otherwise, all paths will be introduced simultaneously.
    • The collectibleBehavior section has been removed.
      • The data inside has been moved to the collectible configs themselves.
  • Changes in sphere data:

    • A few new fields have been added:
      • size - The sphere diameter in pixels. Defaults to 32.
        • The sprite will be resized accordingly based on the size.
      • shadowOffset - The shadow sprite offset, in pixels. Defaults to (4, 4), like it was before.
  • Changes in map data:

    • Added a new optional field to path node: scale.
      • The sphere size on that node will be multiplied by this value.
      • This feature is not fully supported yet, and is filled with bugs - use at your own risk!
  • Changes in level data:

    • Added two optional fields:
      • warmupLoopSound - A looping sound effect which is playing at the beginning of the level, while the spheres are rolling.
      • failLoopSound - A looping sound event which is playing while the spheres are rolling into the exit node.
  • Changes in collectible data:

    • Added two new required fields:
      • speed - The starting speed of this Collectible. It's a Vec2 expression, like beforehand.
      • acceleration - The acceleration of this Collectible. It's a Vec2 expression, like beforehand.
  • Changes in shooter data:

    • A few new fields have been added, all optional:
      • hitboxOffset - Defaults to (0, 0). It changes the relative position of the shooter's hitbox.
      • shotCooldownFade - The duration of the fade in animation. During this time, you still can't shoot the sphere.
      • destroySphereOnFail - If set, the sphere held by the shooter will show its destroy particles if the level is lost.
    • In the reticle section, two new optional fields have been added:
      • colorFadeTime - The time which the reticle should take to fade into the new color, in seconds.
      • nextColorFadeTime - The time which the reticle's next color indicator should take to fade into the new color, in seconds.
  • Changes in color generator data:

    • The near_end type has been renamed to nearEnd.
    • The following fields have been renamed:
      • has_to_exist -> hasToExist
      • select_chance -> selectChance
      • paths_in_danger_only -> pathsInDangerOnly
      • colors_remove_if_nonexistent -> colorsRemoveIfNonexistent
    • The colorsRemoveIfNonexistent field is now optional.
  • Changes in Expressions:

    • A few new functions have been added:
      • sin(theta) - Returns the sine of the given angle, in radians.
      • cos(theta) - Returns the cosine of the given angle, in radians.
      • tan(theta) - Returns the tangent of the given angle, in radians.
      • max(a, b) - Returns the bigger value of a and b.
      • min(a, b) - Returns the lower value of a and b.
      • clamp(a, b, c) - Returns a clamped to the minimum of b and the maximum of c.

General

  • The game will now load resources in 1/20-second intervals, loading as much resources as it can in every such interval. This further improves game loading times.
  • Discord Rich Presence will now detect whether the user's username has been migrated and will not show a #0 discriminator in that case.
  • The Luxor Game Converter script is now available for Linux users - thank you @lottieratworld for converting the script!

Gameplay

  • The default sphere rolling speed is now 2/pi, as it should have been the whole time.
  • The sphere appending animation has been once again tweaked, and it's now even smoother than before.
  • The sphere's shadow now rotates alongside the sphere itself.
  • The aiming reticle no longer disappears when the shooter is reloading.
  • The F7 debug menu has got a few additions:
    • A few helper lines are drawn when a sphere is being appended to a sphere group.
    • The shooter's hitbox will be shown.
    • Sphere Group origins will be marked as white dots.
  • Vanilla Luxor gameplay:
    • A few parity changes have been implemented, such as adjusted sphere speeds, powerup speeds and accelerations, new sphere reloading animation, sphere breaking animation when the level is lost, and sphere rolling sounds. The fireball has been nerfed.

Boot Screen

  • A new text appears when there are no games installed:
    obraz
  • Luxor_appendix no longer appears as a pre-installed game - it's not a full game!

Game Documentation

Important changes have happened since last release, which are intended to make the config structure updates easier:

  • The game documentation has got a new set of colors which includes a dark background, so it's kind of a dark mode.
  • The source of all game documentation will be a set of DocLang (*.docl) files, located in the /doc/game/data folder.
    • Right now, only JSON schemas are built from these files. This will extend to HTML documentation and config classes, hopefully in the next update.
  • The HTML documentation files have been moved to /doc/game/out. They are also outdated, as there's currently no way to generate them.

Bugfixes

  • [#113] Fixed a bug where clicking a button and moving the cursor away would still perform the click actions.
  • Performing a version check could result in a crash due to the POST request function sometimes returning extra garbage before and after the desired contents. This doesn't matter at all since this feature is still disabled.
  • The game would crash when starting a new level while the F7 debug menu was turned on.
  • Turning Ultimately Satisfying Mode on or off via profile change would need a game restart in order to apply these changes.
  • A new sphere train could spawn when all objectives were reached right after clearing the board. (This bug is actually NOT fixed!)

Beta 4.7.1

19 May 00:26
Compare
Choose a tag to compare

Time for Beta 4.7.1. Not so much added considering how much time has passed.
This will be the last version for a long while: I've made the decision to feature freeze this project until all of the following are fully done:

  • Code documentation
  • Game documentation (including schemas for ALL files)
  • Config classes (for ALL .json files)
  • Incorporation of expressions everywhere when possible (particles, powerup generators, etc.)

After the above things are done, betas will resume starting from 4.8.0 and will focus on adding new features which are required to bump to Beta 5.0.0.

As always, the full list of changes can be found here. Thank you @ShamblesSM for a few contributions!

Happy matching!

Changelog

Game development

UI2

  • An unfinished UI2 is available in this version.
  • No documentation yet, but schemas are available.
  • You can switch between UI1 (the current UI system) and UI2 with a new parameter in the main game config file, as shown right below.

Changes in game config:

  • A new field, useUI2 has been added.
    • If set to true, the game will use UI2 instead of legacy UI.
    • UI2 files are located in ui2 folder, the legacy UI files can still be loaded from ui.
  • In the richPresence section, a new field has been added: applicationID.
    • This field is optional. If specified, this will be the application ID shown when the player is playing that game, instead of a default OpenSMCE application.

Changes in shooter data:

  • A new field has been added, ballPos.
    • The primary ball position. Use {x = 0, y = 5} to retain the current behavior.

Changes in expression format:

  • Added support for multi-parameter functions.
  • Expression evaluation now uses an indexed table, instead of a string of if statements. This makes it go faster.
  • Added new functions:
    • vec2(a, b) returns a Vec2 object. You can perform arithmetics on them as on numbers, except modulo and power.
    • randomf(a, b) returns a random floating point value from range [a, b).

Changes in gameplay.json:

  • The field collectibleBehaviour has been renamed to collectibleBehavior.

  • Inside this section, the speed and accelerations fields are now of an experimental Expression type.

    • This Expression must evaluate into a particular type, in this case Vec2.
    • Because there is a fixed number of types in JSON, Expressions are strings with a special formatting: "$expr{expression}".
    • Example: $expr{vec2(randomf(-100, 100), randomf(-250, -150))}.
  • Added a new section, called net.

    • It's required only when you have Nets in your game.
    • The section contains two fields:
      • "particle" - A persistent particle packet which will be spawned and destroyed when the net appears and disappears, accordingly.
      • "posY" - The Y position of the Net, in pixels.
      • Both fields must exist.
  • You can no longer create malicious UI scripts which could do potentially harmful actions, like deleting files from any place on your computer.

General

  • The log file will now be saved when the engine crashes. This means it will include the crash message, too.
  • It is now possible to bypass the Boot Screen and launch straight into a game of your choice.
    • To accomplish this, create an autoload.txt file with the name of the game. That game will be automatically loaded on engine startup.
  • The settings.json file has been moved out of the engine folder and is now located in the root directory.
    • The engine folder has been removed.
  • When loading the game, the game will no longer crash when it tries to load level files with wrongly formatted names.
  • The Unifont font has been moved to the assets folder.
  • A new font has been added: DejaVu Sans.
    • This font is now used in the Boot Screen instead.
    • This is because the upcoming 12.0 version of LOVE2D changes its default font, which breaks the Boot Screen.

Gameplay

  • The spheres will now be shot when no UI button is pressed, instead of the mouse cursor being at y<560.
  • Changes to F4 debug screen:
    • Colors which are not present on a board will now be hidden in the Color Manager section.
    • The level section will now properly show objectives, instead of a broken progress display.

Boot Screen

  • The build number is no longer shown in Boot Screen or in Discord Rich Presence.
  • Instead, a version status message will pop up. (inactive in this version)
  • Overhauled the settings screen:
    • Now it's more consistent with the main boot screen.
    • The checkboxes have been simplified to colored rectangles and are now arranged similarly to games in the game list.
    • Added tooltips which describe the option which the mouse is currently hovering.

Bugfixes

  • The native resolution now works properly during gameplay, when resizing the window, going back to Boot Screen and is no longer hardcoded.
  • Spheres broken by Scorpions no longer count twice in the progress bar.
  • Fixed Nets not saving when saving a level.
  • The danger color counter could glitch out after using a Color Cloud or a Color Replacer.
  • Fixed a bug which caused to improperly load assets when at least one of the resource types in the Load List was empty.
  • Fixed Expressions failing to tokenize when they contain a false keyword.

Beta 4.7.0

05 Jan 23:32
Compare
Choose a tag to compare

New year, new update! And this time it's a big, biiig, BIIIIIG update! Beta 4.7.0 adds a ton of new features!

Shoutout to @Makowo for his first contribution!

As always, the full list of changes can be found here.

Happy matching!

Changelog

Game development

Changes in shooter data:

  • Zuma Shooter: A new mandatory field has been added: movement.
    • There are two types of shooter movement, in the type field inside:
      • "linear" is the Luxor-styled shooter movement. The shooter will move on a line along X axis. Additional fields include:
        • xMin - The minimum X position of the shooter.
        • xMax - The maximum X position of the shooter.
        • y - The constant Y position of the shooter.
        • angle The constant rotation angle of the shooter, in degrees. 0 means up.
        • All fields are mandatory numbers.
      • "circular" is Zuma-styled shooter movement behavior. The shooter is locked in one place, but is able to rotate in any direction. Additional fields include:
        • x - The X position of the shooter.
        • y - The Y position of the shooter.
        • Again, both should be numbers.
  • Better Shooter appearance customization: New fields were added, so the appearance of the shooter is much less hardocded.
    • spriteOffset ({"x":0,"y":0}) - The offset of the main shooter sprite.
    • spriteAnchor ({"x":0.5,"y":0}) - The anchor point of the main shooter sprite.
    • shadowSpriteOffset ({"x":8,"y":8}) - The offset of the shooter shadow sprite.
    • shadowSpriteAnchor ({"x":0.5,"y":0}) - The anchor point of the shooter shadow sprite.
    • nextBallOffset ({"x":0,"y":21}) - The offset of the next ball indicator sprite.
    • nextBallAnchor ({"x":0.5,"y":0}) - The anchor point of the next ball indicator sprite.
    • sounds - A table with two fields:
      • sphereSwap ("sound_events/shooter_swap.json") - The sound event played when two spheres are swapped with each other.
      • sphereFill ("sound_events/shooter_fill.json") - The sound event played when the shooter gets new spheres.
    • All of these fields are required; in order to retain the current behavior, use values in brackets.
  • Two new fields have been added:
    • shotCooldown - The cooldown between shots.
    • multishot - If set, there can be more than one Shot Sphere on the board.
    • nextBallSprites - Contains next ball sprites for all possible sphere colors, keyed by their ID.
      • Each such object has the following fields:
        • sprite - The path to the next color sprite for that shooter when that's the current next color.
        • spriteAnimationSpeed - The speed of the next sprite animation, in frames per second. Optional; by default it will not be animated.

Changes in level data:

  • Different shooter positions per level: A new optional field has been added, shooter.
    • It contains two fields:
      • name - The name of the shooter, defined in config/shooters/*.json. Defaults to "default".
      • movement - Shooter movement data. The structure is exactly the same as in the shooter data (look above).
        • If not specified, defaults to the movement specified in the shooter data itself.
  • Different/multiple objectives per level: Added a new field, objectives.
    • It's a list of objectives which can be defined for each level.
    • Each objective has two fields:
      • type - Can have the following values:
        • "destroyedSpheres" - if the target describes how many spheres have to be removed from the board,
        • "timeElapsed" - if the target describes how many seconds the level has to be survived for,
        • "score" - if the target describes how much score in that level needs to be gained.
      • target - The amount of spheres/seconds/points needed at minimum to consider the target reached.
  • The field target has been removed.

Changes to sphere data:

  • A new field has been added: destroySound.
    • It is a sound which only works when a sphere of that type is crushed (i.e. a scarab).
    • This is a temporary solution; once more robust sound events are introduced, the crush check will be done in the sound event file instead.
  • A new optional field has been added: spriteRollingSpeed.
    • When defined, the sphere sprite will roll with that speed in frames per pixel. Defaults to 1.
  • The fields nextSprite and nextSpriteAnimationSpeed have been removed.
    • Define next color sprites in the shooter instead. See above for description.

Changes in sphere effect data:

  • Added a new field, ghostTime.
    • If set, the spheres will turn into ghosts for a set amount of time when destroyed using this effect.
      • More about ghost spheres in this commit's description.
  • A number of fields have been renamed, as follows:
    • infection_size -> infectionSize
    • infection_time -> infectionTime
    • apply_sound -> applySound
    • destroy_sound -> destroySound
    • destroy_font -> destroyFont
    • destroy_particle -> destroyParticle
    • destroy_collectible -> destroyCollectible
    • level_loss_protection -> levelLossProtection
    • can_boost_combo -> canBoostCombo
    • can_boost_chain -> canBoostChain
    • apply_chain_multiplier -> applyChainMultiplier
    • can_keep_combo -> canKeepCombo
    • cause_check -> causeCheck

Changes to gameplay.json:

  • In the sphereBehaviour section, six new fields have been added:
    • joinSound - A sound event to be played when two groups of spheres hit each other.
    • newGroupSound - A sound event to be played when a new sphere chain appears on the board.
    • noScarabs - If set to true, there will be no scarabs at the end of the sphere chains.
    • knockbackTime - Optional. If set, this will be the time during which the spheres' knockback speed will be "locked" and will not decrease over time.
    • knockbackStopAfterTime - Optional. If set to true, after the knockbackTime elapses, the spheres will stop abruptly rather than slowly deccelerating.
    • permitLongMatches - If true, the spheres will try to make the biggest clump possible before matching together.
  • The invincible_scarabs field has been renamed to invincibleScarabs.

Changes in expression format:

  • The parser has been completely rewritten, however all existing expressions should work as before.
  • String support has been added!
  • New operators have been added:
    • a^b raises a to the power of b.
    • a..b concatenates any two values together. If they are not strings, they are converted to them.

Changes in UI script:

  • Added four new functions:
    • levelGetObjectives() - Returns a list of objectives the current level has. Each objective has four fields:
      • type (string) - the same as in the level data itself.
      • target (number) - The target value of the objective, specified in the level data.
      • progress (number) - The current value of the objective.
      • reached (boolean) - Whether this objective has been reached (progress >= target).
    • levelGetNewRecord() - Returns true if the currently played level for the current profile has yielded the most score in this level's history.
    • levelGetCombo() - Returns the current level combo.
    • loadingGetProgress() - Returns a percentage of loaded assets during the game loading.
  • Two new callback functions have been added:
    • init - Is executed at the very initialization of the splash.
      • Example contents (which makes it work like before):
      function c.init(f)
        f.getWidgetN("splash"):show()
        f.getWidgetN("splash"):setActive()
        f.musicVolume("menu", 1)
      end
      
    • click - Fired when the player clicks anywhere on the screen.
      • Has no parameters, so it's only usable in "click anywhere to continue" prompts.
  • The levelComplete callback no longer conveys a boolean parameter which said whether the player has earned the new high score for this level.
    • Use the newly introduced levelGetNewRecord function instead.
  • Added an optional integer parameter to the levelGetProgress function.
    • If supplied, the game will return the progress of n-th target defined in the level.
    • By default, the function will return the progress of the first target.
  • Removed the hardcoded progress bar update and the button appearing.
    • Add the following code instead, to the tick callback:
    -- update splash screen
    local splash = f.getWidgetN("splash")
    if splash then
      local progress = f.loadingGetProgress()
      f.getWidgetN("splash/Frame/Progress").widget.valueData = progress
      if progress == 1 then
        f.getWidgetN("splash/Frame/Button_Play"):show()
      end
    end
    

Changes in config.json:

  • Some fields have been renamed, as follows:
    • window_title -> windowTitle
    • engine_version -> engineVersion
    • native_resolution -> nativeResolution
    • rich_presence -> richPresence

Changes in config/highscores.json:

  • The default_scores field has been renamed to defaultScores.

Changes in collectible generator data:

  • A few types have been renamed.
    • collectible_generator -> collectibleGenerator
    • random_pick -> randomPick
    • color_present -> colorPresent
    • cmp_latest_checkpoint -> cmpLatestCheckpoint

Changes in level_set.json:

  • The level_order field has been renamed to levelOrder.
  • The level entry type no_repeat has been renamed to noRepeat.
  • The level entry field unlock_checkpoints_on_beat has been renamed to unlockCheckpointsOnBeat

Gameplay

  • 3D sound is now working much better: the balance is no longe...
Read more

Beta 4.6.1

18 Nov 06:22
Compare
Choose a tag to compare

Hello there, it's time for Beta 4.6.1! This is the last version of this engine this year. I hope the next year will bring even more exciting features! To wrap up this one though, we are introducing a bunch of changes largely regarding the shooter, and an important bugfix.

Before we start out, shoutout to @Shambles_SM for a meaningful contribution to this release (reticle sprites)!

As always, the full list of changes can be found here.

Happy matching!

Changelog

Game development

In the config directory of a game, a new folder called shooters has been created.
For now, the only shooter possible is hardcoded to default, hence the shooter's settings are now stored in shooters/default.json.

The up-to-date schema is available. Note that the documentation is NOT updated.

Changes in shooter data:

  • Added new fields:
    • sprite (string) and shadowSprite (string) allow for change of the appearance of the shooter.
    • speedShotBeam.sprite (string) - A sprite file to be used to draw the speed shot beam.
    • hitboxSize (Vector2) - The size of the Shooter's hitbox in pixels.
  • The shotSpeed field has been renamed to shootSpeed.
  • Speed shot data has been serialized to separate objects.
    • The renames are as follows:
      • speedShotBeamRenderingType -> speedShotBeam.renderingType
      • speedShotBeamFadeTime -> speedShotBeam.fadeTime
      • speedShotBeamColored -> speedShotBeam.colored
      • Note that the speedShotParticle is not migrated and remains a separate field in the main object.
    • A new section, reticle, has been added. It contains the following fields (all of them are optional):
      • sprite (string) - The reticle sprite. If not defined, the old line-based reticle will be displayed instead.
      • offset (Vector2) - The offset of the reticle sprite.
      • nextBallSprite (string) - The sprite of a reticle's next sphere indicator. If omitted, it will not be displayed.
      • nextBallOffset (Vector2) - You probably get it by analogy.
      • radiusSprite (string) - The sprite of a circle indicator used when aiming with a range sphere, such as a fireball or a color cloud.

Changes in config/gameplay.json:

  • In the sphereBehavior section, a new field, called luxorized has been added.
    • If set to true, the engine will enable a few changes to the sphere physics.
    • For now, these are only related to knockback.
      • The chain combo is preserved as long as any sphere is rolling back, not only when the spheres are magnetizing.
      • Chaining spheres now cancel momentum for the frontmost part.
  • In the bonusScarab section, three new fields have been added.
    • shadowSprite is a sprite which should be used to draw the Bonus Scarab's shadow.
    • loopSound is a path to a sound event which should be played in a loop.
    • destroySound is a sound event which will be played when the Bonus Scarab is destroyed.
  • In the scorpion section, five new fields have been added.
    • shadowSprite, loopSound and destroySound - as above.
    • sphereDestroySound is a sound which should be played when the Scorpion destroys a sphere.
    • destroyGenerator is now properly documented. It did exist before.
      • Additionally, a hardcoded check which dictated whether the collectibles would spawn has been removed.
  • The shooter section has been migrated to shooter data and is removed from here.

Changes in sphere data:

  • The field destroy_collectible has been renamed to destroyCollectible.

Changes in collectible effect data:

  • A new effect type, activateNet has been added.

    • It contains one parameter, time, which is the duration of the net.
    • Currently, the net has no graphical representation. This will be added at some point.
    • The net Y position is hardcoded to 550.
  • Changes in level data:

    • An optional field, ambientMusicName has been added.
      • Defines the name of music which is played all the time during this level.
      • This does not interfere with normal level music.
  • Changes to expression format:

    • A negation operator has been added.
      • The syntax is as follows:
        • !<thing to negate>
        • For example, !true will return false.
      • Note this is a binary operator; use with numbers may produce undefined results or crash the game.
    • Added conditional variables.
      • Format: [varname|expr]
      • Loads a variable named varname, but when it doesn't exist, expr is substituted instead.
        • expr can be any Expression, but it may not contain []| characters.
  • Now during a sphere destruction, a crushed variable will be set to a boolean value indicating whether this was a scarab which has been crushed.

  • The exprt command in debug console now prints its debug value in Reverse Polish Notation (the way they are stored).

Gameplay

  • A bunch of changes regarding sphere physics has been made, to bring it even closer to the original Luxor feeling.
    • You can turn them off by setting "luxorized": true to "luxorized": false in games/Luxor/config/gameplay.json.
    • Let me know if you like the changes!
  • Luxor 2-like collectible changes have been reverted.

Boot Screen

  • There's now a build number in the corner, used for debugging purposes.

Code

  • Quite a big portion of code documentation has been added. If you've checked out directly from GitHub, you may notice it's already been there for a long time. But oh well, this is the first release since that change, so I'm including this in the changelog as well!
  • Additionally, a Visual Studio Code snippet has been created to ease class creation.
    • The keyword is !class.
  • The converter is nearly ready to be included into a separate repository. Stay tuned!

Bugfixes

  • [#79] TTF fonts did not work in fused/compiled mode. That is, when not running the code itself. If you don't understand, they just did not work at all for you.
  • Fixed level nil in Rich Presence and the game crashing when trying to store you on a leaderboard.
  • Ultimately Satisfying Mode now works again. Yay....
  • Fixed scarabs dropping gems even when crushed :D

Beta 4.6.0

15 Aug 15:00
Compare
Choose a tag to compare

Today we are releasing Beta 4.6.0. This version adds JSON schemas, stone spheres and a few lesser changes of mostly technical nature.

As always, the full list of changes can be found here.

Changelog

Game development

  • JSON schemas have been introduced.

    • They are helper files for Visual Studio users in order to standardize JSON files made by potential modders.
    • Currently only a few files are supported, let's hope it won't take forever to introduce this to other files.
    • You can try them out, the appropriate schemas (if they exist) are linked in i.e. config/gameplay.json.
  • Expressions have been added!

    • They can be created from a string which is just... well, an expression.
      • For example: 2+2 evaluates to 4 and -(8/0.5)+3 evaluates to -13.
    • Expressions support numbers and booleans only (for now, that is). The operations that can be performed on them are as follows:
      • Arithmetic: a+b, a-b, a*b, a/b, a%b
      • Comparison: a==b, a!=b, a>b, a<b, a>=b, a<=b
      • Boolean logic: a||b, a&&b
      • Unary minus: -a
      • Parenthesis: e.g. (a+b)/c
      • Ternary if: (a?b:c)
      • Functions: floor(a), ceil(a), round(a), random()
      • Access to contextual variables: [<name>]
    • You can test the expressions yourself by entering a command expr <expression> in the console.
    • Later on, along with parameters, expressions will be a key part in doing advanced maths within the configuration files.
    • A few events which happen in the game already have some parameters.
      • Sphere destruction sets four expression variables:
        • length - How many spheres have been destroyed.
        • comboLv - The level combo level at the moment of sphere destruction.
        • chainLv - The chain combo level at the moment of sphere destruction.
        • comboBoost - A boolean. If true, the player has committed to the destruction by shooting a sphere.
      • Both sphere destruction and bonus scarab explosion:
        • offset - A distance from the beginning of the path, in pixels.
        • offsetE - As above, but counted from the end of the path.
        • distance - A percentage of the path counted from the beginning.
  • Changes in sphere data:

    • Added a new field, nextSpriteAnimationSpeed.
      • If set, deternimes the speed of the next sprite animation, in frames per second.
    • Added a new optional field, destroy_collectible.
      • When a sphere is destroyed, it will spawn collectibles from that generator, if provided.
      • Scarabs use this. Note: crushed scarabs also spawn collectibles. This will be fixed later.
    • Added a new field: type.
      • Possible values: "normal", "stone".
        • If "stone", the sphere is a stone sphere.
          • Stone spheres are spheres which are destroyed upon a neighboring match.
  • Changes in collectible generator data:

    • Added a new entry type, "combine".
      • Evaluates a list of given entries and returns a list of all collectibles generated.
      • Syntax in the documentation.
  • Changes in sphere effect data:

    • The fields can_spawn_coin and can_spawn_powerup have been removed.
    • Added a new optional field: destroy_collectible, which is a collectible generator used when the spheres under that effect are destroyed.
    • Added a new field: cause_check.
      • When set to true, two groups of spheres of the same sphere effect which happen to collide will behave as one, ignoring the "cause" sphere.
  • Changes in game module:

    • The coinSpawn() and powerupSpawn() methods are no longer used.
    • Soon, the whole game module system will be removed entirely.
  • Changes in level data:

    • The fields powerupGenerator and gemGenerator have been removed.
  • Changes in color generator data:

    • The fallback field can now contain another color generator data. This allows for nesting.

Gameplay

  • Changes from the previous release have been reverted.
  • Frozen groups will no longer magnetize.
  • "Daisy-chained" sphere chains will now stop if the frontmost one has some immobile spheres.
  • When two sphere groups join, now both of them have their fragile spheres destroyed.
  • During game loading, sounds will now load much faster.

Code

  • Sphere Entities now move smoothly between shot spheres and spheres.
  • Simplified algorithm for Sphere Chain collision calculation.
  • Sphere debug screen (F6) now displays the distance between sphere chains.

Bugfixes

  • Buttons on 2nd and further pages in the Boot Screen game list were not highlighted properly.
  • Color counters now work properly for non-positive sphere IDs.
  • The sphere chains would overlap if invincible scarabs were turned on and the frontmost chain was frozen.

That's it for now. Happy matching!

Beta 4.5.0

04 Jun 16:44
Compare
Choose a tag to compare

It's time for another big release: Beta 4.5.0, which introduces a lot of changes, mostly regarding spheres.

As always, the full list of changes can be found here.

Changelog

Game development

  • Changes in level effects:

    • The level effects: "slow", "stop" and "reverse" have been removed.
    • A new level effect has been added, "speedOverride".
      • It contains the following fields:
        • speedBase - A value to be added to the current path speed.
        • speedMultiplier - A value which the current path speed will be multiplied with.
        • decceleration (optional) - A different sphere decceleration value to be applied.
        • time - How long the effect will be.
      • Speed overrides do not stack. If one is applied, it overwrites the current one, if exists.
    • A new effect type has been added, "setCombo".
      • It has one parameter, combo.
      • When executed, the level combo counter is set to the combo value.
  • Changes to config/gameplay.json:

    • In the gameplay section:
      • The fields slowDecceleration, slowSpeedMultiplier and reverseSpeed have been removed.
        • Use these values as parameters for the speed override effects instead.
      • Added a new field: invincible_scarabs.
        • It's a boolean value. If set to true, scarabs cannot be crushed by spheres behind them.
          • Such daisy-chained trains may behave slightly differently than normal trains, especially in terms of movement.
    • In the bonusScarab section, new fields, coinGenerator and destroyGenerator have been added.
      • The first one is spawned periodically depending on coinDistance, the second one is spawned when the Bonus Scarab explodes.
    • In the scorpion section, added a new field: destroyGenerator.
      • It is spawned when the Scorpion gets destroyed, but with a hardcoded check, which will be rectified in the future.
  • Added a new folder: config/sphere_effects.

    • It contains sphere effects, a name of each is their file name.
    • Each sphere effect contains the following fields:
      • particle (optional) - A persistent particle packet to be assigned to a sphere when under such effect.
      • time - The duration of the effect, in seconds. Starts counting down when the infection size equals to 0.
      • infection_size - An initial infection size of this effect.
      • infection_time - Every how long the sphere under that effect will afflict its neighbors, in seconds.
      • apply_sound (optional) - A sound event to be launched when a sphere gets the effect.
      • destroy_sound - A sound event to be played when spheres under that effect are destroyed.
        • If set to "hardcoded", the match will use a hardcoded collapse sound.
      • destroy_font - A font used for the score.
        • If set to "hardcoded", the font used will be picked from a matchFont field of a corresponding "cause" sphere.
      • level_loss_protection - If set to true, sphere groups which contain spheres under such effect will not cause a level loss if reached the end point.
      • immobile - If set to true, sphere groups which contain such spheres will be unable to move.
      • fragile - If set to true, spheres with that effect upon impact with a shot sphere will be destroyed.
      • destroy_particle - A one-time packet which is launched when a sphere under that effect is destroyed.
      • can_boost_combo - Whether a combo counter should be incremented if other conditions are passed.
      • can_boost_chain - Similar one for chain combo counter.
      • apply_chain_multiplier - If true, the score will be multiplied by the current chain combo value.
      • can_spawn_coin - If true, a level-defined collectible generator will be used.
      • can_spawn_powerup - If true, a level-defined collectible generator will be used.
      • can_keep_combo - If set to true, any shot spheres which have this effect will prevent the combo value from dropping to 0.
    • A single sphere cannot have two same effects applied at the same time, but it can have any number of different effects applied at the same time.
    • Sphere effects allow powerups like Poison and Freeze to be created.
  • Added a new folder: config/color_generators.

    • It contains shooter color generators. Each generator is one file, and the generator name is the same as the file name.
    • Each generator has these fields:
      • type - a type of the generator. For now, these types are supported:
        • "random" - Returns a random color from the list.
        • "near_end" - Selects a random path and selects a color from the group which is the closest to the end point.
      • colors - A pool of colors to be generated.
      • fallback - When the algorithm does not find any spheres or fails, this value is returned instead,
      • colors_remove_if_nonexistent - If a sphere of a color which is in this list is in the shooter and does not exist on the board, it gets removed.
    • The "random" type has additionally this field:
      • has_to_exist - if set to true, a color will not appear if it is not already on the board.
    • The "near_end" type has additionally these fields:
      • select_chance - A percentage value which determines how likely is the sphere to be picked. If it is not, then a second closest sphere is picked, and so on.
      • paths_in_danger_only - If set to true, paths which are not in danger are not taken into account.
        • When there are no paths in danger, the algorithm will still try to pick any non-empty path first before giving up.
  • The files config/collectibles.json and config/spheres.json have been split into collectibles and spheres folders there, respectively.

    • Now every collectible/sphere is a single JSON file.
      • A name for a collectible file is X.json, where X is the collectible name.
      • A name for a sphere file is sphere_X.json, where X is the sphere ID.
        • The sphere ID still must be an integer number.
    • The data for both spheres and collectibles remain largely unchanged, however there are new fields described below.
  • Changes in UI script:

    • Added a new UI callback: comboEnded with two parameters:
      • 1: The combo multiplier.
      • 2: The total score from combo.
        This can be handled by UI script for example to show big combos.
  • Changes in sphere data:

    • From the "lightning" sphere shoot behavior type, a field resetCombo has been removed.
    • Instead, a new field has been added to the root sphere data, shootEffects. It's optional.
      • It's a list of effects to be executed when the sphere is launched, similarly to Collectibles.
    • The field generatable has been removed.
    • A new optional field, effects, has been added into the hitBehavior object of type "default".
      • It's a list of names of effects to be applied to the shot sphere.
  • Changes in level data:

    • Two new fields have been added, colorGeneratorNormal and colorGeneratorDanger.
      • These are the names for a shooter color generator used during normal gameplay and during danger, respectively.
    • Added a new field: matchEffect.
      • It's a match effect ID which is going to be used when spheres are matched.
  • Changes in font data:

    • Added a new field, type.
      • Can have two values:
        • "image" - in that case, the rest of the fields stay the same.
        • "truetype" - in that case, the following fields are applicable:
          • path - A path to the font file. Use a font_files folder in the root game folder.
          • size - A size of the font.
          • color - A font color.
        • Example:
        {
            "type": "truetype",
            "path": "font_files/unifont.ttf",
            "size": 36,
            "color": {
                "r": 0.95,
                "g": 0.8,
                "b": 0
            }
        }
        
  • Ordinary color matches/chains now, instead of destroying spheres immediately, apply a sphere effect.

  • Files with extensions other than .json will now be ignored in any subfolders located in config. This makes .DS_Store files to be ignored, and therefore saves a crash.

Gameplay

These are temporary changes and will be reverted in the next release.

  • Bonus Scarabs drop coins and gems, similarly to Luxor 2.
  • After every combo, a score value will appear in the console on the screen.

Code

  • Spheres now use sphere entities for rendering.
    • This is an internal change; no files are changed.
  • JSON parser error now shows the file name. This allows for quicker bug-hunting.
  • Rearranged how the colors in the Color Manager are stored.
  • Added _MathIsValueInTable(t, v).

Boot Screen

  • If the game count exceeds 8, excess games are now put on the next pages instead of overflowing the list.

Bugfixes

  • Code: Fixed a bug in _GetDirListing() where the extension filter did not work.

That's it for now. Happy matching!

Beta 4.4.0

26 May 12:45
Compare
Choose a tag to compare

Time for Beta 4.4.0! It introduces a few changes, mostly regarding collectibles. Enjoy!

As always, the full list of changes can be found here.

Changelog

Game development

  • The config/powerups.json file has been renamed to config/collectibles.json.

  • A few changes inside that file have been made as well:

    • Some new fields have been added:
      • pickupParticle - A one-time particle packet which is launched when that collectible is collected.
      • spawnSound - A sound effect launched when the collectible is spawned.
      • dropEffects (optional) - A list of effects to be executed when a powerup falls off the board without the player catching it.
    • The fields pickupName and pickupFont are now optional. If not set, no label will spawn upon picking that collectible up.
    • The field effects is now also optional.
  • A few new level effects have been added:

    • grantScore - Adds score to the player. It has one field, score - an integer value determining how much score to add.
    • grantCoin - Grants a coin to the player.
    • incrementGemStat - Adds 1 to the gem stats for the current level.
  • Level format changes:

    • A new field, gemGenerator, has been added. It contains a reference to the collectible generator which is now used to spawn gems.
    • The gems field has been removed.
  • Collectible generator changes:

    • The collectible generators data structure has been completely revamped.
      • Each collectible generator is an entry of a certain type.
      • Every collectible generator entry evaluates to a list of collectibles.
        • That means each generator now returns a list of collectibles, and not either one or nil.
      • There are four types of entries, for now:
        • "collectible"
          • Has one field, name.
          • Always evaluates to a single collectible.
        • "collectible_generator"
          • Has one field, which is also called name.
          • Evaluates to a given collectible generator result.
        • "repeat"
          • Has two fields: entry and count.
          • Evaluates an entry count times, and returns a list of all collectibles evaluated from each iteration.
        • "random_pick"
          • Has a single field: pool. It's a list of entries, which have an entry field and an optional weight field, which defaults to 1.
          • Evaluates all choices from the pool, and then picks one randomly.
            • Empty choices are ignored.
            • The choice weights can be modified by giving an appropriate weight value.
    • A new condition type has been added: cmp_latest_checkpoint.
      • Compares the current player's latest checkpoint value.
      • There are three optional fields for this condition: min, max and value.
      • If the value is greater than min, lower than max or not equal to the value, this condition does not pass.
      • If either of the fields is missing, the corresponding check is not performed.
      • Examples:
        • This condition will pass if the value is between 1 and 3, both inclusive:
          {
              "type": "cmp_latest_checkpoint",
              "min": 1,
              "max": 3
          }
          
        • This condition will pass if the latest checkpoint value is equal to 5:
          {
              "type": "cmp_latest_checkpoint",
              "value": 5
          }
          
  • config/gameplay.json changes:

    • The field sphereBehaviour.attractionSpeed has been split into attractionSpeedMult and attractionSpeedBase.
      • The old formula for the maximum magnetization speed was attractionSpeed * max(combo, 1).
      • The new formula is now attractionSpeedBase + attractionSpeedMult * max(combo, 1).
      • In order to retain current behavior, set attractionSpeedBase to 0 and rename attractionSpeed to attractionSpeedMult.
  • config.json changes:

    • The file now looks like this:
    {
    	"name": "Luxor",
    	"window_title": null,
    	"engine_version": "v0.40.0",
    	"native_resolution": {
    		"x": 800,
    		"y": 600
    	},
    	"rich_presence": {
    		"enabled": false
    	}
    }
    
    • Fields:
      • name (optional): The game name to be displayed in Rich Presence and in the game window.
      • window_title (optional): How the window should be named.
      • engine_version: Specifies the version a game is for. Not really used at the moment, but mandatory.
      • native_resolution: The native resolution of the game. Same as above.
      • rich_presence: An object which contains the following field:
        • enabled: Should be always true, unless you want the game to be a secret.
          • Loading a game with this flag set to false causes Rich Presence to disconnect.
  • Powerups, both internally and in runtime.json, are now stored simply by their names instead of an object with type, name and color fields.

  • Bonus scarabs, scorpions and large matches now use the, for now hardcoded, vanilla_coin.json collectible generator.

  • The level now waits for all collectibles to despawn before firing the level win callback.

Gameplay

  • The default coin drop rate has been changed to match the original Luxor game:
    # of spheres    Old   New
    3               0%    0%
    4               20%   0%
    5               40%   50%
    6               60%   75%
    7               80%   100%
    8 or more       100%  100%
    
    • You can still change it manually in modules/game.lua.

Boot Screen

  • You can now cancel edits to the settings.
  • The version label in the settings is now aligned correctly.
  • Fixed a few grammar errors in the outdated game message.

Converter

  • The Python conversion script should now work with Mac OS systems.
  • The convert.bat script will now show an appropriate message when the Python script fails, and will revert all changes if the user chooses to do so.
  • Converted levels should now land in the correct directory once again.

Bugfixes

  • Apparently none!

Beta 4.3.0

16 May 00:19
Compare
Choose a tag to compare

After a pretty long time period, it's finally here! Beta 4.3.0 adds a lot of interesting features and fixes some bugs.

As always, the full list of changes can be found here.

Changelog

Outline

  • Added Zuma sphere generation!
  • Added different parameters for each path in a single level!
  • Added Bezier speed transitions!
  • Added level order randomizers!
  • Added emergency save!
  • Added speed shot particles!
  • Fixed speed shot beam!
  • Changed crash screen!
  • Increased stability!

Additions

Game development

Level files

  • Zuma sphere generation!

    • A new field, named spawnRules has been added. It's an object with the following fields:
      • type - it can be either "waves" or "continuous". If set to "waves", sphere trains will spawn as usual. If set to "continuous", there will be only one sphere train per path which would continuously spawn spheres until the win condition is met, like in Zuma.
      • amount - Required only for "waves" type. Specifies the amount of spheres to be generated per wave.
    • The field spawnAmount has been removed.
  • Per-path level settings!

    • A new field, pathsBehavior, has been added.
    • It's a list of objects containing these fields: colors, colorStreak, spawnRules, spawnDistance, dangerDistance, dangerParticle, speeds.
    • The above fields have been also removed from the root object.
    • The pathsBehavior list can contain any number of these path behavior objects.
    • Each path is assigned the next path behavior on the list, and the list can wrap around.
      • This means you can have one path behavior table and it will be applied to all paths on a map.
  • Smooth speed interpolation!

    • In a speed node definition, a new optional field, transition, has been added.
    • It contains an object with a type field, which can be set to either "linear" or "bezier".
    • If set to "bezier", two more fields are required, point1 and point2. These fields define the control points for Bezier interpolation between speeds.
    • Interpolation between speeds is set in the first node, so it applies between that and the next node.
  • Additionally, the name field has been removed.

  • An example showcasing all the changes:

    -- "name": "1-1",
    -- "colors": [1, 2, 3, 4],
    -- "colorStreak": 0.45,
    -- "spawnAmount": 30,
    -- "spawnDistance": 0.6,
    -- "dangerDistance": 0.75,
    -- "speeds": [ ... ]
    
    ++ "pathsBehavior": [
    ++     {
    ++         "colors": [1, 2, 3, 4],
    ++         "colorStreak": 0.45,
    ++         "spawnRules": {
    ++             "type": "waves",
    ++             "amount": 30
    ++         },
    ++         "spawnDistance": 0.6,
    ++         "dangerDistance": 0.75,
    ++         "speeds": [
    ++             {
    ++                 "distance": 0,
    ++                 "speed": 800,
    ++                 "transition": {
    ++                     "type": "bezier",
    ++                     "point1": 0.9,
    ++                     "point2": 0.9
    ++                 }
    ++             },
    ++             ...
    ++         ]
    ++     },
    ++     ...
    ++ ]
    

Level sets

  • The levels folder has been moved to config/levels.
  • All levels now must have an ID which can be any integer number. It doesn't have to be continuous, too.
  • Levels inside the levels folder must match the pattern level_X.json, where X is the level ID.
  • The journey-level naming of levels has been scrapped. Once again, now levels are defined by only one number.
  • The config/level_set.json file has a new syntax. The root objects has three fields:
    • level_order is a list containing level entries. Levels will be played in this order. More about these later.
    • checkpoints is a list of integers, containing index numbers corresponding to level IDs in the level_order field.
    • startCheckpoints is, as before, a list of integers, which are the indices for the checkpoints list.
    • Example:
    {
        "level_order": [
            {
                "type": "level",
                "level": 101,
                "name": "1-1"
            },
            {
                "type": "level",
                "level": 102,
                "name": "1-2"
            },
            {
                "type": "level",
                "level": 103,
                "name": "1-3",
                "unlock_checkpoints_on_beat": [ 2 ]
            },
            ...
            {
                "type": "level",
                "level": 403,
                "name": "4-3"
            }
        ],
        "checkpoints": [
            1, 4, 7, 10
        ],
        "startCheckpoints": [
            1
        ]
    }
    
  • Level data, which stores things such as win/lose counts or level records, now is stored per level ID in each profile.
  • Level entries are objects which define what levels to load and play throughout the game. It consists of the following fields:
    • type: The entry type. Can have either of these values:
      • "level" - in this case, this entry is a single level, and the following fields must be set:
        • level: A level ID to be loaded.
        • name: A level name.
      • "randomizer" - in this case, this entry contains a group of levels, played in a random order. The following fields are required:
        • pool: A list of level IDs to be choosen from.
        • names: A list of level names. The level names will not be shuffled, and this list should have the same length as the count field.
        • count: Defines how many levels to be picked from the pool.
        • mode: How the levels will be randomized. There are three possible values:
          • "repeat" - Every next level is simply drawn at random from the list.
          • "no_repeat" - Same as above, but an entry is removed from the pool once it's been picked.
          • "order" - Chooses count entries from the pool, without changing their order.
          • Both "no_repeat" and "order" modes need the pool size to be greater or equal to the count.
      • The randomizer works dynamically, which means only the next level at the time is generated at maximum. The whole sequence is not known nor stored anywhere, so you can't peek it.
    • unlock_checkpoints_on_beat: Applies for both entry types and is optional. A list of checkpoint IDs to be unlocked after this level entry has been beaten.
    • An example of a randomizer entry, which shuffles levels 201 through 205:
    {
        "type": "randomizer",
        "pool": [201, 202, 203, 204, 205],
        "names": ["2-1", "2-2", "2-3", "2-4", "2-5"],
        "count": 5,
        "mode": "no_repeat"
    }
    

Changes

Game development

  • UI script changes:
    • Removed functions:
      • profileGetNextLevelN()
      • profileGetJourney()
      • profileGetJourneyLevelCount(n)
      • configGetLevelData(n)
      • configGetJourneyName(n)
      • configGetLevelPath(p)
    • Renamed functions:
      • configGetLevelData2(name) -> configGetLevelData(name)
      • configGetCheckpointData(n) -> configGetCheckpointID(n)
    • Added functions:
      • profileGetLevelName() - Returns the player's current level name.
      • profileGetLatestCheckpoint() - Returns the nearest passed checkpoint from current level number.
      • profileIsCheckpointUpcoming() - Returns true if the next level is going to have a checkpoint.
      • configGetLevelID(n) - Returns the n-th entry from level_order list in the level set.
      • configGetLevelName(n) - Returns the name of the n-th level entry in the level order. This does not work for randomizers!
      • configGetCheckpointLevel(n) - Returns the real level number the n-th checkpoint is pointing to, instead of the level order entry.

Gameplay

  • Changes to Speed Shot:
    • The speed shot beam animation is now always smooth. Previously the beam would rapidly appear or vanish most of the time.
    • New keys in config/gameplay.json:
      • shooter.speedShotBeamFadeTime: The speed shot beam fade time.
      • shooter.speedShotParticle: Speed shot particles! They can be defined there. This field is optional, and should contain a path to a particle packet when defined.

Technical

  • The engine is now once again based on the 11.3 version of LOVE2D.
    • This is because of very unstable nature of 11.4, with strange glitches and memory leaks being common due to an unpolished LuaJIT 2.1 included in that version.
    • This means that now, once again, the engine should be stable as much as it was before Beta 4.2.0.
  • Now when trying to load a JSON file which does exist, but it does not contain a valid JSON structure, a proper error will be shown.
  • Debug Screen rendering has been greatly optimized.
  • Crash screen changes:
    • Emergency Save is finally here!
    • Fixed a few grammar mistakes in the upper text.
    • Error info is now framed.
    • Only left mouse button will now work.
    • The buttons have been shrinked a bit.
    • Added text below the buttons, which displays a description for the hovered item, and emergency save status.

Bugfixes

  • Emergency Save now works properly! [#20]
  • The converter no longer produces sprite files pointing to nonexistent images. This, in turn, would create errors in the console.

Enjoy!

Beta 4.2.2

07 Mar 14:45
Compare
Choose a tag to compare

Time for another beta version, this time Beta 4.2.2, with another pack of features and bugfixes.

As always, the full list of changes can be found here.

Changelog

Additions

Game development

  • Added, changed and removed a few extra parameters to config/gameplay.json, in sphereBehaviour:
    • Added attractionAcceleration, which is an acceleration rate used during magnetizing two sphere groups together. It's optional.
    • The foulAcceleration field is now optional.
    • Added knockbackSpeedBase and knockbackSpeedMult, which replace collisionSpeed.
      • knockbackSpeedBase: Speed induced when a group of spheres crashes into another sphere group behind it. This and knockbackSpeedMult form a final value together using this expression: knockbackSpeedBase + max(1, chainLv) * knockbackSpeedMult.
      • The previous formula used was collisionSpeed * max(1, chainLv). This means, setting knockbackSpeedMult to collisionSpeed and knockbackSpeedBase to 0 will yield the same behavior as before.

Rich Presence

  • The OpenSMCE icon will now appear in Discord Rich Presence status!

Changes

Gameplay

  • When launching a game for the first time, the default sound and music volumes have been reduced from 100% to 25% in order to save any headphone users from blowing their ears up.

Boot screen

  • Changed the position of version label by just a few pixels, so it's now cent... Eh, why talking about that, no one would even notice...

Appearance

  • Slightly changed the banner:
    obraz
    • No, still nowhere to see it in action.

Bugfixes

  • Now the engine does not crash when pressing any key in the Boot Screen.
  • Crashing the engine deliberately in Boot Screen (who would even do that?!) would yield the same witty message each time. Every. Single. Time.

:)